はじめに
以前に初心者(私)が初心者向けにCloudFormationテンプレート作成記事を書きましたが、初心者でもとっつきやすくてもっと手軽にテンプレートを作成する方法がないか調べてみました。
そしたら、下記の記事を発見し、参考にしてみました。
AWS のリソース構築の自動化に取り組んでみよう ! ~ AWS CloudFormation テンプレートの効率的な作成方法(AWSウェブマガジン)
■4. Amazon CodeWhisperer の活用
Amazon Whisperer は、AI により生成されたコードを提案・自動挿入できるツールです。求めるコードについてコメントに自然言語で記述すれば、Amazon CodeWhisperer がそのコメントの内容や既存のコードから、次に書くべきコードを提案してくれます。
Amazon CodeWhisperer は、Python や JavaScript、TypeScript、Go などのアプリケーションを作成するコードを提案してくれるだけでなく、AWS CloudFormation の JSON や YAML のテンプレートや、AWS Cloud Development Kit (AWS CDK) (TypeScript、Python)、HashiCorp Terraform (HCL) のコードの提案も可能です。
今回はこれを実践してみたらCloudFormationテンプレート作成がめちゃくちゃ捗りました。
ちなみにCodeWhispererは現在はAmazonQに統合されているようです。
したがって、今回はAmazonQの実践です。
上記記事は少し古いようなので現在ではもっといいツールが存在するのかもしれませんが、温かい目で見守っていただけると嬉しいです。
私について
2026年1月からITエンジニア完全未経験でSESに転職しました。
前職は自動車業界に10年程度在籍していました。
保有資格は下記3つ
- AWS CLF
- AWS SAA
- Linuc レベル1
前職在籍中に時間を作って独学で学習し、1年ほどかけて取得しました。
いずれも試験問題を解くだけの知識としては保有しておりますが、実際にAWSマネジメントコンソールやターミナル上での操作をほとんどやったことがない所謂エアプ状態です。
前提条件
Visual Studio Codeがインストールしてあること
今回はVSCodeの拡張機能を使用します。
バージョンは1.113.0で実施しました。
実践
拡張機能追加
下記リンクを参考にしましょう。
AmazonQを使ってみる
AmazonQの拡張機能が正常にインストールされていれば、VSCodeにAmazonQのアイコンが追加されるのでそれを開けばAIとのチャットが可能です。
まずは空のyamlファイルを作成し、VSCodeで開きます。

