こんにちは、ちゃりおです。
GithubActonsとCodeBuildでCDKを自動デプロイする方法についてです。
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両方の料金がかかるというデメリットがありますが、要件に合えば試してみてください。