🎃

ecspressoでEBS付きECSタスクを実行する

2024/01/19に公開

ECSのEBS連携がサポートされ、EBSストレージを付与してECSタスクを実行できるようになった。
実際にecspressoからこのようなECSタスクを実行してみる。

https://aws.amazon.com/jp/about-aws/whats-new/2024/01/amazon-ecs-fargate-integrate-ebs/

準備

必要なリソースのセットアップ

まず始めに必要なIAMロールをterraformで作成する。
単にECSを実行するために必要なECSタスク実行ロールと、EBSを作成するために必要なECSインフラストラクチャーロールが必要。

## EBSを作成するために必要なIAMロール

resource "aws_iam_role" "ecs_infrastructure" {
  name               = "sample-ecs-infrastructure-role"
  assume_role_policy = data.aws_iam_policy_document.assume_ecs.json

  managed_policy_arns = [
    "arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRolePolicyForVolumes",
  ]
}

data "aws_iam_policy_document" "assume_ecs" {
  statement {
    effect  = "Allow"
    actions = ["sts:AssumeRole"]
    principals {
      type        = "Service"
      identifiers = ["ecs.amazonaws.com"]
    }
  }
}

## ECSタスクを作成するために必要なIAMロール

resource "aws_iam_role" "ecs_task" {
  name               = "sample-ecs-task-role"
  assume_role_policy = data.aws_iam_policy_document.assume_ecs_task.json

  managed_policy_arns = [
    "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy",
  ]
}

data "aws_iam_policy_document" "assume_ecs_task" {
  statement {
    effect  = "Allow"
    actions = ["sts:AssumeRole"]
    principals {
      type        = "Service"
      identifiers = ["ecs-tasks.amazonaws.com"]
    }
  }
}

## その他

data "aws_kms_alias" "ebs" {
  name = "alias/aws/ebs"
}

data "aws_subnet" "public" {
  id = "subnet-0573061dd09dba117"
}

ecspresso-nightlyの準備

2024-01-19 現在ではecspressoにEBSを扱う機能はリリースされていない。その替わりにecspresso-nightlyには既にリリースされている。
こちらをインストールして利用する。

$ ecspresso-nightly version
ecspresso v2.3.1-nightly-c780f9f3672d7c0fced8eed43cc66a573611d848

ecspresso関連ファイルの作成

ecspressoでECSタスクを実行するために必要な、ecspresso.yml、ecs-service-def.json、ecs-task-def.jsonは以下の通り。
EBSをどのようにECSタスクにアタッチするか(マウントパスなど)はECSタスク定義ファイルに記述するが、EBSをどのように作成するか(容量やIOPS、ボリュームタイプなど)はECSサービス定義に記述する。

ecspresso.yml
region: "ap-northeast-1"
cluster: default
task_definition: ecs-task-def.json
service_definition: ecs-service-def.json
timeout: "10m0s"
plugins:
  - name: tfstate
    config:
      path: terraform.tfstate
ecs-service-def.json
{
  "deploymentConfiguration": {
    "deploymentCircuitBreaker": {
      "enable": false,
      "rollback": false
    },
    "maximumPercent": 200,
    "minimumHealthyPercent": 100
  },
  "desiredCount": 1,
  "enableECSManagedTags": false,
  "healthCheckGracePeriodSeconds": 0,
  "launchType": "FARGATE",
  "networkConfiguration": {
    "awsvpcConfiguration": {
      "assignPublicIp": "ENABLED",
      "subnets": [
        "{{ tfstate `data.aws_subnet.public.id` }}"
      ]
    }
  },
  "placementConstraints": [],
  "placementStrategy": [],
  "platformVersion": "LATEST",
  "schedulingStrategy": "REPLICA",
  "serviceRegistries": [],
  "volumeConfigurations": [
    {
      "name": "ecsEBSvolume",
      "managedEBSVolume": {
        "encrypted": true,
        "kmsKeyId": "{{ tfstate `data.aws_kms_alias.ebs.target_key_arn` }}",
        "volumeType": "gp3",
        "sizeInGiB": 10,
        "tagSpecifications": [
          {
            "resourceType": "volume",
            "tags": [
              {
                "key": "Name",
                "value": "ecs-ebs-volume"
              }
            ],
            "propagateTags": "NONE"
          }
        ],
        "roleArn": "{{ tfstate `aws_iam_role.ecs_infrastructure.arn` }}",
        "terminationPolicy": {
          "deleteOnTermination": true
        },
        "filesystemType": "ext4"
      }
    }
  ]
}
ecs-task-def.json
{
  "family": "sample-ecs-volumes",
  "containerDefinitions": [
    {
      "name": "container-using-ebs",
      "image": "amazonlinux:2",
      "essential": true,
      "entryPoint": [
        "sh",
        "-c"
      ],
      "command": [
        "ls -al /mount/ebs && df"
      ],
      "readonlyRootFilesystem": true,
      "mountPoints": [
        {
          "containerPath": "/mount/ebs",
          "readOnly": false,
          "sourceVolume": "ecsEBSvolume"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-create-group": "true",
          "awslogs-group": "/ecs/sample-ecs-volumes",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "main"
        }
      }
    }
  ],
  "cpu": "256",
  "memory": "512",
  "ephemeralStorage": {
    "sizeInGiB": 50
  },
  "executionRoleArn": "{{ tfstate `aws_iam_role.ecs_task.arn` }}",
  "networkMode": "awsvpc",
  "requiresCompatibilities": [
    "FARGATE"
  ],
  "runtimePlatform": {
    "cpuArchitecture": "X86_64",
    "operatingSystemFamily": "LINUX"
  },
  "volumes": [
    {
      "name": "ecsEBSvolume",
      "configuredAtLaunch": true
    }
  ]
}

