はじめに
「コンソールで20ステップかかったVPC設計をコードで再現したい」——それを実現するのが AWS CloudFormation です。
この記事では、template.yaml 1ファイルにVPC・サブネット・ルートテーブル・セキュリティグループ・EC2(2台)を定義し、コマンド1本でAP+DB 2層構成を一括構築するハンズオンを紹介します。コンソール版(AWSコンソール版ハンズオン)と全く同じ構成を、CloudFormationで自動化します。
ローカル環境(VSCode)
└── template.yaml + AWS CLI
↓ スタック作成(コマンド1本)
AWS環境
└── VPC(10.0.0.0/16)
├── インターネットゲートウェイ
│
├── [パブリックサブネット 10.0.1.0/24]
│ ├── パブリックルートテーブル(0.0.0.0/0 → IGW)
│ └── APサーバEC2(Apache / パブリックIP あり)
│
└── [プライベートサブネット 10.0.2.0/24]
├── プライベートルートテーブル(VPC内のみ)
├── S3 VPC Gateway Endpoint(dnf用・無料)
└── DBサーバEC2(MariaDB / パブリックIP なし)このハンズオンで体験できること:
- VPC・サブネット・IGW・ルートテーブルを
template.yaml1ファイルで定義する方法 - S3 VPC Gateway Endpoint の
DependsOnによる起動順序制御 SubnetIdでEC2の配置サブネットを明示する方法aws cloudformation create-stackコマンド1本での17リソース一括デプロイdelete-stackによる複雑な依存関係を持つVPCリソースの一括削除
このハンズオンの特徴:
- コンソール版では20ステップ以上・30〜40分かかった作業が、コマンド1本(8〜12分)で完了
delete-stack1本でVPC・サブネット・IGW・RTの依存関係を自動解決して削除
-->
CloudFormation vs コンソール:どれだけ違うか
| 比較項目 | CloudFormation | コンソール(手動) |
|---|---|---|
| VPC・IGW・サブネット・RTの設定 | template.yaml に定義済み | 6画面・20ステップ以上 |
| S3 VPC Endpoint作成 | template.yaml に定義済み | 画面でポチポチ |
| EC2×2台の起動 | コマンド1本(並列作成) | 2回インスタンス起動操作 |
| 全体のデプロイ | コマンド1本(8〜12分) | 20ステップ以上(30〜40分) |
| 削除(依存関係あり) | delete-stack 1本(自動解決) | 8ステップ・手動管理 |
| 再現性 | 高い(同じ構成を何度でも再現可能) | 低い(手順漏れのリスク大) |
| バージョン管理 | Gitで管理可能 | 不可 |
キーワード解説
| 用語 | 意味 |
|---|---|
| CloudFormation | AWSが提供するIaC(Infrastructure as Code)サービス |
| スタック | CloudFormationが管理するリソースのまとまり。今回は17リソースを1スタックで管理 |
DependsOn | CloudFormationでリソースの作成順序を明示するプロパティ |
SubnetId | EC2インスタンスを特定のサブネットに配置するプロパティ |
| S3 VPC Gateway Endpoint | プライベートサブネットからS3にアクセスするための無料エンドポイント |
!Select [0, !GetAZs ''] | リージョン内の最初のAZを自動取得するCloudFormation関数 |
前提条件
| ツール | 確認コマンド | 最低バージョン目安 |
|---|---|---|
| AWS CLI v2 | aws --version | 2.x |
| Git | git --version | 2.x |
| VSCode | - | - |
AWS認証確認:
aws sts get-caller-identitytemplate.yaml の全文
以下が今回使用する template.yaml の全文です(17リソース)。プロジェクトフォルダ(ec2-2tier-web/)直下に配置します。
⚠️ コピー前に確認:
Default: '123.456.78.901/32'の箇所はダミーIPです。このまま使うとスタック作成は成功しますが、SSHもWebもアクセスできません。--parametersでIPを上書きするか(推奨)、Defaultを自分のIPに書き換えてから使ってください。
AWSTemplateFormatVersion: '2010-09-09'
Description: 'EC2 2-tier Architecture (AP + DB) with VPC public/private subnet separation (Phase 1-4)'
Parameters:
KeyName:
Type: String
Default: 'my-ec2-2tier-key'
Description: Name of an existing EC2 KeyPair
MyIP:
Type: String
Default: '123.456.78.901/32'
Description: Your IP address to allow SSH and HTTP access (CIDR format e.g. 203.0.113.1/32)
Resources:
# VPC and Network
# ============================================================
# VPC: isolated network space for this hands-on
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: 'my-vpc'
# Internet Gateway: connects the VPC to the internet
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: 'my-igw'
# Attach Internet Gateway to VPC
IGWAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
# Public Subnet: AP server goes here (internet accessible)
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select [0, !GetAZs '']
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: 'my-public-subnet'
# Private Subnet: DB server goes here (no direct internet access)
PrivateSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.2.0/24
AvailabilityZone: !Select [0, !GetAZs '']
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: 'my-private-subnet'
# Public Route Table: routes internet traffic via Internet Gateway
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: 'my-public-rt'
# Default route for public subnet: all traffic -> Internet Gateway
PublicRoute:
Type: AWS::EC2::Route
DependsOn: IGWAttachment
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
# Associate public subnet with public route table
PublicSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PublicRouteTable
# Private Route Table: no internet route (local traffic only)
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: 'my-private-rt'
# Associate private subnet with private route table
PrivateSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet
RouteTableId: !Ref PrivateRouteTable
# S3 VPC Gateway Endpoint: allows private subnet to reach S3 (for dnf package downloads)
# Gateway endpoints are FREE - no hourly charge
S3VPCEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId: !Ref VPC
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3'
VpcEndpointType: Gateway
RouteTableIds:
- !Ref PrivateRouteTable
# ============================================================
# IAM
# ============================================================
# IAM Role: allows EC2 to use Session Manager
EC2Role:
Type: AWS::IAM::Role
Properties:
RoleName: 'my-ec2-2tier-role'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Tags:
- Key: Name
Value: 'my-ec2-2tier-role'
EC2InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
InstanceProfileName: 'my-ec2-2tier-profile'
Roles:
- !Ref EC2Role
# ============================================================
# Security Groups
# ============================================================
# AP Server Security Group: SSH and HTTP from MyIP
APSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: 'my AP server SG (public subnet)'
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !Ref MyIP
Description: SSH from my IP
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: !Ref MyIP
Description: HTTP from my IP
Tags:
- Key: Name
Value: 'my-ap-sg'
# DB Server Security Group: MySQL from AP SG only, SSH from AP SG (via bastion)
DBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: 'my DB server SG (private subnet)'
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
SourceSecurityGroupId: !GetAtt APSecurityGroup.GroupId
Description: SSH from AP server only (bastion access)
- IpProtocol: tcp
FromPort: 3306
ToPort: 3306
SourceSecurityGroupId: !GetAtt APSecurityGroup.GroupId
Description: MySQL from AP server only (SG-to-SG control)
Tags:
- Key: Name
Value: 'my-db-sg'
# ============================================================
# EC2 Instances
# ============================================================
# AP Server: Apache in public subnet
APInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64}}'
InstanceType: t2.micro
KeyName: !Ref KeyName
SubnetId: !Ref PublicSubnet
SecurityGroupIds:
- !GetAtt APSecurityGroup.GroupId
IamInstanceProfile: !Ref EC2InstanceProfile
UserData:
Fn::Base64: |
#!/bin/bash
dnf update -y
dnf install -y httpd
systemctl start httpd
systemctl enable httpd
cat > /var/www/html/index.html << 'HTMLEOF'
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>AP Server - Phase 1-4</title></head>
<body>
<h1>AP Server (Public Subnet)</h1>
<p>This AP server is in the PUBLIC subnet and can reach the DB server in the PRIVATE subnet.</p>
</body>
</html>
HTMLEOF
Tags:
- Key: Name
Value: 'my-ap-instance'
# DB Server: MariaDB in private subnet (no public IP)
DBInstance:
Type: AWS::EC2::Instance
DependsOn:
- S3VPCEndpoint
- PrivateSubnetRouteTableAssociation
Properties:
ImageId: '{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64}}'
InstanceType: t2.micro
KeyName: !Ref KeyName
SubnetId: !Ref PrivateSubnet
SecurityGroupIds:
- !GetAtt DBSecurityGroup.GroupId
IamInstanceProfile: !Ref EC2InstanceProfile
UserData:
Fn::Base64: |
#!/bin/bash
dnf update -y
dnf install -y mariadb105-server mariadb105
systemctl start mariadb
systemctl enable mariadb
sudo mysql -u root << 'SQLEOF'
SET PASSWORD FOR root@localhost = PASSWORD('Admin1234!');
CREATE USER IF NOT EXISTS 'handson'@'%' IDENTIFIED BY 'Handson1234!';
GRANT ALL PRIVILEGES ON *.* TO 'handson'@'%' WITH GRANT OPTION;
CREATE DATABASE IF NOT EXISTS sampledb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
FLUSH PRIVILEGES;
SQLEOF
Tags:
- Key: Name
Value: 'my-db-instance'
Outputs:
VPCId:
Description: VPC ID
Value: !Ref VPC
APPublicIP:
Description: AP server public IP (open in browser or SSH)
Value: !GetAtt APInstance.PublicIp
DBPrivateIP:
Description: DB server private IP (connect via AP server bastion)
Value: !GetAtt DBInstance.PrivateIp
WebsiteURL:
Description: AP server website URL
Value: !Sub 'http://${APInstance.PublicIp}'
APSSHCommand:
Description: SSH command to AP server
Value: !Sub 'ssh -i C:\Users\username\.ssh\${KeyName}.pem ec2-user@${APInstance.PublicIp}'
DBSSHCommand:
Description: SSH command to DB server (run this FROM the AP server)
Value: !Sub 'ssh -i ~/.ssh/${KeyName}.pem ec2-user@${DBInstance.PrivateIp}'
MySQLConnectCommand:
Description: MySQL connect command (run this FROM the AP server)
Value: !Sub 'mysql -h ${DBInstance.PrivateIp} -u handson -pHandson1234! sampledb'template.yaml の重要ポイント:
1. VpcId を指定した SecurityGroup
カスタムVPCを使う場合は VpcId を明示します。VpcId を指定することで !GetAtt APSecurityGroup.GroupId が確実にSG IDを返します。
APSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref VPC # ← カスタムVPCを指定(必須)
DBSecurityGroup:
SecurityGroupIngress:
- SourceSecurityGroupId: !GetAtt APSecurityGroup.GroupId # ← !Refではなく!GetAtt2. S3 VPC Gateway Endpoint(無料)
プライベートサブネットのEC2は直接インターネットに出られませんが、Amazon Linux 2023のパッケージリポジトリはS3上にあります。S3 VPC Gateway EndpointをプライベートルートテーブルにアタッチするとS3経由で dnf install が動作します。
S3VPCEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcEndpointType: Gateway # Gatewayタイプは無料
ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3'
RouteTableIds:
- !Ref PrivateRouteTable # プライベートRTにS3ルートが追加される3. DBInstance の DependsOn
DBサーバEC2のUserDataが dnf install を実行するとき、S3 VPC Endpointが有効になっている必要があります。
DBInstance:
DependsOn:
- S3VPCEndpoint
- PrivateSubnetRouteTableAssociation4. SubnetId でサブネットを指定
EC2インスタンスがどのサブネットに配置されるかを明示します。
APInstance:
SubnetId: !Ref PublicSubnet # パブリックサブネットに配置
DBInstance:
SubnetId: !Ref PrivateSubnet # プライベートサブネットに配置構築されるリソース一覧(17個):
| # | リソース | 論理ID |
|---|---|---|
| 1 | VPC | VPC |
| 2 | インターネットゲートウェイ | InternetGateway |
| 3 | IGW-VPCアタッチ | IGWAttachment |
| 4 | パブリックサブネット | PublicSubnet |
| 5 | プライベートサブネット | PrivateSubnet |
| 6 | パブリックルートテーブル | PublicRouteTable |
| 7 | パブリックルート(→IGW) | PublicRoute |
| 8 | パブリックRT関連付け | PublicSubnetRouteTableAssociation |
| 9 | プライベートルートテーブル | PrivateRouteTable |
| 10 | プライベートRT関連付け | PrivateSubnetRouteTableAssociation |
| 11 | S3 VPC Gateway Endpoint | S3VPCEndpoint |
| 12 | IAMロール | EC2Role |
| 13 | インスタンスプロファイル | EC2InstanceProfile |
| 14 | APサーバSG | APSecurityGroup |
| 15 | DBサーバSG | DBSecurityGroup |
| 16 | APサーバEC2 | APInstance |
| 17 | DBサーバEC2 | DBInstance |
作業順序
⓪ 自分のIPアドレスを確認する
↓
① キーペアを作成する(コンソールで実施)
↓
② プロジェクトフォルダに移動する
↓
③ スタックを作成する(aws cloudformation create-stack)
↓
④ 作成完了・Outputsを確認する
↓
⑤ 動作確認(Web・踏み台SSH・MySQL接続)
↓
⑥ スタックを削除する(aws cloudformation delete-stack)⓪ 自分のIPアドレスを確認する
curl https://checkip.amazonaws.com控えておく情報: 自分のIPアドレス(例: 203.0.113.1)
① キーペアの作成(コンソールで実施)
キーペアのみコンソールで作成します。
AWSコンソール → EC2 → キーペア → 「キーペアを作成」
| 設定項目 | 値 |
|---|---|
| 名前 | my-ec2-2tier-key |
| キーペアのタイプ | RSA |
| プライベートキーファイル形式 | .pem |
C:\Users\ユーザー名\.ssh\my-ec2-2tier-key.pem② プロジェクトフォルダに移動する
cd C:\my-aws\aws-learning-projects\ec2-2tier-webdir template.yaml③ スタックの作成
203.0.113.1 は⓪で確認した自分のIPアドレスに置き換えてください。
aws cloudformation create-stack ^
--stack-name my-ec2-2tier-stack ^
--template-body file://template.yaml ^
--region ap-northeast-1 ^
--capabilities CAPABILITY_NAMED_IAM ^
--parameters ^
ParameterKey=KeyName,ParameterValue=my-ec2-2tier-key ^
ParameterKey=MyIP,ParameterValue=203.0.113.1/32各オプションの説明:
| オプション | 意味 |
|---|---|
--stack-name my-ec2-2tier-stack | スタック名(英字始まり) |
--template-body file://template.yaml | 使用するテンプレートファイル |
--region ap-northeast-1 | デプロイ先リージョン(東京) |
--capabilities CAPABILITY_NAMED_IAM | 名前付きIAMロール作成の明示的な許可 |
--parameters ... | テンプレートのParametersに渡す値 |
成功するとStackIdが表示されます。
{
"StackId": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/my-ec2-2tier-stack/xxxxx"
}④ 作成完了・Outputsの確認
スタック作成完了まで約8〜12分かかります(VPCリソース×10個 + EC2×2台 + MariaDBインストールの時間)。
作成状況の確認
aws cloudformation describe-stacks ^
--stack-name my-ec2-2tier-stack ^
--query "Stacks[0].StackStatus" ^
--output text| ステータス | 意味 |
|---|---|
CREATE_IN_PROGRESS | 作成中(しばらく待つ) |
CREATE_COMPLETE | 作成完了 |
CREATE_FAILED | 作成失敗(トラブルシューティングを参照) |
ROLLBACK_COMPLETE | 失敗してロールバック完了 |
Outputs の確認
aws cloudformation describe-stacks ^
--stack-name my-ec2-2tier-stack ^
--query "Stacks[0].Outputs" ^
--output table以下のような出力が表示されます。
--------------------------------------------------------------------------------------
| DescribeStacks |
+--------------------+---------------------------------------------------------------+
| OutputKey | OutputValue |
+--------------------+---------------------------------------------------------------+
| VPCId | vpc-xxxxxxxxxx |
| APPublicIP | x.x.x.x |
| DBPrivateIP | 10.0.2.xxx ← APサーバからの接続に使用 |
| WebsiteURL | http://x.x.x.x |
| APSSHCommand | ssh -i ...pem ec2-user@x.x.x.x |
| DBSSHCommand | ssh -i ~/.ssh/...pem ec2-user@10.0.2.xxx |
| MySQLConnectCommand| mysql -h 10.0.2.xxx -u handson -pHandson1234! sampledb |
+--------------------+---------------------------------------------------------------+控えておく情報:
APPublicIP: APサーバのパブリックIPDBPrivateIP: DBサーバのプライベートIP(10.0.2.xxx形式)APSSHCommand: APサーバへのSSHコマンドDBSSHCommand: APサーバからDBサーバへのSSHコマンドMySQLConnectCommand: APサーバから実行するMySQL接続コマンド
⑤ 動作確認
5-1. APサーバのWeb確認
WebsiteURL をブラウザで開きます。AP Server (Public Subnet) が表示されれば成功です。
5-2. APサーバへのSSH接続
APSSHCommand を実行します(パスを実際のパスに修正します)。
ssh -i C:\Users\ユーザー名\.ssh\my-ec2-2tier-key.pem ec2-user@(APPublicIP)5-3. キーペアをAPサーバにコピーする(踏み台SSH準備)
ローカルPCの別ターミナルで実行します:
scp -i C:\Users\ユーザー名\.ssh\my-ec2-2tier-key.pem ^
C:\Users\ユーザー名\.ssh\my-ec2-2tier-key.pem ^
ec2-user@(APPublicIP):~/.ssh/APサーバのSSHセッションでパーミッションを設定します。
chmod 400 ~/.ssh/my-ec2-2tier-key.pem5-4. APサーバ経由でDBサーバにSSH接続(踏み台接続)
APサーバのSSHセッションから実行します:
ssh -i ~/.ssh/my-ec2-2tier-key.pem ec2-user@(DBPrivateIP)[ec2-user@ip-10-0-2-xxx ~]$ が表示されれば踏み台接続成功です。
# DBサーバ上でMariaDBの状態を確認
sudo systemctl status mariadb
# MariaDBに接続
mysql -u root -pAdmin1234! -e "SHOW DATABASES;"
exit5-5. APサーバからMySQLに接続(AP→DB通信確認)
APサーバのSSHセッションに戻り、MySQLConnectCommand をそのまま実行します。
# mysqlクライアントをインストール
sudo dnf install -y mariadb105
# OutputsのMySQLConnectCommandをそのまま使う
mysql -h (DBPrivateIP) -u handson -pHandson1234! sampledbCREATE TABLE IF NOT EXISTS messages (id INT AUTO_INCREMENT PRIMARY KEY, text VARCHAR(100));
INSERT INTO messages (text) VALUES ('Hello from AP server!');
SELECT * FROM messages;
EXIT;exit⑥ スタックの削除
課金を止めるために、ハンズオン完了後は必ず削除してください。
CloudFormationはVPC・サブネット・IGW・RT・SG・EC2の依存関係を自動解決して正しい順序で削除します。
aws cloudformation delete-stack ^
--stack-name my-ec2-2tier-stack ^
--region ap-northeast-1削除完了まで約8〜12分かかります。
aws cloudformation describe-stacks ^
--stack-name my-ec2-2tier-stack ^
--query "Stacks[0].StackStatus" ^
--output text| ステータス | 意味 |
|---|---|
DELETE_IN_PROGRESS | 削除中(しばらく待つ) |
DELETE_FAILED | 削除失敗(トラブルシューティングを参照) |
削除完了の確認(以下のエラーが表示されれば削除完了)。
aws cloudformation describe-stacks ^
--stack-name my-ec2-2tier-stack ^
--region ap-northeast-1An error occurred (ValidationError) when calling the DescribeStacks operation:
Stack with id my-ec2-2tier-stack does not existキーペアは手動で削除します。
EC2 → キーペア → my-ec2-2tier-key → 「削除」
コンソール版との比較
コンソール版で20ステップ以上かかった作業が、CloudFormationでは template.yaml に定義されています。
| CFnの記述 | コンソールでやること |
|---|---|
VPC | VPC → VPCを作成 |
InternetGateway + IGWAttachment | IGWを作成 → VPCにアタッチ(2ステップ) |
PublicSubnet + PrivateSubnet | サブネットを2つ作成 |
PublicRouteTable + PublicRoute + PublicSubnetRouteTableAssociation | パブリックRTを作成・ルート追加・サブネット関連付け(3ステップ) |
PrivateRouteTable + PrivateSubnetRouteTableAssociation | プライベートRTを作成・サブネット関連付け(2ステップ) |
S3VPCEndpoint | VPCエンドポイントを作成 |
APSecurityGroup + DBSecurityGroup | SGを2つ作成(APサーバSG → DBサーバSGの順) |
APInstance + DBInstance | EC2を2回起動(各5〜10分) |
delete-stack | 8ステップの手動削除(依存関係を手動管理) |
トラブルシューティング
| 症状 | 原因 | 対処 |
|---|---|---|
CREATE_FAILED になる | キーペアが存在しない | コンソールでキーペアを確認・作成 |
CREATE_FAILED になる | 同名のIAMロールが既に存在する | IAMコンソールでロールを削除してから再実行 |
stackName failed to satisfy regular expression | スタック名が数字始まり | CloudFormationのスタック名は英字で始まる必要がある |
Unable to load paramfile エラー | template.yaml に日本語が含まれている | template.yaml のコメントは英語のみで記述する |
| DBサーバのMariaDBが起動していない | S3 VPC EndpointのRouteTableへの反映が遅延 | DBサーバに踏み台接続して sudo dnf install -y mariadb105-server を手動実行 |
| APサーバからDBにSSH接続できない | DBサーバSGのSSHソースが正しくない | CloudFormationのイベントログで CREATE_FAILED を確認 |
DELETE_FAILED になる | VPC内のリソースが残っている | コンソールで my-vpc 内の残存リソースを確認して手動削除 |
まとめ
今回のハンズオンで実現できたこと:
| 確認項目 | 内容 |
|---|---|
| VPCリソースのIaC化 | VPC・IGW・サブネット・RT 10リソースを template.yaml 1ファイルで定義 |
| S3 VPC Endpoint | DependsOn でDBサーバEC2の起動前にEndpointが有効になることを保証 |
| 一括デプロイ | create-stack 1本で17リソースを8〜12分で構築 |
| 依存関係の自動解決 | delete-stack 1本でVPC内のリソースを正しい順序で自動削除 |
| Outputs活用 | DBPrivateIP・MySQLConnectCommand が自動生成されるため手動でコマンドを組み立てる必要なし |
CloudFormationのメリットを実感できたポイント
- コンソール版では20ステップ以上・30〜40分かかった作業がコマンド1本(8〜12分)で完了
- VPC・サブネット・RT・SGの複雑な削除順序をCloudFormationが自動管理
template.yamlをGitで管理することで、ネットワーク設計の変更履歴が残せる
コンソール版と比較してみる
CloudFormationが裏で何をやっているか、同じ構成をAWSコンソールのみで構築する手順をまとめました。VPCリソースの作成・削除順序や依存関係を視覚的に確認できます。
AWSコンソールでVPC設計からAP+DB 2層構成を構築する手順
関連記事
-->
コメント