aws ecs

1つのAmazon ECSタスク定義にバックエンドとフロントエンドなど複数コンテナがある場合でも、aws-actions/amazon-ecs-render-task-definition を連続して呼び出すことで、すべてのコンテナイメージを更新できます。

OIDCを使ったGitHub ActionsからECSへのデプロイの基本手順は、GitHub Actionsを使ったECSへの自動デプロイを参照してください。本記事では、複数コンテナ向けの差分に絞って解説します。

サムネイル

ディレクトリ構成例

.
├── .aws
│   └── task-definition.json
├── .github
│   └── workflows
│       └── deploy.yml
├── backend
│   └── docker
│       └── Dockerfile
└── frontend
    └── docker
        └── Dockerfile

ポイント

amazon-ecs-render-task-definition は、タスク定義JSON内の特定コンテナの image だけを書き換えます。

複数コンテナがある場合は、1つ目のレンダー結果を2つ目の task-definition に渡します。最終的に両方のイメージが更新されたタスク定義を amazon-ecs-deploy-task-definition へ渡します。

ワークフローの設定例

環境変数は次のように用意します。

env:
  AWS_REGION: ap-northeast-1
  ECR_REPOSITORY_BACKEND: my-backend
  ECR_REPOSITORY_FRONTEND: my-frontend
  ECS_SERVICE: my-service
  ECS_CLUSTER: my-cluster
  ECS_TASK_DEFINITION: .aws/task-definition.json
  CONTAINER_NAME_BACKEND: backend
  CONTAINER_NAME_FRONTEND: frontend

OIDC用に id-token: write を付与し、AWS認証はロールをassumeします。

permissions:
  id-token: write
  contents: read

steps:
  - name: Configure AWS credentials
    uses: aws-actions/configure-aws-credentials@v1
    with:
      role-to-assume: ${{ secrets.ROLE_TO_ASSUME }}
      aws-region: ${{ env.AWS_REGION }}

イメージのビルドとプッシュは、コンテナごとに行います。

- name: Build, tag, and push backend image to Amazon ECR
  id: build-image-backend
  env:
    ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
    IMAGE_TAG: ${{ github.sha }}
  run: |
    docker build -t $ECR_REGISTRY/$ECR_REPOSITORY_BACKEND:$IMAGE_TAG -f ./backend/docker/Dockerfile .
    docker push $ECR_REGISTRY/$ECR_REPOSITORY_BACKEND:$IMAGE_TAG
    echo "image=$ECR_REGISTRY/$ECR_REPOSITORY_BACKEND:$IMAGE_TAG" >> $GITHUB_OUTPUT

- name: Build, tag, and push frontend image to Amazon ECR
  id: build-image-frontend
  env:
    ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
    IMAGE_TAG: ${{ github.sha }}
  run: |
    docker build -t $ECR_REGISTRY/$ECR_REPOSITORY_FRONTEND:$IMAGE_TAG -f ./frontend/docker/Dockerfile .
    docker push $ECR_REGISTRY/$ECR_REPOSITORY_FRONTEND:$IMAGE_TAG
    echo "image=$ECR_REGISTRY/$ECR_REPOSITORY_FRONTEND:$IMAGE_TAG" >> $GITHUB_OUTPUT

重要なのは、レンダーステップの連結です。

- name: Fill in the new backend image ID in the Amazon ECS task definition
  id: task-def-backend
  uses: aws-actions/amazon-ecs-render-task-definition@v1
  with:
    task-definition: ${{ env.ECS_TASK_DEFINITION }}
    container-name: ${{ env.CONTAINER_NAME_BACKEND }}
    image: ${{ steps.build-image-backend.outputs.image }}

- name: Fill in the new frontend image ID in the Amazon ECS task definition
  id: task-def
  uses: aws-actions/amazon-ecs-render-task-definition@v1
  with:
    task-definition: ${{ steps.task-def-backend.outputs.task-definition }}
    container-name: ${{ env.CONTAINER_NAME_FRONTEND }}
    image: ${{ steps.build-image-frontend.outputs.image }}

- name: Deploy Amazon ECS task definition
  uses: aws-actions/amazon-ecs-deploy-task-definition@v1
  with:
    task-definition: ${{ steps.task-def.outputs.task-definition }}
    service: ${{ env.ECS_SERVICE }}
    cluster: ${{ env.ECS_CLUSTER }}
    wait-for-service-stability: true

設定のポイント

  • 1つ目のレンダー出力(steps.task-def-backend.outputs.task-definition)を、2つ目の task-definition に渡す
  • 最終成果物(steps.task-def.outputs.task-definition)をデプロイに使う
  • CONTAINER_NAME_* は、タスク定義の containerDefinitions 内のコンテナ名と一致させる

参考

この記事は Gemini の会話ログをもとに、Gemini によって生成されました。

関連記事