7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

2024/02/09のアップデートで、CodePipelineで、追加のパイプライントリガーフィルターに対応しました。
CodePipeline が追加のトリガーフィルターと新しい実行モードのサポートを開始

本機能を利用することで、特定ブランチやリポジトリ内の特定ファイルなど、指定したイベントをトリガーとしてCodePipelineを起動できるようになりました。
ですが、CDK Pipelinesで作ったパイプラインにV2を利用しようとすると、工夫が必要になります。
そこで今回はCDK Pipelines+CodePipeline V2を実現させ、その上で新機能を試してみたいと思います。

条件

  • CodePipeline V2であること
  • 以下のソースであること
    • GitHub.com
    • GitHub Enterprise Server
    • Bitbucket.com
    • GitLab.com
    • GitLab セルフマネージド

記載のように、AWS CodeCommitでは本機能が利用できません。
現状、CodeCommit環境では簡単には実装できず、AWS公式ドキュメントにLambdaを使ったアーキテクチャが公開されておりました。

Automatically detect changes and initiate different CodePipeline pipelines for a monorepo in CodeCommit

今回はGitHubを利用して実装します。

バージョン情報

aws-cdk: 2.143.0 で検証。

実装イメージ

cdkpipelines_image.png

CodeStarConnectionの準備

CodePipelineの設定>接続より、事前にGitHubとの接続を作成しておく必要があります。

codestar.png

CodePipeline V2対応

CDK PipelinesのデフォルトPropsで自動作成されるパイプラインではV2に対応しておらず、V1が作られてしまいます。
ですが、CDK PipelinesのL3 Construct CodePipelineには、
codePipelineプロパティがあり、別途定義したCodePipelineを利用できます。

そのため、aws-codepipelineのL2 Construct PipelineをV2で作成し、そのパイプラインをCDK Pipelines用のパイプラインとして利用することで間接的にV2を利用できます。

サンプルコード

import * as codepipeline from "aws-cdk-lib/aws-codepipeline";
import {
  CodeBuildStep,
  CodePipeline,
  CodePipelineSource,
} from "aws-cdk-lib/pipelines";

export class PipelineStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props: PipelineProps) {
    super(scope, id, props);

// <中略>

  // GitHub Connection
  const source = CodePipelineSource.connection(
      "github_user_name/repository_name", // GitHubのリポジトリ名を設定
      "main",                             // ブランチ名を設定
      {
      connectionArn:
          "arn:aws:codestar-connections:ap-northeast-1:XXXXXXXXXXXX:connection/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", // CodeStarConnectionのARNを設定
      }
  );

  // aws-cdk-lib/aws-codepipeline のPipelineをV2で作成
  const codePipeline = new codepipeline.Pipeline(this, "CDKPipelineV2", {
      pipelineName: "CDKPipelineV2",
      pipelineType: codepipeline.PipelineType.V2,
      role: pipelineRole,
      crossAccountKeys: true,
      restartExecutionOnUpdate: false,
  });

  // aws-cdk-lib/pipelines" のPipelineを作成し、上で作成したcodePipelineを設定。
  const cdkPipeline = new CodePipeline(
      this,
      "Docs"
      {
      codePipeline: codePipeline,
      synth: new CodeBuildStep("BuildStep", {
          input: source,
          installCommands: getInstallCommands(),
          commands: ['npm ci','npm run build','mkdocs build','npx cdk synth'],    // ビルドコマンドを記入
      }),
      selfMutation: true,
      dockerEnabledForSynth: true,
      }
  )};
};

Deployステージの補足

今回の主題でないためカットしていますが、本来はパイプライン上にデプロイステージ等が必要です。
デプロイステージでは以下のような要素を含んだStackを投入しています。

  • WAF
  • CloudFront Distribution
  • 公開用のS3
  • s3deploy.BucketDeploymentによるアセットのS3デプロイ

GitHub Connection

aws-cdk-lib/pipelinesのCodePipelineSource.connectionを利用して、コネクションを設定します。

aws-cdk-lib/aws-codepipeline のPipelineをV2で作成

aws-cdk-lib/aws-codepipelineで新しいCodePipelineを作成します。
事前に作成することで、pipelineTypeをV2に設定できます。
※サンプルコードでは中略していますが、pipelineRoleは必要なIAM Roleを定義しています。

aws-cdk-lib/pipelines" のPipelineを作成し、上で作成したcodePipelineを設定

aws-cdk-lib/pipelinesでCDK Pipelinesを作成します。
codePipelineパラメータに、上で作ったV2パイプラインを指定することでV2対応できます。
synth:CodeBuildStepのinputには、GitHub Connectionで作成したconnectionを設定します。

