Open5

CDK (v2) pipelines の思想をリファレンスから紐解く & "self-mutation" とどう付き合うか考えてみる試み

hassaku63hassaku63

pipelines を構成するデプロイの単位について。

Pipeline があるのはまあ自明なので省略する。

Stage, Wave の2つの概念が主要っぽい。

Stage は cdk.Stage のサブクラスで表現する。一緒にデプロイしたい Stack の集合が Stage になる。CodePipeline にも "Stage" という用語があるが、それとは別概念。

CDK 側の "Stage" はコアモジュールから取っているクラスなので、そこが疑問...というか、非直感的と感じるポイント

// https://docs.aws.amazon.com/cdk/v2/guide/cdk_pipeline.html#cdk_pipeline_stages
import * as cdk from 'aws-cdk-lib';
import { Construct } from "constructs";
import { MyLambdaStack } from './my-pipeline-lambda-stack';

export class MyPipelineAppStage extends cdk.Stage {

    constructor(scope: Construct, id: string, props?: cdk.StageProps) {
      super(scope, id, props);

      const lambdaStack = new MyLambdaStack(this, 'LambdaStack');
    }
}

Stack 間に依存関係がないなら、Stage サブクラス内で定義された複数個の Stack は並列デプロイされる。

Wave は 1つの Stage で並列デプロイできる概念らしい。同じスタックをマルチリージョンで展開する事例が紹介されている。

// https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines.Wave.html
const wave = pipeline.addWave('wave');
wave.addStage(new MyApplicationStage(this, 'MyAppEU', {
  env: { account: '111111111111', region: 'eu-west-1' }
}));
wave.addStage(new MyApplicationStage(this, 'MyAppUS', {
  env: { account: '111111111111', region: 'us-west-1' }
}));
hassaku63hassaku63

どうやら CDK pipelines は、プロダクトコード (IaC) とその CI/CD を同一レポジトリで管理する形態をデフォルト扱いしており、設計にもその思想が出ているように見える。

まあ、実際これは自然だと思う。
Web アプリケーション + GHA による CI/CD で話を置き換えるとなにも違和感はない。むしろ、分離した方が相互影響する変更点のレビューが(PR が分離することで)難しくなってしまうのでスタンダードの感すらある

一方で、今私がやりたいことに照らすとそれだと困る用事もある。

私が今考えているのは、複数レポジトリに分断したプロダクトコード (IaC) を同一アカウントにデプロイしようとするもの。そのデプロイのタイミング(ライフサイクル)もかなり似ている。本当はこれらの分断は統合した方が綺麗では?と考えた。

各プロダクトコードの CI/CD 実装を作ることを契機として、CI/CD だけを切り出して単独レポジトリに作ってしまってはどうか?と構想している。そうなると Pipelines のデフォルトの思想とは喧嘩することになってしまう。さてどうしましょうか?というのが今整理したい事項。


それはそれとして、pipelines の一番簡単なサンプルの self-mutation ありパターンの Cfn 実装は少々気持ち悪さがあった

同一パイプラインの中で、プロダクトコードのデプロイと自分自身 (Pipeline) のデプロイを一緒にやろうとしている。synth した Cfn を見ると、
source → build (my code) → build (pipeline)
という構成をしていた。

hassaku63hassaku63

私が考えている話とはちょっと主旨が違うけど、ソースとなるレポジトリを複数定義したいという issue は上がっている模様。

https://github.com/aws/aws-cdk/issues/14493

(複数レポジトリをまとめて一緒のパイプラインでデプロイしたい、と言っているので自分の話とはちょっとズレてる)

hassaku63hassaku63

上記に関連するPRとして以下がある

https://github.com/aws/aws-cdk/issues/10872

ここに書いてある文章や、リンク先の 安全なハンズオフデプロイメントの自動化 は自分の文脈とは関係なく参考になりそうなので読む価値がありそう。

PR に「シンプルさを手にするために多くのカスタマイズ性を捨てる」という感じの思想が書かれいて、pipelines は基本これだと思って良さそうな気がする

This means we explicitly give up a bunch of freedom that CodePipeline allows, in order to make a simpler application deployment model. We'll reject adding multiple source stages, multiple builds, and many types of actions in weird locations people might want to insert into the pipeline; if they want to do that, they should drop down to building a complete CodePipeline pipeline.