🌟
Github Actions で aws copilot の複数サービスを並列でデプロイ(処理)する
動機
aws copilotは デプロイ 時に、ひとつひとつのサービスをデプロイ処理し、サービスが複数あるときはすごい時間がかかります。
ひとつのサービスで 5分弱× 30回(デプロイ回数)です。
サービスがひとつや2つなら、ローカルでデプロイコマンドを叩きますが、サービスが30個ぐらい運用しているので、ターミナルのタブを増やしてコマンドを叩くのもやぶさかではありません。
Github Actions の matrix を使用
Github Actions の matrix は 並列で job を実行できる仕組みです。
最大256個の job が実行できるようですね!
流れ
-
copilot svc ls --json
で サービスを抽出 - matrixの引数に渡して、各デプロイに必要なjobを実行させる
設定yamlファイル
.github/workflows/deploy-all-svcs.yml
name: 🚀 Copilot Deploy All Services
on:
push:
branches: [deploy] # deploy で push されたとき のみ 実行
workflow_dispatch:
branches: [ master ]
jobs:
set-matrix:
name: Set All Services
runs-on: ubuntu-latest # { "services": [{ "app": "copilot", "name": "copilot-svc-1", "type": "Load Balanced Web Service" },... ] } => ["copilot-svc-1", "copilot-svc-2" ...]
outputs:
svcs: ${{ steps.set-matrix.outputs.value }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: AWS Configure And Setup Copilot
uses: ./.github/actions/setup-copilot
with:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Set Outputs
id: set-matrix
run: |
allsvcs=$(copilot svc ls --json | jq -c '[.services[].name]')
echo "::set-output name=value::${allsvcs}"
deploy-all:
needs: set-matrix
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
svc: ${{ fromJSON(needs.set-matrix.outputs.svcs) }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: AWS Configure And Setup Copilot
uses: ./.github/actions/setup-copilot
with:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: 🎡 Deploy All Services
shell: bash
run: |
copilot svc deploy --name ${{ matrix.svc }}
.github/actions/setup-copilot/action.yml
name: Setup Copilot
description: Login AWS For Setup Copilot
inputs:
AWS_ACCESS_KEY_ID:
description: AWS Access Key ID
default: ''
required: true
AWS_SECRET_ACCESS_KEY:
description: AWS Secret Access Key
default: ''
required: true
AWS_REGION:
description: AWS Region
default: ap-northeast-1
required: false
runs:
using: 'composite'
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ inputs.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ inputs.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ inputs.AWS_REGION }}
- name: Install Copilot CLI
shell: bash
run: |
mkdir -p $GITHUB_WORKSPACE/bin
# download copilot
curl -Lo copilot-linux https://github.com/aws/copilot-cli/releases/download/v1.8.3/copilot-linux && \
# make copilot bin executable
chmod +x copilot-linux && \
# move to path
mv copilot-linux $GITHUB_WORKSPACE/bin/copilot && \
# add to PATH
echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH
ポイント
- トリガーは deploy ブランチ に push されたとき または、Github Actionsのコンソールから手動実行にしていますが、任意でOKです。
- set-matrix で、copilot svc ls を実行するための copilot をインストール
- 2の結果を 次のjobで並列実行するため、取得したサービス名の配列を outputs で渡す
- deploy-allの job で 再度 copilot を インストール(job間で環境は引き継がれない)
- copilot svc deploy で サービス名を指定した copilot コマンドを実行
-
action.yml
は 2と4で copilot のインストールと aws のセットアップが重複した処理を共通化した内容です。using: 'composite'
を使うことで、処理を共通化しています。
結果
デプロイに 30サービス × 5分 = 150分 が 10分弱ぐらいで完了します。
おまけ:slackに通知
すべて job が 完了したら結果をまとめてslackに流したい場合は、slack-workflow-statusというactionsが公開されているのでそれを使ってみても良さそうです。
自分が実装したときは、下記のymlファイルになりました。
jobs:
# deploy-all までの job は省略
slack-workflow-status:
if: always()
name: Post Workflow Status To Slack
needs: deploy-all
runs-on: ubuntu-latest
steps:
- name: 💁 Copilot Deploy All Services Result
uses: Gamesight/slack-workflow-status@master
with:
repo_token: ${{ github.token }}
slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
channel: "#your-channel-name"
include_jobs: true
Discussion