🚢

CodePipeline V2のQUEUEモードをCDKで作って検証してみた

2024/03/12に公開

概要

CodePipeline V2が発表されて以降、色々な機能が追加されていっていますが、特にQUEUEモードというものが気になり、検証してみた、という記事になります。

検証してみようと思った日の夜にCDKでQUEUEモード(ExecutionMode)がリリースされてとても嬉しかったです。

CodePipeline V2とは

  • 2023/10:CodePipeline V2が発表
    • この時点では主に以下の点がアナウンス
      • 入力パラメータをパイプライン実行に動的に渡すことができる
      • V1とV2では料金体系が異なる
  • 2024/02:トリガーフィルターと新しいパイプライン実行モードをサポートすることを発表
    • トリガーフィルター
      • 特定のディレクトに更新があった場合に実行する等の機能
    • 新しいパイプライン実行モード
      • Parallel
      • Queued
  • CDKでも光の速さで対応される
    • AWS CDK v2.128.0(2024/02/16): V2対応、アクション内でパイプライン変数へアクセス可能
    • AWS CDK v2.132.0(2024/03/11): executionMode対応
    • AWS Hero @365_step_tech さんに感謝

Git Pull Requestトリガーの機能などについてもレビュー待ちの状態(2024/03/12)のようで、近日マージ・リリースされそうです。
https://x.com/365_step_tech/status/1757582258255650869?s=20
https://x.com/365_step_tech/status/1767226197770170681?s=20

ExecutionModeについて

本記事で検証する対象のExecutionModeについて少し詳しく触れたいと思います。

元々CodePipeline V1でサポートしていた実行モードはSUPERSEDEDモードというらしいです。自分はSUPERSEDEDであるということを知らなかったのですが、V2が出て以降、UI上でも実行モードが表示されるようになり、元々存在していたPipelineはSUPERSEDEDモードとなっていて、モードを指定せずにV2で作成するとSUPERSEDEDモードになります。

新しく発表されたPARALLELモード、QUEUEモードと合わせてみると以下のようなモードがサポートされていることになります。

  • SUPERSEDED
    • より新しい実行が古い実行よりも優先される可能性があります。これはデフォルトです。
  • QUEUE
    • パイプラインタイプ V2 が必須
    • キューに入れられた順序で1つずつ実行が処理される
  • PARALLEL
    • パイプラインタイプ V2 が必須
    • 他の実行の完了を待たずに、実行が開始または終了する

ちょうどCodePipeline V1を使っていて、でマージトリガーで動作させる際に複数のマージを同時多発的にすると挙動が不安定になるという課題を持っていたのでQUEUEモードがどんな感じなのか気になっていました。

詳細は以下のドキュメントを参照ください。

https://www.sunnycloud.jp/column/20240211-02/

https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/execution-modes.html

CodePipeline V2の料金体系

CodePipeline V1とV2では料金体系が異なります。
詳細は以下のドキュメント等でご確認ください。

https://aws.amazon.com/jp/codepipeline/pricing/
https://dev.classmethod.jp/articles/codepipeline-pipelinetype/

CDKで実装してみた

動作確認目的なのでマネジメントコンソールで構築しても良かったのですが、後々CDKで実装することになる可能性も高いのでCDKでどんな感じに実装できるかを調べる目的も兼ねてCDKで実装しました。

Pipelineを作って消してということもしやすいので一時的な検証目的でもCDK等のIaCで実装するのは個人的にはアリだと思います。

※CDK Pipelineというpipelinesモジュールで実装する方法でなく、aws_codepipelineを使ったCodePipelineを実装する方法の紹介になります。

Pipelineの実装

Sourceステージ用のアクション:

    const sourceArtifact = new codePipeline.Artifact();
    const sourceAction = new codePipelineActions.CodeStarConnectionsSourceAction({
      actionName: 'source',
      owner: 'owner',
      repo: 'repo',
      branch: 'main',
      connectionArn: 'arn:aws:codestar-connections:ap-northeast-1:111111111111:connection/xxxxxxxx-9999-1111-xxxx-999999999',
      output: sourceArtifact,
      triggerOnPush: true,
    });

実験用のビルドステージ:

    const codeBuildDeployProject = new codeBuild.PipelineProject(
      this,
      'CodeBuildDeployProject',
      {
        projectName: `sample-deploy-project`,
        buildSpec: codeBuild.BuildSpec.fromSourceFilename('./buildspec.yml'),
      }
    );

