悪い...やっぱCDKつれぇわ...そりゃ(黒魔術は)つれぇでしょ...

3 min read読了の目安(約3000字

くそなんだよ..全然(CDKの情報)出てこねーな

俺な、覚悟してCDK選んだんだよ

けど、なんかこうして運用してたらさ...

わりぃ、やっぱつれぇわ

なぜCDKを選択するのか

現状、AWSでIaCを運用する場合第一選択肢となるツールは

  • terraform
  • Cloudformation (以下CFn)
  • AWS CDK

あたりが挙げられるでしょう。

このうち、CFn, terraform, CDK の順にコードが宣言的なものになります。
またterraformはAWSではなくHashicorpのツールとなるので、クラウドベンダに依存しないのが特徴です。

なのでツール選定の際に

クラウドベンダ純正のツールだからCFnを使いたい。
しかしyamlを宣言的に記述するのは大変だ。
最近CDKが流行ってるらしいからこれにしよう。

的なノリでCDKが採用されることがあるようです。
特にアプリのコードも書いてインフラも書くようなフルスタック気味のエンジニアが提唱するケースが多い印象。
Terraformを使わない理由も

非純正ツールは対応が遅い可能性が高い。
CFnやCDKなら純正ツールだからサービスの対応速度も早いはず

という言及を見かけるのですよね。

純正ツールだからサービスとのシナジーが良いという幻想

CFn、およびCDKがAWS純正ツールだから、シナジーが良いというのは幻想です。(きっぱり)
CDKもCFnのラッパーなので、CFnの制限をもろに受けます。
それに加えてCDK特有の問題やバグと格闘する羽目になります。

例(CFnの制限)

最近ではDynamoDBのGSIを複数登録しようとしていたのですが、
DynamoDBテーブル一度の更新につき、GSIは一つしか登録できません。
なのでCFn、CDKもこれのせいで一つ登録してはデプロイし、もう一つ登録してはデプロイし...
とせざるを得ません。

[How to delete more than one Global Secondary Index from the CloudFormation at once?
]
(https://stackoverflow.com/questions/47920665/how-to-delete-more-than-one-global-secondary-index-from-the-cloudformation-at-on)

ちなみにTerraformはこの制限を受けないそうです。
多分複数回テーブルを更新してゴリ押ししてるんじゃないですかね。

他にもCodeDeploy + ECSのデプロイとなるとサポートされていない部分があったりと
純正ツールにしてはサービス間の連携が実装できなかったりしてつれぇです。

AWS CDKを(途中まで)使用してAmazon ECSの Blue/Greenデプロイ環境を構築する

例(クロスリージョン)

CDKはリージョンを跨いで情報を渡すことができません。
なので要件次第では完全自動化からは遠のきます。
例えばWAFv2のCloudfront向けルールは米国リージョンでしか作成できません。
すると割当てるCloudfrontも米国名義で作ることになり、S3も米国名義で作ることになります。
東京リージョンにしたい場合はCloudfrontとの連携を手作業で行います。

※無理やりやるとすれば、ssmパラメータにidやarnを保存して、カスタムリソースで抜き取るという手段もあります。個人的には最後の手段なので気が進みませんが...

コード一発での作成から遠のきますね。

例 バージョンアップが激しい

CDKは体感値で2週間に一度(もっと多いかも)ぐらいの頻度でバージョンアップが行われます。
中には破壊的変更もあって、これの動作確認をすることになります。
CDKでの構築中にバグに遭遇し、回避策を考えている間にバージョンアップでフィックスされることもままあります。

情報が少ない

AWS純正ツールの割に、情報が圧倒的に少ないです。
IaCはterraformが覇権を握っているようで、CDKはまだまだアーリーアダプタな感じですね。
terraformでは複数環境構築の際はworkspace派かmodule派かで分かれていますが、
CDKではそんな流派さえまだ存在しないようです。結果的に自分で分岐させることになるので属人性の高いコードになりがちです。

ベストプラクティスも見当たらない中、上記の問題に遭遇するのは

そりゃ...つれぇでしょ...

プログラマブルなのは恩恵か、負債か

CDKのメリットは既存言語で分岐・繰り返しを駆使してインフラを書けるだと思います。
これのおかげで、

開発環境はwebサーバは一台で
DBは最小スペック
ステージング環境はwebサーバ2台・DBもプライマリ・セカンダリ構成

みたいな動的に変わるインフラに対応しやすいです。
その代わり条件が増えるほど、コードの複雑度も上がります。
とりわけ開発中は特に、インフラの構成に細かい注文が追加でされることも少なくないです。
冗長性を排除しすぎるとそういった注文に対応するのに時間を食われるようになるでしょう。
なのでわざと冗長に記述して変更に強くするという判断も必要になります。
結局その判断基準が属人性を持つようになります。

そういった属人性を排除するためにコードを皆が書ける言語でレビュー合うべきだ

という理想が実行できるかも現実的には微妙なところでして、
CDKをレビューするためには

  • 対応言語がある程度読めること
  • AWSインフラの知識がある程度持っていること
  • CDKの知識があること
  • IaCの冗長性と宣言性のバランスが理解できること
  • これらに対応する時間が割けること

上記条件が整わないと難しいかなぁという印象です。
インフラ担当エンジニアがいたとして、他のエンジニアはフロントなりバックエンドなりの作業で一杯の場合インフラ担当同士でレビューし合うしかない状況にもなり得ます。

条件が整わない場合、CDKの黒魔術に進みかねないので...
#####そりゃつれぇでしょ...

それでも書き心地はトップクラス

そういったもろもろの問題はありますが、CFnやterraformと比べて圧倒的に書き心地が良いのも事実です。
得にTypeScriptを使用していれば、型定義の恩恵を十分に発揮し保守性と可読性を保つことができるでしょう。コード量自体、CDKが最も少ないので実装速度も早いと思います。

AWSの純正ツールということに過信しすぎなければ、使うメリットは十分あります。
昨今のIaCツールはどれも何かしらの辛みを持っているわけで、技術選定時にはその比較をしておくべきというだけの話ですね。

ちゃんとメリットも言えたじゃねぇか
聞けてよかった...