インフラ

GithubActions + CodeBuildでCDKを自動デプロイする

cdk

こんにちは、ちゃりおです。

GithubActonsとCodeBuildでCDKを自動デプロイする方法についてです。

Contents

GibhuActions + CodeBuildにした理由

  • GithubActionsに設定するアクセスキーにAdmin権限を渡したくない
    • CDKデプロイでは、IAMの変更もあるので強い権限が必要
  • アプリケーションリポジトリにCDKを配置していて、cdk配下のフォルダに変更があったときだけCDKを自動デプロイしたかった
    • CodeBuild単体だとフォルダーに変更があったときだけをトリガーにできない
  • push以外をトリガーに設定したいときにCodeBuildだと少し面倒
    • PR時にcdk diff、push時にcdk deployなど分けたいとき

主な理由は、セキュリティの強化です。
GithubActions単体でCDKデプロイをしており強いIAM権限を、GithubActionsのアクセスキーに割り当てていました。
リポジトリのwrite権限があれば、AWSのAdmin権限を使用することが可能でした。

デメリットはCodeBuild、GithubActions2重の料金がかかることです。
しかし、アプリケーションに比べ変更頻度が少なく実行される機会も少ないと思うので料金増加は大きくないと思います。

CDK自動デプロイを設定する

サンプルコード

https://github.com/msato0731/cdk-deploy-githubactions-codebuild

GithubActions用IAMユーザー・アクセスキーの作成

GithubActionsからCodeBuildを実行するために必要なIAMユーザーを作成し、アクセスキーを作成します。

Actionsはaws-actions/aws-codebuild-run-buildを使用します。
IAMユーザーに割り当てる権限は、ActionのREADMEに書いてあるものを使います。

import * as iam from '@aws-cdk/aws-iam';
import * as cdk from '@aws-cdk/core';

export class IamUserStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    const accountId = cdk.Stack.of(this).account;
    const region = cdk.Stack.of(this).region;
    
    const codebuildRunPolicy = new iam.Policy(this, "codebuild-run", {
      policyName: "codebuild-run"
    })
    codebuildRunPolicy.addStatements(
      new iam.PolicyStatement({
        actions: ["codebuild:StartBuild", "codebuild:BatchGetBuilds"],
        effect: iam.Effect.ALLOW,
        resources: [`arn:aws:codebuild:${region}:${accountId}:project/*`]
      })
    )
    codebuildRunPolicy.addStatements(
      new iam.PolicyStatement({
        actions: ["logs:GetLogEvents"],
        effect: iam.Effect.ALLOW,
        resources: [
          `arn:aws:logs:${region}:${accountId}:log-group:/aws/codebuild/*:*`
        ]
      })
    )
    const user = new iam.User(this, "githubactions", {
      userName: "githubactions",
    })
    user.attachInlinePolicy(codebuildRunPolicy)
  }
}
$ cdk deploy IamUserStack

CDK実行したあとに、以下のコマンドでアクセスキーを作成します。

$ aws iam create-access-key --user-name githubactions

生成されたアクセスキーは、GithubActionsのシークレットに登録しておきます。

「cdk deploy」を実行するCodeBuildの設定

次にCodeBuildを用意します。

import * as cdk from '@aws-cdk/core';
import * as codebuild from '@aws-cdk/aws-codebuild';
import * as iam from '@aws-cdk/aws-iam';

export class CdkDeployCodeBuildStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const buildImage = codebuild.LinuxBuildImage.fromDockerRegistry(
      "public.ecr.aws/bitnami/node:14.17.6-prod"
    )
    const project = new codebuild.Project(this, "Project", {
      projectName: "cdk-deploy-sample",
      environment: {
        buildImage
      },
      buildSpec: codebuild.BuildSpec.fromObject({
        version: "0.2",
        phases: {
          install: {
            commands: [
              "npm ci" 
            ]
          },
          build: {
            commands: [
              'npx cdk deploy --require-approval never "*"'
            ]
          }
        }
      })
    })
    
    project.role?.addManagedPolicy(
      iam.ManagedPolicy.fromAwsManagedPolicyName("AdministratorAccess")
    )
  }
}

デプロイします。

$ cdk deploy CdkDeployCodeBuildStack

CodeBuildのトリガー用GithubActionsの設定

最後にGithubActionsの設定です。
「.github/workflows」に下記のファイルを配置します。

name: deploy-cdk

on:
  push:
  workflow_dispatch:
  
jobs:
  deploy-cdk:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-1

      - name: CDK Deploy
        uses: aws-actions/aws-codebuild-run-build@v1
        with:
          project-name: cdk-deploy-sample

pushされると、CodeBuildが実行されます。
ログをGithub上で確認できて便利ですね。

まとめ

CodeBuild + GithubActionsを使ってCDKのデプロイフローについてでした。
CodeBuildを使うことでAdmin権限をGithubに登録不要、GithubActionsを使うことでトリガーを柔軟に設定できました。

CodeBuild + GithubActions両方の料金がかかるというデメリットがありますが、要件に合えば試してみてください。

Amzonで「AWS」の本を見てみる

楽天で「AWS」の本をみてみる!!

cdk
「cdk diff」に必要なIAMポリシーこんにちは、ちゃりおです。 CI時に「cdk diff」を行いたいことがありました。 ローカルから実行するときは、「cdk deplo...
cdk
CDK「Export <アウトプット> cannot be deleted as it is in use by <スタック名>」こんにちは、ちゃりおです。 CDKの自動で追加されるクロススタック参照で以下のエラーがでました。 Export cannot be...
cdk
AWS CDKのADVANCED WORKSHOPやってみたこんにちは、ちゃりおです。 CDK Pipelineをざっくり試したいと思っていて、なにかいいチュートリアルないかと探していたら。「A...