今回は、GitHub ActionsでECSに自動デプロイする方法を紹介します。
ECSにデプロイするまでの話も記事にしています。
今回は、GitHubActionsの細かい話しません。ECRとECSにデプロイする流れを説明して、コードを紹介します。
GitHubActionsとは?
GitHub Actionsは、GitHub上でCI/CDを簡単に実行できるサービスです。この機能を使うことで、コードをプッシュしたり、プルリクエストをマージした際に、テストやビルド、デプロイなどの一連のタスクを自動で行えます。
Circle CIやAWSのcodeシリーズなど、同じようなサービスは複数ありますが、GitHubActionsがコスト(工数、費用)が少いのでおすすめです。
privateレポジトリでもある程度は無料で使えます。
【参照】
実装について
今回は、ECSに対してローリングアップデートで実装します。
ローリングアップデートかBlue/Greenデプロイのいずれかを採用することが多いと思います。
一長一短ですが、シンプルで安価に実装できるローリングデプロイとしています。
【参照】
全体の流れ
下記のような感じです。非常にシンプルですね。
ECRにDocker imageをpushして、ECS Serviceを更新するような流れです。
ECSのサービス定義で、必要なタスク2、最小実行タスク100%、最大実行タスク200%の設定を前提としています。
ポイント
ECRにimageをpushする際に、タグ付けができます。
基本的には、LATESTタグを付与して、ECSでLATESTタグのイメージを使えば、常に最新版で運用できるのでいいかと思います。
ただ、問題発生時にどのイメージで問題が起こっているのか追跡できるようにするために、今回はLATESTタグに加えて、gitコミットハッシュ値を持たせておきます。
ECRのイメージにコミットハッシュをタグとしてつけることで、追跡性、一意性、ロールバックの容易さなど、多くの利点を享受できます。
そもそもLATEST運用がアンチパターンという意見もあるみたいなので、
プロダクトによってご検討ください。
では、実装を見ていきます。
「# 変更してください」という記述の部分は、環境変数的なところなので、
ご自身で設定してください。
ディレクトリ構成
cd-workflow.ymlで実装していきます。
── .github
│ ├── pull_request_template.md
│ └── workflows
│ ├── cd-workflow.yml
### 流れ
- マシーンを起動、ソースコードを取得
- OIDCでAWS認証をする
- docker build, tagを付与し、ECRにプッシュする
- ECSを更新する
- おしまい
実際のコード
下記ですね。細かい説明は後述します。
name: push image to ECR and deploy to ECS
on:
pull_request:
branches:
- main
types: [closed]
jobs:
push:
name: push image to ECR and deploy to ECS
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v3
# - name: Set AWS CLI Debug Output (if needed for debugging)
# run: |
# echo "AWS_DEFAULT_OUTPUT=text" >> $GITHUB_ENV
# echo "AWS_PAGER=" >> $GITHUB_ENV
# # echo "AWS_DEBUG=true" >> $GITHUB_ENV
- uses: aws-actions/configure-aws-credentials@v1
with:
aws-region: 'ap-northeast-1' #変更してください リージョン名
role-to-assume: 'arn:aws:iam::hogehogehoge:role/oidc-role' #変更してください ロール名
- uses: aws-actions/amazon-ecr-login@v1
id: login-ecr
- name: Build, tag, and push docker image to ECR
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
REPOSITORY: "twitter-clone" #変更してください ECRのリポジトリ名
IMAGE_TAG: ${{ github.sha }}
run: |
docker build . --tag ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
docker push ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
docker tag ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }} ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:latest
docker push ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:latest
- name: Force new deployment and wait for services stability in ECS
env:
CLUSTER_NAME: "ProjectA-ecs-cluster" #変更してください クラスター名
SERVICE_NAME: "ProjectA-esc-service4" #変更してください サービス名
run: |
aws ecs update-service --cluster ${{ env.CLUSTER_NAME }} --service ${{ env.SERVICE_NAME }} --force-new-deployment
aws ecs wait services-stable --cluster ${{ env.CLUSTER_NAME }} --service ${{ env.SERVICE_NAME }}
aws ecs describe-services --cluster ${{ env.CLUSTER_NAME }} --service ${{ env.SERVICE_NAME }}
1.マシーンを起動、ソースコードを取得
この辺りは、GithubActionsを触ったことがある人ならすぐにわかると思いますが、GitHubActionsでgithub上のソースコードを使うためのお約束的なのです。
- mainブランチへのマージをトリガーにしています。
- マシーンは、ubuntu-latest
- timeout-minutesは、バグった時に、GithubActionsの無駄使いしないように設定しています。
- permissionsは、後述のOIDC認証した時に、AWSリソースを扱うために必要な記述です。
- uses: actions/checkout@v3で、ソースコードを取得できます。
name: push image to ECR and deploy to ECS
on:
pull_request:
branches:
- main
types: [closed]
jobs:
push:
name: push image to ECR and deploy to ECS
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v3
2.OIDCでAWS認証をする
AWSの認証**: AWSのリソースにアクセスするためには、適切な権限を持ったIAMロールをGitHub Actionsに付与する必要があります。これを簡単に行うためのアクションがaws-actions/configure-aws-credentials@v1です。
設定方法など、下記の記事がめっちゃわかりやすいので、見てください。
【参照】
- uses: aws-actions/configure-aws-credentials@v1
with:
aws-region: 'ap-northeast-1'
role-to-assume: 'arn:aws:iam::925173743335:role/oidc-role'
3.docker build, tagを付与し、ECRにプッシュする
まず、ECRへのログインが必要です。これはaws-actions/amazon-ecr-login@v1を使用して簡単に行えます。
ockerイメージのビルド、タグ付け、プッシュ: リポジトリに変更があった場合、Dockerイメージをビルドし、それをECRにプッシュします。
タグには、gitコミットのハッシュ値と、最新のイメージとしてlatestタグを追加します。
- uses: aws-actions/amazon-ecr-login@v1
id: login-ecr
- name: Build, tag, and push docker image to ECR
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
REPOSITORY: "twitter-clone"
IMAGE_TAG: ${{ github.sha }}
run: |
docker build . --tag ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
docker push ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }}
docker tag ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:${{ env.IMAGE_TAG }} ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:latest
docker push ${{ env.REGISTRY }}/${{ env.REPOSITORY }}:latest
4.ECSを更新する
- ECSのサービスを更新して新しいタスクを起動します。
- ECSのサービスが安定するまで待機します。
- そして、最後にログを出力してくれます。
2,3はおまけみたいなもので処理に結構時間がかかるので、1だけでもOKです。
- name: Force new deployment and wait for services stability in ECS
env:
CLUSTER_NAME: "ProjectA-ecs-cluster"
SERVICE_NAME: "ProjectA-esc-service4"
run: |
aws ecs update-service --cluster ${{ env.CLUSTER_NAME }} --service ${{ env.SERVICE_NAME }} --force-new-deployment
aws ecs wait services-stable --cluster ${{ env.CLUSTER_NAME }} --service ${{ env.SERVICE_NAME }}
aws ecs describe-services --cluster ${{ env.CLUSTER_NAME }} --service ${{ env.SERVICE_NAME }}
まとめ
GitHub Actionsを使用することで、ソースコードの変更を簡単にAWSのECSサービスにデプロイすることができました。これにより、開発のサイクルが速くなり、リリースの頻度を上げることが可能となります。
お楽しみに!
下記、関連記事も書いているので、よかったら見てください。