3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GPT-4oで手書きのスケッチからAWS CDKのコードを生成してみた

Last updated at Posted at 2024-05-14

はじめに

スケッチから HTML を生成できるなら、CDK のコードも生成できるのでは?と思い、試してみました。

試してみる

画像解析力を試したいので、あえてプロンプトは入力しませんでした。

image.png

生成結果です。プロンプトがないためか英語で応答されましたが、期待通り CDK のコードが生成されました。画像の中に書かれた指示まで読み取ってくれるのは、確かに便利ですね。

image.png

付け加えておくと、最初の指示は「CDK でよろしく」だけでした。意に反して Python のコードが生成されたため「TypeScript で」を追加しました。

生成されたコードはこちらです。

import * as cdk from 'aws-cdk-lib';
import { Stack, StackProps } from 'aws-cdk-lib';
import { Vpc, SubnetType, InstanceType, InstanceClass, InstanceSize, MachineImage } from 'aws-cdk-lib/aws-ec2';
import { ApplicationLoadBalancer, ApplicationProtocol, ListenerAction } from 'aws-cdk-lib/aws-elasticloadbalancingv2';
import { Construct } from 'constructs';

export class MyVpcStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // Create a VPC
    const vpc = new Vpc(this, 'MyVpc', {
      maxAzs: 2,
      subnetConfiguration: [
        {
          subnetType: SubnetType.PUBLIC,
          name: 'PublicSubnet',
        },
        {
          subnetType: SubnetType.PRIVATE_WITH_NAT,
          name: 'PrivateSubnet',
        },
      ],
    });

    // Create an Application Load Balancer
    const alb = new ApplicationLoadBalancer(this, 'MyALB', {
      vpc,
      internetFacing: true,
    });

    // Add a listener to the ALB
    const listener = alb.addListener('Listener', {
      protocol: ApplicationProtocol.HTTP,
      defaultAction: ListenerAction.fixedResponse(200, {
        contentType: 'text/plain',
        messageBody: 'Hello, world!',
      }),
    });

    // Add EC2 instances in the private subnets
    const ec2Instance1 = new ec2.Instance(this, 'EC2Instance1', {
      vpc,
      instanceType: InstanceType.of(InstanceClass.T2, InstanceSize.MICRO),
      machineImage: MachineImage.latestAmazonLinux(),
      vpcSubnets: {
        subnetType: SubnetType.PRIVATE_WITH_NAT,
      },
    });

    const ec2Instance2 = new ec2.Instance(this, 'EC2Instance2', {
      vpc,
      instanceType: InstanceType.of(InstanceClass.T2, InstanceSize.MICRO),
      machineImage: MachineImage.latestAmazonLinux(),
      vpcSubnets: {
        subnetType: SubnetType.PRIVATE_WITH_NAT,
      },
    });

    // Add the instances to the ALB target group
    listener.addTargets('EC2Targets', {
      port: 80,
      targets: [ec2Instance1, ec2Instance2],
    });
  }
}

CDKコードのエラーを修正する

CDK プロジェクトを作成し、上記のコードで置き換えます。

mkdir my-vpc
cd my-vpc/
npx cdk init -l typescript

エディタで開くと、エラーが表示されているので、修正します。

image.png

修正したコードはこちらです。

エラーと deplicated な箇所を修正し、ALB -> EC2 のトラフィック許可を追加しました。

lib/my-vpc-stack.ts
- import * as cdk from 'aws-cdk-lib';
import { Stack, StackProps } from 'aws-cdk-lib';
- import { Vpc, SubnetType, InstanceType, InstanceClass, InstanceSize, MachineImage } from 'aws-cdk-lib/aws-ec2';
+ import { Vpc, SubnetType, InstanceType, InstanceClass, InstanceSize, MachineImage, Instance, Port } from 'aws-cdk-lib/aws-ec2';
import { ApplicationLoadBalancer, ApplicationProtocol, ListenerAction } from 'aws-cdk-lib/aws-elasticloadbalancingv2';
+ import * as elbv2_tg from 'aws-cdk-lib/aws-elasticloadbalancingv2-targets'
import { Construct } from 'constructs';

