Amazon Web Services ブログ

Amazon ECS におけるデプロイメントの可視性の向上

この記事は Improving deployment visibility for Amazon ECS services (記事公開日 : 2024 年 11 月 7 日) の翻訳です。

ソフトウェアをデプロイする際、デプロイメントプロセスのすべてのステップを可視化することは非常に重要です。安全で信頼性の高いリリースプロセスを実現するためには、進行中のデプロイメントの状況を把握し、問題が発生した際にはトラブルシューティングを行い、過去のデプロイメントの監査証跡を保持しておく必要があります。これらのニーズに対応するために、Amazon Elastic Container Service (Amazon ECS) は、強化された可視性とトレーサビリティの機能を提供開始しました。新しく導入されたサービスデプロイメント (サービスデプロイ) とサービスリビジョンを活用することで、Amazon ECS におけるアプリケーションデプロイメントについて、より深い洞察を得ることができます。

Amazon ECS において、ECS サービスは長時間実行されるアプリケーションを管理するリソースであり、同一の ECSタスクのグループが Amazon ECS によってデプロイ、管理、スケーリングされます。新しいバージョンのソフトウェアをリリースする際は、Amazon ECS がデプロイメントプロセスを管理し、古いタスクを新しいタスクに段階的に置き換えます。Amazon ECS では、安全なソフトウェアリリースを実現するためのビルトインの保護機能を提供しており、例えば ECS deployment circuit breaker を用いると、新しいデプロイメントが失敗した際に、自動的に前のバージョンのサービスにロールバックさせることが可能です。今回のリリースでは、Amazon ECS の 2 つの新しいリソース (サービスリビジョン、サービスデプロイメント) と新しい API (listServiceDeploymentsdescribeServiceRevisionsdescribeServiceDeployments) が導入され、デプロイメントプロセスの可視性が向上しました。

まず、サービスリビジョンは、Amazon ECS がデプロイするワークロードの設定を記録します。これには、タスク定義、コンテナイメージ、サービスレベルのパラメーター (Amazon Elastic Block Store (Amazon EBS) ボリュームやロードバランサー、ECS Service Connect の設定など) が含まれます。

また、サービスデプロイメント (サービスデプロイ) は、進行中または以前のサービスリビジョンのデプロイメントに関する包括的な視点を提供します。ここでは、デプロイメントの開始点 (ソースリビジョン)、どのデプロイメントがロールアウトされているのか (ターゲットリビジョン)、設定したサーキットブレイカーや Amazon CloudWatch アラームを含むデプロイメントの状況を確認することができます。

これまで、Amazon ECS のデプロイメントの履歴を追跡することは困難でした。今回のリリースにより、成功したかどうかに関わらず、各サービスデプロイメントは 90 日間保持され、Amazon ECS コンソールまたは listServiceDeployments API を通じて確認できるようになりました。これにより、Amazon ECS サービスのデプロイメントの履歴を確認し、各ロールアウトでどのサービスリビジョンが使用されたかを把握することができます。

Amazon ECS は、これらの強化された可視性とトレーサビリティの機能を提供することで、アプリケーションデプロイメントに関するより優れた監視、トラブルシューティング、管理を可能にし、より信頼性と透明性の高いリリースプロセスを実現します。以下の図は、既存の Amazon ECS リソースと、新しく導入されたサービスデプロイメントおよびサービスリビジョンの関係を示します。

Amazon ECS のサービスリビジョンとサービスデプロイメント

図 1 : サービスリビジョンとサービスデプロイメントの関係

ソリューション概要

このセクションでは、Amazon ECS にソフトウェアをデプロイする際に、サービスリビジョンとサービスデプロイメントがどのように可視性を向上させるのか、ハンズオン形式で説明していきます。この例では、まず新しいサービスを作成し、安定するまで待ちます。次に、既知のバグを含むリビジョンを作成し、エラーのトラブルシューティングやサーキットブレイカーの状態の管理において、新しく導入されたサービスデプロイメント API と Amazon ECS コンソールの「デプロイ」タブがどのように役立つかを確認していきます。

前提条件

このウォークスルーを完了するには、以下の前提条件が必要です。

ウォークスルー

1. まず、このウォークスルー全体で使用する環境変数を設定 (export) します。これらのリソースが自身の AWS アカウントに存在することを確認し、自身のリソースの値に置き換えてください。

