インフラ

CDKで複数コンテナのECSタスクを作成する際はDefaultコンテナの指定を忘れずやろう

cdk

こんにちは、ちゃりおです。

ECSで複数コンテナを動かすタスク定義をCDKで書いていました。
しかし、想定したコンテナがALBのターゲットグループで指定されるコンテナと違うものになってしまうことがありました。

「defaultContainer」を指定してなかったからでした。
具体例を交えつつブログにします。

Contents

複数コンテナが存在するECSタスクを作成するCDK

デフォルトコンテナを指定する場合と、指定してない場合についてのCDKと実行結果です。

デフォルトコンテナを指定しない場合

nginx→nodeみたいな構成で、デフォルトコンテナ(ALBのヘルチェックがくるコンテナ)をnginxにしたいとします。

しかし、以下のように書くとnode(3000)の方がデフォルトコンテナになります。
何も指定しないと、タスク定義の上にある方がデフォルトコンテナになるようです。

import * as cdk from '@aws-cdk/core';
import * as ec2 from '@aws-cdk/aws-ec2';
import * as ecs from '@aws-cdk/aws-ecs';
import { ApplicationLoadBalancedFargateService } from '@aws-cdk/aws-ecs-patterns';

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


    const vpc = new ec2.Vpc(this, 'vpc', {
      natGateways: 0
    })

    const cluster = new ecs.Cluster(this, 'cluster', {
      vpc,
      clusterName: 'sample-cluster',
    });
    const nodeImage = ecs.ContainerImage.fromRegistry('node:latest');
    const nginxImage = ecs.ContainerImage.fromRegistry('nginx:latest');

    const taskDef = new ecs.FargateTaskDefinition(this, "taskdef", {
      family: "sample-task-def"
    })

    const nodeContainer = taskDef.addContainer('node-container', {
      image: nodeImage,
    })
    nodeContainer.addPortMappings({
      hostPort: 3000,
      containerPort: 3000
    })

    const nginxContainer = taskDef.addContainer('nginx-container', {
      image: nginxImage
    })
    nginxContainer.addPortMappings({
      hostPort: 80,
      containerPort: 80,      
    })

    new ApplicationLoadBalancedFargateService(this, 'service', {
      cluster,
      taskDefinition: taskDef
    })
  }
}

nodeコンテナ(3000)が指定されました。

Amazon_ECS_3000

気をつけてデフォルトコンテナにしたい方を、上に書けばいいのですがミスりそうで好ましくないと思います。
ちなみに、デフォルトコンテナはサービス作成時にしか指定できないため、変更したいときはサービスを削除する必要があります。

デフォルトコンテナを指定する場合

タスク定義の「defaultContainer」で指定できます。


   // 省略
    const nginxContainer = taskDef.addContainer('nginx-container', {
      image: nginxImage
    })
    nginxContainer.addPortMappings({
      hostPort: 80,
      containerPort: 80,      
    })
    // 追加
    taskDef.defaultContainer = nginxContainer

   // 省略
    new ApplicationLoadBalancedFargateService(this, 'service', {
      cluster,
      taskDefinition: taskDef
    })

nginxのコンテナ(80)が指定されることが確認できました。

Amazon_ECS_80

まとめ

「このコンテナをデフォルトにしてほしいのに別のコンテナが指定される」ことがありました。
調べたら明示的に指定する必要があり、変えるためにサービスの再作成が必要でちょっと面倒でした。

複数コンテナがあるタスクをCDKで作る際は、デフォルトコンテナを明示的に指定したほうが良さそうです。

Amzonで「AWS」の本を見てみる

楽天で「AWS」の本をみてみる!!

cdk
CDKでCloudwatchLogsのエラーログをSlack通知するLambdaを作るこんにちは、ちゃりおです。 LambdaのBlueprintの「cloudwatch-alarm-to-slack-python」をC...
cdk
CDKの始め方 ワークショップではまらないためにこんにちは、ちゃりおです。 先日、社内向けに「CDKの始め方」をテーマに勉強会を行いました。 本記事では、内容をブログ向けにまとめまし...
実践AWS CDK
CDKの基礎を「実践 AWS CDK – TypeScript でインフラもアプリも!」で学ぼうこんにちは、ちゃりおです。 以前から気になっていた「実践 AWS CDK – TypeScript でインフラもアプリも!」を読みまし...