はじめに
「CloudFormation の YAML 460行をもっとシンプルに書けないか」——それを実現するのが AWS CDK(Cloud Development Kit) です。
この記事では、CloudFormation版ハンズオンで構築した ALB + EC2(Tomcat) + RDS の3層構成を、AWS CDK(Python) で再現します。YAML を Python コードで書き直すことで、460行 → 約200行に削減できることを体験します。
インターネット
↓ HTTP(80)
[ALB: my-cdk-alb-alb] ← インターネット向け / パブリックサブネット 2AZ
↓ HTTP(8080) ← ALB SG → EC2 SG(SG-to-SG 制御)
[EC2: my-cdk-alb-ap-instance] ← Tomcat / パブリックサブネット AZ-a
↓ MySQL(3306) ← EC2 SG → RDS SG(SG-to-SG 制御)
[RDS: my-cdk-alb-rds-mysql] ← MySQL 8.0 / プライベートサブネット AZ-a
[VPC: my-cdk-alb-vpc (10.0.0.0/16)]
├── パブリックサブネット (10.0.0.0/24) [AZ-a] ← ALB + EC2
├── パブリックサブネット (10.0.1.0/24) [AZ-b] ← ALB(2AZ 必須)
├── プライベートサブネット (10.0.2.0/24) [AZ-a] ← RDS 配置
└── プライベートサブネット (10.0.3.0/24) [AZ-b] ← DBサブネットグループ用このハンズオンで体験できること:
- Python コードで AWS インフラを定義する CDK の世界観を理解
ec2.Vpc1つでVPC・IGW・ルートテーブルを自動生成する L2 Construct の威力を体験cdk synthで CloudFormation テンプレートを生成・確認cdk diffでデプロイ前の差分確認(CloudFormation の変更セット相当)cdk deploy/cdk destroyでワンコマンドデプロイ・削除
このハンズオンの特徴:
- CloudFormation 版で460行必要だった YAML が Python コード約200行で記述できる
cdk destroy1本でALB・RDS・IAMなど全リソースを自動削除- コードの変更差分を
cdk diffで即確認できる(CloudFormation の変更セットより簡単)
この記事は CloudFormation版ハンズオン の発展記事です。
同じ構成を CDK で再現し、IaC の進化を体験したい方向けです。CDK のコード詳細は GitHub を参照してください。
-->
キーワード解説
| 用語 | 意味 |
|---|---|
| AWS CDK | Python・TypeScript などのプログラミング言語で AWS インフラを定義する IaC フレームワーク |
| CDK App | app.py がエントリポイント。cdk synth でここから CloudFormation テンプレートを生成 |
| CDK Stack | 1つの CloudFormation スタックに対応する単位。今回は CdkAlbEc2RdsStack |
| L2 Construct | AWS がベストプラクティスを組み込んだ高レベルな抽象クラス(ec2.Vpc 等)。内部で複数の AWS リソースを自動生成 |
| CDK Context | cdk.json に書くデプロイ設定。-c key=value で上書き可能 |
| CDK Bootstrap | CDK が AWS にデプロイするために必要な事前準備(S3 バケット等を作成)。同じアカウント・リージョンで初回のみ |
| cdk synth | Python コードから CloudFormation テンプレートを生成(デプロイなし) |
| cdk diff | 現在のデプロイ状態と新しいコードの差分を表示 |
| cdk deploy | CloudFormation スタックをデプロイ |
| cdk destroy | CloudFormation スタックとその全リソースを削除 |
CloudFormation vs CDK:どれだけ違うか
| 比較項目 | CloudFormation(alb-ec2-rds) | CDK(このハンズオン) |
|---|---|---|
| 記述言語 | YAML(宣言型) | Python(プログラミング言語) |
| コード量 | 約460行 | 約200行 |
| VPC 定義 | 15+ リソースを手動定義 | ec2.Vpc 1つで IGW・ルートテーブル等を自動生成 |
| SG-to-SG 制御 | SourceSecurityGroupId: !GetAtt で参照 | add_ingress_rule(alb_sg, ...) で直感的に記述 |
| ALB + TG + リスナー | 3リソースを別々に定義 | add_listener → add_targets でメソッドチェーン |
| 変数・ループ | !Sub / !If でのみ表現 | Python の変数・f-string・for文が使える |
| デプロイコマンド | aws cloudformation deploy ... | cdk deploy |
| 削除コマンド | aws cloudformation delete-stack ... | cdk destroy |
| 差分確認 | 変更セット(手動作成) | cdk diff(自動) |
使用するAWSサービス
| サービス | 役割 | 料金 |
|---|---|---|
| VPC | カスタムネットワーク空間 | 無料 |
| EC2(t2.micro) | APサーバ(Tomcat) | 月750時間まで無料枠あり |
| RDS MySQL(db.t3.micro) | マネージドDBサーバ | 月750時間まで無料枠あり |
| ALB | ロードバランサー | 約$0.008/時間 + LCU料金(無料枠なし) |
| SSM Parameter Store | DBパスワードの安全な保管 | スタンダード層は無料 |
| IAM | EC2にSSM・Parameter Store権限を付与 | 無料 |
注意: ALBは無料枠がありません。ハンズオン後は必ず
cdk destroyで削除してください。
前提条件
| ツール | 確認コマンド |
|---|---|
| AWS CLI v2 | aws --version |
| Python 3.9 以上 | python --version |
| Node.js 18 以上 | node --version |
| CDK CLI | cdk --version |
AWS 認証確認:
aws sts get-caller-identityNode.js と CDK CLI のインストール手順は docs/setup/09_nodejs-cdk.md を参照してください。
構築されるリソース
CDK が cdk deploy 時に自動生成するリソース一覧です。
| カテゴリ | リソース |
|---|---|
| ネットワーク | VPC / IGW / パブリックサブネット×2 / プライベートサブネット×2 / ルートテーブル×2 |
| セキュリティ | ALB SG / EC2 SG / RDS SG |
| IAM | EC2ロール / インスタンスプロファイル |
| パラメータ | SSM Parameter Store(DBパスワード) |
| データベース | RDS DBサブネットグループ / RDS MySQL 8.0 |
| ロードバランサー | ターゲットグループ / ALB / リスナー |
| コンピュート | EC2インスタンス(Tomcat) |
CloudFormation 版では約27リソースを YAML に個別定義しましたが、CDK では
ec2.Vpc1つがVPC・IGW・ルートテーブル等を自動生成するため、Python コードとして書くのは主要リソースのみです。
作業順序
⓪ 自分のIPアドレスを確認する
↓
① キーペアを作成する(AWS CLI で実施)
↓
② プロジェクトのセットアップ(Python 仮想環境)
↓
③ cdk.json を設定する
↓
④ CDK Bootstrap(初回のみ)
↓
⑤ CDK Synth(テンプレート確認)
↓
⑥ デプロイ(cdk deploy)
↓
⑦ 動作確認(ALBアクセス・SSH・RDS接続)
↓
⑧ CDK diff(参考)
↓
⑨ リソース削除(cdk destroy)【重要】⓪ 自分のIPアドレスを確認する
curl https://checkip.amazonaws.com控えておく情報: 自分のIPアドレス(例: 203.0.113.1)
セキュリティグループで
203.0.113.1/32の形式(末尾に/32)で使用します。
① キーペアの作成
CDK では cdk deploy 時にキーペアのダウンロードができないため、事前に AWS CLI で作成します。
%USERPROFILE%\.ssh\が存在しない場合は先にmkdir %USERPROFILE%\.sshを実行してください。
aws ec2 create-key-pair ^
--key-name my-cdk-alb-key ^
--query KeyMaterial ^
--output text ^
--region ap-northeast-1 > %USERPROFILE%\.ssh\my-cdk-alb-key.pem控えておく情報: キーペア名 my-cdk-alb-key
② プロジェクトのセットアップ
CDK の Python プロジェクトを実行するために、Python 仮想環境(venv)を作成してパッケージをインストールします。
cd C:\my-aws\aws-learning-projects\cdk-alb-ec2-rds
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt仮想環境が有効になると、プロンプトの先頭に (.venv) が表示されます。
重要: CDK のコマンド(synth / deploy / diff / destroy)はすべてこの仮想環境が有効な状態で実行する必要があります。
ターミナルを閉じると仮想環境の有効化が解除されるため、ターミナルを開き直した際は必ず最初に以下を実行してください。cd C:\my-aws\aws-learning-projects\cdk-alb-ec2-rds .venv\Scripts\activateプロンプトに
(.venv)が付いていることを確認してから CDK コマンドを実行してください。
③ cdk.json の設定
cdk.json の context セクションを自分の環境に合わせて編集します。
{
"context": {
"employee_id": "my",
"my_ip": "203.0.113.1/32",
"db_password": "Handson1234!",
"key_name": "my-cdk-alb-key",
"tomcat_version": "10.1.28"
}
}| 設定項目 | 値 | 説明 |
|---|---|---|
employee_id | my | リソース名のプレフィックス(my-cdk-alb-xxx という名前になる) |
my_ip | ⓪で確認したIP /32 | EC2へのSSHを許可するIP |
db_password | Handson1234! | RDS MySQL のパスワード |
key_name | my-cdk-alb-key | ①で作成したキーペア名 |
tomcat_version | 10.1.28 | Tomcat バージョン |
cdk.jsonはバージョン管理に含めます(cdk.context.jsonは.gitignore対象)。
CDK の詳細なコード(
stacks/alb_ec2_rds_stack.pyなど)は GitHub を参照してください。
④ CDK Bootstrap(初回のみ)
CDK が AWS 環境にデプロイするために必要なリソース(S3 バケット等)を事前にセットアップします。
同じアカウント・リージョンで一度だけ実行すれば以降は不要です。
cdk bootstrapはapp.pyを実行しないため、仮想環境の有効・無効に関わらず実行できます。② で有効にした仮想環境はそのままで進めてください。
rem アカウントIDを確認
aws sts get-caller-identity --query Account --output text
rem Bootstrap を実行(アカウントIDを置き換えて実行)
cdk bootstrap aws://123456789012/ap-northeast-1正常完了すると「CDKToolkit」という CloudFormation スタックが作成されます。
| ステータス | 意味 |
|---|---|
CREATE_COMPLETE | Bootstrap 完了 |
ALREADY_EXISTS | 既に Bootstrap 済み(スキップ可) |
⑤ CDK Synth(テンプレート確認)
デプロイ前に CDK が生成する CloudFormation テンプレートを確認します。この段階では AWS へのデプロイは行われません。
cdk synthcdk.out/ ディレクトリに CloudFormation テンプレート(JSON)が生成されます。
CloudFormation 版との比較ポイント:
- CDK が自動生成したVPC・ルートテーブル等のリソースが含まれていることを確認
- Python コード(約200行)から生成されたテンプレートの行数を確認(はるかに多い)
なぜテンプレートは増えるのか: CDK の Python コードは「人間が書く量」を減らすための抽象化です。実際に AWS に渡される CloudFormation テンプレートは CDK が自動生成するため、行数は多くなります。
rem 生成されたテンプレートをテキストエディタで確認
notepad cdk.out\CdkAlbEc2RdsStack.template.json⑥ デプロイ
cdk deploy実行中に「Do you wish to deploy these changes?」と表示されたら y を入力します。
所要時間: RDS の作成に 15〜20 分かかります。
デプロイ完了後、Outputs が表示されます:
Outputs:
CdkAlbEc2RdsStack.ALBEndpoint = http://my-cdk-alb-alb-xxxx.ap-northeast-1.elb.amazonaws.com
CdkAlbEc2RdsStack.EC2PublicIP = x.x.x.x
CdkAlbEc2RdsStack.RDSEndpoint = my-cdk-alb-rds-mysql.xxxx.ap-northeast-1.rds.amazonaws.com
CdkAlbEc2RdsStack.SSHCommand = ssh -i %USERPROFILE%\.ssh\my-cdk-alb-key.pem ec2-user@x.x.x.x
CdkAlbEc2RdsStack.MySQLConnectCommand = mysql -h my-cdk-alb-rds-mysql.xxxx... -u admin -pHandson1234! sampledb控えておく情報: ALBEndpoint、EC2PublicIP、RDSEndpoint
⑦ 動作確認
7-1. ALB のヘルスチェック確認
EC2 → ターゲットグループ → my-cdk-alb-tg → 「ターゲット」タブ
EC2 のステータスが 「healthy」 になるまで待ちます(EC2 起動後 5〜10 分)。
| ステータス | 意味 |
|---|---|
initial | 初期ヘルスチェック中(待つ) |
healthy | 正常(トラフィック転送される) |
unhealthy | 異常(Tomcat が起動していない可能性) |
Tomcat の起動はEC2が「実行中」になってからさらに 3〜5 分かかります。
ターゲットグループの ARN を CLI で確認する場合:
aws elbv2 describe-target-groups ^
--names my-cdk-alb-tg ^
--query TargetGroups[0].TargetGroupArn ^
--output text ^
--region ap-northeast-17-2. ALB 経由でWebアクセス確認
Outputs の ALBEndpoint の URL をブラウザで開きます。
http://(ALBEndpoint の DNS 名)以下が表示されれば正常です:
AP Server - my-cdk ALB + EC2 + RDS
Deployed via AWS CDK (Python). Connects to RDS MySQL in the private subnet.EC2 のパブリック IP に直接アクセスしても表示されません(ポート 8080 は ALB SG からのみ許可しているため)。
7-3. EC2 に SSH 接続する
Outputs の SSHCommand を実行します(パスは実際のパスに修正します)。
ssh -i %USERPROFILE%\.ssh\my-cdk-alb-key.pem ec2-user@(EC2PublicIP)7-4. EC2 から RDS への接続確認
EC2 に SSH 接続後(以下は EC2 上での操作):
sudo dnf install -y mariadb105
# SSM Parameter Store からパスワードを取得
DB_PASSWORD=$(aws ssm get-parameter \
--name /my/cdk-alb/db-password \
--query Parameter.Value \
--output text \
--region ap-northeast-1)
# RDS に接続(Outputs の RDSEndpoint を使用)
mysql -h <RDSEndpoint> -u admin -p${DB_PASSWORD} sampledb-- テーブル作成
CREATE TABLE items (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- データ挿入
INSERT INTO items (name) VALUES ('Apple'), ('Banana');
-- データ確認
SELECT * FROM items;
-- 後片付け
DROP TABLE items;
EXIT;7-5. SSH 接続を切断する
exit7-6. UserData の実行ログ確認
EC2 に SSH 接続後(以下は EC2 上での操作):
sudo cat /var/log/user-data.logエラーなく最後まで実行されていれば正常です。
⑧ CDK の差分確認(参考)
コードを変更した後、デプロイ前に差分を確認できます。これが CDK の強力な機能の1つです。
cdk diffCloudFormation の変更セット相当の情報が自動で表示されます。
Stack CdkAlbEc2RdsStack
Resources
[~] AWS::EC2::Instance EC2Instance
└─ [~] UserData
└─ [~] .Fn::Base64
└─ ...⑨ リソース削除
課金を止めるために、ハンズオン完了後は必ず削除します。
cdk destroy「Are you sure you want to delete?」に y を入力します。
所要時間: RDS の削除に 10〜15 分かかります。
削除されるリソース一覧
| リソース | 削除タイミング |
|---|---|
| ALB・リスナー・ターゲットグループ | cdk destroy 実行直後 |
| EC2 インスタンス | cdk destroy 実行直後 |
| RDS インスタンス | 10〜15 分(削除ポリシー: DESTROY) |
| VPC・サブネット・SG | RDS 削除後 |
| SSM Parameter Store | スタック削除と同時 |
| IAM ロール・インスタンスプロファイル | スタック削除と同時 |
キーペアの削除(手動)
CDK が管理していないリソースは手動で削除します:
aws ec2 delete-key-pair ^
--key-name my-cdk-alb-key ^
--region ap-northeast-1
del %USERPROFILE%\.ssh\my-cdk-alb-key.pem仮想環境の終了
ハンズオンが終わったらプロンプトの (.venv) を外します。
deactivate(.venv) が消えて通常のプロンプトに戻れば完了です。
(.venv)が付いている状態とは: このプロジェクト専用の Python 環境(venv)が有効な状態です。deactivateしなくてもターミナルを閉じれば自動的に解除されます。次回 CDK コマンドを使う際は再度.venv\Scripts\activateが必要です。
削除完了の確認
aws cloudformation describe-stacks ^
--stack-name CdkAlbEc2RdsStack ^
--region ap-northeast-1「Stack with id CdkAlbEc2RdsStack does not exist」エラーが出れば削除完了です。
CDK Bootstrap リソースの削除(任意)
CDK を今後も使う場合は残したままでよいです。
削除する場合は AWS コンソールで CDKToolkit スタックを手動削除します。
CDK のポイント解説
L1 / L2 / L3 Construct の違い
| レベル | 名前 | 説明 | 例 |
|---|---|---|---|
| L1 | Cfn Construct | CloudFormation リソースと 1:1 対応。Cfn プレフィックス | ec2.CfnVPC |
| L2 | Default Construct | AWS のベストプラクティスを組み込んだ高レベル抽象 | ec2.Vpc |
| L3 | Pattern | 複数サービスを組み合わせた再利用可能なパターン | ecs_patterns.ApplicationLoadBalancedFargateService |
このハンズオンでは主に L2 Construct を使用しています。ec2.Vpc 1つを書くだけで、CloudFormation では15+ リソースが必要だったVPC・IGW・ルートテーブル・サブネット設定を自動生成します。
CDK Context 変数
cdk.json の context に設定した値は self.node.try_get_context("key") で取得できます。
デプロイ時に -c key=value で上書きも可能です:
cdk deploy -c my_ip=1.2.3.4/32 -c db_password=MyPass123!cdk synth で CloudFormation テンプレートを確認
rem cdk.out/ に生成されたテンプレートをテキストエディタで確認
notepad cdk.out\CdkAlbEc2RdsStack.template.jsonCDK コードの詳細(stacks/alb_ec2_rds_stack.py 全文)は GitHub を参照してください。
トラブルシューティング
| 症状 | 原因 | 対処 |
|---|---|---|
cdk deploy で認証エラー | AWS 認証情報が未設定 | aws sts get-caller-identity で確認 |
cdk bootstrap が必要と言われる | Bootstrap 未実施 | ④の手順を実施 |
ModuleNotFoundError: aws_cdk | 仮想環境が無効 | .venv\Scripts\activate を実行してから再度 CDK コマンドを実行 |
| ALB にアクセスすると 502 | Tomcat 起動前 | 3〜5 分待ってリトライ |
| SSH できない | my_ip が違う、またはキー名が違う | cdk.json の my_ip と key_name を確認 |
| RDS に接続できない | SG 設定の問題 | EC2 SG から RDS SG への 3306 ルールを確認 |
cdk destroy が途中で止まる | RDS の削除待ち | 10〜15 分待つ(自動的に続行される) |
No match for argument: mysql | AL2023 では mysql パッケージが存在しない | sudo dnf install -y mariadb105 を使う |
デプロイ失敗時のログ確認:
aws cloudformation describe-stack-events ^
--stack-name CdkAlbEc2RdsStack ^
--region ap-northeast-1 ^
--query "StackEvents[?ResourceStatus=='CREATE_FAILED'].[ResourceType,ResourceStatusReason]" ^
--output tableコンソール版・CloudFormation版との比較
| 作業 | コンソール(手動) | CloudFormation | CDK(今回) |
|---|---|---|---|
| VPC + サブネット4つ + IGW + RT | 約20〜30分 | template.yaml に定義済み | ec2.Vpc 1行で自動生成 |
| SG 3つ(ALB/EC2/RDS)の作成 | 3画面で個別設定 | template.yaml に定義済み | Python コードで直感的に記述 |
| ALB + TG + Listener の作成 | 3つの画面で設定 | template.yaml に定義済み | メソッドチェーンで接続 |
| コード量 | — | 約460行(YAML) | 約200行(Python) |
| 全体のデプロイ | 約40〜50分 | コマンド1本(RDS待ち15〜20分) | cdk deploy 1本(同等) |
| 削除 | 13ステップ手動 | delete-stack 1本 | cdk destroy 1本 |
| 差分確認 | — | 変更セット(手動作成) | cdk diff(自動・即時) |
| バージョン管理 | 不可 | Gitで管理可能 | Gitで管理可能 |
まとめ
| ステップ | 内容 |
|---|---|
| ①② | キーペア作成 + Python 仮想環境のセットアップ |
| ③ | cdk.json に自分の環境(IP・パスワード・キー名)を設定 |
| ④ | cdk bootstrap(初回のみ。以降は不要) |
| ⑤ | cdk synth で CloudFormation テンプレートを確認(デプロイなし) |
| ⑥ | cdk deploy でデプロイ(RDS 待ち 15〜20 分) |
| ⑦ | ALB DNS 名でアクセス → EC2 → Parameter Store → RDS への接続テスト |
| ⑨ | cdk destroy で全リソースを一括削除 |
CDK の最大の魅力は プログラミング言語でインフラを書ける点です。CloudFormation の460行の YAML が Python 約200行に削減されただけでなく、cdk diff による差分確認や L2 Construct による抽象化など、開発者体験が大きく向上します。
コンソールで3層構成の概念を視覚的に学びたい場合は AWSコンソール版ハンズオン、まずCloudFormationで同じ構成を試したい場合は CloudFormation版ハンズオン を参照してください。
コメント