CDKでECSをいじいじしてみた

CDKでECSをいじいじしてみた

こんにちは。コロナウイルスが怖いので家にこもってあつ森を始めましたがすぐに飽きました。なのでECSをCDKで触ってみることにしました。

目的としては、業務で使っているようなECSの環境をCDKで再現できるようにします

やってみた

公式ドキュメントにECSの始め方が記載されていたので試しました。

適度に割愛しますがコアなコードはこの部分です。

公式ドキュメントの記述通りにすると、タスクが6個/CPUが512/メモリ制限が2048と贅沢な構成なのでその部分は小さく変更しています

    const vpc = new ec2.Vpc(this, "MyVpc", {
      maxAzs: 3 // Default is all AZs in region
    });

    const cluster = new ecs.Cluster(this, "MyCluster", {
      vpc: vpc
    });

    // Create a load-balanced Fargate service and make it public
    new ecs_patterns.ApplicationLoadBalancedFargateService(this, "MyFargateService", {
      cluster: cluster, // Required
      cpu: 256, // Default is 256
      desiredCount: 2, // Default is 1
      taskImageOptions: { image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), },
      memoryLimitMiB: 512, // Default is 512
      publicLoadBalancer: true // Default is false
    });

VPCとECSをここでリソースとして定義しているのはすぐにわかりましたが、ecs_patterns.ApplicationLoadBalancedFargateServiceというリソースを作っています。

とりあえずドキュメント通り作ってみます。

$ yarn
$ yarn build
$ cdk deploy
...省略

 ✅  EcsStack

Outputs:
EcsStack.MyFargateServiceLoadBalancerDNS704F639 = EcsSt-MyFar-M4E9AHL4B21H-109053054.ap-northeast-1.elb.amazonaws.com
EcsStack.MyFargateServiceServiceURL4CF8398 = http://EcsSt-MyFar-M4E9AHL4B21H-109053054.ap-northeast-1.elb.amazonaws.com

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:29457322832:stack/EcsStack/ab8039e-7193-11ea-a0fd-0a9b6e22c78

出力されたURLにアクセスすると早速繋がりました..ここまで手を動かしたのは5分くらい。恐るべきスピード。。。(cdk deployの待ち時間は10分くらいあった気がする)

/img/2020-03-29/01.png

わずか5分でECSが開通した

出力されたリソースをみる限り、VPCもサブネットもロードバランサーもセキュリティグループも全て含まれていて、コンソールから見ても立ち上がっていました。

/img/2020-03-29/vpc.png

VPC

/img/2020-03-29/subnet.png

subnet

/img/2020-03-29/securitygroup.png

securitygroup

どうやらecs_patternsがVPCなどの諸々コミコミのリソースを用意してくれているようです。

ただ、仕事の環境とはタスクを配置するサブネットが異なっていました。具体的には、仕事の環境の場合はpublicなサブネットにタスクを配置する構成が、上記のCDKの環境の場合はprivateなサブネットにタスクを配置している構成(ただし、タスクから外部へのリクエストはNATゲートウェイを通じて可能な形)になっていました。

どうにかしてprivateサブネットに配置しようとecs_patterns.ApplicationLoadBalancedFargateServiceassignPublicIp というプロパティでタスクにパブリックIPを付与するかどうかを設定できるのでtrueに書き換えて反映してみましたが、 タスクはprivateサブネットのまま・NATゲートウェイはそのままでした。

結論として、ecs_patternsパッケージで提供される構成の場合は、アプリケーションがprivateサブネットに配置され、容易に変更することはできなかったです。ただ、タスクから外部へのリクエストも問題なく疎通できるので全く支障はないと思います。これを機にタスクはpriavteサブネットにおくようにしても良いかもしれません。

ecs_patterns

ちなみにecs_patternsには、他にもECSに絡んだ環境が登録されており、FargateではなくプレーンなEC2を使った環境やスケジュール実行環境・キュー実行環境などが用意されています。

This library provides higher-level Amazon ECS constructs which follow common architectural patterns. It contains:

  • Application Load Balanced Services
  • Network Load Balanced Services
  • Queue Processing Services
  • Scheduled Tasks (cron jobs)
  • Additional Examples

https://docs.aws.amazon.com/cdk/api/latest/docs/aws-ecs-patterns-readme.html

用意された機能の中でも特にスケールイン・アウトが簡単に設定できる点が魅力的に感じました

/img/2020-03-29/02.png

CPUやメモリ以外のカスタムメトリクスでもスケールが可能

/img/2020-03-29/autoscaling.png

こんな感じでバッチリ反映されている

ただscaleOnRequestCountのオプションには targetGroup が必要なのがよくわからなかったです。

コンテナのポートが変わった場合

試したサンプルだとコンテナのポートが80ですが、もしそれ以外の場合はセキュリティグループのインバウンドポートなどなどがズレて環境が壊れるんじゃないかと思ったので taskImageOptionsを変更して反映してみました。

taskImageOptions: { 
    image: ecs.ContainerImage.fromRegistry("registry.gitlab.com/xxxxxxxxxxxxx:latest"),
    containerPort: 1313
},

結果セキュリティグループやロードバランサーのポートも動的に変更されていました。素晴らしい👏👏

Black Belt

NATゲートウェイでモヤモヤしてるときに偶然見つけました。BlackBeltはAWSが開催しているセミナー?なのですが、その内容がこちらにまとめられています。AWSの公式ドキュメントは、概念をわかっていない状態では読みにくい印象がありますが、この資料を読んで概念を理解すると公式ドキュメントがすんなり理解できると思います。

CacooのAWS構成図

cdk deployした後に、AWSの各コンソールを開いてリソースの関係を確認するのが面倒だったので、CacooのAWS構成図を出力できる機能を使ってみました。

/img/2020-03-29/cacoo.png

結果がこちら

線が少なくこれだけでは理解できませんでした(私の理解度のなさも原因だと思いますが)。。せっかくトライアル入ったのに残念。。

感想

  • CDKに求めている環境がecs_patternsにフィットすればCDKを採用するべき。効率的になるはず。
    • フィットしない場合だともっと低レベルなリソースを自分で記述することになり苦しくなりそう
      • それでも一度書いてしまえば再利用ができるので吟味してもいいかも
  • NATゲートウェイ完全に理解した
    • Black Belt分かり易すぎて感動した
  • CacooのAWS構成図は思ったよりショボかった
tech  AWS 

See also