Cloud Build Webhook トリガーを始めよう(応用編)

Rnrn
google-cloud-jp
Published in
8 min readAug 1, 2021

こんにちは、Cloud Support の Rnrn です。この記事は「Cloud Build Webhook トリガーを始めよう」の応用編です。Webhook トリガーで特定の条件に合った時のみジョブを走らせるフィルタやリクエスト時に決まる変数の受け渡しをするパターンを扱います。基本編はこちらから。

変数の受け渡し

Cloud Build ではビルド時に置換できる変数 substitution を定義・利用することができます。$PROJECT_ID や $TRIGGER_NAME など一部の変数はデフォルトで準備され、ビルド構成ファイル内ですぐに利用することができます。デフォルトで準備される substitutions については公式ドキュメントが詳しいです。

今回はデフォルトの変数とは異なり、ユーザーが好きなように定義して使うことができるユーザー定義の置換を試していきます。基本編と同じ手順でコンソールで設定をすすめて、詳細設定で変数を指定します。変数名には _ で始める必要があるなどいくつか制約が存在するので、命名にあたっては公式ガイドを確認することをおすすめします。

値には静的な値も動的な値も設定することができますが、Webhook トリガーの場合は substitution をリクエストのペイロードでやりとりするため、ペイロードバインディングを使う必要があります。例えば画像のように変数 _SUB_ONE に 値 $(body.message.one) を指定すると、ビルド起動時に Webhook URL に投げたリクエストの Body の JSON の message プロパティ以下の one の値が _SUB_ONE に代入されます。

curl -X POST -d '{"message":{"one":"prod","two":"two"}}' "https://cloudbuild.googleapis.com/v1/projects/<PROJECT_ID>/triggers/<TRIGGER_NAME>:webhook?key=<API_KEY>&secret=<SECRET_VALUE>"

この例でいうと、_SUB_ONE = “prod” で _SUB_TWO = “two” になります。

次に、変数をビルド構成ファイルに追加します。substitutions という階層に使いたい変数とそのデフォルト値を指定するだけで準備完了です。指定した変数は ${} で囲うことで利用できます (その他詳細は公式ドキュメントに記載あり) 。今回は変数の中身を確認したいので、シンプルに変数の中身を表示するビルドにします。

steps:
- name: ubuntu
args: ['echo',
'${_SUB_ONE}',]
- name: ubuntu
args: ['echo',
'Hello ${_SUB_TWO}',]
substitutions:
_SUB_ONE: 'dev' # default value
_SUB_TWO: 'Amy' # default value

ただ、ここで設定したデフォルト値は Webhook トリガーの場合は使われることがありません。というのも前述した通り Webhook トリガーではペイロードで substitution の受け渡しを行うためバインディングで指定されたペイロードがない場合にはビルド実行後にペイロードのパース失敗でビルドが失敗するからです。Webhook トリガーで変数を使う際には必ずバインドしたフィールドが存在するように注意しましょう。

ここまで終われば準備は万端です。先程と同じ curl コマンドを投げると、それぞれ prod と two がペイロードから代入されていることがビルドログからわかります。

イベントのフィルタリング

Cloud Build では、Webhook トリガーに関わらず Common Expression Language (以降 CEL) を使用したビルドイベントのフィルタリングに対応しています。フィルタ機能をつかうことで、例えば Webhook トリガーであればリクエストのペイロードに基づいてビルドの起動有無を制御することができます。

リクエストのペイロードをフィルタ条件に使うには、まず使いたいフィールドを変数にとる必要があります。今回の例では記事の前半で作成した_SUB_ONE をフィルタ条件として使用します。

コンソールから登録する場合はトリガー詳細 >フィルタ > フィルタを追加で表示されるパネルのプルダウンに自動で登録済の変数が表示されるので少し便利です🙂

今回は _SUB_ONE が prod という文字列だった時のみビルドを実行したいので以下のように「_SUB_ONE が prod に 一致する」フィルタを指定します。

ちなみに、同等の内容をコマンドラインで指定する場合はトリガー作成時に以下のような形で指定します。

gcloud alpha builds triggers create webhook \
--name=substitution-test2 \
--secret=projects/<PROJECT_NUMBER>/secrets/<NAME>/versions/<VERSION> \
--substitutions=_SUB_ONE='$(body.message.one)',_SUB_TWO='$(body.message.two)' \
--filter='_SUB_ONE == "prod"' \
--inline-config=build.yaml \

公式ドキュメントにも記載がありますが、2021 年 7 月現在このようにコマンドラインで filter を指定するとトリガーの作成は成功しているにも関わらず INVALID_ARGUMENT エラーが出る問題があります。アルファ段階であることもあり修正や仕様変更で状況が変わる可能性があるのでご利用の際は上記ドキュメントで最新情報の確認をお願いします🙇‍♀

無事にフィルタの設定ができたら実際にフィルタを試してみます。以下のリクエストだと body.message.one = _SUB_ONE = “dev” != “prod” でありフィルタに合致しないためビルドは実行されません。

curl -X POST -d '{"message":{"one":"dev","two":"two"}}' "https://cloudbuild.googleapis.com/v1/projects/<PROJECT_ID>/triggers/<TRIGGER_NAME>:webhook?key=<API_KEY>&secret=<SECRET_VALUE>"

一方で、以下の場合は body.message.one = _SUB_ONE = “prod” なのでビルドが実行されます。

curl -X POST -d '{"message":{"one":"prod","two":"two"}}' "https://cloudbuild.googleapis.com/v1/projects/<PROJECT_ID>/triggers/<TRIGGER_NAME>:webhook?key=<API_KEY>&secret=<SECRET_VALUE>"

ちなみにフィルタに合致せずビルドが実行されなかった場合はコンソールの履歴やロギングには何も記録が残りません。例えばフィルタに合致する ->しない ->するの順番でリクエストを投げた時のビルド履歴はこのようになります。

以上で応用編は終了です、おつかれさまでした!substitution やフィルタも活用しながら快適な Webhook トリガーライフをお過ごしください🌱

--

--

Rnrn
google-cloud-jp

Technical Solutions Engineer for Cloud Support