君は一体なんどやってきただろうか。
ため息が出るほど繰り返される車輪の発明。
何度も何度も繰り返す。
「やったぞ!これがあれば車や電車はスムーズに道を走れる!」
「車輪と名付けよう。これがあれば……!」
CircleCIだけに。
CircleCIだろうとAWSだろうとTerraformだろうと、開発者の君がやりたいことなんて最初からお見通し。
「言うてもほら、これがやりたいんでしょ。車輪、作っといたよ。これで初めてでもすぐに走れるね」
って、サービス提供者は予め用意してくれている。それに気づくかどうかで作業工数は大きく変わる。
ここで言いたいのは、車輪の再発明を全否定するということではない。車輪がどうやってできているかを知るのはエンジニアにとってとても良い経験だ。中身を知るのは必要だ。
問題は勉強目的ではないときに、車輪の再発明をしてしまうのは心底時間が勿体無いということだ。
CircleCI Orbs
CI/CDサービスでは初のパッケージ提供らしい。これまで、CircleCIで使うコンテナの設定は自分でインストールするなりして記述していた。
これをCircleCI 2.1なら、予め作成されたパッケージを使える。
AWSやGCPなどメジャーなクラウドサービスを使って基盤を構築しているなら、概ね開発者がやりたいことは一緒だったりする。
TL;DR
- ジョブ、コマンド、Executor のような設定要素をまとめた共有可能なパッケージ。要は自分で設定を記述しなくてもOK
- CircleCI 独自の認証済み Orb
- パートナー企業によるサードパーティ製 Orb
- 自分たちでOrbを作成可能。他のプロジェクトにも共有できる
- レジストリで探せるので、configを書く前に探したほうがいい
はじめかた
circleci2.1を使えるようにするところから。しかしこれは至って簡単。
Settings >> Advanced Settings
CircleCI側の設定はこれでOK
config側では、以下のようにバージョン指定すればよい。
version: 2.1 ~省略~
つかいかた
これも非常に簡単だ。たった二行でよい。
orbs: aws-ecr: circleci/aws-ecr@4.0.1
抽象化するとこんな感じ。<name>の部分はあとで呼び出す名前になるのでわかりやすく付けておくとよい。
orbs: <name>: <orb_name>
実践
サンプルだけでは虚しいので実際にどう使っているかも書いておこう。
- Dockerイメージをビルドして、ECRにPushしたい
という流れをCircleCIでやりたいとする。
実際にこれを手動で書くとしたら、
- CircleCIでマシンを用意
- AWS CLIのインストール
- aws configureの設定
- ECR Login
- ECR Push
を記述していかなければならない。実際、僕が勉強不足によりOrbsの存在を知らなかったときはECR Loginがうまく書けずに苦戦した。 aws configureの設定も、どう書いたらCircleCIのマシンに設定できるのかも悩んだ。
が、これをOrbsを使えばどうか?こうなる。
workflows: ecr_build_and_push_image: #Workflowの名前。任意 jobs: - request-build_and_push: #CircleCI画面で、手動承認しないとbuild_and_push_imageが実行されないように制御するJob type: approval - aws-ecr/build_and_push_image: #Orbで定義されている <name>/<job_name> requires: - request-build_and_push #このJobの実行が終了次第開始 context: <CONTEXT_NAME> #contextという単位で環境変数を設定 account-url: AWS_ECR_ACCOUNT_URL #contextに設定した環境変数 aws-access-key-id: AWS_ACCESS_KEY_ID #contextに設定した環境変数 aws-secret-access-key: AWS_SECRET_ACCESS_KEY #contextに設定した環境変数 region: AWS_REGION #contextに設定した環境変数 repo: <REPO_NAME> #ECRにPushするリポジトリ名 tag: <DOCKER_IMAGE_TAG> #Dockerイメージのタグ名
aws-ecr/build_and_push_image
は、Orbの名前と該当するJob名を指定している。
勘違いしてはいけないのは、あくまでJobsに定義されたJobしかWorkflowでは実行できない。 Commandsに定義されているCommandは、stepsで使用することができる。
こうして書くだけで、さきほど書いた流れを自動で呼び出して実行してくれる。なんて簡単なのでしょう。
ちなみに実際に何が実行されているのか見たい場合も可能。
実行されたビルドの詳細から Configurationのタブを見れば良い。ここで実行されているコマンドは別で流用できる。
context
環境変数はリポジトリ単位でしか設定できないと思っていたが、contextという単位で設定できる。 これでprdならこうだー、stgならこうだーときめ細かい設定ができる。
トラブルシュート:approval
僕が地味にハマったのは手動承認でWorkflowを進めるための記述。type: approval
を記述すればよいとドキュメントには書いてあるが、うまく動かなかった。
workflows: ecr_build_and_push_image: jobs: - aws-ecr/build_and_push_image: type: approval #このJobを手動承認にしたかったのでここに記述していた requires: - request-build_and_push context: <CONTEXT_NAME> account-url: AWS_ECR_ACCOUNT_URL aws-access-key-id: AWS_ACCESS_KEY_ID aws-secret-access-key: AWS_SECRET_ACCESS_KEY region: AWS_REGION repo: <REPO_NAME> tag: <DOCKER_IMAGE_TAG>
この書き方をすると、Jobの中身は一切実行されずに正常終了する。おかしーなーと思っていたけどこれは仕様だった。
俺はcircleciのapprovalを勘違いしていたようだ…
— VTRyo (@3s_hv) 2019年5月20日
こいつはただJobを承認するかどうかを聞くためだけのものに過ぎないのか…
だからapprovalをつけたところにはJobを定義することはできなくて、approvalのあとに実行させたいJobを定義しないとならない。https://t.co/QXeLDu3ekb
approvalはあくまで承認するためだけのものなので、approval用のJobを作る必要があったようだ。
まだ車輪の再発明する?
簡単にOrbのはじめかたを書いた。何度も言うけど再発明が悪いわけではない。しかし、早く実装したいのに手動でイチから書くのは勿体無いと思う。
CircleCI、やり込むと面白いので時間があるときに自分で新しい車輪を作っていければいいんじゃないだろうか。