はじめに
スケッチから HTML を生成できるなら、CDK のコードも生成できるのでは?と思い、試してみました。
試してみる
画像解析力を試したいので、あえてプロンプトは入力しませんでした。
生成結果です。プロンプトがないためか英語で応答されましたが、期待通り CDK のコードが生成されました。画像の中に書かれた指示まで読み取ってくれるのは、確かに便利ですね。
付け加えておくと、最初の指示は「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
エディタで開くと、エラーが表示されているので、修正します。
修正したコードはこちらです。
エラーと deplicated な箇所を修正し、ALB -> EC2 のトラフィック許可を追加しました。
- 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 サーバーを構成していないのでヘルスチェックでエラーになっていますが、リソースは期待どおりに作成されました。
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 のコードを生成できました。画像の中に書かれた指示まで読み取ってくれたのは、驚きました。生成されたコードにはエラーがありましたが、修正して正常に動作することを確認しました。
本番環境など品質を求められる用途には精査が必要ですが、プロトタイピングやデモンストレーションなどには十分使えると思います。