Buildとは一体何者なのかCI/CDこんにちは。SWETの加瀬(@Kesin11)です。Build(以後GCBと略します)というものが発表されました。https://cloud.google.com/cloud-build/https://www.youtube.com/watch?v=iyGHW4UQ_TsCI/CDサービスを追っているものとして、これは要チェック!ということで、GCBを軽く使ってみて分かった特徴をCircleCIと比較してまとめてみました。最初にまとめを書いてしまうと、GCBはCI/CDとして見るとCircleCIと比べてまだまだ扱いづらいところがあります。一方で、従量課金制のフルマネージドなビルドサービスというCircleCIとは違った使い方もできるところが特徴と言えます。GCBの特徴1ステップ1コンテナ一般的なCI/CDサービスでは、以下のようなステップをGUIや専用のファイルに自分で記述していきます。checkout依存ライブラリのインストールビルドテスト実行デプロイCircleCIを例にすると、それぞれのステップは1つの仮想マシン、あるいは最近では1つのdockerコンテナ上で実行されるのが一般的です。test上の.circleci/config.ymlの場合、circleci/node:9のコンテナ上で全てのステップが実行されることになります。Workflowsを活用した場合には複数のコンテナを使用してビルドフローを構築することも可能ですが、基本的には1コンテナ上で複数のステップを実行するという考え方です。GCBではここから根本的に異なっており、1ステップ1コンテナで実行されます。'.']各ステップに必ずdockerイメージ名が記載されており、実際にこのコンテナ上で各ステップが実行されます。buildしたいときはdockerが使えるコンテナを指定します。Buildではよく使われるコマンドを実行できるdoockerイメージをGitHub上で公式とコミュニティがメンテしています。gcloud、kubectl、firebaseなどが使えるイメージが存在します。Buildによってメンテされているdockerイメージ以外も使用可能です。先ほどのcloud-buildersのnpmのディレクトリにあるREADMEを見ると、以下のようにentrypointを指定することで公式のnodeイメージを使用することも可能であると書かれています。Stepsのドキュメントを参照するとよいでしょう。APIというものが公開されました。Requestの画面からCI結果の詳細が見られるようになるという新機能なのですが、まだ対応されているサービスは多くありません。Center、そしてGCBの3つしかないようです。https://developer.github.com/v3/checks/CircleCIは5月の発表時点では名を連ねていましたが、まだ使えるようになっていません。Registry(GCR)との連携が挙げられます。GCRはプライベートなコンテナレジストリを提供してくれるサービスで、特にGCPのコンテナを扱うサービス(GKEなど)を利用する上ではとても便利です。buildしたイメージをimagesで指定するだけで、自動的にGCRにpushしてくれます。認証のための鍵などを考える必要はなく、非常にお手軽です。pushをひたすら繰り返すことになります。.このコマンド一発だけでローカルのソースコードを全てtarで固めて、cloudbuild.yamlに従ってクラウド上ジョブが実行されるので非常に簡単です。pushして動作確認するのもそれほど手間ではありませんが、トライ&エラーの時期にはコマンド一発で動作確認ができるのは意外と便利です。buildなどを実行できる便利なサービスとして使うこともできるでしょう。ちなみにGCBでも手動で実行するだけではなく主要なCIサービスと同様に、GitHubにpushしたタイミングで自動的にジョブが動くように設定することは可能です。https://cloud.google.com/cloud-build/docs/run-builds-on-github?hl=en8コア、32コアマシンGCBではビルドを実行するマシンのスペックを簡単に選択できます。どれだけ簡単かというと、先程のコマンドに--machine-typeオプションを追加するだけです。.これだけでビルドを実行するマシンは8コアのスペックになります。オプション1つでマシンスペックを上げることが可能なので、非常に時間がかかるビルドフローを実行する場合だけハイスペックマシンにするという使い方が可能です。cloudbuild.yamlに直接マシンスペックを記載することで、常に8コアマシンを使用してビルドするように設定することも可能です。https://cloud.google.com/cloud-build/docs/api/reference/rest/v1/projects.builds#machinetype従量課金制CircleCIは月額課金制で、並列数やコンテナ数に応じて料金が変動する料金体系になっています。https://circleci.com/pricing/GCBでは料金体系が一般的なCIサービスとは異なっており、月額課金ではなくて従量課金制です。1コアマシンなら毎日120分は無料で、それを超えた先は分単位で課金されます。ちなみに無料枠は1コアマシンだけのようで、先程紹介した8コア、32コアマシンの場合は無料枠がありませんので注意してください。https://cloud.google.com/cloud-build/pricing?hl=enCircleCIとは料金体系が異なるのでどちらが良いとは一概に言えませんが、少なくともGCBの場合はハイスペックマシンが必要な瞬間や、ビルドフローによってマシンスペックを変更することが可能という柔軟性があります。GCBのイマイチな点ここまでGCBの特徴として基本的に良い点を取り上げてきましたが、使ってみてイマイチだと感じた点もあるのでこちらについても触れておきます。Slack連携がない。Functionでやるしかないこれが痛すぎるマイナスポイント。なんとビルドの成功/失敗を通知するという基本的な機能ですらデフォルトでSlackやメールに対応していません。Functionを自前で用意してSlackなりMailgunのようなメール送信サービスのAPIを叩けということのようです。https://cloud.google.com/cloud-build/docs/configure-third-party-notificationsCircleCIのような主要なCI/CDサービスではSlackなどに簡単に接続できるので、この点はだいぶ方針が異なると思いました。キャッシュの記法が無いCircleCIでは、ビルド時間を短くするために有効な方法として依存ライブラリのキャッシュがあります。CircleCIではキャッシュの読み取り/保存のためにrestore_cacheとsave_cacheという特別なステップが用意されています。GCBの場合には、そのようなキャッシュのためのステップは用意されていないようです。自分がドキュメントを探した限りでは代替手段の解説も見当たりませんでした。Storage(GCS)をキャッシュの代わりに使用することで実現できるかも...?並列ビルドフローの書き方が分かりにくい、フローのGUIが無いCircleCIでは2.0からWorkflowを使うことで比較的簡単に並列のビルドフローを組み立てることができ、さらにビルドフローの図をGUIで表示してくれます。https://circleci.com/docs/2.0/workflows/GCBでも並列のビルドフローを組み立てることは可能ですが、設定ファイルの記述方法がCircleCIと比較してとても把握しやすいとは言えません。Hostingにデプロイする用のディレクトリが存在する場合に並列で処理させる場合の書き方を比較します。ディレクトリの構成はこのような感じです。storeまずはCircleCI。deployのジョブに分割し、最後のworkflowsで順序や依存関係を記述するスタイルです。以下の設定ではこのような流れになります(キャッシュ周りなど、今回の説明に不要な一部のステップは省略しています)。build-web次がGCBです。ステップごとにidを設定しておき、waitForで依存するステップを記述するスタイルです。waitForが無いステップでは、自動的に1つの上のステップに依存するという挙動になります。waitForで'-'を指定した場合は特別で、どのステップにも依存しないという意味になるので並列化する部分の起点になります。deployが実行されます。['FIREBASE_TOKEN']個人的には、どの部分が並列に実行されるかがwaitForの挙動を把握していたとしても分かりづらいと感じました。CircleCIのworkflowと比べてyaml上で全体的なフローが把握しにくいだけではなく、GUIでフロー図を出してくれる機能もないのがマイナスポイントです。お手軽にマシンスペックを変更可能な点がGCBの長所なのですが、この並列ビルドフローの書きにくさがその長所を活かしにくくしてしまっています。https://cloud.google.com/cloud-build/docs/configuring-builds/configure-build-step-order?hl=en設定ファイル中に分岐処理を記述できないCircleCIのconfig.ymlにはif-elseや、ブランチの指定などによって例えばmasterブランチの場合にだけデプロイのステップを実行する、といった制御を行うことができます。先ほどのconfig.ymlも最後のworkflowsの部分にfiltersを追加することで、最後のdeployのジョブはmasterブランチの場合のみ実行されるといった制御が可能です。master一方で、GCBには1つの設定ファイルの中で条件分岐を行うための記法が存在しません。分岐させたい処理だけシェルスクリプトに記述して実行させるという方法でおそらく実現は可能だと思いますが、全体の見通しは悪くなってしまうでしょう。代わりにGCBはビルドトリガーを設定する際に、ブランチ名を正規表現で指定してビルドに使用する設定ファイルをcloudbuild.yaml以外にも指定できます。以下のようにブランチ毎に使用する設定ファイルを分けることでブランチ毎のフロー制御が可能です。developブランチcloudbuild.yaml(lintやテストを行う)masterブランチcloudbuild_deploy.yaml(デプロイを行う)ただし、CircleCIと異なり設定ファイルを分割する必要があるので、保守性の観点から個人的にはCircleCIの方法の方が好みです。シークレットキーの扱いが面倒デプロイを実行するフローを構築する場合に、秘密にしておく必要があるトークンをどうやってCIサービス中に読み取るかという問題があります。トークンが記されたファイルをリポジトリに含めてしまうのが最も簡単ですが、セキュリティ的な観点からは望ましくありません。CircleCIではconfig.yamlとは別にCircleCIのGUIから環境変数の登録が可能なため、秘密にしておきたいトークンなどは環境変数にセットしてしまうのが一般的な方法です。KMS)というまた別のサービスと連携させる必要があります。先程のcloudbuild.yamlでは、secrets:の箇所で暗号化されたトークンを環境変数としてセットしています。https://cloud.google.com/cloud-build/docs/securing-builds/use-encrypted-secrets-credentials?hl=en#encrypting_an_environment_variable_using_the_cryptokey詳しい使い方は上記のドキュメントを参照してください。環境変数を登録したいだけなのにCircleCIと比較すると手順が多いという印象です。Buildの良い点、イマイチな点を紹介しました。最後にまとめとして、自分の主観ですがざっくりとした比較表を用意してみました。従量課金GCBをCircleCIと比較してみて、個人的にはCI/CDとしてはまだ発展途上かなという印象でした。GCPとの連携は強みですが、ビルドフローが書きにくかったり、Slack通知がデフォルトでは無いあたりが現時点では少々扱いづらい点です。Buildというその名の通りフルマネージドな従量課金ビルドサービスとして非常に便利だと思います。buildを並列に行ってコンテナレジストリに登録したり、ソースコードのコンパイルといった、シンプルにコア数の多いハイスペックマシンを用意できると時間が短縮できるタスクを行う方が向いているという印象です。近い将来、もはやビルド用のハイスペックマシン実機を手元に置いておく必要はなくなるかもしれません。コーディング環境はコード補完が不自由ない程度のスペックのPCを使い、ビルドしたいときだけGCBにソースコードを送りつけてビルドしてもらう。そんな未来が来るかもしれないですね。...2018-09-18reviewdogによるGoのコードレビューこんにちは。開催はじめまして、SWETの金子(theoden9014)です。(1)リンクプライバシーポリシースターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。