とりあえずECS/Fargate + EFSでのデプロイ実装ができた。CircleCI → AWS CodeBuildにkickする感じ。詳細はブログ書くか〜〜💪
— adachin👾SRE (@adachin0817) March 17, 2021
前回はECS/Fargate + EFSでWordPressの構築でハマったことをブログしましたが、今回はStg、本番環境にデプロイできるように実装したのでブログします。答えを言ってしまうとCircleCIとAWS CodeBuildを組み合わせれば可能です。ちなみに自分はCodeBuildを触ったことがなかったので非常にお勉強になりました。まずはSystem Managerの設定から行いましょう。
System Managerの設定
GitHub専用の秘密鍵をSystem Managerに登録しておきます。後ほど設定するCodeBuildで環境変数として鍵を配置するためですね。
- パラメータの作成
タイプは安全な文字列で上記のように設定してもらい、値は秘密鍵をペーストして作成すれば完了です。
AWS CodeBuildの設定
- プロジェクトの設定/ソース
プロジェクトは何でも良いです。チェック項目は特にしません。EFSは既にリポジトリがマウントされている前提ですので、ソースプロバイダはGitHubのリポジトリを連携できますが、リリース時に何個もリポジトリがあるとCodeBuildのプロジェクトを作成しなければならなく、管理が雑多になってしまうため、1つのプロジェクトでかつCircleCIでデプロイメントできるようにしました。なので今回は設定しなくてOKとなります。
- 環境
OSはAmazon Linux 2にしました。特権付与はEFSでマウント時にアクセス権限を付与しないとプロジェクトが作成されないので必ずチェックしましょう。追加設定ではVPCは各自設定してください。環境変数では先程System Managerで設定した秘密鍵をパラメータとして追加します。他にも環境変数としてgithubのメールアドレスとユーザー名も追加しましょう。ファイルシステムは識別子がEFS_1でIDは選択すると候補が出るので指定します。マウントポイントも忘れずに。
- Buildspec
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
version: 0.2 phases: build: commands: - echo Deploy started on `date` - yum install sudo -y - userdel codebuild-user - adduser --uid 1000 adachin - mkdir ~/.ssh & chmod 700 ~/.ssh - echo "${SSH_KEY}" > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa - | cat <<EOF > ~/.ssh/config Host github.com User git Hostname github.com IdentityFile ~/.ssh/id_rsa EOF - | - cp -rp ~/.ssh /home/adachin/ - chown -R adachin:adachin /home/adachin/.ssh - cd /mnt/www/${RELEASE_PATH} - sudo -u adachin git config --global user.email "${MAIL}" - sudo -u adachin git config --global user.name "${USER}" - chmod -R 0777 .git/objects/ - sudo -u adachin git checkout master - sudo -u adachin git pull - sudo -u adachin git branch --merged | grep -vE '^\*|master$|develop$' | xargs -I % git branch -d % - sudo -u adachin git checkout ${BRANCH} - sudo -u adachin git pull - echo Deploy completed on `date` |
- EFS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/mnt/www/adachin-wordpress$ ls -la drwxrwxr-x 11 adachin adachin 6144 3月 19 18:19 . drwxr-xr-x 15 adachin adachin 6144 2月 14 01:49 .. drwxr-xr-x 2 adachin adachin 6144 3月 18 15:53 .circleci drwxrwxr-x 8 adachin adachin 6144 3月 19 18:19 .git drwxr-xr-x 2 adachin adachin 6144 4月 17 2020 .github -rw-r--r-- 1 adachin adachin 693 5月 21 2019 .gitignore drwxr-xr-x 2 adachin adachin 6144 5月 21 2019 .idea -rw-r--r-- 1 adachin adachin 6066 3月 18 15:53 README.md drwxr-xr-x 2 adachin adachin 6144 3月 18 15:53 deploy -rw-r--r-- 1 adachin adachin 926 4月 17 2020 gulpfile.js -rw-r--r-- 1 adachin adachin 1098 5月 31 2019 package.json drwxrwxr-x 4 adachin adachin 6144 3月 18 15:28 stylus drwxrwxr-x 10 adachin adachin 6144 11月 22 15:13 wordpress -rw-r--r-- 1 adachin adachin 2346 12月 21 2018 wordpress_setup.md -rw-rw-r-- 1 adachin adachin 80924 5月 1 2017 yarn-error.log -rw-rw-r-- 1 adachin adachin 111316 11月 22 15:13 yarn.lock |
BuildspecではGitHubの鍵を配置して、変数化したブランチをgit pullするだけになります。この変数化したBRANCHやRELEASE_PATHは後ほどCircleCIで使いますので後で説明します。ちなみに今回EFSの権限ですが、仮のadachinユーザーとしましょう。CodeBuildのAmazon Linux 2は初めにcodebuild-userでbuildをしますが、このホームディレクトリは以下のように/home配下ではありません。(なぜよ…)それにホームディレクトリの権限は何故かrootでしたので、そのままホームディレクトリに鍵を配置してもrootユーザーでgit pullされてしまうということがあったので、一旦codebuild-userを削除し、対象ユーザーを作成、鍵をコピー、sudoで対象ユーザーを指定しながらgit pullをすると対象ユーザで権限が揃うことができました。(ここは二日くらいハマった…)
1 2 |
[Container] 2021/03/18 12:42:01 Running command pwd /codebuild/output/src308584337/src |
あとはそのままログはCloudWatch Logsに飛ぶように設定してもらい、以下System Manager用のポリシーを作成したら上記のロールに設定してください。
- build-id_rsa
1 2 3 4 5 6 7 8 9 10 |
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ssm:GetParameters", "Resource": "*" } ] } |
以上でStg環境のAWS CodeBuildの設定は完了です。本番環境も同様に作成してください。
■デプロイの仕組み
まず、CircleCIの実装よりも前に上記で設定したCodebuid/Buildspecの環境変数について説明します。${BRANCH} は名前の通りブランチ名を指定する環境変数です。${RELEASE_PATH} はリポジトリ名(ディレクトリ先)となります。これを毎回CircleCIでリリースするためにはaws cliを使って、Codebuidの環境変数を上書きして実行すれば可能です。aws cliでの実行方法としては以下になります。
https://docs.aws.amazon.com/cli/latest/reference/codebuild/start-build.html
1 |
$ aws --region ap-northeast-1 codebuild start-build --project-name hoge_release --environment-variables-override name=RELEASE_PATH,value=adachin-wordpress name=BRANCH,value=branch |
残りはCircleCIで実装すれば完了です。以下図を作ってみました。
・Stg環境はシェルスクリプトでCircleCIのAPIからブランチ名を引数として実行
・Dockerコンテナからaws cliでcodebuild実行
・特定のブランチにgit checkoutとgit pullでデプロイ完了
・本番環境はMasterマージでDockerコンテナからaws cliでcodebuild実行
・Masterブランチにgit checkoutとgit pullでデプロイ完了
CircleCIでAPIリリース方法は以下ブログ書いているので参考に。
CircleCI
- .circleci/config.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
version: 2.1 orbs: aws-cli: circleci/aws-cli@2.0.0 slack: circleci/slack@3.4.2 parameters: deploy_stg_codebuild: type: boolean default: false executors: docker_build: machine: docker_layer_caching: true jobs: deploy_stg_codebuild: working_directory: ~/app executor: docker_build steps: - checkout - aws-cli/setup: aws-region: AWS_REGION aws-access-key-id: AWS_ACCESS_KEY_ID_STG aws-secret-access-key: AWS_SECRET_ACCESS_KEY_STG override-installed: true - run: name : fix branch command: | echo ${CIRCLE_BRANCH} |sed -ri "s/BRANCH_NAME/$CIRCLE_BRANCH/g" ~/project/deploy/deploy_codebuild.sh - run: name : deploy stg command: | ~/project/deploy/deploy_codebuild.sh - slack/status: fail_only: true mentions: 'here' failure_message: 'Error Deploy Stg🚨 \n :innocent: ${CIRCLE_USERNAME} :branch: ${CIRCLE_BRANCH}' webhook: ${SLACK_WEBHOOK} - slack/notify: title: Stg color: '#42f486' message: 'Deploy OK ✨ \n :smile: ${CIRCLE_USERNAME} :branch: ${CIRCLE_BRANCH}' webhook: ${SLACK_WEBHOOK} deploy_prd_codebuild: working_directory: ~/app executor: docker_build steps: - checkout - aws-cli/setup: aws-region: AWS_REGION aws-access-key-id: AWS_ACCESS_KEY_ID_PRD aws-secret-access-key: AWS_SECRET_ACCESS_KEY_PRD override-installed: true - run: name : fix branch command: | echo ${CIRCLE_BRANCH} |sed -ri "s/BRANCH_NAME/$CIRCLE_BRANCH/g" ~/project/deploy/deploy_codebuild.sh - run: name : deploy prd command: | ~/project/deploy/deploy_codebuild.sh - slack/status: fail_only: true mentions: 'here' failure_message: 'Error Deploy Prd🚨 \n :innocent: ${CIRCLE_USERNAME} :branch: ${CIRCLE_BRANCH}' webhook: ${SLACK_WEBHOOK} - slack/notify: title: Prd color: '#42f486' message: 'Deploy OK ✨ \n :smile: ${CIRCLE_USERNAME} :branch: ${CIRCLE_BRANCH}' webhook: ${SLACK_WEBHOOK} workflows: version: 2 deploy_stg: when: << pipeline.parameters.deploy_stg_codebuild >> jobs: - deploy_stg_codebuild deploy_prd: jobs: - deploy_prd_codebuild: filters: branches: only: master |
aws-cliはOrbsでインストールしてクレデンシャルの設定をします。特に35行目でcodebuild用シェルのBRANCH_NAMEからCircleCIの環境変数であるブランチにsedで置換しています。これによって特定のブランチでもCodebuidの環境変数に上書きして、git pullがEFS上でできるようになり、リリースに繋がります。では早速テストしてみましょう!
- stg-deploy.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
#!/bin/bash BRANCHNAME=$1 url="https://hooks.slack.com/services/xxxxxxxxxxxxxxxxxxx" username='Stg-WordPress' to="wordpress" subject='Stgデプロイを開始しました:docker2:' color="#0000FF" message="ブランチ名: `"${BRANCHNAME}"` https://app.circleci.com/pipelines/github/xxxxxxx/adachin-wordpress" help() { echo " 下記のようにブランチを指定して実行してください。 (例) ~/www/adachin-wordpress/deploy/stg-deploy.sh ブランチ名 " } if [ $# -ne 1 ];then help exit fi curl -u xxxxxxxxxxxxxxxxxx: -X POST --header "Content-Type: application/json" -d '{ "branch": "'"${BRANCHNAME}"'", "parameters": { "deploy_stg_codebuild": true } }' https://circleci.com/api/v2/project/github/xxxxxxx/adachin-wordpress/pipeline echo " ブランチ名/ "${BRANCHNAME}" のStgデプロイを開始しました。 " payload="payload={ \"channel\": \"${to}\", \"username\": \"${username}\", \"text\": \"${subject}\", \"attachments\": [ { \"color\" : \"${color}\", \"text\" : \"${message}\", } ] }" curl -m 5 --data-urlencode "${payload}" ${url} |
- deploy_codebuild.sh
1 2 3 |
#!/bin/bash aws --region ap-northeast-1 codebuild start-build --project-name hoge_release --environment-variables-override name=RELEASE_PATH,value=adachin-wordpress name=BRANCH,value=BRANCH_NAME |
Test
- シェルでStgリリースする
1 2 3 4 5 6 7 8 |
$ ./stg-deploy.sh test { "number" : 36, "state" : "pending", "id" : "xxxxxxxxxxxxxxxxxxxxx", "created_at" : "2021-03-17T13:36:00.299Z" } ブランチ名/ add_circleci のeStgデプロイを開始しました。 |
- CircleCI
- Codebuild
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
/mnt/www/adachin-wordpress$ git branch * test master /mnt/www/adachin-wordpress$ git pull Already up-to-date. /mnt/www/adachin-wordpress$ ls -la drwxrwxr-x 11 adachin adachin 6144 3月 19 18:19 . drwxr-xr-x 15 adachin adachin 6144 2月 14 01:49 .. drwxr-xr-x 2 adachin adachin 6144 3月 18 15:53 .circleci drwxrwxr-x 8 adachin adachin 6144 3月 19 18:19 .git drwxr-xr-x 2 adachin adachin 6144 4月 17 2020 .github -rw-r--r-- 1 adachin adachin 693 5月 21 2019 .gitignore drwxr-xr-x 2 adachin adachin 6144 5月 21 2019 .idea -rw-r--r-- 1 adachin adachin 6066 3月 18 15:53 README.md drwxr-xr-x 2 adachin adachin 6144 3月 18 15:53 deploy -rw-r--r-- 1 adachin adachin 926 4月 17 2020 gulpfile.js -rw-r--r-- 1 adachin adachin 1098 5月 31 2019 package.json drwxrwxr-x 4 adachin adachin 6144 3月 18 15:28 stylus drwxrwxr-x 10 adachin adachin 6144 11月 22 15:13 wordpress -rw-r--r-- 1 adachin adachin 2346 3月 17 2021 test2.html -rw-rw-r-- 1 adachin adachin 80924 5月 1 2017 yarn-error.log -rw-rw-r-- 1 adachin adachin 111316 11月 22 15:13 yarn.lock |
ちゃんとStg環境がデプロイされてtest2.htmlファイルが追加されていました!本番環境はMasterマージすればOKなので以下試してみましたが問題なくデプロイされてました!
まとめ
危うく各リポジトリごとにCodebuidのプロジェクトを設定するところだった… そしてTerraform化すればヨカタ…
Codebuidはじめて触ってみましたが、かなり便利ですね。CircleCIと同じで何でもできそう。ただ、CircleCIのようにSSHデバッグができないのでひたすらlsしまくって確認してましたが、直接インスタンスにログインするというデバッグ方法があったというね…EFSでのリリース実現できてよかった!
0件のコメント