はじめに
AWS-CDKを使ってTypescriptの型定義の恩恵を受けつつ手軽にAWSのリソースを作りたいけど、bootstrapでIAMロールやS3が自動的に作られて開発できない・・・っていう人向けです
Typescriptで書くと型推論でサクサクかけますし、TSdocも書かれていて定数も用意されているのでプロパティの設定値に迷いません
前提
- Node.jsがインストール済み
- AWS-CLIが使える環境であること
- AWS-CLIで使う認証情報において以下の権限が付与されていること(他にも必要かも+CDKでコンテナのビルドを行う際はECRのPush権限も必要)
- CloudformationのStackを作成・参照できる権限
- 既存のS3に対してオブジェクトのPutの権限がある
流れ
- bootstrapのテンプレートファイルを用意する
- bootstrapのテンプレートファイルをカスタマイズする
- bin/xx.tsでStackを作るところで、引数にCliCredentialsStackSynthesizerを渡す
bootstrapのテンプレートの用意
テンプレートの雛形の用意は以下のどちらか
- AWS-CDKのリポジトリからDL
- 以下のコマンド
> cdk bootstrap --show-template > bootstrap.yml
bootstrapをカスタマイズ
最低限必要なリソースは以下の通り
AWSTemplateFormatVersion: 2010-09-09
Description: This stack includes resources needed to deploy AWS CDK apps into this environment
Parameters:
Qualifier:
Type: String
AllowedPattern: '[A-Za-z0-9_-]{1,10}'
ConstraintDescription: Qualifier must be an alphanumeric identifier of at most 10 characters
# 以下2つのパラメーターは不要だが、"cdk bootstrap"コマンド時に失敗するために用意する。
# マネジメントコンソールからデプロイする場合消してもOK
FileAssetsBucketKmsKeyId:
Description: This parameter is unnecessary, but it is defined because it causes a validation error in the bootstrap command.
Default: 'UNUSED'
Type: String
PublicAccessBlockConfiguration:
Description: This parameter is unnecessary, but it is defined because it causes a validation error in the bootstrap command.
Default: 'true'
Type: 'String'
AllowedValues: ['true']
Resources:
# The SSM parameter is used in pipeline-deployed templates to verify the version of the bootstrap resources.
CdkBootstrapVersion:
Type: AWS::SSM::Parameter
Properties:
Type: String
Name: !Sub '/cdk-bootstrap/${Qualifier}/version'
Value: '13'
Outputs:
BucketName:
Description: This output is defined because it is needed by the Bootstrap command.
Value: "<一時的な置き場に使用する既存のバケット名>"
BucketDomainName:
Description: This output is defined because it is needed by the Bootstrap command.
Value: "<一時的な置き場に使用する既存のバケット名>.s3.amazonaws.com"
BootstrapVersion:
Description: The version of the bootstrap resources that are currently mastered
in this stack
Value: !GetAtt CdkBootstrapVersion.Value
Bootstrapを用意したテンプレートでデプロイ
以下のどちらかの方法でDeployする
- AWSマネジメントコンソールのCloudformationからデプロイ
- Stack名はcdk.jsonの"toolkitStackName"で指定されているもの(デフォルトはCDKToolkitというStack名)
- コマンドでデプロイ
- AWS-CLIでプロファイルを設定している場合は
--profile
オプションを付ける
- AWS-CLIでプロファイルを設定している場合は
> cdk bootstrap --template ./bootstrap.yml --qualifier <お好みの10文字>
実際にDeployする前に
Deploy時に一時的なファイル置き場となるS3の指定と認証情報が必要になるため、bin/xx.tsに定義しているStackにCliCredentialsStackSynthesizerを渡してAWS-CLIと同じ認証情報を使う
import * as cdk from 'aws-cdk-lib'
import { Stack } from '../lib/stack'
const app = new cdk.App()
const synthesizerProps = {
fileAssetsBucketName: "<一時的な置き場に使用する既存のバケット名>",
// s3://<fileAssetsBucketName>/<bucketPrefix>abcd1234.zip になるイメージ
bucketPrefix: "<S3に置かれるファイ名のプレフィックス>",
imageAssetsRepositoryName: "<ビルド後のイメージ保管に使用する既存のECRリポジトリ>",
dockerTagPrefix: "<bucketPrefixと同じようにイメージのタグ付けの際にプレフィックスを付与する>",
qualifier: "<BootstrapのStackに合わせてたほうが良いです>"
}
new Stack(app, "<スタック名>", {
synthesizer: new cdk.CliCredentialsStackSynthesizer(synthesizerProps),
env: { region: 'ap-northeast-1' }
})
注意事項
- CDKでCodeBuildやLambdaなどCloudwatchにログを送るリソースはIAMを勝手に作ろうとしたり、既存のRoleに権限を付与しようとする
- Roleプロパティがあるリソースは明示的に指定する
- 既存Roleを使う場合は以下のように明示的にmutableをfalseにする
import * as IAM from 'aws-cdk-lib/aws-iam' const lambdaRole = IAM.Role.fromRoleArn(this, 'LambdaRole', 'arn:aws:iam::xxxxxxxxx:role/LambdaRole', { mutable: false })
余談
-
実際にBootstrapで作成されるリソースは以下のページがわかりやすく解説してくれています
-
CliCredentialsStackSynthesizer を使うと以下のメリットがあります。(本来であればCDKで使うものはCDKで構築してアカウント・環境ごとに差分をなくすのが目的だと思いますが・・・)
- CodeBuildやEC2からも利用できる(適切なRoleをアタッチしていれば)
- CodeBuildとCodePipelineを組み合わせたときに、CodeBuildやCodePipelineとCDKで使う権限が違うといったトラブルが起きない(同一Roleを使ってる前提)
- AWS-CLIでプロファイルを指定して使う場合は以下のいずれかでプロファイルを指定する
- cdk.jsonで"profile"を指定する
- Deployコマンドのオプション引数
--profile
を指定する
- 明示的にECRリポジトリやS3のバケットを指定できる
-
ローカルではCDK使えないけど、CodeBuild上で使いたい!という場合も事前にマネジメントコンソールからBootstrapをデプロイすればOK
- Stack名はcdk.jsonの"toolkitStackName"で指定されているもの(デフォルトはCDKToolkitというStack名)
-
cdk synth
というコマンドを実行すると、cdk.out
にCFnテンプレートが吐き出されるのでこのJSONファイルをマネジメントコンソールからデプロイするのも可能(別途Lambdaなどのソースコードが詰まっているasset.xxxをS3に転送する必要がある)
-
CDKにはテストツールがあるが、CDKでできたCloudFormationテンプレート(JSON)のプロパティをテストするツールなので使いづらい
- Typescript上ではプロパティ名が
role
だがCloudformationテンプレートではRole
になる - 特定のリソースが作られないというテストが書きづらい
- Typescript上ではプロパティ名が