export AWS_REGION=ap-northeast-1
export ECS_EXECUTION_ROLE="arn:aws:iam::111222333444:role/ecsTaskExecutionRole"
export ECS_CLUSTER="your-cluster-name"
export VPC_SUBNET_ONE="subnet-07bd4d10ea848a008"
export VPC_SUBNET_TWO="subnet-0ebc3139ba5dcf871"
export VPC_SECURITY_GROUP="sg-003bf5ba3cb1a1168"

2. 無限にスリープする単一のコンテナで構成された、新しい ECS タスク定義を登録します。

cat <<EOF >>taskdefinition_one.json
{
    "family": "deployment-demo",
    "executionRoleArn": "${ECS_EXECUTION_ROLE}",
    "networkMode": "awsvpc",
    "containerDefinitions": [
        {
            "name": "demo",
            "image": "public.ecr.aws/amazonlinux/amazonlinux:2023-minimal",
            "command": [
                "/bin/bash",
                "-c",
                "echo 'sleeping' && sleep infinity"
            ]
        }
    ],
    "requiresCompatibilities": [
        "FARGATE"
    ],
    "cpu": "256",
    "memory": "512"
}
EOF

aws ecs register-task-definition \
    --cli-input-json file://taskdefinition_one.json

3. タスク定義を登録したら、既存の VPC サブネットとセキュリティグループを使用して、AWS Fargate 上で実行するように設定した ECS サービスを作成します。

cat <<EOF >>service.json
{
    "cluster": "${ECS_CLUSTER}",
    "serviceName": "deployment-demo",
    "taskDefinition": "deployment-demo",
    "desiredCount": 1,
    "launchType": "FARGATE",
    "deploymentConfiguration": {
        "deploymentCircuitBreaker": {
            "enable": true,
            "rollback": true
        }
    },
    "networkConfiguration": {
        "awsvpcConfiguration": {
            "subnets": [
                "${VPC_SUBNET_ONE}",
                "${VPC_SUBNET_TWO}"
            ],
            "securityGroups": [
                "${VPC_SECURITY_GROUP}"
            ],
            "assignPublicIp": "ENABLED"
        }
    }
}
EOF

aws ecs create-service \
    --cli-input-json file://service.json

4. 新しく導入された listServiceDeployments API を使用すると、作成したサービスに関連するサービスデプロイメントの一覧を確認することができます。(訳註 : もしエラーが出た場合は、AWS CLI のバージョンが十分新しいか、確認してください。)

aws ecs list-service-deployments \
    --service deployment-demo \
    --cluster "${ECS_CLUSTER}"

このサービスは作成されたばかりなので、サービスデプロイメントは 1 つのみです。このサービスデプロイメントでは、ステータスが IN_PROGRESS (進行中) であり、ターゲットサービスリビジョンは 1544415738210471021 であることを確認できます。(これらの値はあくまで例で、実行する環境によって異なります。)

{
    "serviceDeployments": [
        {
            "serviceDeploymentArn": "arn:aws:ecs:ap-northeast-1:111222333444:service-deployment/default/deployment-demo/zKMCwZeZGjT20CtLyq9X9",
            "serviceArn": "arn:aws:ecs:ap-northeast-1:111222333444:service/default/deployment-demo",
            "clusterArn": "arn:aws:ecs:ap-northeast-1:111222333444:cluster/default",
            "startedAt": "2024-11-20T10:46:40.661000+09:00",
            "createdAt": "2024-11-20T10:46:36.612000+09:00",
            "targetServiceRevisionArn": "arn:aws:ecs:ap-northeast-1:111222333444:service-revision/default/deployment-demo/1544415738210471021",
            "status": "IN_PROGRESS"
        }
    ]
}

サービスデプロイメントの一覧は、Amazon ECS コンソールの「デプロイ」タブでも確認できます。

ECS コンソールのデプロイタブ

5. 新しく導入された describeServiceDeployments API を使用すると、特定のサービスデプロイメントに関して、そのリビジョンの希望タスク数やサーキットブレイカーの状況などの詳細情報を確認できます。

DEPLOYMENT_ARN=$(aws ecs list-service-deployments \
    --service deployment-demo \
    --cluster "${ECS_CLUSTER}" \
    --query "serviceDeployments[0].serviceDeploymentArn" \
    --output text) 

aws ecs describe-service-deployments \
    --service-deployment-arns $DEPLOYMENT_ARN

ここで、出力の sourceServiceRevisions キーが空になっていることを確認できます。これは、このデプロイメントが、このサービスの最初のデプロイメントであることを示しています。

