123. パイプラインはステージを流れる工場のラインである — アーティファクトの受け渡しとbuildspecの4フェーズ
CodePipelineの「1つの変更がIDを持ってステージを順に流れ、ステージ同士はS3経由でファイルを渡す」という背骨を1枚の図で追い、後半はその中で実際にビルドを走らせるbuildspecの4フェーズを図で追っていきます。
① パイプラインの語彙は3階層 — パイプライン > ステージ > アクション
- 公式定義 — stageは「環境を分離し、その環境での同時変更数を制限する論理単位(a logical unit you can use to isolate an environment and to limit the number of concurrent changes)」。
- アクションは直列(series)にも並列(parallel)にも構成でき、順序はrunOrderで決まる。横並びのアクション=並列実行。
- 有効なアクションタイプはsource, build, test, deploy, approval, invokeの6つ。
パイプラインは「リリースプロセス全体」で、ステージが「環境の分離単位」、アクションが「実際の作業」。この3階層と6つのアクションタイプが、CI/CDを語るときの最小の語彙になる。
② 動くものは「実行(execution)」— 1つの変更がIDを持ってラインを流れる
- 公式定義 — executionは「パイプラインがリリースする変更の集合(a set of changes released by a pipeline)」で「各実行は一意でそれ自身のIDを持つ(unique and has its own ID)」。
- パイプライン全体は複数実行を同時処理できるが、「1つのステージは同時に1実行しか処理しない(a pipeline stage processes only one execution at a time)」。処理中のステージはロックされ、2つの実行が同じステージを同時に占有できない。待っている実行をinbound executionと呼ぶ。
- ステージが失敗すると実行は停止しロックは解除され、より新しい実行が空いたステージに入れる。失敗した実行はretryできるが、superseded済みまたはretry不能の場合を除く(You can retry a failed execution unless the failed execution has been superseded or is not retryable)。
「1変更 = ID付きの実行」が工場のラインを流れるワークピース。ステージのロックは「同じ工程を2つのワークピースが同時に占有しない」という排他制御そのもの。これはメッセージング編の可視性タイムアウト(処理中のメッセージを一時的に他から隠す)と同じ、「作業中の対象を独占する」ロックの発想だ。
③ 既定はSUPERSEDEDモード — 常に最新だけを届ける
- 公式言い回し — 「SUPERSEDED is the default execution mode」。ロック中ステージに入るのを待つ実行に、より新しい実行が追いつくと古い方はSUPERSEDEDステータスで停止し「置き換えられた後はもうretryできない(You can no longer retry the superseded execution)」。
- 追いつく(supersede)ポイントはステージとステージの間。他のモードとしてPARALLEL / QUEUEDがある。
- トランジションは「実行が次ステージへ移る点」で、無効化すると実行はそこで待ち、「複数の実行が無効トランジションに到達したとき、有効化すると最新の実行だけが次へ進む(only the latest execution continues)」。
SUPERSEDEDは「新しい実行が古い実行を破棄して、常に最新だけを届ける」設計。これは可観測性編で見た「最新の状態だけが真実」という収束の思想のCI/CD版であり、CPUパイプラインで後続命令が先行の結果に依存するとき最新の値へ揃えるハザード処理とも通じる。
④ ステージ同士は直接会話しない — S3のアーティファクトストアを介して渡す
- 公式言い回し — 「Actions pass output to another action for further processing using the pipeline artifact bucket. CodePipeline copies artifacts to the artifact store, where the action picks them up.」
- アーティファクトはソースコード・ビルド済みアプリ・依存・定義ファイル・テンプレートなどの「データの集合」で、あるアクションの出力(output artifacts)が別アクションの入力(input artifacts)になる。
- 失敗したステージはretryでき(You can retry a failed stage)、「ステージを指定した過去の成功実行へrollbackできる(You can roll back a stage to a specified previous successful execution)」。
これが疎結合の要 — ステージは互いに直接データを渡さず、S3という共有バッファ経由でファイルを受け渡す。これはメッセージング編のキュー(送り手と受け手をバッファで疎結合にする)とまったく同じ設計を、メッセージ粒度でなくファイル粒度でやったものだ。だから失敗は工程単位で切り離してリトライ・ロールバックできる。
⑤ Buildアクションの中身 — buildspecの4フェーズ
- 公式仕様 — 既定では「buildspec.yml」という名前でソースディレクトリのルートに置く。名前・場所は上書き可能だが「1プロジェクトに指定できるbuildspecは1つ(only one buildspec for a build project)」。バージョンは0.2を推奨。
- フェーズはinstall→pre_build→build→post_buildの順で、各commandsは「1つずつ、記載順に最初から最後まで(one at a time, in the order listed)」実行。finallyブロックは「commandsの中のコマンドが失敗しても走る(run even if a command in the commands block fails)」。
- on-failureはABORT(中止)/ CONTINUE(次フェーズへ)/ RETRY(既定で最大3回まで再試行)。回数や対象エラーを指定するRETRY-{count}(0〜100)・RETRY-{regex}などの派生形もある。なおon-failureはEC2コンピュートのイメージ専用で、Lambdaコンピュートやリザーブドキャパシティでは使えない。
buildspecはビルドの手順書。4フェーズは「環境を整える→前準備→本体→後始末」という自然な順序で、finallyは例外処理のtry/finallyそのもの — 途中でコケてもログ出力やクリーンアップを必ず走らせる保険だ。
⑥ buildspecの受け渡し2経路 — ファイル(artifacts)と値(exported-variables)
- 同名変数の優先順位は「start build操作の値が最優先 > プロジェクト定義 > buildspec宣言が最下位」。
- artifactsは「ビルド出力をS3出力バケットへアップロードする対象と準備方法」。
- exported-variablesは「現在のビルドステージから後続ステージへ環境変数をエクスポートする」もので、値はinstallフェーズ開始時から利用可能でpost_build終了後は変更不可。ただしAWS_で始まる変数や、ビルドプロジェクトで指定したParameter Store / Secrets Managerのシークレットはエクスポート不可。
ビルドの成果は2つの経路で次へ渡る — artifactsがファイルをS3経由で、exported-variablesが値を後続ステージへ。そしてappspec / buildspec / テンプレートに共通するのは「やることをファイルに書いてリポジトリに入れる」こと。これはキャッシュ編のバージョン付きファイル名と同じ「変更を不変の単位で扱い、コードと一緒にバージョン管理する」原則の適用だ。