AWS CDKでmackerel-container-agentを同梱したECSタスク定義を作成する

AWS CDKからmackerel-container-agentをサイドカーにしたタスク定義を作成したいことがよくあるので,ライブラリを継承してmackerel-container-agentを必ず同梱するようなタスク定義クラスを作ってみた.

コードは以下.

import * as cdk from '@aws-cdk/cdk'
import * as ecs from '@aws-cdk/aws-ecs'

export interface Ec2TaskDefWithMackerelProps extends ecs.Ec2TaskDefinitionProps {
  mackerelRoles: string
  mackerelApiKey?: string
}

export class Ec2TaskDefWithMackerel extends ecs.Ec2TaskDefinition {
  constructor(scope: cdk.Construct, id: string, props: Ec2TaskDefWithMackerelProps) {
    super(scope, id, props)

    const platform = this.networkMode === ecs.NetworkMode.AwsVpc
      ? 'ecs_awsvpc'
      : 'ecs'

    const mackerelContainer = this.addContainer('mackerel-container-agent', {
      image: new ecs.DockerHubImage('mackerel/mackerel-container-agent:latest'),
      environment: {
        MACKEREL_CONTAINER_PLATFORM: platform,
        MACKEREL_ROLES: props.mackerelRoles,
        MACKEREL_APIKEY: props.mackerelApiKey || 'YOUR_API_KEY',
      },
      memoryLimitMiB: 128,
    })

    if (this.networkMode !== ecs.NetworkMode.AwsVpc) {
      this.addVolume({
        name: 'cgroup',
        host: {
          sourcePath: '/cgroup',
          // or Amazon Linux 2
          // sourcePath: '/sys/fs/cgroup', 
        },
      })

      this.addVolume({
        name: 'docker_sock',
        host: {
          sourcePath: '/var/run/docker.sock',
        },
      })

      mackerelContainer.addMountPoints(
        {
          containerPath: '/host/sys/fs/cgroup',
          sourceVolume: 'cgroup',
          readOnly: true,
        },
        {
          containerPath: '/var/run/docker.sock',
          sourceVolume: 'docker_sock',
          readOnly: true,
        },
      )
    }

    this.defaultContainer = undefined
  }
}

現状はEC2の場合のみ対応していて,どのネットワークモードでも動作する.(デフォルトはBridgeモード)

const apiTaskDef = new Ec2TaskDefWithMackerel(this, 'ApiTaskDef', {
  mackerelRoles: 'sample:api'
})

mackerel-container-agentのドキュメントはこちら.

mackerel.io

余談

this.defaultContainer = undefined

この部分は,mackerel-container-agentがdefault containerとしてセットされるのを防いでいる.

default containerはALBがタスクにアクセスする際のコンテナ,つまり「Container to load balance(負荷分散用のコンテナ)」としてアクセスされるコンテナのこと.

これはAWS CDKの用語で,ドキュメントに説明がある.

https://awslabs.github.io/aws-cdk/refs/_aws-cdk_aws-ecs.html?highlight=defaultcontainer#@aws-cdk/aws-ecs.Ec2TaskDefinition.defaultContainer

The first essential container that is added to this task will become the default container. と書いてあるとおり,最初にessential: trueなコンテナが選ばれるという動作になっており,mackerel-container-agentが選ばれてしまうので回避が必要.