{
    "serviceDeployments": [
        {
            "serviceDeploymentArn": "arn:aws:ecs:ap-northeast-1:111222333444:service-deployment/default/deployment-demo/zKMCwZeZGjT20CtLyq9X9",
            ...
            "sourceServiceRevisions": [],
            "targetServiceRevision": {
                "arn": "arn:aws:ecs:ap-northeast-1:111222333444:service-revision/default/deployment-demo/1544415738210471021",
                "requestedTaskCount": 1,
                "runningTaskCount": 1,
                "pendingTaskCount": 0
            },
            "status": "IN_PROGRESS",
            "deploymentConfiguration": {
                "deploymentCircuitBreaker": {
                    "enable": true,
                    "rollback": true
                },
                "maximumPercent": 200,
                "minimumHealthyPercent": 100
            },
            "deploymentCircuitBreaker": {
                "status": "MONITORING",
                "failureCount": 0,
                "threshold": 3
            },
            "alarms": {
                "status": "DISABLED"
            }
        }
    ],
    "failures": []
}

サービスデプロイメントは、コンソール画面からも確認できます。

ECS コンソールのサービスデプロイメント画面

6. describeServiceRevisions API を使用すると、デプロイされているリソース (サービスリビジョン) に関するより詳細な情報を確認できます。

REVISION_ARN=$(aws ecs list-service-deployments \
    --service deployment-demo \
    --cluster "${ECS_CLUSTER}" \
    --query serviceDeployments[0].targetServiceRevisionArn \
    --output text)

aws ecs describe-service-revisions \
    --service-revision-arns $REVISION_ARN

この情報は、タスク定義リビジョンとサービスレベルのパラメーターで構成されています。

{
    "serviceRevisions": [
        {
            "serviceRevisionArn": "arn:aws:ecs:ap-northeast-1:111222333444:service-revision/default/deployment-demo/1544415738210471021",
            "serviceArn": "arn:aws:ecs:ap-northeast-1:111222333444:service/default/deployment-demo",
            "clusterArn": "arn:aws:ecs:ap-northeast-1:111222333444:cluster/default",
            "taskDefinition": "arn:aws:ecs:ap-northeast-1:111222333444:task-definition/deployment-demo:3",
            "launchType": "FARGATE",
            "platformVersion": "1.4.0",
            "platformFamily": "Linux",
            "networkConfiguration": {...},
            "containerImages": [
                {
                    "containerName": "demo",
                    "imageDigest": "sha256:96bbe031e236f8e767a358f6ba2e05a378508ae6227a814848a1c8a7833b5850",
                    "image": "public.ecr.aws/amazonlinux/amazonlinux:2023-minimal"
                }
            ],
            "guardDutyEnabled": false,
            "createdAt": "2024-11-20T10:46:26.169000+09:00"
        }
    ],
    "failures": []
}

7. 次のステップに進む前に、デプロイメントが SUCCESSFUL になるのを待ちます。これには数分かかる可能性があります。以下のコマンドを実行して、デプロイメントの状態を確認してください。

aws ecs list-service-deployments \
    --service deployment-demo \
    --cluster "${ECS_CLUSTER}" \
    --query "serviceDeployments[0].status" \
    --output text

8. 次に、不正な設定 (bash で exit 1 コマンドを実行) を含む新しいサービスリビジョンをロールアウトします。そのために、まず 2 つ目のタスク定義を登録します。

cat <<EOF >>taskdefinition_two.json
{
    "family": "deployment-demo",
    "executionRoleArn": "${ECS_EXECUTION_ROLE}",
    "networkMode": "awsvpc",
    "containerDefinitions": [
        {
            "name": "demo",
            "image": "public.ecr.aws/amazonlinux/amazonlinux:2023-minimal",
            "command": [
               "/bin/bash",
                "-c",
                "echo 'sleeping' && sleep 15 && echo 'exiting' && exit 1"
            ]
        }
    ],
    "requiresCompatibilities": [
        "FARGATE"
    ],
    "cpu": "256",
    "memory": "512"
}
EOF

aws ecs register-task-definition \
    --cli-input-json file://taskdefinition_two.json

update-service コマンドを実行し、新しいサービスリビジョンを作成してデプロイメントを開始します。

cat <<EOF >>updateservice.json
{
    "cluster": "${ECS_CLUSTER}",
    "service": "deployment-demo",
    "desiredCount": 1,
    "taskDefinition": "deployment-demo"
}
EOF

aws ecs update-service \
    --cli-input-json file://updateservice.json

