[アップデート] Amazon Q Developer IDE のコンテキスト機能がイメージをサポートしたので AWS アーキテクチャ構成図から CloudFormation テンプレートを作成させてみた

[アップデート] Amazon Q Developer IDE のコンテキスト機能がイメージをサポートしたので AWS アーキテクチャ構成図から CloudFormation テンプレートを作成させてみた

Clock Icon2025.07.21

いわさです。

少し前ですが Amazon Q Developer IDE がアップデートされコンテキスト機能がイメージファイルをサポートしました。v1.83.0 以降で使うことができます。

23325090-4737-4B07-A8F6-94CB656ADB5A.png

この機能を使うことで、画像を含めた指示が出来るようになるので、例えば UI のイメージやシーケンス図などからコードを生成したり、構成図などからインフラテンプレートなどを作成することが出来るようになります。
あるいは私は AWS のアーキテクチャ構成図ベースでのレビューなどを行うことも多いので、構成図を与えて Q Developer を活用したレビューなども出来そうです。とても良さそうです。

使い方

使い方は非常に簡単で、今回のアップデートでコンテキスト機能に「Image」が追加されています。

DCD64CC5-9ECE-4346-B3C6-BAC9D6A84CAB.png

こちらを選択すると次のようにファイル選択ダイアログが表示されるのでローカル上の画像ファイルを指定します。

D6C132D2-2175-42C7-B611-E1C40250EB22.png

そうするとコンテキストとして認識されるようになります。
もちろん少し前にアップデートされたコンテキストのピン留めにも対応しています。[1]

54648798-2C3A-4D5A-A49C-63AD7649B361_4_5005_c.jpeg

AWS アーキテクチャ構成図から CloudFormation テンプレートを作成してみた

今回は AWS の builders.flash の記事の中にある適当な AWS アーキテクチャ構成図から CloudFormation テンプレートを作成させてみました。
先ほどの流れで以下の画像をコンテキストとして追加します。

img_way-to-draw-architecture_03.08e1366ebaecaf76a333002acbe1e2bd363acd4b.png
AWS のアーキテクチャ図を描きたい ! でもどうすれば良いの ? - 変化を求めるデベロッパーを応援するウェブマガジン | AWSより

そして、CloudFormation テンプレートを作成するよう指示します。
すると、構成図を読み込んでそれを基にテンプレートを作成してくれそうですね。

AB6CF2E1-8502-41DE-B21E-BA5BF8027E4E.png

VPC、EC2、RDS、ALB、S3 については含んでくれていそうです。ただ、Route53 や CloudFront が含まれていないですね。おやおや。

と思ったら、テンプレートの初版作成後に勝手にブラッシュアップしはじめまして、Route 53、CloudFront を追加し、更に VPN Gateway まで追加しようとしてくれています。ちゃんと細かいところまで見てますね。

67905C37-25E7-4C2F-94EA-FAC4B954A59E.png

それっぽいテンプレートをさっと作成して終わるのではなく、その後も作っては検証を行って細かい調整を繰り返してくれます。

image.png

最終的に出来上がったテンプレートは以下です。私が確認した限りではかなり高品質なテンプレートが出来上がっていると思いました。これが特に設定なしですぐに使えるのはすごい。

作成された CloudFormation テンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Enterprise web application infrastructure with Route 53, CloudFront, VPC, EC2, RDS, Elastic Load Balancing, S3, and VPN Gateway'

Parameters:
  KeyPairName:
    Type: AWS::EC2::KeyPair::KeyName
    Description: EC2 Key Pair for SSH access
  
  DBPassword:
    Type: String
    NoEcho: true
    MinLength: 8
    Description: RDS database password
  
  DomainName:
    Type: String
    Description: Domain name for the application
    Default: example.com
  
  CustomerGatewayIP:
    Type: String
    Description: Public IP address of the customer gateway
    AllowedPattern: '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'
  