export class MyVpcStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // Create a VPC
    const vpc = new Vpc(this, 'MyVpc', {
      maxAzs: 2,
      subnetConfiguration: [
        {
          subnetType: SubnetType.PUBLIC,
          name: 'PublicSubnet',
        },
        {
-         subnetType: SubnetType.PRIVATE_WITH_NAT,
+         subnetType: SubnetType.PRIVATE_WITH_EGRESS,
          name: 'PrivateSubnet',
        },
      ],
    });

    // Create an Application Load Balancer
    const alb = new ApplicationLoadBalancer(this, 'MyALB', {
      vpc,
      internetFacing: true,
    });

    // Add a listener to the ALB
    const listener = alb.addListener('Listener', {
      protocol: ApplicationProtocol.HTTP,
      defaultAction: ListenerAction.fixedResponse(200, {
        contentType: 'text/plain',
        messageBody: 'Hello, world!',
      }),
    });

    // Add EC2 instances in the private subnets
-   const ec2Instance1 = new ec2.Instance(this, 'EC2Instance1', {
+   const ec2Instance1 = new Instance(this, 'EC2Instance1', {
      vpc,
      instanceType: InstanceType.of(InstanceClass.T2, InstanceSize.MICRO),
-     machineImage: MachineImage.latestAmazonLinux(),      
+     machineImage: MachineImage.latestAmazonLinux2023(),
      vpcSubnets: {
-       subnetType: SubnetType.PRIVATE_WITH_NAT,
+       subnetType: SubnetType.PRIVATE_WITH_EGRESS,
      },
    });
+   ec2Instance1.connections.allowFrom(alb, Port.tcp(80), 'Allow inbound traffic on port 80 from the ALB only');

-   const ec2Instance1 = new ec2.Instance(this, 'EC2Instance2', {
+   const ec2Instance2 = new Instance(this, 'EC2Instance2', {
      vpc,
      instanceType: InstanceType.of(InstanceClass.T2, InstanceSize.MICRO),
-     machineImage: MachineImage.latestAmazonLinux(),      
+     machineImage: MachineImage.latestAmazonLinux2023(),
      vpcSubnets: {
-       subnetType: SubnetType.PRIVATE_WITH_NAT,
+       subnetType: SubnetType.PRIVATE_WITH_EGRESS,
      },
    });
+   ec2Instance2.connections.allowFrom(alb, Port.tcp(80), 'Allow inbound traffic on port 80 from the ALB only');

    // Add the instances to the ALB target group
    listener.addTargets('EC2Targets', {
      port: 80,
-     targets: [ec2Instance1, ec2Instance2],      
+     targets: [new elbv2_tg.InstanceTarget(ec2Instance1), new elbv2_tg.InstanceTarget(ec2Instance2)],
    });
  }
}

動作確認する

デプロイします。

$ npx cdk deploy
# Do you wish to deploy these changes (y/n)? y
# MyVpcStack: deploying... [1/1]
# MyVpcStack: creating CloudFormation changeset...

#  ✅  MyVpcStack

# ✨  Deployment time: 222.7s

# Stack ARN:
# arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/MyVpcStack/9cebe450-1230-11ef-bf56-0a943cda165d

# ✨  Total time: 226.68s

Web サーバーを構成していないのでヘルスチェックでエラーになっていますが、リソースは期待どおりに作成されました。

image.png

ALB の DNS 名にアクセスします。

curl http://MyVpcS-MyALB-UrksBygjrlzv-1011360440.ap-northeast-1.elb.amazonaws.com
# <html>
# <head><title>502 Bad Gateway</title></head>
# <body>
# <center><h1>502 Bad Gateway</h1></center>
# </body>
# </html>

ヘルスチェックが通っていないので、502 Bad Gateway が返ってきますが、EC2 インスタンスを構成すれば、正常に動作するはずです。

まとめ

GPT-4o でスケッチから CDK のコードを生成できました。画像の中に書かれた指示まで読み取ってくれたのは、驚きました。生成されたコードにはエラーがありましたが、修正して正常に動作することを確認しました。

本番環境など品質を求められる用途には精査が必要ですが、プロトタイピングやデモンストレーションなどには十分使えると思います。

3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?