注意事項としてこのファイルはデスクトップでもどこでもいいので一度保存しましょう。
保存しておかないと拡張機能がファイルを読み込めない可能性があります。
あとはテンプレートとして記述したい内容をAmazonQに送ると、AmazonQがファイルを書き換えてくれます。
ちなみにチャット機能を使用しないで、エディタ上でコメント行を書くことでもコードを提案してくれます。
ちょっと分かりづらいですが、エディタ上で薄くなっている部分がAmazonQの提案です。
AWSTemplateFormatVersion: "2010-09-09"
Resources:
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
#インターネットゲートウェイを作成 #このコメント行を入力し、Enter
InternetGateway: #数秒後にこの行以下の記述を提案してくれた
Type: AWS::EC2::InternetGateway
#VPCにインターネットゲートウェイをアタッチ #上記のコメント行からIGWのアタッチも同時に提案してくれた
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref MyVPC
試しに作成したテンプレート
初心者でもAmazonQに慣れれば、こんな長いテンプレートもすぐに記述できます。
ここで表示できます
AWSTemplateFormatVersion: "2010-09-09"
Resources:
# VPCの作成
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
Tags:
- Key: Name
Value: test-vpc
# パブリックサブネットを2つ作成
PublicSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: VPC
CidrBlock: 10.0.1.0/24
AvailabilityZone:
Fn::Select:
- 0
- Fn::GetAZs: ""
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: public-subnet-1a
PublicSubnetC:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: VPC
CidrBlock: 10.0.2.0/24
AvailabilityZone:
Fn::Select:
- 1
- Fn::GetAZs: ""
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: public-subnet-1c
# プライベートサブネットを4つ作成
PrivateSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: VPC
CidrBlock: 10.0.11.0/24
AvailabilityZone:
Fn::Select:
- 0
- Fn::GetAZs: ""
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: private-subnet-1a
PrivateSubnetB:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: VPC
CidrBlock: 10.0.12.0/24
AvailabilityZone:
Fn::Select:
- 1
- Fn::GetAZs: ""
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: private-subnet-1c
PrivateSubnetC:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: VPC
CidrBlock: 10.0.21.0/24
AvailabilityZone:
Fn::Select:
- 0
- Fn::GetAZs: ""
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: db-subnet-1a
PrivateSubnetD:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: VPC
CidrBlock: 10.0.22.0/24
AvailabilityZone:
Fn::Select:
- 1
- Fn::GetAZs: ""
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: db-subnet-1c
# サブネットグループ作成
DBSubnetGroup:
Type: AWS::RDS::DBSubnetGroup
Properties:
DBSubnetGroupDescription: Subnet group for RDS
SubnetIds:
- Fn::GetAtt:
- PrivateSubnetC
- SubnetId
- Fn::GetAtt:
- PrivateSubnetD
- SubnetId
Tags:
- Key: Name
Value: db-subnet-group
# Internet Gatewayの作成
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: test-IGW
# IGWをVPCにアタッチ
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId:
Ref: InternetGateway
VpcId:
Ref: VPC
# パブリックルートテーブルの作成
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId:
Ref: VPC
Tags:
- Key: Name
Value: test-RT-Public
# パブリックルートテーブルへのルート追加
PublicRoute:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId:
Ref: PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId:
Ref: InternetGateway
# パブリックサブネットとパブリックルートテーブルの関連付け
PublicSubnetARouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId:
Ref: PublicRouteTable
SubnetId:
Ref: PublicSubnetA
PublicSubnetCRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId:
Ref: PublicRouteTable
SubnetId:
Ref: PublicSubnetC
# NatGatewayを1つ作成
NatGateway:
Type: AWS::EC2::NatGateway
Properties:
AllocationId:
Fn::GetAtt:
- ElasticIP
- AllocationId
SubnetId:
Ref: PublicSubnetA
Tags:
- Key: Name
Value: test-Nat-1a
# EIPの作成
ElasticIP:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
Tags:
- Key: Name
Value: test-EIP
# プライベートルートテーブルの作成
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId:
Ref: VPC
Tags:
- Key: Name
Value: test-RT-Private
# プライベートルートテーブルへのルート追加
PrivateRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId:
Ref: PrivateRouteTable
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId:
Ref: NatGateway
# プライベートサブネットとプライベートルートテーブルの関連付け
PrivateSubnetARouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId:
Ref: PrivateRouteTable
SubnetId:
Ref: PrivateSubnetA
PrivateSubnetBRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId:
Ref: PrivateRouteTable
SubnetId:
Ref: PrivateSubnetB
# privatesubnet用S3VPCエンドポイント作成
S3VPCGatewayEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
VpcId:
Ref: VPC
ServiceName:
Fn::Sub:
- com.amazonaws.${Region}.s3
- Region:
Ref: AWS::Region
VpcEndpointType: Gateway
RouteTableIds:
- Ref: PrivateRouteTable
# パブリックサブネットにALBを作成
ALB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: test-ALB
Subnets:
- Ref: PublicSubnetA
- Ref: PublicSubnetC
SecurityGroups:
- Ref: ALBSecurityGroup
Scheme: internet-facing
Type: application
IpAddressType: ipv4
# ALB用のセキュリティグループを作成
ALBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security Group for Application Load Balancer
VpcId:
Ref: VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: test-alb-sg
AlbEgressRule:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: !Ref ALBSecurityGroup
IpProtocol: tcp
FromPort: 80
ToPort: 80
DestinationSecurityGroupId: !Ref EC2SecurityGroup
# プライベートサブネットにEC2を作成
EC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0f373f45fcf743d30
InstanceType: t3a.xlarge
KeyName: test-prod-web
NetworkInterfaces:
- AssociatePublicIpAddress: false
DeviceIndex: 0
SubnetId:
Ref: PrivateSubnetA
GroupSet:
- Ref: EC2SecurityGroup
IamInstanceProfile:
Ref: EC2InstanceProfile
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
VolumeSize: 100
VolumeType: gp3
DeleteOnTermination: true
Encrypted: true
UserData:
Fn::Base64: !Sub |
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
# CloudWatch Agentインストール
yum install -y amazon-cloudwatch-agent
# SSL設定用(Let's Encryptまたは証明書設定)
yum install -y mod_ssl
# アプリケーションのデプロイ設定
# [アプリケーション固有の設定を記載]
Tags:
- Key: Name
Value: test-web
# EC2用のセキュリティグループを作成
EC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security Group for EC2 Instance
VpcId:
Ref: VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/32
- IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: !Ref ALBSecurityGroup
Tags:
- Key: Name
Value: test-ec2-sg
#EC2-1
Ec2EgressRule1:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: !Ref EC2SecurityGroup
IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
#EC2-2
Ec2EgressRule2:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: !Ref EC2SecurityGroup
IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
#EC2-3
Ec2EgressRule3:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: !Ref EC2SecurityGroup
IpProtocol: tcp
FromPort: 3306
ToPort: 3306
DestinationSecurityGroupId: !Ref RDSSecurityGroup
# EC2インスタンスプロファイルの作成
EC2InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- Ref: EC2Role
# EC2ロールの作成
EC2Role:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Tags:
- Key: Name
Value: test-Role
#RDSを作成(MySQL)
RDS:
Type: AWS::RDS::DBInstance
Properties:
DBInstanceIdentifier: test-RDS2
DBSubnetGroupName:
Ref: DBSubnetGroup
Engine: mysql
EngineVersion: 8.4.6
MasterUsername: admin
MasterUserPassword: RDSPassword123!
DBInstanceClass: db.t3.xlarge
AllocatedStorage: 100
StorageType: gp3
VPCSecurityGroups:
- Ref: RDSSecurityGroup
BackupRetentionPeriod: 7
DeletionProtection: false
MultiAZ: false
Tags:
- Key: Name
Value: test-RDS2
# RDSのセキュリティグループの作成
RDSSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security Group for RDS
VpcId:
Ref: VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 3306
ToPort: 3306
SourceSecurityGroupId: !Ref EC2SecurityGroup
Tags:
- Key: Name
Value: test-rds-sg
# キーペア作成
KeyName:
Type: AWS::EC2::KeyPair
Properties:
KeyName: test-prod-web
Tags:
- Key: Name
Value: test-prod-web
まとめ
以前に下記記事においては、テンプレート作成したいなら、AWSドキュメントのリファレンスからひな形を持ってきましょう~なんて話しましたが、この機能があればその手間もなくなるし、AIが前後の記述を把握して適切な記述をしてくれるからめちゃくちゃ捗ると感じました。
実際面白いように記述できて、夢中になれましたし、スタック作成も成功したので有用なツールです。
さいごに
まだまだ初心者ですが、日々自己研鑽を頑張っていこうと思います。
CloudFormationテンプレート作成ツールでもっといいものあるよ!というのがあれば、コメント欄で教えていただけると嬉しいです。
職場で導入した際にはプロキシ環境でAmazonQが上手くいかない場面があり、下記記事を参考にしました。
職場でプロキシ環境の方はプロキシ設定を確認しましょう。
ちなみにVSCodeの拡張機能でAmazonQの他にCloudFormation Linterを入れており、こちらはテンプレートの間違いや不整合にすぐ気づける機能なので追加するとさらにテンプレート作成が捗ります。
私は下記記事を参考にしました。
注意点が1つあり、手順の中でPythonランタイムをインストールするのですが、CloudFormation LinterがPython 3.13までの対応となっているようです。
私はPython 3.14を入れたら上手くいきませんでした。
最終的に私はPython 3.13.12で動作しています。

