ステップ1:AWS CDKの基礎とVPC構築
今回のステップの概要とこのカリキュラムとの関連について
このステップでは、AWS CDK(Cloud Development Kit)の基礎を学び、最初のインフラリソースとしてVPCをコード化します。具体的には、AWS CDKのインストール、基本概念の理解、そしてVPC・サブネット・インターネットゲートウェイ・ルートテーブルをTypeScriptコードで記述して自動構築します。
コンテナアプリケーションのインフラにとって、VPCは「土地と敷地の区画整理」のような役割を果たします。家を建てる前に、まず土地を確保し、どのエリアを住宅地にするか、どのエリアを商業地にするか、外部への道路をどこに設けるかを決めます。VPCも同様に、AWSクラウド上で独自のネットワーク空間を確保し、パブリックサブネット(外部と通信可能)とプライベートサブネット(内部のみ)を区分け、インターネットゲートウェイという「出入口」を設置します。
従来、これらのリソースはAWSコンソールで手作業で作成していましたが、AWS CDKを使えばTypeScriptコードで記述し、cdk deploy というコマンド1つで全てを自動構築できます。これは、家の設計図を書いて3Dプリンターで出力するように、コードという設計図を書いてAWSというプラットフォームで自動構築する仕組みです。
このステップで学ぶこと
- AWS CDKの基本概念とインストール方法
- VPCのコード化と構築
- サブネットの設計とコード化
- インターネットゲートウェイとルートテーブルの設定
リソースの関わりと構成説明
ステップ1で作成するリソースは、コンテナアプリケーションを動かすための「ネットワーク基盤」を構築するものです。それぞれのリソースがインフラにどのように関わるのかを説明します。
VPCとインフラの関わり
VPC(Virtual Private Cloud)「仮想プライベートクラウド」は、AWSクラウド上で独自のネットワーク空間を確保する「土地」のような役割を果たします。物理的な店舗で言えば、お店を建てるための「敷地」に相当します。VPCを作成することで、他のAWSユーザーと完全に分離された、あなた専用のネットワーク環境が手に入ります。これにより、セキュリティを確保しながら、自由にネットワーク設計ができます。
サブネットとインフラの関わり
サブネット「サブネットワーク」は、VPCという土地の中を「パブリック(公開)エリア」と「プライベート(非公開)エリア」に区分けする役割を果たします。物理的な店舗で言えば、「接客スペース」と「バックヤード(倉庫)」のような区分けです。パブリックサブネットには、外部からアクセスを受け付けるALB(ロードバランサー)を配置し、プライベートサブネットには、外部から直接アクセスさせたくないコンテナ(ECSタスク)やデータベース(RDS)を配置します。これにより、セキュリティを保ちながら、必要な通信だけを許可できます。
インターネットゲートウェイとインフラの関わり
インターネットゲートウェイ「IGW」は、VPCとインターネットを接続する「出入口の門」のような役割を果たします。物理的な店舗で言えば、「正面玄関」に相当します。パブリックサブネット内のリソースは、このインターネットゲートウェイを通じて外部のユーザーと通信できます。プライベートサブネット内のリソースは、後で学ぶNATゲートウェイを経由して外部と通信しますが、外部から直接アクセスすることはできません。これにより、ユーザーはALBを通じてアプリケーションにアクセスでき、運営者はセキュアなインフラを維持できます。
実際の手順
実際の手順では、たくさんの設定値を入力することになります。 本文中に設定値が指定されていない場合は、デフォルト値のまま作業を進めてください。
1. AWS CDKの環境構築
AWS CDKをローカル環境にインストールし、基本的なプロジェクト構造を作成します。
AWSでの役割
AWS CDK(Cloud Development Kit)は、TypeScript・Python・Javaなどのプログラミング言語でAWSインフラを定義できるオープンソースのIaCフレームワークです。
特徴:
- プログラミング言語の制御構文(if文、for文、関数化)を活用できる
- TypeScriptの型チェックとIDEの補完機能でミスを防げる
- CloudFormationテンプレートを自動生成するため、最終的にはCloudFormationで管理される
- L1/L2/L3 Constructsという3段階の抽象化レベルで、シンプルにも詳細にも記述できる
オンプレミスでの対応
オンプレミス環境では「Ansible、Terraform」が対応します。
- Ansibleはサーバー構成管理とプロビジョニングを自動化
- Terraformはマルチクラウド対応のIaCツールで、HCL(HashiCorp Configuration Language)でインフラを定義
- AWS CDKはAWS専用だが、プログラミング言語で記述できる点が最大の特徴
1-1. Node.jsとnpmのインストール確認
- ターミナルを開き、Node.jsのバージョンを確認します(v18以上が必要)
node --version以下のような出力が表示されればOKです。
v18.17.0- もしNode.jsがインストールされていない、またはバージョンが古い場合は、Node.js公式サイト からLTS版をダウンロードしてインストールしてください
【解説】なぜNode.js v18以上が必要なのか
AWS CDKはNode.js上で動作するTypeScript/JavaScriptのフレームワークです。AWS CDK v2では、最新のJavaScript機能や非同期処理を活用するため、Node.js v18以上が推奨されています。Node.js v18は長期サポート(LTS)版であり、セキュリティアップデートと安定性が保証されています。
ローカル開発環境では、Node.jsのバージョン管理ツール(nvm、nodenv、Voltaなど)を使用することで、プロジェクトごとに異なるNode.jsバージョンを切り替えられます。例えば、あるプロジェクトではNode.js v16、別のプロジェクトではv18というように使い分けられます。
AWS CDKは内部的にTypeScriptコンパイラを使用してTypeScriptコードをJavaScriptに変換し、さらにCloudFormationテンプレートを生成します。この処理には、Node.jsのファイルシステムAPIや非同期処理機能が必要です。
1-2. AWS CDKのグローバルインストール
- AWS CDK CLIをグローバルにインストールします
npm install -g aws-cdk- インストールが完了したら、CDKのバージョンを確認します
cdk --version以下のような出力が表示されればOKです。
2.100.0 (build e6e2c87)【解説】グローバルインストールとプロジェクトローカルインストールの違い
npm install -g は、コマンドラインツールをシステム全体で使えるようにするグローバルインストールです。AWS CDK CLIは cdk init、cdk deploy、cdk destroy などのコマンドを提供するため、グローバルにインストールします。
一方、CDKのライブラリ(@aws-cdk/aws-ec2など)は、プロジェクトごとに異なるバージョンを使用することが多いため、プロジェクトローカルにインストールします。これにより、プロジェクトAではCDK v2.90、プロジェクトBではCDK v2.100というように、異なるバージョンを共存させられます。
グローバルインストールされたコマンドは、通常 /usr/local/bin/ や ~/.npm-global/bin/ に配置され、PATHが通っているため、どのディレクトリからでも実行できます。プロジェクトローカルのコマンドは node_modules/.bin/ に配置され、npx コマンドや npm scripts で実行します。
1-3. AWS認証情報の設定
- AWS CLIがインストールされていることを確認します
aws --version- AWS IAM Identity Centerにアクセスし、認証情報を取得します
AWSアクセスポータル(AWS access portal)にアクセスし、使用するアカウントとロールを選択します。

- 「Access keys」をクリックして、認証情報の取得方法を表示します