Resources:
  # VPC
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: MainVPC

  # Internet Gateway
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: MainIGW

  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  # Public Subnets
  PublicSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: PublicSubnet-A

  PublicSubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.2.0/24
      AvailabilityZone: !Select [1, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: PublicSubnet-B

  # Private Subnets
  PrivateSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.3.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      Tags:
        - Key: Name
          Value: PrivateSubnet-A

  PrivateSubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.4.0/24
      AvailabilityZone: !Select [1, !GetAZs '']
      Tags:
        - Key: Name
          Value: PrivateSubnet-B

  # Route Tables
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: PublicRouteTable

  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:
      SubnetId: !Ref PublicSubnetA
      RouteTableId: !Ref PublicRouteTable

  PublicSubnetBRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetB
      RouteTableId: !Ref PublicRouteTable

  # Security Groups
  ELBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for Elastic Load Balancer
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
          Description: HTTP access from internet
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
          Description: HTTPS access from internet
      Tags:
        - Key: Name
          Value: ELB-SecurityGroup

  EC2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for Amazon EC2 instances
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          SourceSecurityGroupId: !Ref ELBSecurityGroup
          Description: HTTP access from ELB
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 10.0.0.0/16
          Description: SSH access from VPC
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 192.168.0.0/16
          Description: SSH access from corporate network
      Tags:
        - Key: Name
          Value: EC2-SecurityGroup

  RDSSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for Amazon RDS database
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          SourceSecurityGroupId: !Ref EC2SecurityGroup
          Description: MySQL access from EC2 instances
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          CidrIp: 192.168.0.0/16
          Description: MySQL access from corporate network
      Tags:
        - Key: Name
          Value: RDS-SecurityGroup

  # Elastic Load Balancing
  ElasticLoadBalancer:
    Type: AWS::ElasticLoadBalancing::LoadBalancer
    Properties:
      LoadBalancerName: WebApp-ELB
      Scheme: internet-facing
      Subnets:
        - !Ref PublicSubnetA
        - !Ref PublicSubnetB
      SecurityGroups:
        - !Ref ELBSecurityGroup
      Listeners:
        - LoadBalancerPort: 80
          InstancePort: 80
          Protocol: HTTP
      HealthCheck:
        Target: HTTP:80/
        HealthyThreshold: 3
        UnhealthyThreshold: 5
        Interval: 30
        Timeout: 5
      Instances:
        - !Ref EC2InstanceA
        - !Ref EC2InstanceB
      Tags:
        - Key: Name
          Value: Elastic-Load-Balancing

  # EC2 Instances
  EC2InstanceA:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0d52744d6551d851e  # Amazon Linux 2023 (Tokyo region)
      InstanceType: t3.micro
      KeyName: !Ref KeyPairName
      SubnetId: !Ref PrivateSubnetA
      SecurityGroupIds:
        - !Ref EC2SecurityGroup
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          yum update -y
          yum install -y httpd
          systemctl start httpd
          systemctl enable httpd
          echo "<h1>Web Server A - Tokyo Region</h1>" > /var/www/html/index.html
      Tags:
        - Key: Name
          Value: WebServer-A

  EC2InstanceB:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: ami-0d52744d6551d851e  # Amazon Linux 2023 (Tokyo region)
      InstanceType: t3.micro
      KeyName: !Ref KeyPairName
      SubnetId: !Ref PrivateSubnetB
      SecurityGroupIds:
        - !Ref EC2SecurityGroup
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          yum update -y
          yum install -y httpd
          systemctl start httpd
          systemctl enable httpd
          echo "<h1>Web Server B - Tokyo Region</h1>" > /var/www/html/index.html
      Tags:
        - Key: Name
          Value: WebServer-B

  # RDS Subnet Group
  DBSubnetGroup:
    Type: AWS::RDS::DBSubnetGroup
    Properties:
      DBSubnetGroupDescription: Subnet group for RDS database
      SubnetIds:
        - !Ref PrivateSubnetA
        - !Ref PrivateSubnetB
      Tags:
        - Key: Name
          Value: DBSubnetGroup

  # RDS Primary Database (Availability Zone A)
  RDSPrimaryDatabase:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceIdentifier: webapp-db-primary
      DBInstanceClass: db.t3.micro
      Engine: mysql
      EngineVersion: '8.0'
      AllocatedStorage: 20
      MasterUsername: admin
      MasterUserPassword: !Ref DBPassword
      VPCSecurityGroups:
        - !Ref RDSSecurityGroup
      DBSubnetGroupName: !Ref DBSubnetGroup
      BackupRetentionPeriod: 7
      MultiAZ: false
      AvailabilityZone: !Select [0, !GetAZs '']
      Tags:
        - Key: Name
          Value: WebAppDatabase-Primary
        - Key: Location
          Value: Availability-Zone-A

  # RDS Read Replica (Secondary) - Availability Zone B
  RDSSecondaryDatabase:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceIdentifier: webapp-db-secondary
      SourceDBInstanceIdentifier: !Ref RDSPrimaryDatabase
      DBInstanceClass: db.t3.micro
      AvailabilityZone: !Select [1, !GetAZs '']
      VPCSecurityGroups:
        - !Ref RDSSecurityGroup
      Tags:
        - Key: Name
          Value: WebAppDatabase-Secondary
        - Key: Location
          Value: Availability-Zone-B

  # S3 Bucket
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub 'webapp-bucket-${AWS::AccountId}-${AWS::Region}'
      PublicAccessBlockConfiguration:
        BlockPublicAcls: false
        BlockPublicPolicy: false
        IgnorePublicAcls: false
        RestrictPublicBuckets: false
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html

  # S3 Bucket Policy for CloudFront
  S3BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref S3Bucket
      PolicyDocument:
        Statement:
          - Sid: AllowCloudFrontAccess
            Effect: Allow
            Principal:
              AWS: !Sub 'arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${CloudFrontOriginAccessIdentity}'
            Action: 's3:GetObject'
            Resource: !Sub '${S3Bucket}/*'

  # CloudFront Origin Access Identity
  CloudFrontOriginAccessIdentity:
    Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
    Properties:
      CloudFrontOriginAccessIdentityConfig:
        Comment: !Sub 'OAI for ${AWS::StackName}'

  # CloudFront Distribution
  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Origins:
          - Id: S3Origin
            DomainName: !GetAtt S3Bucket.RegionalDomainName
            S3OriginConfig:
              OriginAccessIdentity: !Sub 'origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}'
          - Id: ELBOrigin
            DomainName: !GetAtt ElasticLoadBalancer.DNSName
            CustomOriginConfig:
              HTTPPort: 80
              OriginProtocolPolicy: http-only
        DefaultCacheBehavior:
          TargetOriginId: ELBOrigin
          ViewerProtocolPolicy: redirect-to-https
          AllowedMethods:
            - GET
            - HEAD
            - OPTIONS
            - PUT
            - POST
            - PATCH
            - DELETE
          CachedMethods:
            - GET
            - HEAD
          ForwardedValues:
            QueryString: true
            Cookies:
              Forward: none
        CacheBehaviors:
          - PathPattern: '/static/*'
            TargetOriginId: S3Origin
            ViewerProtocolPolicy: redirect-to-https
            AllowedMethods:
              - GET
              - HEAD
            CachedMethods:
              - GET
              - HEAD
            ForwardedValues:
              QueryString: false
              Cookies:
                Forward: none
        Enabled: true
        Comment: !Sub 'CloudFront distribution for ${AWS::StackName} - Global CDN'
        DefaultRootObject: index.html
        PriceClass: PriceClass_100
        ViewerCertificate:
          CloudFrontDefaultCertificate: true

  # Route 53 Hosted Zone
  Route53HostedZone:
    Type: AWS::Route53::HostedZone
    Properties:
      Name: !Ref DomainName
      HostedZoneConfig:
        Comment: !Sub 'Hosted zone for ${DomainName}'

  # Route 53 Record for CloudFront
  Route53Record:
    Type: AWS::Route53::RecordSet
    Properties:
      HostedZoneId: !Ref Route53HostedZone
      Name: !Ref DomainName
      Type: A
      AliasTarget:
        DNSName: !GetAtt CloudFrontDistribution.DomainName
        HostedZoneId: Z2FDTNDATAQYW2  # CloudFront hosted zone ID

  # Customer Gateway
  CustomerGateway:
    Type: AWS::EC2::CustomerGateway
    Properties:
      Type: ipsec.1
      BgpAsn: 65000
      IpAddress: !Ref CustomerGatewayIP
      Tags:
        - Key: Name
          Value: Corporate-Data-Center-Gateway

  # VPN Gateway
  VPNGateway:
    Type: AWS::EC2::VpnGateway
    Properties:
      Type: ipsec.1
      Tags:
        - Key: Name
          Value: VPN-Gateway

  # VPN Gateway Attachment
  VPNGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      VpnGatewayId: !Ref VPNGateway

  # VPN Connection
  VPNConnection:
    Type: AWS::EC2::VpnConnection
    Properties:
      Type: ipsec.1
      StaticRoutesOnly: true
      CustomerGatewayId: !Ref CustomerGateway
      VpnGatewayId: !Ref VPNGateway
      Tags:
        - Key: Name
          Value: Corporate-VPN-Connection

  # VPN Connection Route
  VPNConnectionRoute:
    Type: AWS::EC2::VpnConnectionRoute
    Properties:
      VpnConnectionId: !Ref VPNConnection
      DestinationCidrBlock: 192.168.0.0/16  # Corporate network CIDR

  # Private Route Table for VPN
  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: PrivateRouteTable

  # Route to VPN Gateway
  VPNRoute:
    Type: AWS::EC2::Route
    DependsOn: VPNGatewayAttachment
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      DestinationCidrBlock: 192.168.0.0/16
      VpnGatewayId: !Ref VPNGateway

  # Associate Private Subnets with Private Route Table
  PrivateSubnetARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnetA
      RouteTableId: !Ref PrivateRouteTable

  PrivateSubnetBRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnetB
      RouteTableId: !Ref PrivateRouteTable

Outputs:
  VPCId:
    Description: VPC ID
    Value: !Ref VPC
    Export:
      Name: !Sub '${AWS::StackName}-VPC-ID'

  LoadBalancerDNS:
    Description: Elastic Load Balancer DNS name
    Value: !GetAtt ElasticLoadBalancer.DNSName

  CloudFrontDomainName:
    Description: CloudFront Distribution Domain Name
    Value: !GetAtt CloudFrontDistribution.DomainName

  Route53HostedZoneId:
    Description: Route 53 Hosted Zone ID
    Value: !Ref Route53HostedZone

  S3BucketName:
    Description: S3 Bucket Name
    Value: !Ref S3Bucket

  PrimaryDatabaseEndpoint:
    Description: RDS Primary Database Endpoint
    Value: !GetAtt RDSPrimaryDatabase.Endpoint.Address

  SecondaryDatabaseEndpoint:
    Description: RDS Secondary Database Endpoint
    Value: !GetAtt RDSSecondaryDatabase.Endpoint.Address

  VPNGatewayId:
    Description: VPN Gateway ID
    Value: !Ref VPNGateway

  CustomerGatewayId:
    Description: Customer Gateway ID
    Value: !Ref CustomerGateway

先日のアップデートであるルールファイルをうまく使うことで、さらに意図通りのテンプレートが作れそうですね。すごいです。

https://dev.classmethod.jp/articles/qdev-context-project-rules/

さいごに

本日は Amazon Q Developer IDE のコンテキスト機能がイメージをサポートしたので AWS アーキテクチャ構成図から CloudFormation テンプレートを作成させてみました。

Amazon Q Developer 以外でたまにこういった画像から何か指示を行うことはありましたが、Amazon Q Developer で使いやすくなったのは嬉しいです。

ファイルタイプとしては JPEG、PNG、GIF、WebP がサポートされており、最大サイズは 3.75 MB まで、サイズは 8,000 x 8,000 ピクセル以下であること、ひとつのメッセージに最大 20 枚までという制限や上限が一応ありますのでそのあたりも気にしながら使ってみてください。詳細は以下に記載されていました。

https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/ide-chat-context.html#image-context

脚注
  1. [アップデート] Amazon Q Developer IDE でコンテキストのピン留めが出来るようになりました | DevelopersIO ↩︎

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.