はじめに
こんにちは、KUDs です。
前回までで、S3 に Web サイトを公開し、GitHub でコードを管理できるようになりました。
今回は AWS CDK を使って、手で打っていた aws コマンドを「コード」として書き直します。
所要時間は45分ほど。
費用はこの記事の範囲で数円程度ですが、後述するように少しだけ消し残りが出ます。そこも正直に扱います。
先に言っておきます。
この回は、これまでで一番難易度が上がります。
Node.js という新しいものが必要になりますし、bootstrap という一度きりの準備作業もあります。
それでも取り上げるのは、ここから先の「開発らしい進め方」の入口になるからです。
この記事について
この記事は、AWS を初めて触る方向けのシリーズの1本です。
シリーズ全体の地図と読む順番は、ロードマップにまとめてあります。

前回の「GitHub と git・gh の初期設定」まで終わっていることを前提にしています。

CDK とは何か
AWS CDK(Cloud Development Kit)は、AWS のリソースをプログラミング言語で書くための道具です。
前回まで、こういうコマンドを打っていました。
aws s3 mb s3://バケット名
aws s3api put-public-access-block ...
aws s3api put-bucket-policy ...
aws s3 website s3://バケット名 ...
これを、こう書けるようにするのが CDK です。
const bucket = new s3.Bucket(this, 'PracticeSiteBucket', {
websiteIndexDocument: 'index.html',
publicReadAccess: true,
});
このようにインフラをコードとして書く考え方を、IaC(Infrastructure as Code) と呼びます。
何が嬉しいのか
1. 同じ環境をいつでも作り直せる
コマンドを手で打つと、何をやったかは記憶にしか残りません。
半年後に「あのとき何を設定したっけ」となります。コードなら残ります。
2. 変更前に差分が見える
cdk diff を実行すると、「いまの状態と比べて何が変わるか」を実行前に確認できます。
手作業では、実行してみるまで分かりません。
3. 後片付けが一発で終わる
前回の後片付けでは、バケット名を確認して、中身を消して、バケットを消して…と手順がありました。
CDK なら cdk destroy の1回で片付きます。しかも消し忘れが起きません。
正直に言うと、今回の規模では割に合いません
HTML 1枚のサイトを作るだけなら、コマンドを4回打つほうが速いです。
CDK のほうがコードは長くなりますし、準備も必要です。
CDK が効いてくるのは、リソースが増えてきたときと、同じものを何度も作るときです。
今回は「仕組みを理解するための練習」だと思ってください。
この回で増える負担
正直に書いておきます。3つあります。
1. Node.js が必要になります
CDK は Node.js の上で動きます。Python で書く場合でも Node.js は必要です。
とはいえ、Homebrew を入れてあるのでインストールは自動で済みます。
2. bootstrap という一度きりの準備があります
CDK を使うには、AWS アカウント側に作業用のリソースを用意する必要があります。
これが cdk bootstrap です。何が作られるかは後述します。
3. 少しだけ消し残りが出ます
bootstrap で作られたものは、そのまま残すのが公式の推奨です。
料金はほぼゼロですが、「すべて消す」という前回までの方針とは少し変わります。ここも後述します。
手順1: CDK を入れる
ターミナルで1行です。
brew install aws-cdk
Node.js も一緒に入ります。 別途インストールする必要はありません。
インストールできたか確認します。
cdk --version
補足: 公式の手順は npm です
AWS の公式ドキュメントが案内しているのは、次の方法です。
npm install -g aws-cdk
Homebrew の aws-cdk は AWS ではなく Homebrew 側で管理されているもので、AWS の公式手順には登場しません(中身は同じ npm パッケージを取得しています)。
このシリーズでは導入の手軽さを優先して Homebrew を使いますが、公式に沿いたい方や、うまくいかない場合は npm を使ってください(その場合は先に brew install node が必要です)。
バージョン番号に驚かないでください
cdk --version を実行すると、2.1136.0 のようなやたら大きい数字が出ます。
これは壊れているわけではありません。
2025年2月から、CDK のコマンド本体とライブラリは別々のバージョン番号になりました。
- コマンド(
aws-cdk) …2.1136.0のような番号 - ライブラリ(
aws-cdk-lib) …2.265.0のような番号
古い記事には「両方のバージョンを揃えましょう」と書かれていることがありますが、現在は揃いません。
公式も「CDK のコマンドは常に最新にして問題ない」としています。
使用状況の送信について
CDK のコマンドは、既定で使用状況のデータを AWS に送信します(バージョン 2.1100.0 以降)。
気になる方は、次のコマンドで停止できます。
cdk cli-telemetry --disable
手順2: プロジェクトを作る
ここからは、ステップ4で作った作業フォルダ ~/aws-claude-practice(ステップ8で GitHub リポジトリにしたもの)の中で進めます。
最終回まで、使うフォルダはこの1つだけです。途中で別の場所に作業フォルダを作ることはありません。
VS Code でこのフォルダを開いて、Claude Code にこう頼んでください。
このリポジトリの中に infra というフォルダを作って、
その中で AWS CDK の TypeScript プロジェクトを初期化してください。
Claude は、こういうことを実行します。
mkdir infra
cd infra
cdk init app --language typescript
なぜ infra というフォルダを作るのか
cdk init は、フォルダが空でないと失敗します。
作業フォルダには前回までのファイルが入っているので、そのままでは初期化できません。
かといってまったく別の場所に作ってしまうと、GitHub の管理から外れます。次回、そこで困ります。
そこで、リポジトリの中に空のサブフォルダを作り、その中で初期化するという形にしています。
インフラのコードを infra/ にまとめるのは、実際の開発でもよく使われる置き方です。
(.git のような隠しファイルは判定に数えられません。数えられるのは目に見えるファイルだけです)
何が作られたか確認する
初期化が終わると、infra の中にいくつかのファイルが生成されます。
以下のコマンドを入力すれば、それぞれ作成されたファイルやフォルダが確認できます。
ターミナル上で確認したい場合
ls -la ./infra
Finder で確認したい場合
open ./infra
VS Code で確認したい場合
code ./infra
編集されるのは infra/lib/ の中にある infra-stack.ts というファイルです。
言語は TypeScript を選んでいます。AWS は「初心者はこちら」とは明言していませんが、CDK 自体が TypeScript で作られており、公式のサンプルコードもほとんどが TypeScript です。情報量の面で有利です。
cdk と npm run cdk の違い
cdk init を実行すると、infra の中にも CDK が入ります。
そのため、同じ操作に2つの書き方が存在します。
| 書き方 | 何が動くか |
|---|---|
cdk deploy | 手順1で入れたもの(パソコン全体で共通) |
npm run cdk -- deploy | infra の中に入っているもの |
この記事では、短い cdk deploy のほうで統一します。
ただし、Claude Code に頼むと npm run cdk -- deploy を提案してくることがあります。
これは間違いではなく、プロジェクトに用意された方法を優先する、むしろ丁寧な判断です。そのまま承認して構いません。
-- は「ここから先は npm ではなく cdk への指示です」という区切りです。
どちらでも結果は同じなので、書き方の違いに戸惑わないでください。
以降のコマンドは、すべて infra フォルダの中で実行します。
手順3: bootstrap する
CDK を使う前に、AWS アカウント側に作業用の置き場を用意します。
これはアカウントとリージョンごとに一度だけ必要な作業です。
先に、IAM の権限を1つ足しておいてください
ただ、この作業を実施する前に、実行するユーザーに以下のインラインポリシーを追加しておいてください。
( IAM ユーザー my-dev-user に付与されている PowerUserAccess は IAM 権限を持たないため、このままでは cdk bootstrap に失敗します。理由は後述)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CdkBootstrapIamRoles",
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:GetRole",
"iam:DeleteRole",
"iam:TagRole",
"iam:UntagRole",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy",
"iam:PutRolePolicy",
"iam:GetRolePolicy",
"iam:DeleteRolePolicy",
"iam:ListRolePolicies",
"iam:ListAttachedRolePolicies",
"iam:PassRole"
],
"Resource": "arn:aws:iam::*:role/cdk-*"
}
]
}
この追加作業だけは、ルートユーザーでログインして行ってください。
my-dev-user は自分自身に権限を足すことができません(それができてしまったら、権限を分けている意味がなくなるためです)。
IAM →「ユーザー」→ my-dev-user →「許可を追加」→「インラインポリシーを作成」→ JSON で貼り付け、という流れです。
Resource を arn:aws:iam::*:role/cdk-* に絞っている点に注目してください。
これで、CDK が作るロール以外には手を出せません。「IAM 権限が要る」と言われたときに IAMFullAccess を付けてしまうのは、いちばんやってはいけない対処です。
インラインポリシーの追加が完了したら、いよいよブートストラップ実行です。
cdk bootstrap
(infra フォルダの中で実行すれば、アカウントとリージョンは自動で判別されます)
何が作られるのか
正直に列挙します。CDKToolkit という名前のスタックができ、その中に次のものが作られます。
| リソース | 用途 |
|---|---|
| S3 バケット | デプロイするファイルの一時置き場 |
| ECR リポジトリ | Docker イメージの置き場(今回は使いません) |
| IAM ロール 5つ | CDK が代わりに作業するための権限 |
| SSM パラメータ | bootstrap のバージョン記録 |
「思ったより多い」と感じたと思います。私もそう思います。
ただ、これらは CDK が動くために必要なもので、一度作れば以降は使い回されます。
さきほどの IAM 権限が必要だったのは、この「IAM ロール 5つ」を作るためです。
PowerUserAccess は「IAM 以外はほぼ何でもできる」権限なので、ここだけがぴったり足りませんでした。
注意点をひとつ。 既定では、CDK が使うロールに管理者権限が付きます。
学習用のアカウントなら問題ありませんが、業務で使うアカウントでは権限を絞る設定を検討してください。
料金について
アイドル状態ならほぼゼロです。
- S3 バケット … バケットが存在するだけの料金はありません。中に入れたファイルの容量分だけ
- ECR リポジトリ … 空なら 0
- IAM ロール・SSM パラメータ … 無料
公式ドキュメントの表現は「these resources are used with the AWS CDK(これらのリソースが CDK で使われるとき)料金が発生しうる」というものです。
今回の規模なら、置かれるファイルは数KBなので、実質的に無視できる金額です。
手順4: Claude Code にコードを書いてもらう
ここが、このシリーズでいちばん「積み上げてきたもの」が効く場面です。
ここまでで、Homebrew も AWS CLI も Claude Code も安全設定も揃っています。
なので、TypeScript を自分で書く必要はありません。 Claude に頼みます。
VS Code の Claude Code パネルで、こう指示してください。
infra の CDK で、静的ウェブサイト用の S3 バケットを作ってください。
- 公開するファイルはリポジトリ直下の site/ フォルダに置き、
その中身がバケットにアップロードされるようにしてください
- 簡単な自己紹介ページを site/index.html として作ってください
- cdk destroy でバケットの中身ごと消えるようにしてください
- 公開 URL を出力してください
Claude は、infra/lib/infra-stack.ts を書き換え、site/index.html を作ります。
【重要】承認する前に、差分を読んでください
ここは飛ばさないでください。 この記事でいちばん大事なところです。
Claude Code は、ファイルを書き換える前に差分(どこがどう変わるか)を見せて、承認を求めます。
ステップ6で defaultMode を default にしたのは、まさにこのためです。
読むポイントは3つだけです。
1. 公開の設定が2つ揃っているか
publicReadAccess: true,
blockPublicAccess: {
blockPublicAcls: false,
blockPublicPolicy: false,
ignorePublicAcls: false,
restrictPublicBuckets: false,
},
publicReadAccess: true だけでは動きません。
CDK の公式リポジトリの説明には、こう書かれています。
Note that to enable
publicReadAccess, make sure both bucket-level and account-level block public access control is disabled.(
publicReadAccessを有効にするには、バケットレベルとアカウントレベルの両方でブロックパブリックアクセスを無効にしておく必要があります)
古い記事のサンプルコードには、この指定がないものが多くあります(AWS 自身のドキュメントにも、この指定が抜けた例が残っています)。
Claude が古い書き方をしてきたら、エラーになる前にあなたが気づけるというわけです。
なお、シリーズのステップ2で確認したアカウントレベルのブロックパブリックアクセスも、オフになっている必要があります。
これは CDK からは変更できないので、マネジメントコンソールで確認してください。
2. 後片付けの2行があるか
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
この2行が、このシリーズ的にはいちばん大事です。
CDK は既定で、データが入りうるリソースを削除しません。
cdk destroy してもバケットが残り、しかも残ったままだと次のデプロイも失敗します(名前が衝突するため)。
removalPolicy: DESTROY… 削除対象にするautoDeleteObjects: true… 中身が入っていても削除できるようにする
両方必要です。 片方だけだと、バケットが空でない限り削除に失敗します。
3. アップロードの設定があるか
site/ の中身をバケットに入れるために、BucketDeployment というものが追加されているはずです。
new s3deploy.BucketDeployment(this, 'DeploySite', {
sources: [s3deploy.Source.asset('../site')],
destinationBucket: bucket,
});
これを使うと、Lambda 関数・IAM ロール・ログ出力先が自動で追加されます。
「S3 バケット1個のはずが、なぜか色々増えた」と驚かないでください。アップロードを代行する仕組みが必要だからです。
書かれたコードが読めなくても大丈夫です
全部を理解する必要はありません。
大事なのは、「公開する」「消せるようにする」「中身を置く」の3つが入っているかを確認できることです。
文法を覚えるより、何が作られようとしているかを読むほうが、実務ではずっと役に立ちます。
手順5: 差分を確認してデプロイする
いきなりデプロイせず、まず何が作られるかを確認します。
cdk diff
[+] が追加、[-] が削除、[~] が変更です。
この確認ができるのが、手作業に対する CDK の大きな利点です。
さきほど Claude の差分を読みましたが、あれは「コードがどう変わるか」でした。
cdk diff が見せるのは「AWS に何が作られるか」です。確認が二重になっていることに気づいてください。
問題なければデプロイします。
cdk deploy
途中で確認を求められます
公開バケットを作るため、途中で「権限が広がる変更です」という確認が入ります。
これは CDK の安全機能で、セキュリティに関わる変更のときだけ表示されます。
内容を読んで、問題なければ y を入力してください。
完了すると、最後に Outputs として URL(InfraStack.WebsiteUrl のような名前)が表示されます。
その URL をブラウザで開いてください。
Claude が作った自己紹介ページが表示されます。
ここまで、TypeScript は1行も自分で書いていません。
手順6: GitHub に保存する
最後に、いまの状態を GitHub に保存します。
次回はこのコードを使うので、この手順は飛ばさないでください。
これも Claude Code に頼めます。
ここまでの変更をコミットして、GitHub に push してください。
node_modules や cdk.out のような巨大で自動生成されるフォルダは、.gitignore で除外されているはずです。
cdk init が .gitignore を用意してくれているので、通常はそのままで問題ありません。
念のため、git status に node_modules が出ていないかだけ確認してください。
【必須】後片付け
infra フォルダの中で、次を実行します。
cdk destroy
これだけです。
前回は「バケット名を確認して、中身を消して、バケットを消す」という手順でしたが、
コードに書いたものが全部まとめて消えます。 autoDeleteObjects を書いたので、中の index.html も一緒に消えます。
アップロードのために自動で増えた Lambda 関数・IAM ロール・ログ出力先も、まとめて消えます。
「勝手に増えたものを消し忘れる」という、手作業でいちばん起きやすい事故が起きません。
これが CDK のいちばん分かりやすい利点だと思います。
念のため確認しておきましょう。
aws s3 ls
なお、次回はこのバケットをもう一度使います。
いま消しても、cdk deploy を1回打てば戻ってきます。それを実感してもらうのが次回の入り口です。
bootstrap で作ったものはどうするか
結論から言うと、残しておいて構いません。
理由は2つあります。
1. 料金がほぼ発生しないから(前述のとおり)
2. AWS 自身が「消して作り直すな」と言っているから
After your environment is bootstrapped, do not delete and recreate the environment’s bootstrap stack.
(環境を bootstrap したあとは、bootstrap スタックを削除して作り直さないでください)
また CDK を使うときに再利用されるので、そのままにしておくのが素直です。
それでも完全に消したい方へ
「学習用に作ったものは1つ残らず消したい」という方向けに、手順を書いておきます。
ただし、これは AWS が公式に手順として案内しているものではありません。 私が調べた範囲での手順なので、実行する際はご自身で確認しながら進めてください。
- まず
cdk destroyで自分のスタックを消す - bootstrap で作られた S3 バケット(
cdk-hnb659fds-assets-アカウントID-リージョン)を中身ごと手動で削除する - マネジメントコンソールで
CDKToolkitスタックを削除する
手順2が必要な理由は、この S3 バケットに「スタックを消しても残す」設定が入っているためです。
スタックだけ消すと、バケットだけが取り残されます。
なお、このバケットはバージョニングが有効になっているため、削除には過去のバージョンも消す必要があります。
Claude Code に「このバケットをバージョンごと完全に削除して」と頼むのが早いと思います。
古い情報に注意
CDK は変化が速く、日本語の記事はかなり古くなっています。調べていて気づいた点を挙げます。
| よく見る記述 | 2026年8月時点の実際 |
|---|---|
publicReadAccess: true だけで公開バケットが作れる | blockPublicAccess の明示が必須。書かないとエラー |
| CDK のコマンドとライブラリのバージョンを揃える | 2025年2月から別体系。揃わないのが正常 |
| Node.js 16 / 18 で動く | どちらもサポート終了。22 以上を推奨 |
| bootstrap で KMS キーが作られる(課金される) | 現在は既定で作られない |
うまくいかないときは
Q. cdk: command not found と出ます
A. ターミナルを開き直してください。それでも駄目なら brew install aws-cdk が成功しているか確認してください。
Q. cdk init が失敗します
A. フォルダが空でないと失敗します。 作業フォルダの直下ではなく、その中に作った空の infra フォルダで実行してください。
なお、判定されるのは目に見えるファイルだけなので、.git しか入っていないフォルダなら実行できます。
Q. --app is required... というエラーが出ます
A. プロジェクトのフォルダにいない可能性が高いです。cdk.json があるフォルダで実行してください。
Q. SSM parameter /cdk-bootstrap/... not found と出ます
A. bootstrap がまだです。cdk bootstrap を実行してください。
Q. publicReadAccess のところでエラーになります
A. blockPublicAccess の指定が抜けています。本文のコードをそのまま使ってください。
Q. cdk destroy してもバケットが残ります
A. removalPolicy と autoDeleteObjects の指定が抜けている可能性があります。残ってしまった場合は、マネジメントコンソールから手動で削除してください。
Q. bootstrap が iam:GetRole などの権限エラーで失敗します
A. PowerUserAccess には IAM の権限が含まれていません。 手順3のインラインポリシーを追加してください(追加はルートユーザーで行います)。
Q. インラインポリシーを足したのに、まだ失敗します
A. 失敗した CDKToolkit スタックが残っていると、やり直しても失敗し続けます。 マネジメントコンソールの CloudFormation から CDKToolkit を削除してから、もう一度 cdk bootstrap を実行してください。
Windows をお使いの方へ
- Node.js を入れてから
npm install -g aws-cdkで導入してください - winget が使える場合は
winget install --id OpenJS.NodeJS.LTSで Node.js が入ります cdkコマンド以降の手順は Mac と同じです- フォルダの区切りが
\になる以外、infraフォルダを作る流れも同じです
よくある質問
Q. CDK 自体に料金はかかりますか?
A. かかりません。AWS の FAQ に「There is no additional charge for AWS CDK(追加料金はありません)」と明記されています。料金がかかるのは、CDK で作ったリソースに対してです。
Q. TypeScript が書けないと使えませんか?
A. Python など他の言語も使えます。ただしどの言語を選んでも Node.js は必要です。また、サンプルコードの量では TypeScript が有利です。
Q. CloudFormation とは違うのですか?
A. CDK は、書いたコードを CloudFormation のテンプレートに変換して実行しています。cdk synth を実行すると、変換後のテンプレートが見られます。
Q. 前回まで手で打っていたコマンドは無駄だったのでしょうか?
A. まったく無駄ではありません。何が起きているか分かっているからこそ、CDK のコードが読めます。 いきなり CDK から入ると「動いたけど何をしているのか分からない」状態になりがちです。
Q. Claude Code に全部書いてもらってもいいですか?
A. むしろ、そうするための準備をここまでしてきました。 ただし、差分と cdk diff の結果は自分で読んでください。何が作られるかを確認せずにデプロイするのは、手作業のときより危険です。
Q. npm run cdk -- deploy と cdk deploy はどちらが正しいですか?
A. どちらも正しく、結果は同じです。 前者は infra の中に入っている CDK、後者は Homebrew で入れた CDK を使います。
動作がおかしいと感じたら、cdk --version と npm run cdk -- --version を見比べてみてください。
さいごに
AWS CDK を使って、手で打っていたコマンドをコードとして書き直すところまでを解説しました。
やったことをまとめます。
brew install aws-cdkで CDK を入れる- リポジトリの中の
infraフォルダでcdk initする - ルートユーザーで IAM のインラインポリシーを足してから
cdk bootstrapする(一度きり) - Claude Code にコードを書いてもらい、差分を自分で読む(
blockPublicAccessと後片付けの2行) cdk diffで確認してからcdk deploy- GitHub に push してから、
cdk destroyで片付ける
「同じものをもう一度作れる」状態になりました。
コードが残っているので、削除したあとでも cdk deploy すれば同じ環境が戻ってきます。
手作業ではこうはいきません。
次回はシリーズの最終回です。
GitHub に保存したら、自動で AWS に反映される仕組みを作ります。
しかも、長期のアクセスキーを一切使わない方法で構成します。

シリーズの全体像は、ロードマップから確認できます。

KUDs のサービス
KUDs では、実際に AWS 上で動く Web サービスを公開しています。


ご質問やご指摘は contact@kuds.jp までお寄せください。
「ここで詰まった」という報告は、記事を良くするうえでいちばんありがたいフィードバックです。

コメント