0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

未経験エンジニアがAmazon Q DeveloperでCloudFormationを書いてみたら爆速だった話

0
Posted at

はじめに

以前に初心者(私)が初心者向けに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で開きます。
{948B8A31-97B0-45FC-90E7-DE1FF8507DF5}.png

注意事項としてこのファイルはデスクトップでもどこでもいいので一度保存しましょう。
保存しておかないと拡張機能がファイルを読み込めない可能性があります。

あとはテンプレートとして記述したい内容をAmazonQに送ると、AmazonQがファイルを書き換えてくれます。

{ABDAA479-386E-4C47-9A95-B60439B6AB74}.png

ちなみにチャット機能を使用しないで、エディタ上でコメント行を書くことでもコードを提案してくれます。

{7CB1C10F-74A9-4787-B25F-643021A018F8}.png

ちょっと分かりづらいですが、エディタ上で薄くなっている部分が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に慣れれば、こんな長いテンプレートもすぐに記述できます。

ここで表示できます
.yaml

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で動作しています。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?