やりたいこと
masterにpushしたらデプロイする
- アプリのビルド
- ビルドキャッシュしてほしい
- アプリのテスト
- 全てのブランチでテストしたい
- dockerのビルド
- デプロイ関連はmasterだけでいい
- ECRへpush
- ECSタスク定義の更新
- masterがデプロイされるようにさしかわってほしい
- ECSデプロイ!
ディレクトリ構成
repository
├── .github
│ └── workflows
│ └── build_and_deploy.yml
├── ops
│ ├── ECS
│ │ └── task-definition.json
│ └── app
│ ├── Dockerfile
│ └── app.jar
└── src
大切な要素は3つです
-
/.github/workflows/build_and_deploy.yml
Github Actionsが参照するファイル
ファイル名はなんでもいいです -
/ops/ECS/task-definition.json
ECSタスク定義を更新する元になるTaskDefinitionを置いてます
通常のTaskDefinitionなので、省略します
ファイル名とフォルダはどこでもいいです -
secretsの登録
Settings > Secretsから、AWSのアクセスキーなどを登録します
大切ですが、画面からポチポチするので省略します
/.github/workflows/build_and_deploy.yml
全体像をのせながら、コメントで細かく注釈していきます
レファレンスはこちら、かなり頻繁に修正されています
https://help.github.com/ja/actions/reference/workflow-syntax-for-github-actions
# nameはなんでもいいが、フロー名として一覧に出る
name: build_and_deploy
# 全てのブランチでpushされた時に起動する
on:
push:
branches:
- '**'
jobs:
# アプリのビルドとテストのjob、名前はなんでもいい
app_build_and_test:
# docker imageを指定するやり方と比べると、選択肢はほとんどないが、winやmacも選べる
runs-on: ubuntu-latest
# stepという区切りでひとつひとつ実行し、失敗した場合、残りのstepが全てスキップされる
# 個別にスキップされないstepを作ることもできる
steps:
# actionsという仕組みをとにかく多用する
# リポジトリチェックアウト
# https://github.com/actions/checkout
- uses: actions/checkout@v2
# javaの準備
# https://github.com/actions/setup-java
- uses: actions/setup-java@v1
with:
java-version: 11
# アプリビルドのキャッシュ
# リストアしたいタイミングで書くが、キャッシュ作成は書く必要がなく、jobが成功で終わった際にキャッシュ作成される
# https://help.github.com/ja/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows
# https://github.com/actions/cache
- uses: actions/cache@v1
with:
path: ~/.gradle
# ${{ ... }} はGithub Actionsの評価式
# 用意されたオブジェクトと関数を使えるだけで、できることは意外と少ない
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
# アプリのビルド、テスト
- name: app build
run: ./gradlew build -x test
- name: app test
run: ./gradlew test
# 作ったjarを別のjobに渡して、それを元にdockerのビルドをしたい
# https://help.github.com/ja/actions/configuring-and-managing-workflows/persisting-workflow-data-using-artifacts
# https://github.com/actions/upload-artifact
- uses: actions/upload-artifact@v1
with:
name: appjar
path: ops/app/app.jar
# dockerのビルドとECSデプロイのjob
docker_build_and_deploy:
# 他のjobをwaitさせることで、直列なフローを作る
needs: app_build_and_test
# dockerまわりの処理はmasterしか動かさない
# 関数とかもちょっと使える
# https://help.github.com/ja/actions/reference/context-and-expression-syntax-for-github-actions
if: contains(github.ref, '/heads/master')
runs-on: ubuntu-latest
# 環境変数はstep別に書くことも、共通で書くこともできる
env:
DOCKER_BUILDKIT: 1
steps:
# チェックアウト
# https://github.com/actions/checkout
- uses: actions/checkout@v2
# 別jobで作ったファイルをダウンロードする
# https://github.com/actions/download-artifact
- uses: actions/download-artifact@v1
with:
name: appjar
path: ops/app
# awsの認証をする
# https://github.com/aws-actions/configure-aws-credentials
- uses: aws-actions/configure-aws-credentials@v1
with:
# secretsはWEBのgithubのrepositoryのsettingsから登録
# ログ含め綺麗にマスクされる
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
# ECRログイン
# https://github.com/aws-actions/amazon-ecr-login
- uses: aws-actions/amazon-ecr-login@v1
# あとで結果を参照するのでidをつけておく
id: login-ecr
# dockerビルドとECRpush
- name: docker build, ECR push
# このstepだけで使える環境変数
env:
# ECRログインstepの結果を使う
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
# secretsはWEBのgithubのrepositoryのsettingsから登録
ECR_REPOSITORY: ${{ secrets.ECR_REPOSITORY }}
run: |
# GITHUB_SHAなど、最初から使える環境変数もある
docker build -t ${ECR_REGISTRY}/${ECR_REPOSITORY}:${GITHUB_SHA} ./ops/app/
docker push ${ECR_REGISTRY}/${ECR_REPOSITORY}:${GITHUB_SHA}
# サンプルで書いてあってのでなんとなくログアウト...
- name: ECR logout
# alwaysを指定することで、どこかで失敗していてもこのstepに関しては動く
if: always()
# Github Actionsの評価式、実はrun内でも使える
run: docker logout ${{ steps.login-ecr.outputs.registry }}
# TaskDefinitionのimageとtagを差し替えした、新しいTaskDefinitionを作る
# https://github.com/aws-actions/amazon-ecs-render-task-definition
- uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
# 元になるTaskDefinitionファイルのパス
task-definition: ./ops/ECS/task-definition.json
# コンテナ名
container-name: ${{ secrets.ECS_CONTAINER_NAME }}
# 新しいイメージ名とタグ
image: ${{ steps.login-ecr.outputs.registry }}/${{ secrets.ECR_REPOSITORY }}:${{ github.sha }}
# あとで参照するのでid
id: render-web-container
# ECSサービスの更新とデプロイ
# https://github.com/aws-actions/amazon-ecs-deploy-task-definition
- uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
# 新しく作ったTaskDefinitionファイルのパスを指定
task-definition: ${{ steps.render-web-container.outputs.task-definition }}
# ECSサービス名
service: ${{ secrets.ECS_SERVICE_NAME }}
# ECSクラスタ名
cluster: ${{ secrets.ECS_CLUSTER_NAME }}
actionsについて
マーケットプレイスが用意されているのでそこから探す
https://github.com/marketplace?type=actions
作ることもできますが、だいたいのユースケースにおいては使うだけだとおもいます
Microsoftが管理してるactionsだけじゃなく、誰でもactionsを上げられる(はず)なので、そういう状況であることを認識して選びましょう
今回使ったのはMicrosoftとAWSが管理してるactionsです
actionsの引数と戻り値どこ見るの
リポジトリのルートのactions.ymlを見るのがシンプルです
READMEに書かれていることも多いです
amazon-ecs-render-task-definitionを例にして、上のjobと見比べるとわかりやすいと思います
https://github.com/aws-actions/amazon-ecs-render-task-definition/blob/master/action.yml
(2020/5) AWS関連のactions、まだあんまりない
一覧はここから見れます
https://github.com/aws-actions
しかしデプロイ関連は、まだあまりないです、2020/1に確認した時は4つだけだったので、ここもすごい勢いで増えています
- https://github.com/aws-actions/configure-aws-credentials
- https://github.com/aws-actions/amazon-ecr-login
- https://github.com/aws-actions/amazon-ecs-render-task-definition
- https://github.com/aws-actions/amazon-ecs-deploy-task-definition
- https://github.com/aws-actions/aws-cloudformation-github-deploy
- https://github.com/aws-actions/aws-codebuild-run-build
といっても、awsコマンドやjqは、ubuntu-latestなどのホストランナーに入っているのであまり困りません
https://help.github.com/ja/actions/reference/software-installed-on-github-hosted-runners
CodeDeploy(Blue/Green)は?
amazon-ecs-deploy-task-definitionが対応したもよう
試せてないです、