☁️

AWS CDKを使えばTypeScriptでAWSインフラを定義できるらしい

2021/04/19に公開

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-cli
    • 1.18.31

環境構築参考:
AWS CDK Intro Workshop > 前提条件

作りたい構成

良さげなサンプルソースがあったので参考にして以下のような構成になればいいなと思ってます。

Untitled Diagram.jpg
aws-samples/aws-cdk-examples/ecs-service-with-advanced-alb-config

準備

プロジェクトを作成します。

cdk init sample-app --language typescript

libディレクトリに構築に使用するファイルが作成されます。

主にこのファイルをいじいじしていくらしいです。

.ts

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

とりあえずきれいにします。

.ts

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

実装

.ts
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バケットが作成されるようです。

<img width="1161" alt="スクリーンショット 2020-04-05 4.21.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246580/f2c710fd-1dc0-084e-2ac2-40de2882828d.png">

デプロイします。

cdk deploy

デプロイに関する変更の確認を求められます。
スクリーンショット 2020-04-05 4.26.27.png

yでデプロイが実施されるのでログを眺めながら待ちます。

作成されました。
スクリーンショット 2020-04-05 4.34.55.png
AWSコンソールでも確認できます。
<img width="1167" alt="スクリーンショット 2020-04-05 4.42.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246580/6e85cdbf-0f83-32bf-dac6-283de24db265.png">

出力されたDNSにアクセスしてみます。
<img width="1172" alt="スクリーンショット 2020-04-05 4.35.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246580/3dc165a4-e98e-19c6-6f46-0f2a28c9fbe9.png">

成功しました。

後処理

デプロイしたリソースもコマンドで消せるようなので消しておきましょう。

cdk destroy

スクリーンショット 2020-04-05 4.44.00.png
yで削除が実施されますのでログを見て待ちます。。

削除されたようです。

スクリーンショット 2020-04-05 4.49.01.png

めでたし。

感想

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

GitHubで編集を提案

Discussion