AWS CDK bootstrap とクロスアカウントデプロイ
この記事の目次
はじめに
AWS CDK(Cloud Development Kit)を使って、異なるAWSアカウント間(クロスアカウント)でリソースをデプロイする方法を解説します。
- 対象読者:AWSちょっとわかるレベル
- 所要時間:約60〜90分
- 実行環境:Windows PowerShell
このハンズオンで学べること
- CDKプロジェクトの初期化とスタック構成
cdk bootstrapの仕組みと役割- クロスアカウントデプロイに必要なIAM設定
--cloudformation-execution-policiesによる最小権限の実現cdk destroyを使ったリソースの後片付け
アカウント構成
本ハンズオンでは2つのAWSアカウントを使用します。

事前準備
必要なツール
- Node.js(v18以上推奨)
- AWS CDK CLI(
npm install -g aws-cdk) - AWS CLI v2
- PowerShell
AWSプロファイルの設定
本ハンズオンでは以下の2つのプロファイルを使用します。
| プロファイル名 | 対象アカウント | 用途 |
|---|---|---|
test-111111111111 | アカウントA(111111111111) | デプロイ先の操作 |
test-A | アカウントB(222222222222)のIAMユーザー | CDKデプロイの実行元 |
~/.aws/credentials および ~/.aws/config に各プロファイルを設定しておいてください。
Step 1:CDKプロジェクトの作成
プロジェクトディレクトリの作成
mkdir C:\github\cdk-crosscd C:\github\cdk-crossCDKアプリの初期化
cdk init app --language typescript実行すると以下のようなプロジェクト構成が生成されます。
cdk-cross/
├── bin/
│ └── cdk-cross.ts # エントリーポイント
├── lib/
│ └── cdk-cross-stack.ts # スタック定義
├── cdk.json # CDK設定ファイル
└── package.jsonNote:
git configの設定がない場合、Unable to initialize git repositoryという警告が出ますが、ハンズオンの進行には影響ありません。
Step 2:スタックの実装
エントリーポイントの編集
bin/cdk-cross.ts を以下のように編集します。デプロイ先のアカウントIDとリージョンを明示的に指定します。
import * as cdk from 'aws-cdk-lib';
import { CdkCrossStack } from '../lib/cdk-cross-stack';
const app = new cdk.App();
new CdkCrossStack(app, 'CdkCrossStack', {
env: {
account: "111111111111", <em>// デプロイ先アカウントA</em>
region: "ap-northeast-1"
}
});ポイント:クロスアカウントデプロイでは
envのaccountとregionを必ず明示する必要があります。省略すると CDK が環境を解決できずエラーになります。
スタック定義の編集
lib/cdk-cross-stack.ts を以下のように編集します。今回はシンプルなS3バケットを1つ作成します。
import * as cdk from 'aws-cdk-lib';
import { Bucket } from 'aws-cdk-lib/aws-s3';
export class CdkCrossStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
new Bucket(this, 'TestBucket', {
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true
});
}
}removalPolicy: DESTROY:cdk destroy実行時にバケットを削除する設定autoDeleteObjects: true:バケット内にオブジェクトが残っていても削除できるようにする設定(ハンズオン向けの設定です。本番環境では慎重に検討してください)
CloudFormationテンプレートの確認
実際にデプロイする前に、CDKが生成するCloudFormationテンプレートを確認しましょう。
cdk synthS3バケット・バケットポリシー・Lambda関数(autoDeleteObjects用)・IAMロールが出力されれば成功です。
Step 3:bootstrap(1回目)
bootstrapとは
CDKでデプロイを行うには、事前に対象アカウント・リージョンにCDKToolkitというCloudFormationスタックを作成する必要があります。これを cdk bootstrap と呼びます。
bootstrapのメリット
- デプロイの自動化:アセット(Lambda ZIPやDockerイメージ)のアップロード先(S3・ECR)が自動で用意されるため、手動でバケットやリポジトリを作成する必要がない
- IAMロールの一元管理:デプロイに必要なIAMロールがまとめて作成・管理されるため、個別にロールを設定する手間が省ける
- クロスアカウント対応:
--trustオプションで他アカウントからのデプロイを安全に許可できる - 権限の最小化:
--cloudformation-execution-policiesでCloudFormationが使う権限を絞り込める - 冪等性(何度実行しても同じ結果になる性質):すでにbootstrap済みの環境に再実行しても、差分のみUpdateとして適用されるため安全に再実行できる
bootstrapはアカウントとリージョンに紐づく
bootstrapは 「AWSアカウント × リージョン」の組み合わせごとに1回実行する必要があります。
- アカウントAの
ap-northeast-1にデプロイ →aws://111111111111/ap-northeast-1にbootstrap - アカウントAの
us-east-1にもデプロイしたい →aws://111111111111/us-east-1に別途bootstrap - アカウントBの
ap-northeast-1にもデプロイしたい →aws://222222222222/ap-northeast-1に別途bootstrap
同じアカウントでもリージョンが異なれば別のbootstrapが必要です。

