著者の感想
CDK を使うときに最初に唱える呪文。ここに書かれている内容が必要になったことはないけど、大量の環境に bootstrap 唱えたいときとかは(CFn で Stack Sets 使う話とか)参考になりそう。
本文
AWS CDK アプリを AWS environment(AWS アカウントとリージョンの組み合わせ)にデプロイするとき、デプロイを実行するために AWS CDK が必要とするリソースをプロビジョニングすることが必要になる場合があります。これらのリソースには、ファイルを格納するための Amazon S3 バケットと、デプロイを実行するために必要なパーミッションを付与する IAM ロールが含まれます。これらの初期リソースをプロビジョニングするプロセスは、bootstrap と呼ばれています。
以下のいずれかに該当する場合、environment を bootstrap する必要があります。
- デプロイされる AWS CDK スタックが Assets を使用している。
- アプリで生成された AWS CloudFormation template が 50 キロバイトを超える。
必要なリソースは、bootstrap スタックと呼ばれる AWS CloudFormation スタックで定義されており、通常 CDKToolkit
という名前になっています。他の AWS CloudFormation スタックと同様に、デプロイされると AWS CloudFormation コンソールに表示されます。
environment は独立しているので、複数の environment(異なる AWS アカウントや同一アカウント内の異なるリージョン)にデプロイする場合は、それぞれの environment を別々に bootstrap する必要があります。
If you attempt to deploy an AWS CDK application that requires bootstrap resources into an environment that does not have them, you receive an error message telling you that you need to bootstrap the environment.
If you are using CDK Pipelines to deploy into another account's environment, and you receive a message like the following:
bootstrap リソースを必要とする AWS CDK アプリケーションを、bootstrap リソースがない environment にデプロイしようとすると、environment を bootstrap する必要があることを伝えるエラーメッセージが表示されます。
CDK Pipelines を使用して他のアカウントの environment にデプロイしているときに、次のようなメッセージが表示された場合、
Policy contains a statement with one or more invalid principals
このエラーメッセージは、適切な IAM ロールが他の environment に存在しないことを意味し、bootstrap が行われていないことが原因である可能性が高いです。
How to bootstrap
bootstrap とは、AWS CloudFormation の template を特定の AWS environment(アカウントとリージョン)に配備することです。bootstrap template は、bootstrap されたリソースのいくつかの側面をカスタマイズするパラメータを受け付けます(Customizing bootstrappingを参照)。したがって、2 つの方法のうちの 1 つで bootstrap を行うことができます。
- AWS CDK Toolkit の
cdk bootstrap
コマンドを使用します。これは最もシンプルな方法で、bootstrap する environment が数少ない場合に有効です。 - AWS CDK Toolkit が提供する template を、他の AWS CloudFormation デプロイツールを使ってデプロイする。これにより、AWS CloudFormation コンソールや AWS CLI だけでなく、AWS CloudFormation Stack Sets や AWS Control Tower を使用することができます。デプロイ前に template に小さな修正を加えることもできます。この方法はより柔軟で、大規模なデプロイメントに適しています。
environment を複数回 bootstrap することはエラーではありません。bootstrap する environment がすでに bootstrap されている場合、その bootstrap スタックは必要に応じてアップグレードされます。
Bootstrapping with the AWS CDK Toolkit
cdk bootstrap
コマンドは、1 つまたは複数の AWS environment を bootstrap するために使用します。このコマンドの基本形は、指定した 1 つ以上の AWS environment(この例では 2 つ)を bootstrap することです。
cdk bootstrap aws://ACCOUNT-NUMBER-1/REGION-1 aws://ACCOUNT-NUMBER-2/REGION-2 ...
次の例は、それぞれ 1 つ、2 つの environment の bootstrap を示しています。(どちらも同じ AWS アカウントを使用しています。) 2 番目の例で示されているように、environment を指定する際に aws://
というプレフィックスは任意です。
cdk bootstrap aws://123456789012/us-east-1
cdk bootstrap 123456789012/us-east-1 123456789012/us-west-1
cdk bootstrap
コマンドで少なくとも 1 つの environment を指定しない場合、AWS CDK Toolkit はカレントディレクトリにある AWS CDK アプリを合成し、アプリで参照されるすべての environment を bootstrap します。スタックが environment に依存しない(つまり、env
プロパティを持っていない)場合、CDK の environment(例えば、--profile
を使用して指定されたもの、またはそれ以外のデフォルトの AWS environment)は、スタックを environment 固有にするために適用され、その environment が次に bootstrap されます。
例えば、次のコマンドは prod
AWS プロファイルを使用して現在の AWS CDK アプリを合成し、その environment を bootstrap します。
cdk bootstrap --profile prod
Bootstrapping from the AWS CloudFormation template
AWS CDK の bootstrap は、AWS CloudFormation の template によって行われます。この template のコピーをファイル bootstrap-template.yaml
で取得するには、以下のコマンドを実行します。
cdk bootstrap --show-template > bootstrap-template.yaml
この template は、AWS CDK GitHub repositoryでも公開されています。
AWS CloudFormation template のお好みのデプロイメントメカニズムを使用して、この template をデプロイしてください。例えば、次のコマンドは、AWS CLI を使用して template をデプロイします。
aws cloudformation create-stack \
--stack-name CDKToolkit \
--template-body file://bootstrap-template.yaml
Bootstrapping template
前述の通り、AWS CDK v1 では Legacy と Modern の 2 つの bootstrap template をサポートしていました。CDK v2 は Modern template のみをサポートしています。参考までに、これら 2 つの template のハイレベルな違いを以下に示します。
Feature | Legacy (v1 only) | Modern (v1 and v2) |
---|---|---|
Cross-account deployments | Not allowed | Allowed |
AWS CloudFormation Permissions | 現在のユーザーの権限でデプロイする(AWS プロファイルや environment 変数などで決定される) | bootstrap スタックのプロビジョニング時に指定された権限を使用してデプロイする(例:--trust を使用する) |
Versioning | bootstrap スタックのバージョンは 1 つだけ | Bootstrap スタックはバージョン管理されており、将来のバージョンで新しいリソースが追加されたり、AWS CDK アプリが最小バージョンを要求したりすることができる |
Resources* | Amazon S3 bucket | - Amazon S3 bucket - AWS KMS key - IAM roles - Amazon ECR repository - SSM parameter for versioning |
Resource naming | Automatically generated | Deterministic |
Bucket encryption | Default key | Customer-managed key |
* 必要に応じて、bootstrap template にリソースを追加します。
Legacy template を使用して bootstrap された environment は、CDK v2 で使用するために再 bootstrap することで Modern template にアップグレードすることができます(そして、そうしなければなりません)。Legacy バケットを削除する前に、少なくとも一度は environment 内のすべての AWS CDK アプリケーションを再デプロイしてください。
Customizing bootstrapping
bootstrap リソースをカスタマイズする方法は 2 つあります。
-
cdk bootstrap
コマンドでコマンドラインパラメータを使用する。これにより、template のいくつかの側面を変更することができます。 - デフォルトの bootstrap template を変更し、それを自分でデプロイする。これにより、bootstrap リソースを無制限に制御することができます。
以下のコマンドラインオプションは、CDK Toolkit の cdk bootstrap
と一緒に使用すると、bootstrap template に一般的に必要とされる調整を提供します。
-
--bootstrap-bucket-name
は、Amazon S3 バケットの名前をオーバーライドします。CDK アプリの変更が必要な場合があります(Stack synthesizers を参照)。 -
--bootstrap-kms-key-id
は、S3 バケットを暗号化するために使用される AWS KMS キーをオーバーライドします。 -
--cloudformation-execution-policies
は、スタックのデプロイ時に AWS CloudFormation が想定するデプロイロールにアタッチされるべき、マネージドポリシーの ARN を指定します。少なくとも 1 つのポリシーが必要で、そうでない場合、AWS CloudFormation はパーミッションなしでデプロイを試み、デプロイは失敗します。
-
--qualifier
bootstrap スタック内のすべてのリソースの名前に追加される文字列です。qualifier を使用すると、同じ environment で 2 つの bootstrap スタックをプロビジョニングするときに、名前の衝突を避けることができます。デフォルトはhnb659fds
です(この値には意味がありません)。qualifier を変更するには、AWS CDK アプリを変更する必要があります(Stack synthesizers を参照) -
--tags
は、bootstrap スタックに 1 つ以上の AWS CloudFormation タグを追加します。 -
--trust
は、bootstrap される environment にデプロイすることができる AWS アカウントをリストアップします。他の environment にある CDK パイプラインがデプロイする environment を bootstrap するときに、このフラグを使用します。bootstrap を行うアカウントは常に信頼されます。 -
--trust-for-lookup
は、bootstrap されている environment からコンテキスト情報を検索することができる AWS アカウントをリストアップします。このフラグを使用すると、アカウントに直接スタックをデプロイする権限を与えずに、environment にデプロイされるスタックを合成する権限を与えることができます。trust で指定されたアカウントは、コンテキスト検索において常に信頼されます。 -
--termination-protection
は bootstrap スタックが削除されないようにします(AWS CloudFormation User Guide の Protecting a stack from being deleted を参照)。
Customizing the template
AWS CDK Toolkit のスイッチで提供できる以上のカスタマイズが必要な場合、bootstrap template を必要に応じて変更することができます。template は --show-template
フラグで取得できることを覚えておいてください。
export CDK_NEW_BOOTSTRAP=1
cdk bootstrap --show-template
変更する場合は、bootstrapping template contractを遵守する必要があります。
AWS CloudFormation template からの bootstrap で説明したように、または cdk bootstrap --template
を使用して、修正した template をデプロイしてください。
cdk bootstrap --template bootstrap-template.yaml
Stack synthesizers
AWS CDK アプリは、デプロイ可能なスタックを正常に合成するために、利用可能な bootstrap リソースについて知っておく必要があります。stack synthesizer は、スタックの template が合成される方法を制御する AWS CDK クラスで、bootstrap リソースの使用方法(例えば、bootstrap バケットに格納されているアセットを参照する方法)を含みます。
AWS CDK の組み込みスタック合成器は、DefaultStackSynthesizer
と呼ばれています。これは、クロスアカウントのデプロイメントと CDK Pipelines のデプロイメントのための機能を含んでいます。
synthesizer
プロパティを使用してスタックをインスタンス化するときに、スタック合成器を渡すことができます。
new MyStack(this, "MyStack", {
// stack properties
synthesizer: new DefaultStackSynthesizer({
// synthesizer properties
}),
});
synthesizer
property を指定しない場合、DefaultStackSynthesizer
が使用されます。
Customizing synthesis
bootstrap template に加えた変更に応じて、合成もカスタマイズする必要があるかもしれません。DefaultStackSynthesizer
は、以下に説明するプロパティを使用してカスタマイズすることができます。これらのプロパティーが必要なカスタマイズを提供しない場合、IStackSynthesizer
を実装するクラスとして synthesizer を書くことができる(おそらく DefaultStackSynthesizer
から派生する)。
Changing the qualifier
qualifier は、別々の bootstrap スタックのリソースを区別するために、bootstrap リソースの名前に追加されます。同じ environment(AWS アカウントとリージョン)で 2 つの異なるバージョンの bootstrap スタックをデプロイするには、スタックに異なる qualifier を付ける必要があります。この機能は、CDK 自体の自動テスト間の名前分離のために意図されています。AWS CloudFormation の実行ロールに与えられた IAM 権限を非常に正確にスコープダウンできない限り、1 つのアカウントで 2 つの異なる bootstrap スタックを持つことによる特権分離のメリットはないので、通常この値を変更する必要はありません。
qualifier を変更するには、プロパティで合成器をインスタンス化するか、DefaultStackSynthesizer
を構成する。
new MyStack(this, "MyStack", {
synthesizer: new DefaultStackSynthesizer({
qualifier: "MYQUALIFIER",
}),
});
または、qualifier を cdk.json
のコンテキストキーとして設定することでも対応可能です。
{
"app": "...",
"context": {
"@aws-cdk/core:bootstrapQualifier": "MYQUALIFIER"
}
}
Changing the resource names
他のすべての DefaultStackSynthesizer
プロパティは、bootstrap template 内のリソースの名前に関連しています。あなたが bootstrap template を修正し、リソース名または命名方式を変更した場合にのみ、これらのプロパティのいずれかを提供する必要があります。
全てのプロパティは、特別なプレースホルダー ${Qualifier}
, ${AWS::Partition}
, ${AWS::AccountId}
, 及び ${AWS::Region}
を受け付けます。これらのプレースホルダーは、それぞれ qualifier
パラメータの値、スタック environment の AWS パーティション、アカウント ID、リージョンの値で置き換えられます。
次の例では、シンセサイザーをインスタンス化するように、DefaultStackSynthesizer
で利用可能なすべてのプロパティをデフォルト値とともに示しています。
new DefaultStackSynthesizer({
// ファイルアセット用のS3バケット名
fileAssetsBucketName:
"cdk-${Qualifier}-assets-${AWS::AccountId}-${AWS::Region}",
bucketPrefix: "",
// Dockerイメージアセット用ECRリポジトリ名
imageAssetsRepositoryName:
"cdk-${Qualifier}-container-assets-${AWS::AccountId}-${AWS::Region}",
// CLIとPipelineがここでデプロイするために想定しているロールのARN
deployRoleArn:
"arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-${Qualifier}-deploy-role-${AWS::AccountId}-${AWS::Region}",
deployRoleExternalId: "",
// ファイルアセット公開に使用するロールのARN(deployロールから想定)
fileAssetPublishingRoleArn:
"arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-${Qualifier}-file-publishing-role-${AWS::AccountId}-${AWS::Region}",
fileAssetPublishingExternalId: "",
// Dockerアセットパブリッシングに使用されるロールのARN(deployロールから仮定)
imageAssetPublishingRoleArn:
"arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-${Qualifier}-image-publishing-role-${AWS::AccountId}-${AWS::Region}",
imageAssetPublishingExternalId: "",
// デプロイメントを実行するためにCloudFormationに渡されるロールのARN
cloudFormationExecutionRole:
"arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-${Qualifier}-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
// 起動スタックのバージョン番号を記述したSSMパラメータ名
bootstrapStackVersionSsmParameter: "/cdk-bootstrap/${Qualifier}/version",
// すべてのtemplateに、必要なbootstrapスタックのバージョンを確認するルールを追加します。
generateBootstrapVersionRule: true,
});
The bootstrapping template contract
bootstrap スタックの要件は、使用するスタックシンセサイザに依存します。もしあなたが独自のスタック合成器を書くなら、あなたは合成器が必要とする bootstrap リソースと、合成器がそれを見つける方法を完全に制御することができます。このセクションでは、DefaultStackSynthesizer
が bootstrap template に持つ期待について説明します。
Versioning
template には、よく知られた名前の SSM パラメータを作成するためのリソースと、template のバージョンを反映させるためのアウトプットが含まれている必要があります。
Resources:
CdkBootstrapVersion:
Type: AWS::SSM::Parameter
Properties:
Type: String
Name:
Fn::Sub: "/cdk-bootstrap/${Qualifier}/version"
Value: 4
Outputs:
BootstrapVersion:
Value:
Fn::GetAtt: [CdkBootstrapVersion, Value]
Roles
DefaultStackSynthesizer
は、5 つの目的のために 5 つの IAM ロールを必要とします。デフォルトのロールを使用しない場合、シンセサイザーは使用したいロールの ARN を伝える必要があります。ロールは以下の通りです。
- deployment ロールは、AWS CDK Toolkit と AWS CodePipeline が environment にデプロイするために想定しているロールです。その
AssumeRolePolicy
は、environment にデプロイできる人を制御します。このロールが必要とする権限は、template で見ることができます。 - lookup ロールは、AWS CDK Toolkit が environment 内のコンテキスト検索を実行するために想定されています。その
AssumeRolePolicy
は、誰が environment にデプロイできるかを制御します。このロールが必要とする権限は、template で見ることができます。 - file publishing ロールと画像公開ロールは、AWS CDK Toolkit と AWS CodeBuild プロジェクトが environment にアセットを公開するために想定しているもので、それぞれ S3 バケットと ECR リポジトリに書き込むためのものです。これらのロールは、これらのリソースへの書き込みアクセスを必要とします。
- AWS CloudFormation execution ロールは、AWS CloudFormation に渡され、実際のデプロイメントを実行します。そのパーミッションは、デプロイが実行されるパーミッションです。パーミッションは、管理されたポリシー ARN をリストアップするパラメータとしてスタックに渡されます。
Outputs
AWS CDK Toolkit では、起動用スタックに以下の CloudFormation 出力が存在することが必要です。
-
BucketName
: ファイルアセットバケットの名前 -
BucketDomainName
: ドメイン名形式のファイルアセットバケット -
BootstrapVersion
: bootstrap スタックの現在のバージョン
Template history
bootstrap template はバージョン管理され、AWS CDK 自体とともに進化していきます。もしあなたが独自の bootstrap template を提供する場合、あなたのがすべての CDK の機能で動作し続けることを確実にするために、標準のデフォルト template でそれを最新に保つ。このセクションには、各バージョンで行われた変更のリストが含まれています。
Template version AWS | CDK version | Changes |
---|---|---|
1 | 1.40.0 | Bucket、Key、Repository、Roles を含む template の初期バージョン |
2 | 1.45.0 | アセット公開ロールをファイル公開と画像公開のロールに分割 |
3 | 1.46.0 | FileAssetKeyArn のエクスポートを追加し、アセットコンシューマーに復号化権限を追加できるように |
4 | 1.61.0 | CdkBootstrapVersion SSM パラメータを追加し、スタック名を知らなくても bootstrap スタックのバージョンを確認できるように |
5 | 1.87.0 | デプロイメントロールは、SSM パラメータを読み取れるように |
6 | 1.108.0 | デプロイメントロールとは別に、ルックアップロールを追加 |
6 | 1.109.0 | aws-cdk:bootstrap-role タグをデプロイメント、ファイルパブリッシング、およびイメージパブリッシングロールにアタッチ |
7 | 1.110.0 | デプロイロールは、ターゲットアカウントの Bucket を直接読めなくなる(ただし、このロールは事実上管理者であり、AWS CloudFormation 権限を使えばいつでも Bucket を読める) |
8 | 1.114.0 | lookup ロールはターゲット environment に対する完全な読み取り専用権限を持ち、同様に aws-cdk:bootstrap-role タグも持つ |
9 | 2.1.0 | S3 アセットのアップロードが、一般的に参照される暗号化 SCP によって拒否されるのを修正 |