9. listServiceDeployments API を使用して、再度このサービスに関連するサービスデプロイメントの一覧を確認しましょう。

aws ecs list-service-deployments \
    --service deployment-demo \
    --cluster "${ECS_CLUSTER}"

このサービスには、現在 2 つのデプロイメントが存在していることを確認できます。1 つは最初に完了したデプロイメント、もう 1 つは新しく開始した IN_PROGRESS (進行中) のデプロイメントです。

{
    "serviceDeployments": [
        {
            "serviceDeploymentArn": "arn:aws:ecs:ap-northeast-1:111222333444:service-deployment/default/deployment-demo/WX4k57j4mYvJeZ3xc6Dli",
            ...
            "targetServiceRevisionArn": "arn:aws:ecs:ap-northeast-1:111222333444:service-revision/default/deployment-demo/7111358678511081979",
            "status": "IN_PROGRESS"
        },
        {
            "serviceDeploymentArn": "arn:aws:ecs:ap-northeast-1:111222333444:service-deployment/default/deployment-demo/zKMCwZeZGjT20CtLyq9X9",
            ...
            "targetServiceRevisionArn": "arn:aws:ecs:ap-northeast-1:111222333444:service-revision/default/deployment-demo/1544415738210471021",
            "status": "SUCCESSFUL"
        }
    ]
}

この一覧は、ECS コンソール「デプロイ」タブの「サービスデプロイ」からも確認できます。

サービスデプロイメントの一覧

10. 新しいサービスデプロイメントの詳細を確認すると、2 つの異なるサービスリビジョン間で ECS サービスを遷移させていることを確認できます。

DEPLOYMENT_ARN=$(aws ecs list-service-deployments \
    --service deployment-demo \
    --cluster "${ECS_CLUSTER}" \
    --query "serviceDeployments[0].serviceDeploymentArn" \
    --output text)

aws ecs describe-service-deployments \
    --service-deployment-arns $DEPLOYMENT_ARN

この例では、ソースリビジョンの ID は 1544415738210471021 で、ターゲットリビジョンの ID は 7111358678511081979 となっています。また、ロールアウトが進行中のため、サーキットブレイカーが MONITORING (監視中) の状態であることが分かります。さらに、このデプロイメントにおいて失敗したタスクの数 (failureCount) と、ロールバックをトリガーするためのしきい値 (threshold) を確認できます。

{
    "serviceDeployments": [
        {
            "serviceDeploymentArn": "arn:aws:ecs:ap-northeast-1:111222333444:service-deployment/default/deployment-demo/WX4k57j4mYvJeZ3xc6Dli",
            ...
            "sourceServiceRevisions": [
                {
                    "arn": "arn:aws:ecs:ap-northeast-1:111222333444:service-revision/default/deployment-demo/1544415738210471021",
                    "requestedTaskCount": 0,
                    "runningTaskCount": 1,
                    "pendingTaskCount": 0
                }
            ],
            "targetServiceRevision": {
                "arn": "arn:aws:ecs:ap-northeast-1:111222333444:service-revision/default/deployment-demo/7111358678511081979",
                "requestedTaskCount": 1,
                "runningTaskCount": 0,
                "pendingTaskCount": 1
            },
            "status": "IN_PROGRESS",
            "deploymentConfiguration": {
                "deploymentCircuitBreaker": {
                    "enable": true,
                    "rollback": true
                },
                "maximumPercent": 200,
                "minimumHealthyPercent": 100
            },
            "deploymentCircuitBreaker": {
                "status": "MONITORING",
                "failureCount": 2,
                "threshold": 3
            },
            "alarms": {
                "status": "DISABLED"
            }
        }
    ],
    "failures": []
}

Amazon ECS コンソールの「デプロイ」タブでは、サービスリビジョンを比較するための画面が新しく導入されています。ここでは、異なるサービスリビジョン間の違いを視覚的に確認することができます。

サービスリビジョンの比較

11. 再度 describeServiceDeployments API を使用して、このデプロイメントの詳細を確認しましょう。

aws ecs describe-service-deployments \
    --service-deployment-arns $DEPLOYMENT_ARN

時間の経過とともに、タスクが失敗し、deploymentCircuitBreaker キーの下の failureCount が増加していきます。最終的に、サーキットブレイカーが TRIGGERED になり、ECS サービスは以前のサービスリビジョンにロールバックされます。