bootstrapで作成されるリソース
bootstrapによって以下のリソースが作成されます。
- S3バケット(StagingBucket):デプロイ用アセットの保存場所
- ECRリポジトリ:Dockerイメージのアセット保存場所
- IAMロール群:CDKがデプロイ操作を行うための各種ロール
DeploymentActionRole:デプロイ操作を担うロールCloudFormationExecutionRole:CloudFormationがリソースを作成する際に使うロールFilePublishingRole/ImagePublishingRole:アセットをS3/ECRにアップロードするロールLookupRole:コンテキスト情報の参照に使うロール
組織のIAMポリシー制限がある場合
組織(AWS Organizations)のSCP(Service Control Policy)やセキュリティポリシーによって、各種リソースの作成が制限されている環境では、bootstrapをそのまま実行できないケースがあります。
その場合は以下のいずれかの対応を取ります。
- 既存のbootstrap済み環境を使う:組織の管理者がすでにCDKToolkitをセットアップしている場合は、そのまま利用する(追加のbootstrapは不要)
- 別途ロールを手動作成して利用する:セキュリティチームが承認した最小権限のIAMロールを事前に作成し、
--role-arnオプションでCDKに指定する
cdk deploy `
--role-arn arn:aws:iam::111111111111:role/MyCustomDeployRole `
--profile test-111111111111アカウントAにbootstrapを実行(1回目)
確認ポイント:デプロイ先アカウントにすでに
CDKToolkitという名前のCloudFormationスタックが存在する場合は、bootstrapは実行済みです。その場合は本Stepをスキップしてください。
まずはシンプルにアカウントAへbootstrapします。
cdk bootstrap aws://111111111111/ap-northeast-1 `
--profile test-111111111111成功すると ✅ Environment aws://111111111111/ap-northeast-1 bootstrapped. と表示されます。
Step 4:アカウントAへのデプロイ(同一アカウント)
まず、アカウントAのプロファイルで直接デプロイできることを確認します。
cdk deploy --profile test-111111111111IAMの変更内容が表示されるので確認し、y を入力します。
Do you wish to deploy these changes (y/n)? y✅ CdkCrossStack と表示されればデプロイ成功です。
Step 5:クロスアカウントデプロイの試行(失敗)
次に、アカウントB(test-A プロファイル)からデプロイを試みます。
cdk deploy --profile test-A以下のエラーが発生します。
Could not assume role in target account using current credentials
(which are for account 222222222222)
User: arn:aws:iam::222222222222:user/test1 is not authorized to perform:
sts:AssumeRole on resource:
arn:aws:iam::111111111111:role/cdk-hnb659fds-deploy-role-111111111111-ap-northeast-1Note:エラーメッセージ中の
cdk-hnb659fdsはCDK bootstrapが生成するデフォルトのqualifier(識別子)です。cdk bootstrap --qualifier <任意の値>で変更可能なため、組織の設定によっては異なる文字列になる場合があります。
本ハンズオンではデフォルト値(hnb659fds)を使用します。
なぜ失敗するのか
CDKのクロスアカウントデプロイでは、操作元アカウントBのユーザーが、デプロイ先アカウントAの DeploymentActionRole を AssumeRole(一時的に引き受ける) することでデプロイを行います。
しかし現時点では、
- アカウントAの
DeploymentActionRoleがアカウントBからのAssumeRoleを許可していない - アカウントBの
test1ユーザーがsts:AssumeRoleを実行する権限を持っていない
この2つを解決する必要があります。
Step 6:最小権限ポリシーの作成
--cloudformation-execution-policies とは
cdk bootstrap の --cloudformation-execution-policies オプションは、CloudFormationがリソースを作成・更新・削除する際に使用するIAMポリシーを指定するものです。
デフォルト(AdministratorAccess)の問題点
指定しない場合は AdministratorAccess(全権限)が使われます。これには以下のリスクがあります。
- CDKスタックのコードに誤りがあった場合、意図しないリソースを削除・変更してしまう可能性がある
- 最小権限の原則(Principle of Least Privilege)に反する
- 組織のセキュリティポリシーに違反するケースがある
最小権限ポリシーを使うべき理由
- CloudFormationが操作できるリソースをスタックで必要なものだけに限定できる
- 万が一のミスや不正アクセス時の被害範囲を最小化できる
- 組織のコンプライアンス要件を満たしやすくなる
今回のスタックで必要な権限は以下の3つです。
- S3:バケットの作成・削除・ポリシー設定
- IAM:Lambda実行ロールの作成・削除・ポリシーアタッチ
- Lambda:autoDeleteObjects用Lambda関数の作成・削除
ポリシーJSONの作成
@"
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:*"],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"iam:PassRole",
"iam:CreateRole",
"iam:DeleteRole",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": ["lambda:*"],
"Resource": "*"
}
]
}
"@ | Set-Content cdk-minimal-policy.jsonポリシーをアカウントAに作成
aws iam create-policy `
--policy-name CdkMinimalPolicy `
--policy-document file://cdk-minimal-policy.json `
--profile test-111111111111作成されたポリシーのARN(arn:aws:iam::111111111111:policy/CdkMinimalPolicy)を控えておきます。
Step 7:bootstrap(2回目)―クロスアカウント対応
なぜ2回bootstrapするのか
1回目のbootstrapは「CDKToolkitを作成する」ための最低限の実行でした。この時点では:
--trust未指定 → アカウントBからのAssumeRoleが許可されていない--cloudformation-execution-policies未指定 →AdministratorAccessが使われている
2回目のbootstrapでは、これらを正しく設定し直します。CDKToolkitスタックはUpdateとして適用されるため、既存リソースを削除せずに設定を変更できます。
Tips:最初からクロスアカウントデプロイを想定している場合は、1回目のbootstrapから
--trustと--cloudformation-execution-policiesを指定することで、2回に分ける必要はありません。
クロスアカウント対応のbootstrapを実行
cdk bootstrap aws://111111111111/ap-northeast-1 `
--profile test-111111111111 `
--trust 222222222222 `
--cloudformation-execution-policies arn:aws:iam::111111111111:policy/CdkMinimalPolicy各オプションの意味:
| オプション | 意味 |
|---|---|
--trust 222222222222 | アカウントB(222222222222)からのAssumeRoleを許可する |
--cloudformation-execution-policies | CloudFormationが使うIAMポリシーをAdministratorAccessから最小権限に変更する |
✅ Environment aws://111111111111/ap-northeast-1 bootstrapped. と表示されれば成功です。
補足:bootstrap再実行によって
CloudFormationExecutionRoleに紐づくポリシーがAdministratorAccessからCdkMinimalPolicyに切り替わります。
ただし、Step 4でデプロイ済みのCdkCrossStackに対して新ポリシーが適用されるのは、次回cdk deployを実行したタイミングです。
既存スタックのリソース自体はそのまま維持されます。
DeploymentActionRoleの信頼ポリシーを確認
bootstrap後、DeploymentActionRole の信頼ポリシーにアカウントBが追加されていることを確認します。
aws iam get-role `
--role-name cdk-hnb659fds-deploy-role-111111111111-ap-northeast-1 `
--query "Role.AssumeRolePolicyDocument" `
--profile test-111111111111 `
--no-cli-pagerレスポンスにアカウントB(arn:aws:iam::222222222222:root)の sts:AssumeRole が含まれていれば正しく設定されています。
Step 8:アカウントBのIAMユーザーにAssumeRole権限を付与
アカウントAのロールを引き受けられるようになりましたが、アカウントBの test1 ユーザー自身にも sts:AssumeRole の権限が必要です。
インラインポリシーのJSONを作成
@"
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111111111111:role/cdk-hnb659fds-deploy-role-111111111111-ap-northeast-1"
}
]
}
"@ | Set-Content assume-role.jsontest1ユーザーにポリシーをアタッチ
aws iam put-user-policy `
--user-name test1 `
--policy-name AllowAssumeCdkDeployRole `
--policy-document file://assume-role.json `
--profile test-AStep 9:AssumeRoleの動作確認
デプロイ前に、実際にAssumeRoleが成功するかを確認します。
aws sts assume-role `
--role-arn arn:aws:iam::111111111111:role/cdk-hnb659fds-deploy-role-111111111111-ap-northeast-1 `
--role-session-name test `
--profile test-A以下のように一時クレデンシャルが返れば成功です。
{
"Credentials": {
"AccessKeyId": "ASIAXXXXXXXXXXXXXXXX",
"SecretAccessKey": "****",
"SessionToken": "****",
"Expiration": "2026-03-24T19:05:06+00:00"
},
"AssumedRoleUser": {
"AssumedRoleId": "AROAXXXXXXXXXXXXXXXXX:test",
"Arn": "arn:aws:sts::111111111111:assumed-role/cdk-hnb659fds-deploy-role-111111111111-ap-northeast-1/test"
}
}Step 10:クロスアカウントデプロイの実行
再度アカウントBからアカウントAへのクロスアカウントデプロイを実行します。
cdk deploy --profile test-A✅ CdkCrossStack (no changes) と表示されれば成功です。(Step 4で既にデプロイ済みのため変更なしと表示されます)
Step 11:後片付け
[!WARNING]
この手順は 本ハンズオン用に作成した検証環境を前提としています。業務システムや他の CDK プロジェクトでも同一アカウント・リージョンで
CDK を利用している場合、以下の操作を実行すると
他のスタックやデプロイ処理に影響を与える可能性があります。
cdk destroyによるリソース削除- CDKToolkit スタック(bootstrap 環境)の削除
- IAM ユーザー/ポリシー/アクセスキーの削除
検証環境以外で実施する場合は、
削除対象が本ハンズオンで作成したものに限定されていることを
事前に十分確認したうえで実行してください。
スタックの削除
クロスアカウント操作の確認ができたら、作成したリソースを削除します。
cdk destroy --profile test-AAre you sure you want to delete: CdkCrossStack (y/n)? に y を入力します。✅ CdkCrossStack: destroyed と表示されれば削除完了です。
スタックが削除されたことを確認
aws cloudformation describe-stacks `
--stack-name CdkCrossStack `
--profile test-111111111111Stack with id CdkCrossStack does not exist というエラーが返れば正しく削除されています。
CDKToolkitスタックの削除
aws cloudformation delete-stack `
--stack-name CDKToolkit `
--profile test-111111111111test1ユーザーのインラインポリシーを削除
aws iam delete-user-policy `
--user-name test1 `
--policy-name AllowAssumeCdkDeployRole `
--profile test-Atest1ユーザーのアクセスキーを削除
まずキーIDを確認します。
aws iam list-access-keys --user-name test1 --profile test-A確認したキーIDを指定して削除します。
aws iam delete-access-key `
--user-name test1 `
--access-key-id AKIAXXXXXXXXXXXXXXXX `
--profile test-AAWSプロファイルの削除
エディタで test-111111111111 および test-A のセクションを削除して保存します。
削除後のプロファイル確認
aws configure list-profiles削除したプロファイルが表示されなければ完了です。
まとめ
cdk bootstrapはアカウントとリージョンの組み合わせごとに実行が必要- すでにbootstrap済みの環境では再実行不要。既存のCDKToolkitをそのまま利用する
- 組織のIAMポリシー制限がある場合は、別途ロールを手動作成して
--role-arnで指定する cdk bootstrap --trustでデプロイ先アカウントが操作元アカウントを信頼する設定を行う--cloudformation-execution-policiesで AdministratorAccess を避け最小権限を使う- 操作元アカウントのIAMユーザーにも
sts:AssumeRole権限が必要 bin/*.tsのenv.accountは必ず明示的に指定する
参考資料
AWS CDK ブートストラップ
AWS CDK で使用する環境をブートストラップする
※本記事は2026年05月時点の情報です。