GitHub ActionsのWorkflowを作成し、対象のブランチにプッシュした際に、
ECRへのコンテナイメージのプッシュ、タスク定義の更新、ECSへのデプロイ、
DBマイグレーションを自動で行えるようにしたので、紹介します。

事前準備

IAMロール

AWSのIAMにアクセスし、GitHub Actions用にECS、ECRへの
権限を付与したIAMロールを作成します。

GitHub Actionsのvariables設定

Githubリポジトリ上でSettingsからEnvironmentsに移動し、
Workflowで使用する設定値を登録します。

Name 内容 備考
APP_ENV envファイル名
DCR_CONTEXT Path context 配下のDockerfileをビルドに使用
ECR_REPOSITORY ECRリポジトリ名 プッシュ対象のリポジトリ

GitHub Actionsのsecrets設定

Githubリポジトリ上でSettingsからEnvironmentsに移動し、
Workflowで使用するIAMロールやECR、ECSなどの機密情報を登録します。

Name 内容 備考
CLUSTER_ARN ECSクラスターARN ECSデプロイ用設定
SERVICE_ARN ECSサービスARN ECSデプロイ用設定
TASK_DEFINITION_ARN ECSタスク定義書ARN ECSデプロイ用設定
ECS_SECURITY_GROUP ECSセキュリティグループ DBマイグレーション用設定
ECS_SUBNETS ECSサブネット DBマイグレーション用設定
IAM_ROLE_TO_ASSUME IAMロールAsumeRole ECR、ECSアクセス用設定

GitHub ActionsのWorkflow

ECRへのログイン

事前準備で作成したIAMロールを使用して、ECRへログインします。
IAMロールは事前準備でsecretsに設定した値を使用します。

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{secrets.IAM_ROLE_TO_ASSUME}}
aws-region: ap-northeast-1

- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2

ECRへのイメージプッシュ

step間で値を共有して実行する為に、GITHUB_OUTPUTに使用する値を設定します。
コンテナイメージのタグはGithubのコミットのSHA値をつけて、
他のイメージと識別できるように設定しています。

前のstepの設定値を使用し、対象のブランチをビルドしてコンテナイメージを作成します。
作成したコンテナイメージをログイン中のECRのリポジトリにプッシュします。

- name: Make Runtime Values
id: runval
run: |
ecr_repo="${{steps.login-ecr.outputs.registry}}/${{vars.ECR_REPOSITORY}}"
echo "currts=$(date +'%s')" >> $GITHUB_OUTPUT
echo "bldnam=${{github.event.repository.name}}:${{github.ref}}:${{vars.APP_ENV}}:${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
echo "tag7=${ecr_repo}:${GITHUB_SHA::7}">> $GITHUB_OUTPUT

- name: Build, tag, and push image to Amazon ECR
uses: docker/build-push-action@v5
with:
context: ${{vars.DCR_CONTEXT}}
push: true
provenance: false
no-cache: false
tags: |
${{steps.runval.outputs.tag7}}
build-args: |
my_build_name=${{steps.runval.outputs.bldnam}}
my_build_time=${{steps.runval.outputs.currts}}
app_env=${{vars.APP_ENV}}
app_name=${{github.event.repository.name}}

タスク定義の更新

secretsで設定したタスク定義ARNにより、ECS上の対象のタスク定義を取得し、
コンテナイメージのURIを前のstepで設定したコミットのSHAの値に
更新したタスク定義を作成します。

- name: Render Amazon ECS task definition
id: render-web-container
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition-arn: ${{secrets.TASK_DEFINITION_ARN}}
container-name: app
image: ${{ steps.runval.outputs.tag7 }}

ECSデプロイ

前のstepで作成したタスク定義を用いて、ECS上のタスク定義を更新します。
secretsで設定したECSのサービスARN、ECSのクラスターARNを使用して、
更新したタスク定義を用いてECS自動デプロイを実行します。

その際に、RunTaskを使用して、データベースのマイグレーションも実行するようにしています。
マイグレーションコマンドを実行する場合は、ECSのサブネットやセキュリティグループを
secretsで設定し、以下のように指定する必要があります。

- name: Deploy to Amazon ECS service
uses: aws-actions/amazon-ecs-deploy-task-definition@v2
with:
task-definition: ${{ steps.render-web-container.outputs.task-definition }}
cluster: ${{secrets.CLUSTER_ARN}}
run-task: true # DBマイグレーションタスクを実行
run-task-container-overrides: |
[{"name": "app", "command": ["sh", "-c", "****"]}]# DBマイグレーションコマンド
run-task-security-groups: ${{ secrets.ECS_SECURITY_GROUP }}
run-task-subnets: ${{ secrets.ECS_SUBNETS }}
service: ${{secrets.SERVICE_ARN}}

まとめ

GitHub Actionsを利用して、対象のブランチにプッシュ時にECSへのデプロイや
DBマイグレーションまで、自動で行うことができます。
一度設定してしまえば、とても便利なのでご活用ください。