{
    "serviceDeployments": [
        {
            "serviceDeploymentArn": "arn:aws:ecs:ap-northeast-1:111222333444:service-deployment/default/deployment-demo/WX4k57j4mYvJeZ3xc6Dli",
            ...
            "sourceServiceRevisions": [
                {
                    "arn": "arn:aws:ecs:ap-northeast-1:111222333444:service-revision/default/deployment-demo/1544415738210471021",
                    "requestedTaskCount": 1,
                    "runningTaskCount": 1,
                    "pendingTaskCount": 0
                }
            ],
            "targetServiceRevision": {
                "arn": "arn:aws:ecs:ap-northeast-1:111222333444:service-revision/default/deployment-demo/7111358678511081979",
                "requestedTaskCount": 0,
                "runningTaskCount": 0,
                "pendingTaskCount": 0
            },
            "status": "ROLLBACK_SUCCESSFUL",
            "statusReason": "Service deployment rolled back because the circuit breaker threshold was exceeded.",
            "deploymentConfiguration": {
                "deploymentCircuitBreaker": {
                    "enable": true,
                    "rollback": true
                },
                "maximumPercent": 200,
                "minimumHealthyPercent": 100
            },
            "rollback": {
                "reason": "Service deployment rolled back because the circuit breaker threshold was exceeded.",
                "startedAt": "2024-11-20T10:57:06.840000+09:00",
                "serviceRevisionArn": "arn:aws:ecs:ap-northeast-1:111222333444:service-revision/default/deployment-demo/1544415738210471021"
            },
            "deploymentCircuitBreaker": {
                "status": "TRIGGERED",
                "failureCount": 3,
                "threshold": 3
            },
            "alarms": {
                "status": "DISABLED"
            }
        }
    ],
    "failures": []
}

12. 最後に、listServiceDeployments API を使用して、すべてのサービスデプロイメントを確認しましょう。

aws ecs list-service-deployments \
    --service deployment-demo \
    --cluster "${ECS_CLUSTER}"

最初のデプロイメントと失敗したデプロイメントの両方が表示されていることを確認できます。

{
    "serviceDeployments": [
        {
            "serviceDeploymentArn": "arn:aws:ecs:ap-northeast-1:111222333444:service-deployment/default/deployment-demo/WX4k57j4mYvJeZ3xc6Dli",
            ...
            "targetServiceRevisionArn": "arn:aws:ecs:ap-northeast-1:111222333444:service-revision/default/deployment-demo/7111358678511081979",
            "status": "ROLLBACK_SUCCESSFUL",
            "statusReason": "Service deployment rolled back because the circuit breaker threshold was exceeded."
        },
        {
            "serviceDeploymentArn": "arn:aws:ecs:ap-northeast-1:111222333444:service-deployment/default/deployment-demo/zKMCwZeZGjT20CtLyq9X9",
            ...
            "targetServiceRevisionArn": "arn:aws:ecs:ap-northeast-1:111222333444:service-revision/default/deployment-demo/1544415738210471021",
            "status": "SUCCESSFUL"
        }
    ]
}

後片付け

以下のコマンドを実行すると、このウォークスルーで作成したサービスとタスク定義を削除できます。このウォークスルーを実施するために ECS クラスターや VPC を作成した場合は、それらのリソースも削除してください。

aws ecs delete-service \
    --cluster "${ECS_CLUSTER}" \
    --service "deployment-demo" \
    --force
TASK_DEFS=$(aws ecs list-task-definitions \
    --family-prefix "deployment-demo" \
    --query taskDefinitionArns \
    --output text)
for TASK_DEF in $TASK_DEFS
do
    aws ecs deregister-task-definition --task-definition "${TASK_DEF}"
done

まとめ

この記事では、新しく導入された Amazon ECS のサービスデプロイメントとサービスリビジョンの機能について深掘りしました。これらの機能により、ソフトウェアリリースプロセスの可視性とトレーサビリティが向上し、より自信を持ってデプロイできるようになります。サービスデプロイメントとサービスリビジョンを使用すると、進行中のロールアウトの状況を深く把握、問題をより効率的にトラブルシューティングし、過去のデプロイメントの履歴を確認できます。この強化された可視性は、より信頼性と透明性の高いソフトウェアリリースライフサイクルを実現するのに役立つでしょう。

Amazon ECS の各機能の詳細については、Amazon ECS 開発者ガイドを確認することをおすすめします。実際に手を動かしながら学びたい場合は、より実践的なガイドと例を含む、Amazon ECS ワークショップもぜひ活用してみてください。