Pipeline本体:

    const pipeline = new codePipeline.Pipeline(this, 'CodePipelineV2Test', {
      pipelineName: 'CodePipelineV2Test',
      pipelineType: codePipeline.PipelineType.V2,
      executionMode: codePipeline.ExecutionMode.QUEUED,
      restartExecutionOnUpdate: true,
      stages: [
        {
          stageName: 'Source',
          actions: [sourceAction],
        },
        {
          stageName: 'Build',
          actions: [
            new codePipelineActions.CodeBuildAction({
              actionName: 'Build',
              project: codeBuildDeployProject,
              input: sourceArtifact,
            }),
          ],
        },
      ],
    });

buildspec.yml(キューの挙動を見るために5分sleepするようにしています)

version: 0.2

phases:
  install:
    commands:
      - echo "install ok"
  build:
    commands:
      - echo "sleep 300s to keep the build running for 5 minutes"
      - sleep 300
      - echo "build ok"

途中、Policyが足りていなくて怒られる

Additional Information: Unable to use Connection: arn:aws:codestar-connections(略). The provided role does not have sufficient permissions.

実行すると、こちらの記事にあるようなエラーが起きました。
CodePipelineのロールにポリシーが足りていなかったようです。ポリシーを追加していきます。
https://chulip.org/entry/2022/12/08/184112

    pipeline.addToRolePolicy(
      new PolicyStatement({
        actions: ['codestar-connections:UseConnection'],
        resources: ['*'],
      })
    );

cdk.aws_codepipeline.PipelinePropsに、roleというプロパティがありロールを作成して指定することもできるのですが、今回は特定のポリシーを追加したいだけだったので上記のようにpipeline.addToRolePolicy()の形でポリシーを追加しています。

QUEUEモードの検証

Pipelineの準備

上記CDKで実装したPipelineをデプロイします。

SourceステージとBuildステージの2つのステージから構成されるPipelineができ、正常に終了することを確認しました。

PR1つ目をマージする:Pipelineの起動

作成しておいた1つ目のPRをマージしてPipelineを起動します。
起動間も無くして、Buildステージに移行してCodeBuildが実行します(sleep 300s)

新たにPRを4つマージする:QUEUEに追加される

新たに4つのPRをマージするとSourceステージとBuildステージの間に、キューに入れられた実行(4) というトグル付きのUIが出てきました。
また、SUPERSEDEDの時のように1つ目のビルドが実行中に2つ目以降のビルドが実行されることなく、1つ目のビルドが実行中のままになりました。

トグルを開くと、このような画面になります。
キューに溜まっている実行が確認できるのと、「実行の停止」というボタンがあります。

キューに溜まっているPR2~PR4を停止・削除する

キューに溜まっている全ての実行が実行/完了されるのを待つのは時間がかかるので、間のPR(2番目から4番目)を停止しようと思います。
実際にも大量のPRがマージされると全ての実行をデプロイして動作確認したいわけではなく最終的にマージされた状態のものを確認したいのでそれだけがデプロイされればいいというシーンはあるかと思います。

「実行を停止」を押すと以下のようなモーダルが現れ、「停止」を実行しました。

※「停止して待機」を選択すると、"実行中のものが終わった後に実行される"のではないかと思ったのですが、実際には実行が動くことはなくキューからも見えなくなったので、待機と中止の差はよくわからなかったです。

停止後、最後にマージしたPRの実行のみが残り、実行されることを確認

3つの実行を停止することができQUEUEの最後にあった実行が1つ目の実行が終わった後に実行させることができました。

まとめ

今回、以下のことを確認(検証)できました。

  • CDKでCodePipelineをQUEUEモードで作成できること
  • QUEUEモードの挙動確認
    • 1つの実行が動いているときに別の実行が開始されない(QUEUEに入る)
    • QUEUEに入ったもの任意の実行をGUIから停止・削除することができる

一方で確認できていないこと、できないこと、不明点としては、

  • Git Pull Requestトリガーの機能などはまだリリースされていない(coming soon)
  • QUEUEが自動的にSourceとBuildステージの間に入ったが任意の箇所にQUEUEを入れられるかどうか不明
  • 実行を停止する際に「停止して待機」を選んだ時の詳細の挙動

などがあるかなと思います。

CodePipeline V2が発表されてからまだ半年も経過していないのと、日々機能が追加されていっている印象なので、引き続きウォッチしていきたいと思います!

以上、CodePipeline V2について気になる方の役に立てば幸いです。

Discussion