- 「Option 1: Set AWS environment variables」セクションに表示されている環境変数を、ターミナルで設定します
export AWS_ACCESS_KEY_ID="your-access-key-id"
export AWS_SECRET_ACCESS_KEY="your-secret-access-key"
export AWS_SESSION_TOKEN="your-session-token"- 認証情報が正しく設定されているかを AWS STS で確認します
aws sts get-caller-identity以下のような出力が表示されればOKです。
{
"UserId": "XXXXXXXXXXXXXXXXX",
"Account": "123456789012",
"Arn": "arn:aws:sts::123456789012:assumed-role/YourRole/YourSession"
}重要: 上記のコマンドは例です。実際には、AWSアクセスポータルに表示されている具体的な値をコピー&ペーストして実行してください。セッショントークンは一定時間で失効するため、有効期限が切れた場合は再度取得する必要があります。
【解説】環境変数による一時的な認証情報の管理
AWS認証情報は、AWSリソースを操作するための「鍵」です。この鍵を使って、EC2インスタンスの作成、S3へのファイルアップロード、RDSの構築など、あらゆるAWS操作が可能になります。そのため、認証情報の管理は非常に重要です。
AWS IAM Identity Centerを使用した認証方法では、一時的なセッショントークンが発行されます。この方法には以下のメリットがあります:
- セキュリティの向上: セッショントークンは一定時間で自動的に失効するため、永続的なアクセスキーよりも安全です
- 権限の明確化: ロールベースでアクセス権限が管理されるため、必要最小限の権限のみを付与できます
- 監査の容易さ: どのユーザーがどのロールでアクセスしたかが明確に記録されます
環境変数に設定した認証情報は、ターミナルセッションが終了すると消失します。そのため、ターミナルを開き直した場合や、セッショントークンの有効期限が切れた場合は、再度AWSアクセスポータルから認証情報を取得して設定する必要があります。
本カリキュラムでは、学習目的でこの方法を使用しますが、実務では以下の方法も推奨されます:
- AWS CLIのSSOプロファイル:
aws configure ssoコマンドでSSOプロファイルを設定し、自動的にトークンを更新する方法 - IAM Roleの利用: EC2やLambdaなどのAWSリソースには、直接IAM Roleをアタッチして認証情報をコードに埋め込まない方法
- CI/CD環境: GitHub ActionsのOIDCプロバイダーを使用してアクセスキー不要で認証する方法
絶対にGitリポジトリに認証情報をコミットしないでください。.gitignore に .env や credentials ファイルを追加することで、誤ってコミットすることを防げます。
2. CDKプロジェクトの初期化
AWS CDKプロジェクトを作成し、TypeScriptで記述する準備をします。
2-1. プロジェクトディレクトリの作成
- 作業用のディレクトリを作成して移動します
mkdir cdk-iac-project
cd cdk-iac-project- CDKプロジェクトを初期化します(TypeScript言語を選択)
cdk init app --language typescript以下のような出力が表示されればOKです。
Applying project template app for typescript
# Welcome to your CDK TypeScript project
This is a blank project for CDK development with TypeScript.
...
✅ All done!2-2. VSCodeでプロジェクトを開く
-
VSCode(Visual Studio Code)を起動します(VSCode以外のエディタでもOKです)
-
メニューから「ファイル」→「フォルダーを開く」を選択し、先ほど作成した
cdk-iac-projectディレクトリを選択します- macOSの場合:メニューバーの「File」→「Open Folder…」
- Windowsの場合:メニューバーの「ファイル」→「フォルダーを開く」
-
VSCodeでプロジェクトが開かれ、左側のエクスプローラーに以下のようなファイル構造が表示されます
cdk-iac-project/
├── bin/
│ └── cdk-iac-project.ts
├── lib/
│ └── cdk-iac-project-stack.ts
├── test/
│ └── cdk-iac-project.test.ts
├── node_modules/
├── .gitignore
├── .npmignore
├── cdk.json
├── package.json
├── package-lock.json
├── README.md
└── tsconfig.json2-3. CDKプロジェクトの初期構造を理解する
生成されたファイルとディレクトリには、それぞれ重要な役割があります。以下、各ファイルの役割を詳しく見ていきましょう。
📁 bin/cdk-iac-project.ts(エントリーポイント)
CDKアプリケーションの「スタート地点」となる起動ファイルです。プログラミングにおける main() 関数のようなもので、CDKがこのファイルを最初に実行して、どのインフラを構築するかを決定します。
このファイルの役割は、建設プロジェクトで言う「着工届」に似ています。建物を建てる際には、「どこに(場所)」「誰が(施工業者)」「何を(建物の種類)」建てるかを役所に届け出ます。同様に、このファイルでは以下を宣言します:
-
AWS環境の指定:どのAWSアカウント(誰が支払うか)と、どのリージョン(どの地域のデータセンター)にインフラを構築するかを指定します。例えば、
account: '123456789012'とregion: 'us-east-1'を指定すると、バージニアリージョンの特定のアカウントにリソースが作成されます。 -
Stackのインスタンス化:どのStackをデプロイするかを決めます。Stackとは、VPC、ECS、RDSなどの複数のAWSリソースをまとめた「設計図のセット」です。例えば、ネットワーク用のStackとアプリケーション用のStackを分けて管理できます。
-
複数Stackの管理:大規模なシステムでは、ネットワーク層、アプリケーション層、データベース層を別々のStackとして管理します。このファイルで、それらのStackをまとめて宣言し、依存関係(「データベースStackはネットワークStackが完成してから作成する」など)を定義できます。
// bin/cdk-iac-project.ts の例
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { CdkIacProjectStack } from '../lib/cdk-iac-project-stack';
const app = new cdk.App();
new CdkIacProjectStack(app, 'CdkIacProjectStack', {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION
},
});📁 lib/cdk-iac-project-stack.ts(インフラ定義)
実際のAWSリソースを定義する、最も重要なStackファイルです。このファイルが、インフラの「詳細な設計図」にあたります。
建築で例えるなら、bin/ のファイルが「着工届(どこに何を建てるか)」だとすると、この lib/ のファイルは「建築設計図(部屋の配置、電気配線、水道管の位置など)」に相当します。具体的には、以下のような情報をTypeScriptコードで記述します:
- VPC(ネットワーク空間):IPアドレスの範囲、サブネットの分割方法、インターネットへの接続設定など
- ECS(コンテナ実行環境):コンテナのCPU・メモリ容量、実行するDockerイメージ、タスク数など
- RDS(データベース):データベースエンジンの種類(MySQL、PostgreSQLなど)、インスタンスサイズ、バックアップ設定など
- ALB(ロードバランサー):外部からのアクセスをどのポートで受け付けるか、どのコンテナに振り分けるかなど
このファイルの中で、new ec2.Vpc() や new ecs.Cluster() のようにTypeScriptのクラスをインスタンス化することで、AWSリソースを定義します。例えば、new ec2.Vpc(this, 'MyVpc', { maxAzs: 2 }) と書くだけで、2つのアベイラビリティゾーンにまたがるVPC、パブリックサブネット2つ、プライベートサブネット2つ、インターネットゲートウェイ、NATゲートウェイ、ルートテーブルなど、合計で数十個のAWSリソースが自動的に作成されます。
従来のCloudFormationでは、これらを1つ1つYAMLで記述する必要があり、数百行のコードが必要でした。しかしCDKでは、わずか数行のTypeScriptコードで、AWSのベストプラクティスに沿った構成を自動生成できます。また、TypeScriptの変数、関数、if文、for文などを活用して、柔軟にインフラを記述できる点も大きな利点です。
// lib/cdk-iac-project-stack.ts の初期状態
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class CdkIacProjectStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// ここにAWSリソースを定義していきます
// 例: VPC、ECS、RDS など
}
}📁 test/cdk-iac-project.test.ts(テストコード)
CDKで定義したインフラが期待通りの構成になっているかを検証するテストコードです。例えば、「VPCが正しく作成されているか」「セキュリティグループのルールが適切か」などをテストできます。
📁 cdk.json(CDK設定ファイル)
CDKアプリケーション全体の「動作ルール」を定義する設定ファイルです。このファイルは、CDKがどのように動作するかを制御する「コントロールパネル」のような役割を果たします。
建築で例えるなら、「工事の進め方のマニュアル」に相当します。「どの順番で作業するか」「どの工具を使うか」「安全基準はどうするか」といった施工ルールを定めるように、cdk.json では以下の重要な設定を行います:
1. app エントリーポイントの指定
"app": "npx ts-node --prefer-ts-exts bin/cdk-iac-project.ts" という設定は、「CDKコマンドを実行したときに、最初にどのファイルを起動するか」を指定しています。
npx ts-node:TypeScriptファイルを直接実行するためのツールです。通常、TypeScriptは一度JavaScriptにコンパイルしてから実行しますが、ts-nodeを使うことで、このステップを省略できます。--prefer-ts-exts:TypeScriptファイルの拡張子(.ts)を優先的に読み込むオプションです。bin/cdk-iac-project.ts:実際に起動するファイルのパスです。
この設定により、cdk deploy や cdk synth などのコマンドを実行すると、CDKは自動的に bin/cdk-iac-project.ts を実行し、そこからインフラの構築が始まります。
2. context 機能フラグの設定
context セクションには、CDKの「機能フラグ」が定義されています。これは、CDKの新しい機能や改善を有効化するためのスイッチです。例えば:
@aws-cdk/aws-lambda:recognizeVersionProps: true:Lambda関数のバージョン管理を改善する機能を有効化@aws-cdk/core:newStyleStackSynthesis: true:最新のCloudFormationテンプレート生成方式を使用
これらのフラグは、AWSがCDKのベストプラクティスを更新するたびに追加されます。古いプロジェクトとの互換性を保ちながら、新しいプロジェクトでは最新の機能を使えるようにする仕組みです。cdk init で生成されたプロジェクトには、その時点での推奨設定がすべて含まれているため、初心者は特に変更する必要がありません。
3. その他の設定項目
requireApproval: never:デプロイ時の確認プロンプトを表示するかどうかtoolkitStackName:CDK Bootstrapで作成されるスタックの名前(デフォルトはCDKToolkit)versionReporting:CDKの使用状況をAWSに報告するかどうか(匿名化された統計情報)
このファイルは、プロジェクト全体で共通の設定を管理するため、Gitで必ずバージョン管理に含めます。チームメンバー全員が同じ設定でCDKを実行することで、「私の環境では動くのに、他の人の環境では動かない」というトラブルを防げます。
📁 package.json(Node.js依存関係管理)
Node.jsプロジェクトの依存関係を管理するファイルです。以下の情報が含まれます:
- 使用するCDKライブラリのバージョン(
aws-cdk-lib、constructsなど) - 開発用パッケージ(TypeScriptコンパイラ、テストライブラリなど)
- npm scripts(
npm run build、npm run testなど)
📁 tsconfig.json(TypeScript設定)
TypeScriptコンパイラの設定ファイルです。型チェックの厳格さ、出力先ディレクトリ、使用するJavaScriptバージョンなどを定義します。
📁 .gitignore(Git管理除外ファイル)
Gitで管理しないファイル・ディレクトリを指定します。以下が含まれます:
node_modules/:npmでインストールしたパッケージ(再インストール可能)cdk.out/:生成されたCloudFormationテンプレート(自動生成されるため不要)*.js、*.d.ts:TypeScriptからコンパイルされたJavaScriptファイル(自動生成されるため不要)
📁 node_modules/(インストール済みパッケージ)
npm install で自動的にインストールされた依存パッケージが格納されるディレクトリです。このディレクトリは非常に大きくなるため、Gitで管理しません。
【解説】CDKプロジェクトの初期構造と開発フロー
cdk init コマンドは、AWS CDKプロジェクトの基本的なディレクトリ構造とファイルを自動生成します。この構造は、「関心の分離(Separation of Concerns)」という設計原則に基づいています。
bin/ ディレクトリには、CDKアプリケーションのエントリーポイント(起動ファイル)が配置されます。ここでAWS環境(アカウントIDとリージョン)を指定し、Stackをインスタンス化します。これは、家を建てる際の「着工届」のようなもので、「どこに(リージョン)」「誰が(アカウント)」「何を(Stack)」建てるかを宣言します。
lib/ ディレクトリには、実際のインフラリソースを定義するStackファイルが配置されます。VPC、ECS、RDSなどのリソースをTypeScriptクラスで記述します。これは、家を建てる際の「設計図」に相当します。複数のStackを作成することで、ネットワーク層、アプリケーション層、データベース層を分離して管理できます。
cdk.json は、CDKアプリケーションの設定ファイルで、エントリーポイントのパスや、CDKの動作をカスタマイズする設定を記述します。package.json は、Node.jsプロジェクトの依存関係を管理するファイルで、使用するCDKライブラリのバージョンや、npm scriptsが定義されます。これらのファイルにより、チームメンバー全員が同じバージョンのCDKライブラリを使用でき、環境の差異によるトラブルを防げます。
TypeScriptは、JavaScriptに型システムを追加したプログラミング言語で、コンパイル時に型チェックが行われるため、実行前にエラーを検出できます。AWS CDKでTypeScriptを使用すると、IDEの補完機能が強力に働き、EC2インスタンスタイプやVPC CIDRブロックなどの設定値を入力する際にミスを防げます。例えば、VPCのCIDRブロックに「10.0.0.0/33」という無効な値を入力すると、TypeScriptコンパイラが「/33は無効なCIDRマスクです」というエラーを表示し、デプロイ前に問題を検出できます。
VSCodeでプロジェクトを開くと、TypeScriptの型情報に基づいて、リアルタイムでエラーチェックとコード補完が行われます。例えば、ec2.Vpc と入力すると、利用可能なプロパティ(maxAzs、natGateways、subnetConfiguration など)が自動的に表示され、各プロパティの説明やデフォルト値も確認できます。これにより、ドキュメントを参照する手間が省け、開発効率が大幅に向上します。
2-4. CDKプロジェクトのBootstrap
- AWS環境をCDK用に初期化(Bootstrap)します
cdk bootstrap --region us-east-1以下のような出力が表示され、CloudFormationスタックが作成されます。
⏳ Bootstrapping environment aws://123456789012/us-east-1...
CDKToolkit: creating CloudFormation changeset...
✅ Environment aws://123456789012/us-east-1 bootstrapped.【解説】CDK Bootstrapの役割と仕組み
cdk bootstrap は、AWS CDKがAWS環境にインフラをデプロイするための「準備作業」です。このコマンドを実行すると、「CDKToolkit」というCloudFormationスタックが作成され、以下のリソースが自動的に構築されます。
まず、S3バケットが作成されます。これはCDKが生成したCloudFormationテンプレートや、Lambda関数のコード、Dockerコンテナイメージなどの「アセット」を保管する場所です。CDKは、デプロイ時にこれらのファイルをS3にアップロードし、CloudFormationがそこから参照します。
次に、ECRリポジトリが作成されます。これはDockerイメージを保管する場所で、後のステップでコンテナアプリケーションをデプロイする際に使用します。さらに、IAM Roleが作成され、CloudFormationがこれらのリソースにアクセスするための権限を持ちます。
Bootstrapは、AWS環境(アカウントとリージョンの組み合わせ)ごとに1回だけ実行すれば良いです。例えば、東京リージョン(ap-northeast-1)とバージニアリージョン(us-east-1)の両方を使用する場合、それぞれでBootstrapが必要です。複数のAWSアカウントを使用する場合(開発用アカウント、本番用アカウントなど)も、各アカウントでBootstrapが必要です。
Bootstrapで作成されたS3バケットには、バージョニングとライフサイクルポリシーが設定されており、古いアセットは自動的に削除されます。これにより、ストレージコストを最適化できます。
3. VPCのコード化と構築
TypeScriptコードでVPCを定義し、実際にAWS環境に構築します。
3-1. VPCスタックの作成
lib/cdk-iac-project-stack.tsファイルを開き、以下の内容に書き換えます
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
export class CdkIacProjectStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// VPCの作成
const vpc = new ec2.Vpc(this, 'MyVpc', {
maxAzs: 2, // 2つのアベイラビリティゾーンを使用
natGateways: 1, // NATゲートウェイを1つ作成(コスト削減のため)
subnetConfiguration: [
{
cidrMask: 24,
name: 'Public',
subnetType: ec2.SubnetType.PUBLIC,
},
{
cidrMask: 24,
name: 'Private',
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
},
],
});
// VPC IDを出力
new cdk.CfnOutput(this, 'VpcId', {
value: vpc.vpcId,
description: 'VPC ID',
});
}
}【解説】CDK Constructsの3つの抽象化レベル:L1、L2、L3の違い
このコードで使用している ec2.Vpc は、AWS CDKの「L2 Construct」と呼ばれる高レベルの抽象化です。AWS CDKには、L1、L2、L3という3つの抽象化レベルがあり、それぞれ「どこまで細かく設定できるか」と「どこまで自動化されるか」のバランスが異なります。これを料理に例えると、L1は「素材から全て自分で調理する」、L2は「レシピ付きの食材キットを使う」、L3は「完成した料理を温めるだけ」といったイメージです。
L1 Constructs(レベル1:最も低レベル、細かい制御が可能)
L1 Constructsは、CloudFormationのリソースをそのままTypeScriptクラスに変換したものです。CloudFormationで AWS::EC2::VPC と書くところを、CDKでは new CfnVpc() と書きます。名前に Cfn というプレフィックスが付いているのが特徴です。
L1を使うと、CloudFormationで設定できる全てのプロパティを細かく制御できます。例えば、VPCのDNSホスト名を有効化するかどうか、IPv6のCIDRブロックを設定するかどうかなど、あらゆる設定を自分で指定できます。その反面、サブネット、ルートテーブル、インターネットゲートウェイ、ルートテーブルアソシエーションなど、全てのリソースを1つ1つ手動で記述しなければなりません。これは、料理で言えば、野菜を切る、調味料を測る、火加減を調整するといった全ての工程を自分で行うようなものです。
L1は、非常に特殊な構成が必要な場合や、最新のAWS機能がまだL2でサポートされていない場合に使用します。初心者が最初から使う必要はありませんが、「こういう低レベルの制御方法もある」と知っておくことは重要です。
L2 Constructs(レベル2:推奨される標準レベル、利便性と柔軟性のバランスが良い)
L2 Constructsは、AWSのベストプラクティスをデフォルト設定として組み込んだ、最も使いやすい抽象化レベルです。このコードで使用している ec2.Vpc がL2に該当します。L2の最大の特徴は、「わずか数行のコードで、数十個のAWSリソースを自動的に作成してくれる」ことです。
例えば、new ec2.Vpc(this, 'MyVpc', { maxAzs: 2 }) というたった1行のコードを書くだけで、以下のリソースが自動的に作成されます。VPCリソース本体、2つのアベイラビリティゾーンにまたがるパブリックサブネット2つ、同じく2つのプライベートサブネット2つ、インターネットゲートウェイ1つ、NATゲートウェイ(デフォルトでは各AZに1つずつ)、パブリックサブネット用のルートテーブル2つ、プライベートサブネット用のルートテーブル2つ、そしてこれらを接続するルート設定とルートテーブルアソシエーション。合計すると、15個以上のCloudFormationリソースが自動生成されます。
もしこれをCloudFormationのYAMLやL1 Constructsで記述すると、200行以上のコードが必要になります。L2を使えば、AWSの専門家が推奨する構成を、初心者でも簡単に作成できます。これは、料理で言えば、「必要な食材と調味料がセットになったレシピ付きキット」を使うようなものです。基本的な手順は決まっていますが、味付けの濃さやトッピングは自由に調整できます。
L2 Constructsは、maxAzs、natGateways、subnetConfiguration といったプロパティで、構成をカスタマイズできます。例えば、natGateways: 1 と指定すれば、コスト削減のためにNATゲートウェイを1つだけ作成できます。maxAzs: 3 とすれば、3つのアベイラビリティゾーンにリソースを分散配置できます。このように、簡単に使えるだけでなく、必要に応じて柔軟にカスタマイズできる点が、L2の大きな利点です。
L3 Constructs(レベル3:最も高レベル、特定のユースケース向けの完全な構成)
L3 Constructsは、「特定のユースケース全体」を1つのクラスで表現する、最も高レベルの抽象化です。例えば、AWS公式が提供する aws-ecs-patterns ライブラリの ApplicationLoadBalancedFargateService というL3 Constructを使うと、「ALB(ロードバランサー)+ Fargateコンテナ + 自動スケーリング + セキュリティグループ + ログ設定」という、Webアプリケーションに必要な構成全体をたった1つのクラスで作成できます。
L3は、よくある構成パターンを「テンプレート」として提供するものです。例えば、「静的WebサイトをS3 + CloudFrontでホスティングする」「Lambda関数をAPI Gateway経由で公開する」「ECSコンテナをALB配下で動かす」といった、頻繁に使われるパターンが、L3として提供されています。これは、料理で言えば、「レンジで温めるだけの完成品」に相当します。非常に簡単ですが、細かいカスタマイズは難しくなります。
L3は初心者にとって非常に便利ですが、カスタマイズの余地が少ないため、要件が複雑になるとL2を使った方が良い場合もあります。例えば、特殊なセキュリティグループルールを設定したい場合や、独自のヘルスチェック設定が必要な場合は、L2で1つ1つのリソースを明示的に定義する方が柔軟です。
実際の開発での使い分け
実際のCDKプロジェクトでは、これらのレベルを組み合わせて使います。基本的にはL2を中心に使い、よくあるパターンではL3を活用し、どうしても細かい制御が必要な部分だけL1を使う、というのが一般的なアプローチです。例えば、VPCはL2の ec2.Vpc で作成し、ECSクラスターとALBの組み合わせはL3の ApplicationLoadBalancedFargateService で作成し、特殊なIAMポリシーはL1の CfnPolicy で細かく定義する、といった具合です。
初心者の方は、まずL2 Constructsの使い方をマスターすることをおすすめします。L2を理解すれば、AWSのベストプラクティスに沿った構成を簡単に作成でき、必要に応じてカスタマイズもできるため、実務で最も役立ちます。L3は、さらに簡単に使えるため、試してみて構成が要件に合えば積極的に活用しましょう。L1は、どうしても必要になったときに学べば十分です。
このコードで使用しているL2 Constructのプロパティ解説
maxAzs: 2 は、2つのアベイラビリティゾーン(AZ)にリソースを分散配置することを意味します。アベイラビリティゾーンは、物理的に離れたデータセンターで、片方が障害を起こしても、もう片方で運用を継続できます。これは、物理的な店舗で言えば、本店と支店を別々の場所に設置するようなものです。
natGateways: 1 は、NATゲートウェイを1つだけ作成する設定です。本番環境では、各AZにNATゲートウェイを配置するのがベストプラクティスですが、学習目的では、コスト削減のために1つに制限しています。NATゲートウェイは、プライベートサブネット内のリソース(ECSタスクなど)がインターネットにアクセスするための「代理出口」です。
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS は、「外部へのアクセスは可能だが、外部からの直接アクセスは不可」なプライベートサブネットを作成します。これにより、コンテナアプリケーションは、外部のAPIを呼び出したり、パッケージをダウンロードしたりできますが、外部からの不正アクセスは防げます。
3-2. CDKコードのSynthesize(CloudFormation生成)
- CDKコードをCloudFormationテンプレートに変換します
cdk synth以下のような出力が表示され、CloudFormationテンプレート(YAML)が生成されます。
Resources:
MyVpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
...【解説】cdk synthの役割とデバッグ方法
cdk synth は、TypeScriptコードを解析し、CloudFormationテンプレート(YAML)を生成するコマンドです。このプロセスを「Synthesize(合成)」と呼びます。Synthesizeは、設計図(CDKコード)を実際の施工図(CloudFormation)に変換する作業に相当します。
生成されたCloudFormationテンプレートは、cdk.out/ ディレクトリに保存されます。初心者の方は、このテンプレートを「答え合わせ」として活用することをおすすめします。具体的には、以下の3ステップで学習を深めてください:
ステップ1:CDKコードを確認する - 例えば new ec2.Vpc(this, 'MyVpc', { maxAzs: 2 }) という1行のコードを書いたとします。この時点では、「VPCが作られるんだな」という程度の理解です。
ステップ2:生成されたCloudFormationテンプレートを確認する - cdk synth を実行して cdk.out/ ディレクトリのテンプレートを開くと、AWS::EC2::VPC、AWS::EC2::Subnet、AWS::EC2::InternetGateway、AWS::EC2::NATGateway、AWS::EC2::RouteTable、AWS::EC2::Route など、15個以上のAWSリソース定義が並んでいることがわかります。これで、「1行のCDKコードが、これだけ多くのAWSリソースを自動生成していたのか!」と気づきます。
ステップ3:実際にAWSコンソールでリソースを確認する - cdk deploy を実行した後、AWSマネジメントコンソールのVPCダッシュボードを開いて、実際に作成されたVPC、サブネット、インターネットゲートウェイ、ルートテーブルなどを1つ1つ確認します。「CloudFormationテンプレートに書かれていた AWS::EC2::Subnet が、実際にはこういうサブネットとして存在しているのか」「ルートテーブルの設定が、こういう形でパブリックサブネットとプライベートサブネットを区別しているのか」と、実物を見ることで理解が深まります。
この3ステップを繰り返すことで、「CDKコードの1行が、実際のAWSインフラでどう表現されるか」という対応関係が身につきます。重要なのは、CloudFormationのYAML構文を覚えることではありません。「CDKで書いたシンプルなコードが、裏側でどれだけ多くのAWSリソースを作成しているのか」「それぞれのリソースがどのように連携してインフラを構成しているのか」を、実際のAWSコンソールで確認しながら理解することです。
この学習方法により、CDKの強力な抽象化のメリット(少ないコードで多くのリソースを作成)と、その裏側で実際に何が起こっているか(どんなAWSリソースが作られているか)の両方を理解できます。将来、トラブルシューティングが必要になった際にも、「このCDKコードは実際にはこういうAWSリソースを作っているはず」と推測できるようになります。
もしTypeScriptコードに文法エラーがあると、cdk synth の段階でエラーが表示されます。TypeScriptの型チェックにより、「存在しないプロパティを指定している」「必須パラメータが不足している」といったミスをデプロイ前に検出できます。これは、実行時エラーを防ぐ大きな利点です。
cdk synth はデプロイ前の検証にも使えます。コードを書いたらすぐに cdk synth を実行し、エラーがないか確認する習慣をつけると、開発効率が向上します。
【解説】なぜCDKはTypeScriptから直接AWSにデプロイせず、CloudFormationを経由するのか
初心者の方は、「TypeScriptでAWSリソースを定義しているのに、なぜわざわざCloudFormationテンプレートに変換してからデプロイするのか?直接AWSにデプロイすれば良いのでは?」と疑問に思うかもしれません。これには重要な理由があります。
1. CloudFormationの強力な状態管理機能を活用するため
CloudFormationは、AWSが提供する「インフラの状態を管理する」専門のサービスです。CloudFormationを使うと、「現在どのリソースが存在するか」「どのリソースとどのリソースが関連しているか」「リソースの変更履歴」などを、AWSが自動的に記録・管理してくれます。
もしCDKがTypeScriptコードから直接AWSリソースを作成すると、「どのリソースがCDKで作成されたのか」「どのリソースを削除すべきか」を自分で管理しなければなりません。これは非常に複雑で、ミスが発生しやすい作業です。例えば、VPCを削除する際に、サブネット、ルートテーブル、インターネットゲートウェイなど、関連するリソースを正しい順序で削除しなければエラーが発生します。CloudFormationを使えば、この依存関係の解決をAWSが自動的に行ってくれます。
2. デプロイ失敗時の自動ロールバック機能
CloudFormationには、デプロイ中にエラーが発生した場合、自動的に「元の状態に戻す(ロールバック)」機能があります。例えば、VPC、サブネット、インターネットゲートウェイまで作成できたが、NATゲートウェイの作成でエラーが発生した場合、CloudFormationは自動的に作成済みのリソースを全て削除し、デプロイ前の状態に戻してくれます。
もし直接AWSリソースを作成していたら、途中でエラーが発生した場合、中途半端な状態のリソースが残ってしまい、手動でクリーンアップする必要があります。これは、夜中のデプロイで失敗した場合など、非常に厄介な状況を引き起こします。CloudFormationの自動ロールバック機能により、「デプロイは成功するか、完全に失敗するか」のどちらかになり、中途半端な状態が残りません。
3. 変更の差分検出と最小限の更新
CloudFormationは、「現在の状態」と「新しい状態」の差分を自動的に検出し、必要最小限の変更だけを行います。例えば、ECSタスクのCPU設定だけを変更した場合、CloudFormationはVPCやサブネットには一切触れず、ECSタスク定義だけを更新します。
もし直接AWSリソースを操作していたら、「どのリソースが変更されたか」「どのリソースは変更不要か」を自分で判定しなければなりません。これは大規模なインフラになると非常に複雑になります。CloudFormationを経由することで、この差分検出が自動化されます。
4. 複数環境での再現性の確保
CloudFormationテンプレートは、単なるYAMLファイルです。このファイルをGitで管理し、開発環境、ステージング環境、本番環境で同じテンプレートを使用することで、全く同じ構成のインフラを複数の環境で再現できます。CDKはTypeScriptコードからCloudFormationテンプレートを生成するため、「TypeScriptコードという開発者が書きやすい形式」と「CloudFormationテンプレートという再現性の高い形式」の両方のメリットを享受できます。
実際の流れの比喩
これを建築で例えると、CDKは「建築士が作成する設計図」で、CloudFormationは「建築確認申請を通過した正式な施工図」に相当します。建築士は使いやすいCADソフトで設計図を作成しますが、実際に建物を建てる際には、役所に提出して承認を得た「正式な施工図」が必要です。役所が承認した施工図があることで、「この建物は建築基準法に適合している」「工事の進捗を管理できる」「問題が発生したら施工図を見れば原因がわかる」というメリットがあります。
同様に、CDKというわかりやすいTypeScriptコードで記述し、CloudFormationという正式な形式に変換することで、AWSの強力な管理機能を活用できるのです。
3-3. VPCのデプロイ
- デプロイ前に、変更内容を確認します
cdk diff以下のような出力が表示され、作成されるリソースが一覧表示されます。
Stack CdkIacProjectStack
Resources
[+] AWS::EC2::VPC MyVpc MyVpcXXXXXXXX
[+] AWS::EC2::Subnet MyVpc/PublicSubnet1/Subnet PublicSubnet1SubnetXXXXXXXX
[+] AWS::EC2::Subnet MyVpc/PrivateSubnet1/Subnet PrivateSubnet1SubnetXXXXXXXX
...【解説】cdk diffで安全にインフラ変更を確認する
cdk diff は、「現在AWSに存在するインフラ」と「これからデプロイしようとしているCDKコード」の差分を表示する、非常に重要なコマンドです。このコマンドを実行せずにいきなり cdk deploy を実行するのは、地図を見ずに知らない道を運転するようなもので、非常に危険です。
diffが表示する記号の意味
cdk diff の出力には、以下の記号が使われます。これらの記号を理解することで、「何が起こるのか」を正確に把握できます:
-
[+](プラス)新規作成 - このリソースは新しく作成されます。初回デプロイの場合、すべてのリソースに [+] が付きます。例:
[+] AWS::EC2::VPC MyVpcは、VPCが新しく作成されることを意味します。 -
[~](チルダ)変更 - 既存のリソースが変更されます。例えば、ECSタスクのCPU設定を変更した場合、
[~] AWS::ECS::TaskDefinitionと表示されます。変更内容の詳細も表示されるため、「どのプロパティが変わるのか」を確認できます。 -
[-](マイナス)削除 - このリソースは削除されます。これが最も注意すべき記号です。例えば、
[-] AWS::RDS::DBInstance MyDatabaseと表示された場合、データベースが削除されることを意味します。本番環境でこの記号を見たら、必ず立ち止まって「本当に削除して良いのか」を確認してください。 -
[+-](プラスマイナス)置き換え - リソースが一度削除され、新しく作り直されます。これは非常に危険な操作で、例えばデータベースの場合、データが全て失われます。
[+-] AWS::RDS::DBInstanceと表示されたら、設定変更が原因でRDSが再作成されることを意味します。この場合、先にデータベースのスナップショットを取得するなど、慎重な対応が必要です。
なぜdiffが重要なのか
実務では、cdk diff を実行せずにデプロイすることは、ほぼあり得ません。以下のような重大な事故を防ぐために、必ず実行します:
事故例1:意図しないリソース削除 - あなたがCDKコードをリファクタリングしていたとします。VPCの定義を別のStackファイルに移動したつもりが、実は元のコードを削除しただけで、新しい場所には追加していませんでした。この状態で cdk deploy を実行すると、VPCが削除され、そのVPC上で動いている全てのアプリケーションが停止します。しかし、事前に cdk diff を実行していれば、[-] AWS::EC2::VPC MyVpc という表示を見て、「おかしい、VPCが削除されるはずがない!」と気づき、事故を防げます。
事故例2:データベースの予期しない再作成 - RDSのインスタンスクラスを db.t3.micro から db.t3.small に変更したとします。多くの場合、これは単純な変更([~])として処理されますが、特定のパラメータを変更すると、RDSが再作成([+-])される場合があります。cdk diff を実行せずにデプロイすると、データベースが削除され、全てのデータが失われます。しかし、cdk diff で [+-] AWS::RDS::DBInstance を確認していれば、「これは再作成だ!先にスナップショットを取らないと!」と気づけます。
事故例3:セキュリティグループの意図しない変更 - セキュリティグループのルールを変更したつもりが、誤って既存のルールを削除していたとします。cdk diff を実行すれば、[-] SecurityGroupIngress 0.0.0.0/0:443 のような表示で、HTTPSアクセスのルールが削除されることがわかります。これに気づかずデプロイすると、Webサイトが外部からアクセスできなくなります。
diffの実際の読み方
cdk diff の出力は、最初は少し読みにくいかもしれませんが、慣れると非常に有用です。以下のような流れで確認します:
-
まずStackの名前を確認 -
Stack CdkIacProjectStackという行で、どのStackに変更が適用されるかを確認します。 -
削除や置き換えがある場合は理由を考える - 「なぜこのリソースが削除されるのか?」「本当に削除して良いのか?」を自問します。意図通りでない場合は、CDKコードを見直します。
ベストプラクティス
実務では、以下のようにdiffを活用します:
-
デプロイ前に必ずdiffを実行 -
cdk diffを実行してから、内容を確認し、問題がなければcdk deployを実行する習慣をつけます。 -
CI/CDパイプラインでもdiffを表示 - GitHub ActionsなどのCI/CDパイプラインでも、
cdk diffの結果をPull Requestのコメントとして自動投稿することで、レビュアーが変更内容を確認しやすくなります。
cdk diff は、「転ばぬ先の杖」です。このコマンドを習慣化することで、多くの事故を未然に防げます。
- 問題がなければ、実際にAWS環境にデプロイします
cdk deploy --region us-east-1確認プロンプトが表示されたら、y を入力してEnterキーを押します。
Do you wish to deploy these changes (y/n)? yデプロイが完了すると、以下のような出力が表示されます。
✅ CdkIacProjectStack
Outputs:
CdkIacProjectStack.VpcId = vpc-0123456789abcdef0
Stack ARN:
arn:aws:cloudformation:us-east-1:123456789012:stack/CdkIacProjectStack/...【解説】cdk deployのデプロイフローとトラブルシューティング
cdk deploy は、実際にCloudFormationスタックを作成し、AWSリソースを構築するコマンドです。デプロイ中は、CloudFormationがリソースの作成状況をリアルタイムで表示します。デプロイに失敗した場合、CloudFormationは自動的にロールバック(元の状態に戻す)を実行するため、環境が中途半端な状態で残ることはありません。
デプロイ時間は、作成するリソースの種類と数によって異なります。VPCとサブネットだけなら1〜2分程度ですが、RDSデータベースやNATゲートウェイを含む場合は5〜10分かかることもあります。デプロイ中にエラーが発生した場合は、エラーメッセージをよく読み、原因を特定してください。多くの場合、IAM権限不足、リソース制限(例:EIPの上限超過)、設定ミス(例:CIDRブロックの重複)が原因です。
デプロイ失敗時の自動ロールバックとno-rollbackオプション
CloudFormationのデフォルト動作では、デプロイ中にエラーが発生すると、作成済みのリソースを全て削除して元の状態に戻します(ロールバック)。これは本番環境では安全な動作ですが、開発中にエラーの原因を調査したい場合は、むしろ不便なことがあります。
例えば、VPC、サブネット、セキュリティグループまでは正常に作成できたが、ECSタスク定義でエラーが発生したとします。デフォルトのロールバックが実行されると、せっかく作成されたVPCやサブネットも全て削除されてしまいます。そして次にデプロイを試すと、また最初からVPCの作成から始まり、時間がかかります。
このような場合に便利なのが --no-rollback オプションです:
cdk deploy --no-rollbackこのオプションを使用すると、デプロイ失敗時にロールバックが実行されず、成功したリソースはそのまま残ります。これにより、以下のメリットがあります:
メリット1:エラー原因の調査が容易になる - 失敗した状態のリソースがAWS上に残るため、AWSコンソールで実際の設定を確認できます。例えば、セキュリティグループのルールが正しく設定されているか、IAM Roleが適切にアタッチされているかなど、実物を見ながら原因を特定できます。
メリット2:再デプロイの時間短縮 - 成功したリソースはそのまま使用できるため、エラーを修正して再度 cdk deploy を実行すると、失敗した部分だけを再度作成しようとします。VPCやサブネットの作成を繰り返す必要がないため、デプロイ時間が大幅に短縮されます。
メリット3:繰り返し試行できる - 開発環境で新しい構成を試す際、何度もデプロイに失敗することがあります。--no-rollback を使えば、成功した部分を保持しながら、失敗した部分だけを修正して再挑戦できます。
注意点:no-rollbackを使った後のクリーンアップ
--no-rollback でデプロイに失敗した後、CloudFormationスタックは「UPDATE_FAILED」や「CREATE_FAILED」という状態になります。この状態のスタックは、通常の cdk deploy では更新できません。以下の手順でクリーンアップする必要があります:
方法1:エラーを修正してロールバックなしで再デプロイ
cdk deploy --no-rollback同じく --no-rollback オプションを付けて再度デプロイすると、失敗した部分だけを再度作成しようとします。エラーを修正していれば、今度は成功する可能性が高いです。
方法2:スタックを削除して最初からやり直す
cdk destroyエラーの原因が複雑で、最初からやり直したい場合は、cdk destroy でスタック全体を削除してから、再度 cdk deploy を実行します。
方法3:AWSコンソールでスタックを削除 CloudFormationコンソールから、失敗したスタックを手動で削除することもできます。ただし、依存関係があるリソースは手動で削除する必要がある場合があります。
実務での使い分け
-
開発環境・学習目的 -
--no-rollbackを積極的に使用して、エラーの原因を調査し、素早く修正・再デプロイします。リソースが残っても問題ないため、試行錯誤しやすいです。 -
本番環境 -
--no-rollbackは使用しません。デフォルトのロールバック機能により、デプロイに失敗した場合でも、確実に元の安定した状態に戻ります。中途半端な状態でサービスが停止することを防ぎます。
その他の便利なオプション
cdk deploy --require-approval never オプションを使用すると、確認プロンプトをスキップして自動的にデプロイできます。CI/CDパイプラインでは、このオプションを使用することが多いです。ただし、手動デプロイの場合は、確認プロンプトで変更内容を再確認するのがベストプラクティスです。
3-4. AWSコンソールでの確認
-
AWSマネジメントコンソール にログインします
-
VPCダッシュボードを開き、作成されたVPCを確認します
- サービス検索で「VPC」と入力してVPCダッシュボードを開く
- 左メニューから「お使いのVPC」を選択
- 「CdkIacProjectStack/MyVpc」という名前のVPCが表示されていることを確認
-
サブネットの確認
- 左メニューから「サブネット」を選択
- パブリックサブネット2つ(PublicSubnet1、PublicSubnet2)とプライベートサブネット2つ(PrivateSubnet1、PrivateSubnet2)が作成されていることを確認
-
インターネットゲートウェイの確認
- 左メニューから「インターネットゲートウェイ」を選択
- VPCにアタッチされたインターネットゲートウェイが作成されていることを確認
-
NATゲートウェイの確認
- 左メニューから「NATゲートウェイ」を選択
- 1つの NAT ゲートウェイ が作成されていることを確認
-
ルートテーブルの確認
- 左メニューから「ルートテーブル」を選択
- パブリックサブネット用とプライベートサブネット用のルートテーブルが作成されていることを確認
- パブリックサブネットのルートテーブルには、0.0.0.0/0 → インターネットゲートウェイのルートが設定されていることを確認
- プライベートサブネットのルートテーブルには、0.0.0.0/0 → NATゲートウェイのルートが設定されていることを確認
【解説】VPCのCIDRブロックとサブネット設計
VPCには、CIDRブロック(例:10.0.0.0/16)というIPアドレスの範囲を指定します。この範囲内で、サブネットにIPアドレスを割り当てます。CIDRブロックの「/16」は、ネットワーク部分のビット数を表し、/16の場合、10.0.0.0 〜 10.0.255.255 の65,536個のIPアドレスが使用可能です。
サブネットには、CIDRマスク(例:/24)を指定します。/24の場合、256個のIPアドレスが使用可能ですが、AWSはサブネットごとに最初の4個と最後の1個のIPアドレスを予約するため、実際に使用可能なIPアドレスは251個です。予約されるIPアドレスは以下の通りです。10.0.0.0はネットワークアドレス、10.0.0.1はVPCルーターのアドレス、10.0.0.2はAmazon提供のDNSサーバーのアドレス、10.0.0.3はAWSで将来使用するために予約されたアドレス、10.0.0.255はブロードキャストアドレスです。
パブリックサブネットとプライベートサブネットの違いは、「ルートテーブルにインターネットゲートウェイへのルート(0.0.0.0/0)が設定されているかどうか」です。パブリックサブネットには、このルートが設定されているため、外部からのアクセスが可能です。プライベートサブネットには、このルートが設定されていない、またはNATゲートウェイへのルートが設定されているため、外部から直接アクセスできません。
マルチAZ構成では、各アベイラビリティゾーンにパブリックサブネットとプライベートサブネットをそれぞれ配置します。これにより、片方のAZが障害を起こしても、もう片方のAZで運用を継続できます。AWS CDKの maxAzs: 2 は、2つのAZにサブネットを自動配置してくれるため、手動で設定する必要がありません。
4. CDKコードのGit管理
CDKコードをバージョン管理し、チームで共有できるようにします。
4-1. Gitリポジトリの初期化
- プロジェクトディレクトリをGitリポジトリとして初期化します
git init.gitignoreファイルが自動生成されていることを確認します(CDK initが自動作成)
cat .gitignore以下のような内容が表示されます。
*.js
!jest.config.js
*.d.ts
node_modules
# CDK asset staging directory
.cdk.staging
cdk.out- 初回コミットを作成します
git add .
git commit -m "Initial CDK project with VPC"【解説】IaCコードのバージョン管理のベストプラクティス
Infrastructure as Code(IaC)の最大のメリットの一つは、インフラの変更履歴をGitで管理できることです。Gitでバージョン管理することで、「誰が」「いつ」「何を」変更したかが明確になり、問題が発生した場合には、過去の状態にすぐに戻せます。
.gitignore ファイルには、Gitで管理すべきでないファイルを指定します。AWS CDKプロジェクトでは、node_modules/(npmでインストールしたパッケージ)、cdk.out/(生成されたCloudFormationテンプレート)、*.js(TypeScriptからコンパイルされたJavaScriptファイル)などは、Gitで管理する必要がありません。これらは、TypeScriptコードから自動生成されるため、ソースコードのみをGitで管理します。
コミットメッセージは、変更内容を簡潔に説明する文章にします。良いコミットメッセージの例としては、「Add VPC with public and private subnets」「Update ECS task definition to use 512 CPU」「Fix security group rule for ALB」などがあります。悪いコミットメッセージの例としては、「update」「fix」「wip」などの曖昧な表現は避けましょう。
ブランチ戦略として、本番環境のインフラを管理する場合は、GitFlowやGitHub Flowなどのブランチ戦略を採用することが推奨されます。例えば、main ブランチは本番環境、develop ブランチは開発環境、feature/xxx ブランチは機能追加用、という使い分けができます。CDK Pipelinesと組み合わせることで、ブランチにプッシュしたら自動的にAWS環境にデプロイされる仕組みも構築できます。
このステップで何をしたのか
このステップでは、AWS CDKの基礎を学び、VPCをTypeScriptコードで構築しました。具体的には、AWS CDKのインストール、CDKプロジェクトの初期化、VPC・サブネット・インターネットゲートウェイのコード化、そして cdk deploy による実際のAWS環境へのデプロイを行いました。また、CDKコードをGitで管理し、変更履歴を記録する仕組みも構築しました。
このインフラでどのような影響があるのか
この構成により、コンテナアプリケーションを動かすための「ネットワーク基盤」が完成しました。VPCという独自のネットワーク空間が確保され、パブリックサブネットとプライベートサブネットが適切に区分けされました。また、インターネットゲートウェイにより、外部からのアクセスが可能になりました。
従来、これらのリソースはAWSコンソールで手作業で作成していましたが、AWS CDKを使うことで、TypeScriptコードで記述し、cdk deploy というコマンド1つで全てを自動構築できるようになりました。これは、家を建てるときに、設計図(CDKコード)を書いて3Dプリンター(AWS CDK)で自動構築するようなものです。
次のステップでは、このVPC上にECSクラスターとALBを構築し、コンテナアプリケーションを動かす準備をします。
技術比較まとめ表
| 技術領域 | AWS | オンプレミス |
|---|---|---|
| IaCツール | AWS CDK TypeScriptでインフラを記述し、CloudFormationテンプレートを自動生成 | Terraform、Ansible HCLやYAMLでインフラを記述し、マルチクラウド対応可能 |
| ネットワーク分離 | VPC 論理的に分離されたネットワーク空間をソフトウェアで定義 | VLAN、物理的なネットワーク分離 スイッチやルーターで物理的に分離 |
| サブネット設計 | パブリックサブネット/プライベートサブネット ルートテーブルで制御、即座に変更可能 | DMZ/内部ネットワーク 物理的な配線変更が必要、変更に時間がかかる |
| インターネット接続 | インターネットゲートウェイ VPCにアタッチするだけで外部接続が可能、マネージドサービス | ルーター、ファイアウォール 物理機器の購入・設置・設定が必要 |
| 高可用性 | マルチAZ構成 複数のデータセンター(AZ)に自動分散配置、AWSがインフラを管理 | 複数データセンター構成 自社で複数拠点を用意し、レプリケーション設定 |
| デプロイ時間 | cdk deploy で1〜2分 コマンド1つで全リソースを自動構築 | 数時間〜数日 物理機器の調達、ラックマウント、配線、設定を手作業で実施 |
| 変更管理 | Git + CloudFormation コードで管理、変更履歴を自動記録、いつでもロールバック可能 | 構成管理ツール + ドキュメント 手動でドキュメント更新、変更履歴が属人化 |
| コスト | 従量課金 使用した分だけ課金、不要になったら即座に削除してコスト削減 | 初期投資大 ハードウェア購入、データセンター賃料、保守費用が固定費 |
学習において重要な技術的違い
1. インフラのコード化による再現性と自動化
- AWS:TypeScriptコードでインフラを記述し、
cdk deployで何度でも同じ構成を再現できる。開発環境、ステージング環境、本番環境を同一コードで管理可能 - オンプレミス:手順書やドキュメントに基づいて手作業で構築するため、人的ミスが発生しやすく、環境ごとに微妙な差異が生じる
2. 高可用性の実現方法
- AWS:マルチAZ構成を
maxAzs: 2という1行のコードで実現。AWSが物理的なデータセンター間のネットワークを管理 - オンプレミス:複数のデータセンターを契約し、専用線で接続し、レプリケーション設定を手動で行う。数百万円〜数千万円の初期投資が必要
3. ネットワーク設計の柔軟性
- AWS:サブネットのCIDRブロックやルートテーブルをコードで変更し、数分でデプロイ可能。間違えてもロールバックが容易
- オンプレミス:VLANやルーターの設定変更には、ネットワーク機器の再設定や配線変更が必要。変更に数時間〜数日かかる
4. コストモデルの違い
- AWS:初期費用ゼロ、従量課金。VPCやサブネット自体は無料で、NATゲートウェイやインターネットゲートウェイの通信量に課金
- オンプレミス:ルーター、スイッチ、ファイアウォールなどのハードウェアを購入する必要があり、初期投資が数十万円〜数百万円。さらに、データセンター賃料、電気代、保守費用が毎月発生
実践チェック:CDKコードと実行結果で証明しよう
下記のチェック項目について、実際にCDKコードを記述し、cdk deploy で構築できていることを確認し、各項目ごとに該当画面のスクリーンショットを撮影して提出してください。
-
AWS CDK CLIがインストールされ、
cdk --versionでバージョンが表示される -
CDKプロジェクトが正常に初期化され、
cdk.json、package.json、bin/、lib/ディレクトリが存在する -
cdk bootstrapが成功し、CDKToolkit CloudFormationスタックがAWS環境に作成されている -
VPCのCDKコード(
lib/cdk-iac-project-stack.ts)が正しく記述され、TypeScriptのコンパイルエラーがない -
cdk synthが成功し、CloudFormationテンプレートがcdk.out/ディレクトリに生成される -
cdk diffを実行し、作成されるリソース(VPC、サブネット、IGW、ルートテーブルなど)が一覧表示される -
cdk deployが成功し、AWSコンソールのVPCダッシュボードでVPCが作成されていることを確認できる -
パブリックサブネット2つとプライベートサブネット2つが、2つのアベイラビリティゾーンに配置されている
-
インターネットゲートウェイがVPCにアタッチされている
-
パブリックサブネットのルートテーブルに、0.0.0.0/0 → インターネットゲートウェイのルートが設定されている
-
CDKコードがGitリポジトリで管理され、初回コミットが作成されている
提出方法: 各項目ごとにスクリーンショットを撮影し、まとめて提出してください。 ファイル名やコメントで「どの項目か」が分かるようにしてください。 CDKコードのスクリーンショットでは、コード全体が見えるようにしてください。
構成図による理解度チェック
このステップで作成したVPC構成図を作成し、ネットワーク基盤を可視化しましょう。
なぜ構成図を作成するのか?
IaCでインフラを構築する場合でも、構成図を作成することは非常に重要です。構成図は、チームメンバーやステークホルダーに対して、インフラの全体像を視覚的に伝えるツールです。コードだけでは、ネットワークの全体的な流れや、リソース間の関係性を直感的に理解することは困難です。
構成図を作成することで、「このVPCにはいくつのサブネットがあるのか」「パブリックサブネットとプライベートサブネットはどのように配置されているのか」「外部からのアクセスはどのルートを通るのか」といった情報を一目で把握できます。また、構成図を作成するプロセス自体が、インフラの理解を深める学習になります。
- ネットワークの全体像の把握: VPC、サブネット、IGW、ルートテーブルの関係性を視覚化する
- アベイラビリティゾーンの理解: 2つのAZにリソースがどのように分散配置されているかを確認する
- 通信経路の理解: 外部からパブリックサブネットへのアクセス経路を確認する
構成図の書き方
draw.io、Lucidchart、AWS公式のアイコンセットなどを使用して、以下の構成図を作成してみましょう。
- VPC: 最も外側に大きな四角形を描き、「VPC (10.0.0.0/16)」とラベルを付ける
- アベイラビリティゾーン: VPCの中に2つの領域(AZ-1、AZ-2)を描く
- パブリックサブネット: 各AZ内に1つずつパブリックサブネット(10.0.0.0/24、10.0.1.0/24)を描く
- プライベートサブネット: 各AZ内に1つずつプライベートサブネット(10.0.2.0/24、10.0.3.0/24)を描く
- インターネットゲートウェイ: VPCの外部に配置し、VPCに接続する線を引く
- NATゲートウェイ: パブリックサブネット(AZ-1)内に配置する
- 通信経路: IGW → パブリックサブネット、プライベートサブネット → NATゲートウェイ → IGW の矢印を描く
💡 ヒント: AWS公式のアーキテクチャアイコンを使用すると、プロフェッショナルな構成図が作成できます。AWS Architecture Icons からダウンロードできます。
理解度チェック:なぜ?を考えてみよう
AWSの各リソースや設計には、必ず”理由”や”目的”があります。 下記の「なぜ?」という問いに自分なりの言葉で答えてみましょう。 仕組みや設計意図を自分で説明できることが、真の理解につながります。 ぜひ、単なる暗記ではなく「なぜそうなっているのか?」を意識して考えてみてください。
Q. なぜVPCを作成する際に、CIDRブロック(例:10.0.0.0/16)を指定する必要があるのですか?また、/16、/24、/32などの数字は何を意味しているのですか?
Q. なぜパブリックサブネットとプライベートサブネットを分ける必要があるのですか?すべてのリソースをパブリックサブネットに配置してはいけないのですか?
Q. なぜマルチAZ構成(2つのアベイラビリティゾーンにリソースを配置する)が推奨されるのですか?単一のAZに全てのリソースを配置する場合と比較して、どのようなメリットがありますか?
Q. AWS CDKで cdk synth を実行すると、CloudFormationテンプレートが生成されます。なぜCDKはTypeScriptコードを直接実行してAWSリソースを作成するのではなく、わざわざCloudFormationテンプレートを経由するのですか?
Q. cdk bootstrap を実行すると、S3バケットとECRリポジトリが作成されます。なぜCDKはこれらのリソースを必要とするのですか?何のために使用されるのですか?
今回のステップで利用したAWSサービス名一覧
- AWS CDK:TypeScriptでAWSインフラを記述し、CloudFormationテンプレートを自動生成するIaCフレームワーク
- VPC:AWS上で独自のネットワーク空間を構築する仮想ネットワーク
- サブネット:VPCを分割して、パブリック/プライベートのネットワークセグメントを作成
- インターネットゲートウェイ:VPCとインターネットを接続するゲートウェイ
- NATゲートウェイ:プライベートサブネット内のリソースがインターネットにアクセスするための代理ゲートウェイ
- CloudFormation:AWSリソースをテンプレートで管理するインフラ自動化サービス(CDKの内部で使用)