こんにちは、ちゃりおです。
ECSデプロイにGithubActionsを使用しています。
コンテナビルドに時間がかかるコンテナが複数ある際に、ECSデプロイへのデプロイまでに時間がかかることがありました。
そこで複数コンテナのビルドを並行化を試してみました。
GithubActionsでコンテナビルドを並行処理する
最終的にこうなりました。
apacheとnodeのコンテナビルドを並列で実行して、その後ECSにデプロイしています。
name: 'deploy'
on:
workflow_dispatch:
push:
env:
AWS_REGION: ap-northeast-1
ECR_REPOSITORY_HTTPD: githubactions-parallel-build-1
ECR_REPOSITORY_NODE: githubactions-parallel-build-2
ECS_SERVICE: githubactions-parallel
ECS_CLUSTER: test
ECS_TASK_DEFINITION: githubactions-parallel
CONTAINER_NAME_HTTPD: httpd
CONTAINER_NAME_NODE: node
jobs:
Build1:
runs-on: ubuntu-latest
outputs:
image: ${{ steps.httpd-image.outputs.image}}
steps:
- uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: httpd Build, tag, and push image to Amazon ECR
id: httpd-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ env.ECR_REPOSITORY_HTTPD}}
IMAGE_TAG: ${{ github.sha }}
run: |
# Build a docker container and
# push it to ECR so that it can
# be deployed to ECS.
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f docker/httpd/Dockerfile .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
echo "::set-output name=image::$ECR_REPOSITORY:$IMAGE_TAG"
Build2:
runs-on: ubuntu-latest
outputs:
image: ${{ steps.node-image.outputs.image}}
steps:
- uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: node Build, tag, and push image to Amazon ECR
id: node-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ env.ECR_REPOSITORY_NODE}}
IMAGE_TAG: ${{ github.sha }}
run: |
# Build a docker container and
# push it to ECR so that it can
# be deployed to ECS.
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG -f docker/node/Dockerfile docker/node
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
echo "::set-output name=image::$ECR_REPOSITORY:$IMAGE_TAG"
Deploy:
runs-on: ubuntu-latest
needs: [Build1, Build2]
steps:
- uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Download task definition
run: |
aws ecs describe-task-definition --task-definition $ECS_TASK_DEFINITION --query taskDefinition > task-definition.json
- name: Render Amazon ECS task definition for first container
id: render-container-httpd
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: task-definition.json
container-name: ${{ env.CONTAINER_NAME_HTTPD }}
image: ${{ steps.login-ecr.outputs.registry }}/${{ needs.Build1.outputs.image }}
- name: Modify Amazon ECS task definition with second container
id: render-container-node
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: ${{ steps.render-container-httpd.outputs.task-definition }}
container-name: ${{ env.CONTAINER_NAME_NODE }}
image: ${{ steps.login-ecr.outputs.registry }}/${{ needs.Build2.outputs.image }}
- name: Deploy Amazon ECS task definition
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.render-container-node.outputs.task-definition }}
service: ${{ env.ECS_SERVICE }}
cluster: ${{ env.ECS_CLUSTER }}
wait-for-service-stability: true
はまったところ
最初コンテナビルド時のOutputを公式ドキュメント通り、以下のようにしていました。
echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
しかし、Deployのジョブ側でOutputを取得しようとすると何も取得できません。
原因は、シークレットを含む値のためGithubActionsに送られていないことでした。
jobs..outputs
シークレットを含む出力はランナー上で編集され、GitHub Actionsには送られません。
$ECR_REGISTRYの部分を見てみると「***dkr...」のようになっていてシークレットが含まれているのがわかります。
回避策として、Build側では$ECR_REGISTRYを含まない形に変更し、Deploy側でもECRログインの処理を実行しました。
# Build Output
echo "::set-output name=image::$ECR_REPOSITORY:$IMAGE_TAG"
# Deploy Image取得
image: ${{ steps.login-ecr.outputs.registry }}/${{ needs.Build1.outputs.image }}
改善したいところ
AWSのキーセットとECRへのログインが毎回必要で書き方が冗長になっています。
書き方直していい感じにしたいです。
GithubActions + CodeBuildでCDKを自動デプロイするこんにちは、ちゃりおです。
GithubActonsとCodeBuildでCDKを自動デプロイする方法についてです。
GibhuAc...
Github Actionsを使ってCDKを自動デプロイするこんにちは、ちゃりおです。
CDK手動反映だと反映漏れが発生することもあり、今回はGithub Actionsを使ってCDKを自動デプ...
「cdk diff」に必要なIAMポリシーこんにちは、ちゃりおです。
CI時に「cdk diff」を行いたいことがありました。
ローカルから実行するときは、「cdk deplo...