ECSタスクの実行

上記の設定にてECSタスクを実行する。
debugオプションを有効にすることで、ECSタスク実行時にVolumeConfigurationsが含まれ、必要なEBSボリューム情報が指定されていることがわかる。
またログ出力内容から、エフェメラストレージとして50GiB、EBSストレージとして10GiBが付与されていることがわかる。
今回のように起動後すぐに終了するECSタスクの場合、EBSもすぐに削除される。今回はEBSの容量が10GiBと小さいこともあるが、ECSタスクの起動や終了にパフォーマンスの影響は発生してはいなさそう。

$ ecspresso-nightly run --debug
2024/01/19 08:38:24 [INFO] ecspresso version: v2.3.1-nightly-c780f9f3672d7c0fced8eed43cc66a573611d848
2024/01/19 08:38:24 /default [DEBUG] config file path: ecspresso.yml
2024/01/19 08:38:24 /default [DEBUG] timeout: 10m0s
2024/01/19 08:38:24 /default [DEBUG] dispatching subcommand: run
2024/01/19 08:38:24 /default Running task
...
2024/01/19 08:38:25 [DEBUG] {"TaskDefinition":"arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task-definition/sample-ecs-volumes:17","CapacityProviderStrategy":null,"ClientToken":null,"Cluster":"default","Count":1,"EnableECSManagedTags":false,"EnableExecuteCommand":false,"Group":null,"LaunchType":"FARGATE","NetworkConfiguration":{"AwsvpcConfiguration":{"Subnets":["subnet-0573061dd09dba117"],"AssignPublicIp":"ENABLED","SecurityGroups":null}},"Overrides":{"ContainerOverrides":null,"Cpu":null,"EphemeralStorage":null,"ExecutionRoleArn":null,"InferenceAcceleratorOverrides":null,"Memory":null,"TaskRoleArn":null},"PlacementConstraints":[],"PlacementStrategy":[],"PlatformVersion":"LATEST","PropagateTags":"","ReferenceId":null,"StartedBy":null,"Tags":[],"VolumeConfigurations":[{"Name":"ecsEBSvolume","ManagedEBSVolume":{"RoleArn":"arn:aws:iam::xxxxxxxxxxxx:role/sample-ecs-infrastructure-role","Encrypted":true,"FilesystemType":"ext4","Iops":null,"KmsKeyId":"arn:aws:kms:ap-northeast-1:xxxxxxxxxxxx:key/60a384ff-f694-4f0c-a515-087494ff1086","SizeInGiB":10,"SnapshotId":null,"TagSpecifications":[{"ResourceType":"volume","PropagateTags":"NONE","Tags":[{"Key":"Name","Value":"ecs-ebs-volume"}]}],"TerminationPolicy":{"DeleteOnTermination":true},"Throughput":null,"VolumeType":"gp3"}}]}
...
2024/01/19 08:38:52 total 24
2024/01/19 08:38:52 drwxr-xr-x 3 root root  4096 Jan 18 23:38 .
2024/01/19 08:38:52 drwxr-xr-x 3 root root  4096 Jan 18 23:38 ..
2024/01/19 08:38:52 drwx------ 2 root root 16384 Jan 18 23:38 lost+found
2024/01/19 08:38:52 Filesystem     1K-blocks    Used Available Use% Mounted on
2024/01/19 08:38:52 overlay         61743100 9799900  49074720  17% /
2024/01/19 08:38:52 tmpfs              65536       0     65536   0% /dev
2024/01/19 08:38:52 shm               475044       0    475044   0% /dev/shm
2024/01/19 08:38:52 tmpfs             475044       0    475044   0% /sys/fs/cgroup
2024/01/19 08:38:52 /dev/nvme2n1    10153236      24  10136828   1% /mount/ebs
2024/01/19 08:38:52 /dev/nvme1n1    61743100 9799900  49074720  17% /etc/hosts
2024/01/19 08:38:52 tmpfs             475044       0    475044   0% /proc/acpi
2024/01/19 08:38:52 tmpfs             475044       0    475044   0% /sys/firmware
2024/01/19 08:40:37 /default Run task completed!

また、AWSマネージメントコンソールから、ECSタスク詳細ではボリュームタブから作成したEBSが、EBSのボリューム一覧にも作成したEBS詳細が確認できる。


Discussion