ECS で「Use AWS CodeDeploy to trigger a new deployment」になったときの対処方法

2023.04.14

困っていた内容

ECS でタスクの更新を行うため update-service コマンドを実行したところInvalidParameterExceptionで失敗します。どうしたら良いでしょうか。

$ aws ecs update-service \
    --service hato-ecs-service \
    --cluster hato-ecs-cluster \
    --force-new-deployment

An error occurred (InvalidParameterException) when calling the UpdateService operation: Cannot force a new deployment on services with a CODE_DEPLOY deployment controller. Use AWS CodeDeploy to trigger a new deployment.

どう対応すればいいの?

create-deploymentコマンドを実行してください。

ECS サービスでデプロイメントコントローラーCODE_DEPLOYを指定している場合、update-service コマンドの実行は制限され、代わりにcreate-deploymentコマンドを実行する必要があります。

UpdateService - Amazon Elastic Container Service

For services using the blue/green (CODE_DEPLOY) deployment controller, only the desired count, deployment configuration, health check grace period, task placement constraints and strategies, enable ECS managed tags option, and propagate tags can be updated using this API. If the network configuration, platform version, task definition, or load balancer need to be updated, create a new AWS CodeDeploy deployment. For more information, see CreateDeployment in the AWS CodeDeploy API Reference.

やってみた

デプロイ設定となる AppSpec ファイル(appspec.yaml)を作成します。

appspec.yaml

version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: "【ECS タスク定義のARN】"
        LoadBalancerInfo:
          ContainerName: "【コンテナ名】"
          ContainerPort: 【ポート番号】

CodeDeployから参照できるように S3 に AppSpec ファイルアップロードします。
※必要に応じて S3 バケットを作成してください。

$ aws s3 cp ./appspec.yaml s3://【バケット名】/appspec.yaml
upload: ./appspec.yaml to s3://【バケット名】/appspec.yaml

create-deploymentコマンドで指定するパラメータファイル(create-deployment.json)を作成します。

create-deployment.json

{
    "applicationName": "【CodeDeploy アプリケーション名】",
    "deploymentGroupName": "【CodeDeploy デプロイグループ名】",
    "revision": {
        "revisionType": "S3",
        "s3Location": {
            "bucket": "【バケット名】",
            "key": "appspec.yaml",
            "bundleType": "YAML"
        }
    }
}

先ほど作成したパラメータファイルを指定して、デプロイメントを作成します。

$ aws deploy create-deployment \                                  
     --cli-input-json file://create-deployment.json
{
    "deploymentId": "d-YSLAHXC4B"
}

デプロイが実施されます。
デプロイが完了し"status": "Succeeded"になることを確認します。
デプロイ IDは先ほどのコマンド結果に含まれるdeploymentId(例:d-YSLAHXC4B)です。
※CodeDeploy の設定次第ではデプロイ完了までにcontinue-deploymentコマンド等 の実行が必要になる場合があります。

$  aws deploy get-deployment-target \
     --deployment-id "【デプロイ ID】" \
     --target-id 【ECS クラスター名】:【ECS サービス名】
{
  "deploymentTarget": {
    "deploymentTargetType": "ECSTarget",
    "ecsTarget": {
      "deploymentId": "d-YSLAHXC4B",
      "targetId": "hato-ecs-cluster:hato-ecs-service",
      "targetArn": "arn:aws:ecs:ap-northeast-1:123456789012:service/hato-ecs-cluster/hato-ecs-service",
      "lastUpdatedAt": "2023-04-01T09:17:12.451000+09:00",
      "lifecycleEvents": [
        {
          "lifecycleEventName": "BeforeInstall",
          "startTime": "2023-04-01T09:15:26.038000+09:00",
          "endTime": "2023-04-01T09:15:26.371000+09:00",
          "status": "Succeeded"
        },
        {
          "lifecycleEventName": "Install",
          "startTime": "2023-04-01T09:15:26.523000+09:00",
          "endTime": "2023-04-01T09:17:09.147000+09:00",
          "status": "Succeeded"
        },
        {
          "lifecycleEventName": "AfterInstall",
          "startTime": "2023-04-01T09:17:09.325000+09:00",
          "endTime": "2023-04-01T09:17:09.629000+09:00",
          "status": "Succeeded"
        },
        {
          "lifecycleEventName": "BeforeAllowTraffic",
          "startTime": "2023-04-01T09:17:10.195000+09:00",
          "endTime": "2023-04-01T09:17:10.487000+09:00",
          "status": "Succeeded"
        },
        {
          "lifecycleEventName": "AllowTraffic",
          "startTime": "2023-04-01T09:17:10.684000+09:00",
          "endTime": "2023-04-01T09:17:11.386000+09:00",
          "status": "Succeeded"
        },
        {
          "lifecycleEventName": "AfterAllowTraffic",
          "startTime": "2023-04-01T09:17:11.951000+09:00",
          "endTime": "2023-04-01T09:17:12.283000+09:00",
          "status": "Succeeded"
        }
      ],
      "status": "Succeeded",
      "taskSetsInfo": [
…(略)…

参考資料