トリガーの設定

2024/05/27時点、TriggerクラスでPush時にフィルタリングする設定が実装されておりませんでした。
Trigger
なので今回はaddPropertyOverrideを利用し、L2 Constructで提供されていない部分を直接編集します。

コンストラクトライブラリからの AWS コンストラクトのカスタマイズ

    
    // 上記サンプルコードの続き
    
    // パイプラインを構築(providerTypeで呼ぶため)
    cdkPipeline.buildPipeline();

    // SourceStageを取得
    const sourceStage = cdkPipeline.pipeline.stages.find(
      (stage) => stage.stageName === "Source"
    );

    const sourceAction = sourceStage!
      .actions[0] as codepipeline_actions.CodeStarConnectionsSourceAction;
    const sourceActionName = sourceAction.actionProperties.actionName;

    // トリガーを追加
    codePipeline.addTrigger({
      providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION,

      // the properties below are optional
      gitConfiguration: {
        sourceAction: sourceAction,

        // pushFilterのBranchとFilepathはまだCDK未対応。tagsを仮設定(addPropertyOverrideで上書きする)
        pushFilter: [
          {
            tagsIncludes: ["tagsIncludes"], // 置換されるので適当な文字列を設定
          },
        ],
      },
    });

    // addPropertyOverrideでトリガー条件を上書きする
    const pushFilterJson = {
      Branches: {
        Includes: ["対象にしたいブランチ名"],
      },
      FilePaths: {
        Includes: ["対象にしたいフォルダパス"],
      },
    };

    // cfnPipelineを取得して、addPropertyOverrideを実施
    const cfnPipeline = cdkPipeline.pipeline.node
      .defaultChild as codepipeline.CfnPipeline;
    cfnPipeline.addPropertyOverride("Triggers", [
      {
        GitConfiguration: {
          Push: [pushFilterJson],
          SourceActionName: sourceActionName,
        },
        ProviderType: "CodeStarSourceConnection",
      },
    ]);

パイプラインを構築(providerTypeで呼ぶため)

cdkPipeline.buildPipeline()を挿入することで、パイプラインがビルドされます。
これを入れることで、後続のsourceStage.actions[0] as codepipeline_actions.CodeStarConnectionsSourceAction;部分が取得可能になります。

トリガーを追加

codePipeline.addTriggerでトリガーを作成します。
gitConfiguration.pushFilterは先述の通りブランチやファイルパスを設定する項目が現時点で存在しないため、tagsIncludesのみ設定し、適当な値を設定しておきます。(何も設定しないとエラーとなりました。)

トリガー条件の設定

pushFilterJsonという変数にフィルター条件を設定します。
必要なブランチ名、フォルダパスを設定します。

addPropertyOverrideを実施

cdkPipeline.pipeline.node.defaultChild as codepipeline.CfnPipelineを使ってcfnPipelineを取得し、
cfnPipeline.addPropertyOverrideを利用してTriggersのプロパティを上書きます。

デプロイ

上記設定でCDK Pipelinesをcdk deployします。

V2のパイプラインが構築されました!
codepipeline_v2.png

トリガー上でブランチ・ファイルパスが導入されています。
codepipeline_trigger.png

addPropertyOverrideで上書きしたことで、タグの条件は削除されています。

特定フォルダの更新テスト

my-projectフォルダを修正します。
今回のフォルダ配下にはMkDocsで作成したMarkdownファイルが格納されています。

「サイト更新テスト」という文章を追加し、GitHubのリモートリポジトリにPushします。
my-project_update.png

パイプラインが起動しました!
my-project-trigger-execution.png

パイプラインが正常終了しました。サイトを見てみましょう。
my-project-trigger-execution2.png

サイトが無事更新されました。(今回はMkdocsの初期レイアウトを配置しています。)
mkdocs_site.png

終わりに

現時点の環境で実現可能な、CDK PipelinesとCodePipeline V2の融合、およびGitHubの特定ブランチや特定ファイルパスの更新をトリガーにする方法を解説しました。
CodePipeline V2では、今回は紹介しませんでしたがQUEUEやParallel等の実行方法も可能になり、より柔軟な設定でパイプラインを実行できます。CDK Pipelinesでもぜひ導入したいところですね。
料金面でもV1はパイプライン1本あたり$1/月が固定でかかる料金体系でしたが、V2では実行時間に対する従量課金制になり、0.002USD/実行時間(分)の料金体系となりました。短時間の実行しかされないような複数のパイプラインを持つ場合でも大幅にコストを抑えられる形となりました。
V2はまだあまり活用できておりませんでしたが、多くの利点があるので今後はV2を軸にパイプライン活用を検討していこうと思います。

参考資料

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?