【AWS CDK】CDK Pipelinesのself-mutateについて理解する

### はじめに  
- この記事は、この記事は [AWS CDK Advent Calendar 2024](https://qiita.com/advent-calendar/2024/aws-cdk) 22日目の記事になります。  
- またこの記事は、私の個人ブログに2024/12/29(日)に投稿した以下の記事と同一の内容になります。  

https://makky12.hatenablog.com/entry/2024/12/29/103135   
  
### 前提：CDK Pipelinesって？  
CDK Pipelinesとは、AWS CodePipeline（以下「CodePipeline」）を利用したデプロイパイプラインをCodeBuildやCodeDeployなどを個別に定義することなく作成できる、AWS CDKのライブラリになります。[^1]  
  
[^1]:なおCDK Pipelinesはaws-cdk-lib/pipelinesモジュールに属しています。ちなみにCodePipelineはaws-cdk-lib/aws-codepipelineモジュールに属していますが、これとは別物です  
  
CDK的にはL3コンストラクタとなっており、より少ない定義でデプロイパイプラインを構築できるので、下記のようなケースに向いています。  
  
- CodePipelineについて詳しく知らないけど、とりあえずデプロイパイプラインを構築したい  
- あまり細かい制御はいらないから、細かい管理はしたくない  
  
なお「CDK Pipelinesの概要を理解したい！」という方は、私が「JAWS-UG CDK支部 #16 ~CDK Conference 2024 Extra~」で発表した資料がありますので、よろしければそちらを参照ください。[^2]  
  
[^2]:本当はCDK Pipelinesについて詳しく書こうとしたのですが、今年はオフラインイベントで結構CDK Pipelinesの事を話しているので、今回はself-mutateにのみフォーカスを当てました  

https://speakerdeck.com/smt7174/cdk-pipelineswozatukurili-jie-suru

### self-mutateって？  
self-mutateとはCDK Pipelinesの機能の1つで、「デプロイが実施された際にCodePipelineの定義を再構成する（≒CodePipelineの部分だけを先にデプロイする）」という仕組みです。  
  
が、この仕組みが結構分かりにくいので、その仕組みを説明します。（これがCDK Pipelinesが敬遠される理由の一つになってます...）  
  
### self-mutateの背景  
CodePipelineでデプロイを行った場合、CodePipelineの定義は「デプロイを行った時点の定義」が適用されます。  
ちょっと分かりにくいのですが、最新のデプロイでの変更内容に「CodePipeline自体の変更」が含まれていたとしても、最新のデプロイの実行にその変更は適用されません。（あくまでも「デプロイを行った時点の定義」でデプロイが行われる）  
  
これの何が不便かというと、最新デプロイにCodePipeline以外のリソース（Lambdaとか）の変更も含まれており、デプロイ時に「変更したCodePipeline定義を適用したい（=最新のCodePipeline定義でデプロイしたい）」という場合、  
  
- 最初にCodePipelineとLambdaをデプロイする  
  - このデプロイでは「変更したCodePipeline定義」は適用されない
- 次にLambdaのみデプロイする
  - このデプロイで「変更したCodePipeline定義」が適用される
  
という2ステップを踏まねばならず、2度手間になってしまいます。  
  
### self-mutateの仕組みとメリット  
上記の問題を解決するための仕組みがself-mutateです。
self-mutateでは上記の問題を「CodePipeline定義だけを先にデプロイする」ことで解決しています。  
  
つまり、最新デプロイにCodePipeline以外のリソースの変更が含まれていても、下記の挙動を取ることで、常に最新のCodePipeline定義でデプロイが実行されるようになっています。  
これがself-mutateのメリットです。  
  
1. まずCodePipelineの変更だけを先にデプロイする  
2. 1が完了後、CodePipeline以外のリソースをデプロイする
  
簡単に図解すると、下記のような感じです。  
![self-mutate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181341/efdc5065-ff68-68db-346a-e21a5c562d26.png)
  
### self-mutateのデメリット  
ただし、当然self-mutateにもデメリットはあり、具体的には以下の点が挙げられます。  
  
#### デプロイに時間がかかる  
先述の通り、self-mutateでは「CodePipeline」と「それ以外のリソース」でデプロイが分かれるため、内部的には2回デプロイが実行されます。  
その結果、デプロイにより多くの時間がかかってしまいます。  
  
本番環境ならともかく、開発環境だと煩わしく感じてしまうかもしれません。  
  
※なおself-mutateは設定でOFFにすることもできますが、あくまでも開発用途での一時的なものであり、本番環境でOFFにすることは推奨されていません。  
    
#### 分かりにくい  
上記の「2回デプロイが実行される」だったり「CodePipeline以外のリソース用のスタックを別で作成する」など複雑な部分があり、最初はどうしても分かりにくいと思います。（実際、それが理由でCDK Pipelinesを敬遠してしまう、というケースも多いと聞きます）  
  
#### CodePipelinesの変更頻度  
（これはself-mutate自体のデメリットではないですが）実際のところ、CodePipelineの変更が発生するのは開発初期の期間のみで、それが終わればあまり変更は発生しないことが多いです。  
また仮に変更が発生したとしても、CodePipeline以外のリソースのデプロイに影響がなければ別に問題ないので、デプロイ時間や手間などのことを考えると「そこまでして導入するメリットが...」となるかもしれません。  
  
### まとめ  
以上、CDK Pipelinesのself-mutateについての説明でした。  
    
正直CDK Pipelinesやself-mutateは最初は分かりにくい部分が多く敬遠されがちですが、慣れると「より少ない定義でデプロイパイプラインを構築できる」「常に最新のデプロイ定義でデプロイを実行できる」などのメリットもあるので、もしデプロイパイプラインを構築で課題を抱えている場合は、一度導入を検討をしてみるのもよいのではないかと思います。  
  
### 宣伝
ちょっと先の話になりますが、来年2/1(土)に富山で開催される「BuriKaigi 2025」において「Amazon Aurora バージョンアップについて、改めて理解する ～ バージョンアップ手法と文字コードへの影響 ～」というセッションで登壇させて頂くことになりました。
  
https://burikaigi.dev/
  
内容としてはAmazon Aurora のバージョンアップ概要やバージョンアップしないことでの影響、またバージョンアップ時に気を付けることなどをお話しする予定です。  
    
### 宣伝その2  
私事になりますが、12月よりKDDIアジャイル開発センター(KAG)に入社しました。  
  
https://kddi-agile.com/
  
主に名古屋オフィスにて、  
  
- ITを活用した地方の発展への貢献  
- 各種コミュニティ活動＆貢献（特に地方）
- 名古屋オフィスの事業拡大  
  
に貢献していきたいと思っていますので、これからもよろしくお願いいたします。（それ以前に、まずは自分の体調を治すことが最優先かもしれませんが...）  
  
なおカジュアル面談を随時募集中ですので「KAGについて詳しく知りたい」「KAG応募したいけど、ちょっと不安がある」などある場合は、ぜひ遠慮なくお声がけください。
  
それでは、投稿遅れてしまってすいませんが、今回はこの辺で。  
皆様、良いお年を！