1. yamotuki

    No comment

    yamotuki
Changes in title
-ElasticBeanstalk の複数環境に対してCircleCI Workflowで同じアプリケーションバージョンのコードをデプロイする
+複数環境に対してCircleCI Workflowで同じコードをデプロイする(ElasticBeanstalk編)
Changes in body
Source | HTML | Preview
@@ -1,131 +1,192 @@
-
### 概要
CircleCI Workflow ではテストを通した後に待たせておいて、任意のタイミングでワンクリックでデプロイするという方法をとることができます。
この記事では特に、AWS ElasticBeanstalk の複数の環境に同じバージョンのアプリケーションをデプロイする方法について書きます。ElasticBeanstalk以外でもworkflowの流れと、ジョブ間での情報の受け渡しの方法は同じなので応用できるかと思います。
具体的用途としては、以下のものを想定しています
-* WebアプリケーションとWorker環境の両方に同じコードを勝手にデプロイして欲しい
-* Dev環境と本番環境の両方にワンクリックで同じコードをデプロイしたい
+* Webアプリケーションとジョブ実行するWorker環境の両方に同じコードを勝手にデプロイして欲しい
+* 開発環境と本番環境の両方にワンクリックで同じコードをデプロイしたい
### 完成イメージ
こちらはCircleCI Workflow 実行時の画面イメージです。
dev の二つの環境にデプロイする場合には以下のような見た目になります。
![貼り付けた画像_2019_11_22_12_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144064/c115a12e-1ea1-769a-c1c2-e4fcaf50910b.png)
テストが通った状態で止まっており、 require-testsのところがクリック可能になって、クリックするとデプロイが始まります(テスト終わった直後は一回リロードしないとクリック可能にならないのでそこだけ注意)
さらに本番へのデプロイを足した場合には以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144064/d9f02a3f-39f5-ce3f-7eba-13e626d16442.png)
-同様に require-dev-deploy が足されており、それをクリックすることで本番デプロイに進むことができます。
+新たに require-dev-deploy が足されており、それをクリックすることで本番デプロイに進むことができます。
### 設定の記述方法
`.circleci/config.yml` に CircleCI Workflow の設定を書くことができます。
前提となるセットアップについては省略し、公式ドキュメントなどにお任せします。
-```.circleci/config.yml
-version: 2
-jobs:
- test-js:
- # ここは今回は詳細記述を省略
- test-php:
- # ここは今回は詳細記述を省略
+先にファイルの全体像がわかるように全部が入ったものを載せます。そのあとに個別の項目について解説していきます。
- deploy-to-dev:
+```.circleci/config.yml
+version: 2.1
+# (※1) executors と commands について を参照のこと
+executors:
+ setup-eb-environment:
docker:
- image: circleci/python:3.6.4
working_directory: ~/repo
+commands:
+ setup-eb-command:
steps:
- checkout
- # ここら辺は eb コマンドのセットアップ
+ # 今回の本流とは関係ないので一部省略。awscli入れて access key 設定などをします
- run:
name: Install awscli
- command: |
- sudo pip install --upgrade pip
- sudo pip install awsebcli --upgrade
+
+jobs:
+ test-js:
+ # 今回は略
+ test-php:
+ # 今回は略
+
+ deploy-to-dev:
+ executor: setup-eb-environment
+ steps:
+ # 上で定義したコマンドを使っています
+ - setup-eb-command
+ - run:
+ name: Deploying to dev webapp
+ # ここでsedなどで出力整形するのもありではあるが、eb deploy コマンドの終了ステータスが破棄されてしまって異常時に正しく止まらないことが考えられたためファイルリダイレクトだけにしている
+ command: eb deploy develop-webapp > /tmp/eb_deploy_output
- run:
- name: Create AWS credentials manually
+ name: Deploying to dev worker
+ # こういう感じのアウトプットを期待してダブルクオートの中を取り出しています。 => Creating application version archive "app-2019-11-18-2-57-gd83f8-191122_104221".
command: |
- mkdir ~/.aws
- touch ~/.aws/config
- chmod 600 ~/.aws/config
- echo "[profile eb-cli]" > ~/.aws/config
- echo "aws_access_key_id=$AWS_ACCESS_KEY_ID" >> ~/.aws/config
- echo "aws_secret_access_key=$AWS_SECRET_ACCESS_KEY" >> ~/.aws/config
- - run:
- name: Deploying to dev app 1
- command: eb deploy my-dev-appliation-1 > /tmp/eb_deploy_output
- - run:
- name: Deploying to dev app 2
- # こういう感じのアウトプットを期待してダブルクオートの中を取り出しています。 => Creating application version archive "app-2019-11-18-2-57-gd83f8-6547657_104221".
- command: eb deploy my-dev-application-2 --label `cat /tmp/eb_deploy_output | grep "version archive" | sed -E 's/.*\"(.*)\".*/\1/'`
- # ジョブ間で情報を共有するためにここが重要で、workspaceに永続化(30日)をします
+ cat /tmp/eb_deploy_output | grep "version archive" | sed -E 's/.*\"(.*)\".*/\1/' > /tmp/app_version_label
+ eb deploy develop-worker --label `cat /tmp/app_version_label`
+ - run:
+ name: check app version
+ command: cat /tmp/app_version_label
+ # (※2) job間での情報受け渡し方法について を参照のこと
- persist_to_workspace:
root: /tmp/
paths:
- app_version_label
deploy-to-production:
- docker:
- - image: circleci/python:3.6.4
-
- working_directory: ~/repo
-
+ executor: setup-eb-environment
steps:
- - checkout
- # workspaceに入っているものを取り出ます
+ - setup-eb-command
+ - checkout
+ # workspaceに保存したものを取り出ます
- attach_workspace:
at: /tmp/
- run:
- # devと同じなので省略
+ name: check app version
+ command: cat /tmp/app_version_label
+ - run:
+ name: Deploying to production worker
+ # (※3) ebコマンドの `--label` でのバージョン指定について を参照のこと
+ command: eb deploy production-worker --label `cat /tmp/app_version_label`
- run:
name: Deploying to production webapp
- command: |
- APP_VERSION_LABEL=`cat /tmp/app_version_label`
- echo $APP_VERSION_LABEL
- eb deploy my-production-app-1 --label $APP_VERSION_LABEL
+ command: eb deploy production-webapp --label `cat /tmp/app_version_label`
workflows:
- version: 2
+ version: 2.1
build-and-test-approval-deploy:
jobs:
- - test-js
+ - test-js:
+ # (※4) filters の動きについて を参照のこと
+ filters:
+ tags:
+ only: /.*/
- test-php:
requires:
- test-js
- # 前提としてtestが通っていて、許可したらデプロイするというのをするなら type: approval を使う。
+ filters:
+ tags:
+ only: /.*/
- require-tests:
type: approval
requires:
- test-php
+ filters:
+ tags:
+ only: /.*/
- deploy-to-dev:
requires:
- require-tests
+ filters:
+ tags:
+ only: /.*/
- require-dev-deploy:
type: approval
requires:
- deploy-to-dev
+ # リリースタグ 2019-11-01 や 2019-11-01-fix などの形に対応。tagがある時にだけリリース可能。
+ filters:
+ tags:
+ only: /^(\d){4}-(\d){2}-(\d){2}.*/
+ branches:
+ ignore: /.*/
- deploy-to-production:
requires:
- require-dev-deploy
+ filters:
+ tags:
+ only: /^(\d){4}-(\d){2}-(\d){2}.*/
+ branches:
+ ignore: /.*/
```
-# 補足
-### ebコマンドの `--label` でのバージョン指定について
+### ※1 executors と commands について
+https://circleci.com/docs/ja/2.0/configuration-reference/#executorsversion21-%E3%81%8C%E5%BF%85%E9%A0%88
+
-`--label` を**指定せずに** eb deploy を複数回実行することもできるかと思いますが、それだと環境が増えるとElasticbeanstalkの管理コンソール上でみれるアプリケーションバージョンが複数発行されてしまい、邪魔になってしまいます。
-`--label` で以前のバージョンを指定すればその問題が起こりません。1回目の eb deploy のアウトプットを取得して整形し、2回目のeb deployコマンドの`--label`オプションの引数に渡しています。
+* executors は `Executors は、ジョブステップの実行環境を定義`
+* commands は `ジョブ内で実行するステップシーケンスをマップとして定義`
+
+要するに、実行環境とあとで使用するコマンドを先に定義しておいて、使いまわすことができます。
-### ジョブ間での情報受け渡し方法について
+### ※2 job間での情報受け渡し方法について
永続化ではなくてジョブ間でのファイル受け渡しに persist_to_workspace(ファイルをworkspaceに30日保存) と attach_workspace(指定のパスに対してworkspaceにあったらアタッチする) のワンセットを使えることがわかった。
参考ドキュメント:
https://circleci.com/blog/build-cicd-piplines-using-docker/
https://circleci.com/docs/ja/2.0/configuration-reference/#persist_to_workspace
`$BASH_ENV` に保存すれば良いという情報もあったが、`$BASH_ENV`に保存されるファイルパスがジョブによって変わってしまって使えなかった。
+
+### ※3 ebコマンドの `--label` でのバージョン指定について
+
+`--label` を**指定せずに** eb deploy を複数回実行することもできるかと思いますが、それだと環境が増えるとElasticbeanstalkの管理コンソール上でみれるアプリケーションバージョンが複数発行されてしまい、邪魔になってしまいます。
+`--label` で以前のバージョンを指定すればその問題が起こりません。1回目の eb deploy のアウトプットを取得して整形し、2回目のeb deployコマンドの`--label`オプションの引数に渡しています。
+
+### ※4 filters の動きについて
+参考: https://qiita.com/sanemat/items/4ddbd4016a5269265166
+
+* branch はデフォルトで全て実行
+* tag はデフォルトで全て無視
+
+なのでtagのfilterを明示的に指定していない場合にgithubでタグが追加された時は最初のジョブからなくなるのでワークフローのリストにも表示されない。
+そういうわけで、タグがついているタスクに対してジョブを実行したければ全てのジョブに以下のfilterを追加してあげる必要があった。
+
+```
+ filters:
+ tags:
+ only: /.*/
+```
+
+### おまけ CircleCI config のシンタックスチェック方法
+circleci コマンドを用いると、いちいちデプロイしなくてもシンタックスチェックができて良いです。こういう仕事は大体時間がかかるので、待ち時間を減らしましょう。
+
+```
+$ circleci config validate -c .circleci/config.yml
+Config file at .circleci/config.yml is valid.
+```
+
+このコマンドのインストール方法などは公式ドキュメントを参照のこと https://circleci.com/docs/ja/2.0/local-cli/
+
+補足: mac PC の環境においてはbrewで入れると circleci update ができなかったのでbrew以外の方法で入れたほうが良さそう。