新規事業開発な会社でCDKを導入していったので軽い振り返り

この記事は、「[Relic Advent Calendar 2022](https://qiita.com/advent-calendar/2022/relic)」の1日目の記事です！

# 今回は書かないこと
- CDKに関する説明
    - CDKについては[Black Belt](https://www.youtube.com/watch?v=1i7kWqpqtoY)を見てね
- 振り返りがメインなのでコードを交えた細かいテクニカルな話

# 背景
弊社は新規事業開発を事業ドメインに据えておりSaaS型自社プロダクトの開発や新規事業開発支援などのクライアントワークと投資などを行う企業です。新規事業の立ち上げが多い弊社において私が所属するSREなチームでは、素早くプロダクトを世に届ける為に開発アセットの標準化に取り組んでおります。

メインで使用しているクラウドプラットフォームがAWSということもあり、AWSリソースのInfrastructure as Code(IaC)にはCloudFromation(CFn)を用いてインフラレイヤの標準化を行っておりました。

そんな中、TerraformかCDKかに置き換えるかをチーム内で検討する機会があり、話し合った結果CDKを選択することとなりました。本記事ではCDKを選択してから約1年という区切りの中でやって来たことや所感などをつらつらと書いてきたいと思います。

# 検証フェーズ
CDKへの置き換えにあたり、チーム全体でCDKのチュートリアルやWorkShopを実施して使い勝手やCloudFormationとの違いや、去年のRe:InventでCDKv2がリリースされたばかりもあって、そもそも余り意識していなかったCDKv1とv2との差分に当時四苦八苦しながら成程CDKとはこういうものかと`cdk diff`のありがみを噛み締めながら検証を実施。

# CloudFormationからCDK置き換えフェーズ
標準としているCFnをCDK（TypeScritp）で記述していくミッションを当時任された私は、ドキュメントやGitHubとにらめっこしつつCFnで定義している各リソース、各設定項目とをひたすら置き換えていきました。

## 循環参照の罠

当時最初にあたった壁としてはCloudFront+OAIのStackとS3のStackに別けて作成してCloudFrontにはOAIとS3を紐付け、DependencyでS3を先にDeployさせようとした際に、下記のエラーにより循環参照エラーが出力され、解決に頭を悩ませました。

```sh
Error: 'sample-dev-cloudfront' depends on 'sample-dev-s3' (dependency added using stack.addDependency()). Adding this dependency (sample-dev-s3 -> sample-dev-cloudfront/sample-dev-public-access-oai/Resource.S3CanonicalUserId) would create a cyclic reference.
```

CloudFormationでStack間リソース参照をする場合はExport/Importを用いて行うのが一般的な方法で、リソースが展開される順番に注意を払えば大体は循環参照を回避出来るものなので、その感覚でいるとこれは非常にハマりポイントでした。

調べても「dependencyを指定しましょう」くらいしか見つけられなかったのでサポートにも問い合わせ、参照方法を変えることでエラーを回避できるようにはなりました。その後チームで議論してCloudFront+S3など、比較的密接に関わるリソースの組み合わせはStackは同じでもよいという方針になり、最終的には同一Stackにて定義することとなりました。

基本的なトラブルシューティングに関しては、ベースとするAWSとCFnの知見(※CDKは最終的にはCFnとしてリソースをプロビジョニングする)があったので特に困りませんでしたが、この1件はちょっとした洗礼のように感じました。

## ドキュメント迷子

また、当時の個人的なつらみとしては1つのリソースを定義する際のドキュメントにおける導線が、CFnの方が自分にとっては分かりやすい(潜れば到達出来る)のに対して、CDKは「この、設定値を定義したいだけなのに…何処に書いてあるんだ…」とドキュメントをあちこち遷移したり、場合によってはGitHubを見に行くシーンが多く、ややヘビーに感じておりました。※今でも度々迷子になる。

## L2対応してない問題

また、CDKの使い始めは「どうせならL2で統一したい！」とか無邪気に意気込んでましたが、よくよく触っていくとL２に対応していないサービスもまだ見受けられたため早々に諦めが必要でした。

例えば、AuroraのDBインスタンスはCFnですと初期起動先のAZを指定できますが、CDKのDatabaseClusterコンストラクトからinstancePropsでDBインスタンスを定義する場合は、AZ指定の項目がそもそもないので、L1を使うor妥協するor手間をかけて工夫するといった選択から方針を決めていく、などですね。

# PJへ活用&フィードバック取込フェーズ
さて、色々あって一通りCFnをCDKに置き換えが完了した後は実際のPJで導入していく事となるのですが、新規の自社サービス1件とクライアントワークの新規事業2件の計3つのプロジェクトにおいてCDKを使ってAWSリソースを展開しました。

諸々の事前準備で手間取った部分はありましたが、`cdk deploy --all`で全stackが無事展開された時はチームみんなで感動した覚えがあります。その後、運用を考えるとCDKならではの事項であったり、これはこうした方がいいんじゃないなどまだまだ粗が見受けられたのでそれらの点を改善&標準へと取り込んでいく必要が出てきました。

- 弊チームで別で動いていたアプリケーションレイヤ標準化との整合性
- これcdk.jsonで扱った方がいいんじゃないかパラメータ
- 命名etc...

ベース部分に対して早い段階でフィードバックをチームで反映出来たこともあり、後続PJでの変更を抑えることが出来たのが非常に良かったと思います。

# 機能追加フェーズ
その後CDKを導入したPJである程度開発が進んでいくと、固有要件で○○を使いたいが当然出てきましてそれらをCDKで定義しては、これは他PJでも流用出来るなと判断したものや、非推奨となったProps(cidrやPRIVATE_WITH_NAT)への対応や、ホスティングで使用していたAmplifyもCDKでのプロビジョニングに置き換えなど各々標準へと取り込んで更なる強化を進めていくフェーズに移っていきました。

様々なPJから良い部分を吸収して素早く次へ活かしていく事が出来るスタイルが、うちの強みだなとひしひしと感じています。

# コミュニティ活動
今年の4月に「[AWS CDK Conference Japan](https://jawsug.connpass.com/event/240422/)」というJAWS-UG東京主催のイベントがあり、当時知見を求めて声をかけて運営サイドとして参加したきっかけもあって、10月には「[JAWS DAYS 2022 - Satellites](https://jawsdays2022.jaws-ug.jp/)」でCDK支部の運営メンバとしてハンズオンイベントの開催であったり[今後の企画](https://jawsug-cdk.connpass.com/)に関わる事が出来ました。まさかCDK単体でこうなるとは年初時点では1㍉も思っていなかったです。

お陰様で他社さんの知見であったり、単純にCDKだけでなく色々と雑談する機会が増えたので実りのあった1年だったなあと感じています。

# まとめ
1年中CDKにべったりと云うわけでは無かったですが、CFnからの置き換えとPJへの導入や運用と一連の流れに関わることが出来たので良い経験となりました。また、今の形がCDKにおけるベストとは思っておらず、まだまだより良くする為のポイントはあるので引き続き強化に励み、来年は更に磨きをかけて新規事業開発とコミュニティに貢献していければと思います。

# CDKをこれから試したい&学びたいという方
- [CDKWorkShop](https://cdkworkshop.com/ja/)
    - 公式、最近日本語対応
- [CDKWorkShop](https://jaws-ug-cdk.github.io/aws-cdk-intro-workshop/)
    - JAWS DAYSに向けてCDK支部で日本語化したもの
- [TypeScriptの基礎から始めるAWS CDK開発 入門](https://catalog.workshops.aws/typescript-and-cdk-for-beginner/ja-JP)
- [CDKWorkShop-EKS-BluePrints](https://aws-quickstart.github.io/cdk-eks-blueprints/pipelines/)
- [CDKベストプラクティス](https://aws.amazon.com/jp/blogs/news/best-practices-for-developing-cloud-applications-with-aws-cdk/)
- [CDK Security and Safety Dev Guide](https://github.com/aws/aws-cdk/wiki/Security-And-Safety-Dev-Guide)
- [API Reference](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html)
- [Black Belt](https://www.youtube.com/watch?v=1i7kWqpqtoY&t=1s)
- [cdk.dev](https://cdk.dev/)
- [GitHub/aws-cdk](https://github.com/aws/aws-cdk)
    - [AWS Construct ライブラリの設計ガイドライン](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)
- [Construct Hub](https://constructs.dev/)
- [AWS Blog-AWS Cloud Development Kit](https://aws.amazon.com/jp/blogs/developer/category/developer-tools/aws-cloud-development-kit/)
- [awesome-cdk](https://github.com/kalaiser/awesome-cdk)
- [JAWS-UG CDK支部connpass](https://jawsug-cdk.connpass.com)
    - [資料一覧もオススメ](https://jawsug-cdk.connpass.com/presentation/)
- [JAWS-UG CDK支部Twitter](https://twitter.com/jawsug_cdk)