AWS CDKなるものを使うとコードでインフラを実装できるらしいです。 やってみます。
What Is the AWS CDK?
使い慣れたプログラミング言語でAWSリソースを定義できるもの。
サポート言語は - TypeScript - JavaScript - Python - Java - C#/.NET とのこと。
CDKの利点
個人的な利点は
- プログラムなのでCFnと比べてレビューの敷居が下がる
- 動的なインフラ定義の幅が広がる(予想)
やってみる
というわけで、やってみます。
環境
- VSCode
- 1.43.2
- node.js
- v12.11.0
- aws-cdk
- 1.31.0
- TypeScrippt
- 3.8.3
- aws-cdk
- v12.11.0
- aws-cli
- 1.18.31
環境構築参考: AWS CDK Intro Workshop > 前提条件
作りたい構成
良さげなサンプルソースがあったので参考にして以下のような構成になればいいなと思ってます。
aws-samples/aws-cdk-examples/ecs-service-with-advanced-alb-config
準備
プロジェクトを作成します。
cdk init sample-app --language typescript
libディレクトリに構築に使用するファイルが作成されます。
主にこのファイルをいじいじしていくらしいです。
import * as sns from '@aws-cdk/aws-sns'; import * as subs from '@aws-cdk/aws-sns-subscriptions'; import * as sqs from '@aws-cdk/aws-sqs'; import * as cdk from '@aws-cdk/core'; export class ElbSampleStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); const queue = new sqs.Queue(this, 'ElbSampleQueue', { visibilityTimeout: cdk.Duration.seconds(300) }); const topic = new sns.Topic(this, 'ElbSampleTopic'); topic.addSubscription(new subs.SqsSubscription(queue)); } }
TypeScriptなのでファイル監視をします。
npm run watch
とりあえずきれいにします。
import * as cdk from '@aws-cdk/core'; export class ElbSampleStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); } }
必要なcdkモジュールをインストールします。
npm i @aws-cdk/aws-elasticloadbalancingv2 npm i @aws-cdk/aws-ecs
実装
import * as cdk from '@aws-cdk/core'; // 使うモジュール import * as elb from '@aws-cdk/aws-elasticloadbalancingv2'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as ecs from '@aws-cdk/aws-ecs'; export class ElbSampleStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props); // Create a cluster const vpc = new ec2.Vpc(this, 'cdk-sample-vpc', { maxAzs: 2 }); const cluster = new ecs.Cluster(this, 'cdk-sample-cluster', { vpc }); cluster.addCapacity('DefaultAutoScalingGroup', { instanceType: ec2.InstanceType.of( ec2.InstanceClass.T2, ec2.InstanceSize.MICRO ) }); // Create Task Definition const taskDefinition = new ecs.Ec2TaskDefinition( this, 'cdk-sample-taskDef' ); const container = taskDefinition.addContainer('web', { image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), memoryLimitMiB: 256 }); container.addPortMappings({ containerPort: 80, hostPort: 8080, protocol: ecs.Protocol.TCP }); // Create Service const service = new ecs.Ec2Service(this, 'cdk-sample-service', { cluster, taskDefinition }); // Create ALB const lb = new elb.ApplicationLoadBalancer(this, 'cdk-sample-elb', { vpc, internetFacing: true }); const listener = lb.addListener('PublicListener', { port: 80, open: true }); // Attach ALB to ECS Service listener.addTargets('ECS', { port: 80, targets: [ service.loadBalancerTarget({ containerName: 'web', containerPort: 80 }) ], // include health check (default is none) healthCheck: { interval: cdk.Duration.seconds(60), path: '/health', timeout: cdk.Duration.seconds(5) } }); new cdk.CfnOutput(this, 'LoadBalancerDNS', { value: lb.loadBalancerDnsName }); } }
デプロイ
CDKを元にCFnを作成します。
cdk synth
デプロイに使用するS3バケットを作成します。
cdk bootstrap
CloudFormationを使用してS3バケットが作成されるようです。
デプロイします。
cdk deploy
デプロイに関する変更の確認を求められます。
y
でデプロイが実施されるのでログを眺めながら待ちます。
作成されました。
AWSコンソールでも確認できます。
出力されたDNSにアクセスしてみます。
成功しました。
後処理
デプロイしたリソースもコマンドで消せるようなので消しておきましょう。
cdk destroy
y
で削除が実施されますのでログを見て待ちます。。
削除されたようです。
めでたし。
感想
AWS CDKが話題になっていたのでなんとなく試してみましたが、CFnに比べて学習コストが2段階くらい下がったような気がします。
ただ、ソース量を見れば分かる通り定義していないものもうまい具合に作成してくれるようなので、意図しないリソースが作成されないように注意しなければいけないと感じました。
参考
【コードでインフラ定義】CDKという異次元体験をさくっとやるのに便利なAWS公式Workshopの紹介 | Developers.IO
AWS Cloud Development Kit (AWS CDK) ワークショップ
aws-samples/aws-cdk-examples/ecs-service-with-advanced-alb-config