🎉

[AWS] [お試し] CodePipeline が追加のトリガーフィルターと新しい実行モードのサポートを開始

2024/12/31に公開

概要

CodePipelineの今年のアップデートを実際に試してみる記事その1です。
まずはトリガーフィルターと実行モードの追加について。

https://aws.amazon.com/jp/about-aws/whats-new/2024/02/codepipeline-trigger-filters-execution-modes/

これ、結構わかりづらい挙動をするので、実際にプロダクション環境で活用するならば挙動をちゃんと抑えておいたほうが良いかなと思います。

トリガーフィルター

記事から引用すると下記の通り。

パイプライントリガーフィルターを使用すると、
GitHub.com、GitHub Enterprise Server、Bitbucket.com、GitLab.com、
および GitLab セルフマネージドのソースを使用しているお客様は、
パイプラインの実行をトリガーするタイミングを制御できます。

以前までは、CodePipeline側で変更に追従して、自動的にCodePipeline自身をトリガーしようとすると、特定のブランチに対するpush もしくは、特定のtagをつけるしかありませんでした。つまり、たとえば前者の場合、特定のブランチに対するpushが行われると「常に」Codepipelineがトリガーされることになります。

このアップデートでより細かい条件による、CodePipelineのトリガーが実現できます。

こちらがトリガーフィルターの設定になります。

Event Typeはわかりやすいですね。GitHub側での操作の種類に応じたEvent Typeが設定されるのでしょう。一方で、 "Start pipeline under these conditions", "Don't start pipeline under these conditions"は、それぞれ意味はわかりますが、両方の条件が競合するような場合の優先度がUIからは不明瞭ですね。こちらは後で試してみましょう。※後でわかりますが、これUIと実際の評価順序がずれてて結構複雑なことになってます。(ネタバレ:AWS公式ドキュメント、2024年12月時点では日本語に詳細情報はありませんので英語でご確認ください)

新しい実行モード

こちらも記事から引用。

Parallel 実行モードでは、同じパイプラインの他の実行に影響を与えずに、
パイプラインの各実行を並行して実行できます。
Queued 実行モードでは、パイプラインの各実行が開始された順序で
パイプライン内を進行し、最近の実行ではオーバーライドされません。

つまりは既存に加えて2つの実行モード、PARALLEL, QUEUEDが追加されています。各モードの詳細については下記に記載があります。

https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/concepts-how-it-works.html

  • SUPERSEDED モード: より最近の実行は、古い実行を追い越す可能性があります。これがデフォルトです。
  • QUEUED モード: 実行は、キューに入れられた順序で 1 つずつ処理されます。これにはパイプラインタイプ V2 が必要です。
  • PARALLEL モード: PARALLELモードでは、実行は互いに独立して同時に実行されます。実行は、開始または終了する前に他の実行が完了するまで待機しません。これにはパイプラインタイプ V2 が必要です。

さて、私はこの説明を見ても、各モードの挙動について誤解しておりました。その点について列挙しておきます。

  • SUPERSEDED モード:
    • 誤: PARALLELと同一の挙動をする(違うモードとして存在する以上そんなはずはないんですが。。。)
    • 正: 英語の意味の通り、「取って代わる」、つまり追い越す際に前のジョブを上書きする。
  • QUEUED モード:
    • 誤: 後発のパイプラインは、先発のパイプライン全体の実行完了を待つ
    • 正: 後発のパイプラインは、先発のパイプラインが実行中のステージに追いついたところで待つ

[やってみる] トリガーフィルター

いくつかのパターンを試してみます。

まず、下記の設定で、mainブランチで、README.txtを更新してPushしてみますと、Codepipelineはトリガされました。

おなじ設定を用いて、mainブランチで、do-not-start.txtを作成して、PushするとこちらはCodepipelineはトリガされませんでした。このあたりは直感通りですね。書いた条件に合致する通り。

次は下記の例です。Do not start側にブランチ条件として、mainを書いてREADME.mdを更新してPushをしてみますと、今度はCodepipelineはトリガされませんでした。どうやら、Do not start側が優先されるようです。

さて、では、次の下記の設定で、mainブランチで、do-start.txtを更新すると何が起きるでしょうか。

これ、Codepipelineはキックされません。UIから(少なくとも私は)、Start側の設定とDon't start側の設定はそれぞれでグループ化されていて、あるPushに対して、StartとDon't startの条件が全てAND評価され、どちらも真である場合には、Don't startを優先する=開始しないという挙動かと思っていました。つまり上記の例では、Startは真で、Don't startが偽なので、開始して欲しいところですが、そういう挙動にはなってませんね。

種明かし、というか仕様はドキュメントに記載がありました。

https://docs.aws.amazon.com/codepipeline/latest/userguide/pipeline-requirements.html#pipeline.triggers

branchはbranchのみで Start or Don't startが評価され、filepathもfilepathのみで評価、その後、それぞれの結果をAND評価 (開始する=真、開始しない=偽)をすることになっているようです。つまり、今回の設定の場合、mainブランチに対する変更という時点で、branch評価が偽、つまり開始しないことになっているので、filepathの評価がどうなろうが、開始しないことが決定してしまっています。

そのため、こちらの評価順序や評価方法には注意しておかないと、開始するはずだったパイプラインが開始されないということになりそうです。

[やってみる] 新しい実行モード

さて、新しい実行モードも同様に試して行きます。それぞれの挙動を確認するため、Buildフェーズに60秒のスリープを入れたPipelineを作成し、モードをSUPERSEDED, QUEUED, PARALLELのそれぞれに変更しつつ、aws codepipeline start-pipeline-executionを3回連続で実行していきます。

QUEUED

下記がQUEUEDで実行したものです。スタートは同じ時刻ですが、完了までが違いますね。私はこれが、スタート自体が違う時刻になる(前の実行をまってからパイプラインを実行)だと思っていたのですが、どうやら、そうではなく、同一ステージになった場合に待ち状態になる、つまり、Buildフェーズでのスリープをやっているパイプラインがいる場合に後続はBuildフェーズまでは来て、そこで待ち状態になります。

SUPERSEDED

下記がSUPERSEDEDで実行したものです。2番目の実行がSUPERSEDED(取って代わる)されています。1番目の実行がSleepで待っている間、2番目が待機状態に入りますが、そこで3番目が来ることで、2番目が3番目に取ってかわられ、最終的に3番目は正常終了しています。

PARALLEL

下記がPARALLELで実行したものです。これは分かりやすく、全て同時に開始し、止まることなく並列に実行され同じ時間帯で終了しています。

終わりに

トリガーフィルターと実行モードの追加について調べてみました。ちゃんとみてみると案外複雑で、便利になってはいるのですが、ちゃんと理解して使わないと思わぬ落とし穴にハマりそうですね。気をつけたいです。

Discussion