AWS CDK の良さを感じるタイミングってどんなとき?(私見)

記事タイトルとURLをコピーする

...という質問を社内でもらったので、私なりにパッと思いつく意見を Slack でお答えしました。せっかくなのでもうちょっと言語化して、外向けにも発信してみようと思い、この記事を書きはじめました。

採用検討している方や、興味を持っている方、技術選定を考える方への思考の材料になれば。

前提事項

この手の技術選定に関わる話題は少なからずポジショントーク的な要素が、言い換えると採用した当事者や案件・組織における文脈が大前提ですので、それを踏まえて読んでいただけたらと思います。CDK 以外の IaC を下げる意図はありませんし、あくまで私の「お気持ち」の域を出ない私見であることをご了承ください。

私自身の属性ですが、社内SE 的な立場で Lambda や ECS 等といったインフラ構築や、その上で動作する業務アプリケーションの開発・保守などが IT 技術の側面における主な職務になります。

インフラごと新規開発したものもありますが、引き継ぎしたものも多数あります。システムによって使っている技術スタックはバラけます。IaC なら Serverless Framework, CDK, Cloud Formation(あるいは IaC 管理されていない環境)などが、アプリロジックなら TypeScript や Python や bash などが、それぞれのプロジェクトごとの管理方法で散在している感じです。扱っている業務的なコンテキストはそれぞれで全く異なります。

比較対象として想定しているのは terraform と Cloud Formation になります。

terraform も多少は経験ありますが、「実務で使えます!!!」と自信持って言えるほどの経験値はないです。基本的な Remote backend の設定だとか、モジュール構成のやり方だとか、ソースが公開されてるプロジェクトを close していじってデプロイしてみるだとか、そういうのが多少できる、という程度です。時間軸の長いプロジェクトでは経験したことがありません。

私なりの、CDK にして嬉しいこと

自分の場合は、だいたい次の3つだと思います。

  • TypeScript の型定義のパワーを享受できる
  • 適切な抽象化によって、生の API 仕様を意識しないでも少ない行数で「意図」を表現したコードが書ける
  • デプロイ前に動かせるバリデーションやテストの方法が充実していること

具体的な使い勝手ではもちろん一長一短があり、場合によっては「terraform の方が良いなぁ」と思うこともあります。とはいえ私自身は CDK が提示してくれた、DSL 的な考えとは対極の位置とも言える思想*1に強く共感しているので、CDK を推している、という感じです。

日々の技術選定自体はできるだけ個人の趣味嗜好を省いて、組織や案件ごとのメリットや中長期のライフサイクルの想定も踏まえフラットに見たいとは思っていますが、少なくとも自社内で完結する開発プロジェクトであるなら(私の現在の職務範囲において)私は CDK をファーストチョイスとして挙げ続けると思います。

型定義の支援

型定義の有用性は改めて説明するほどのことはないと思いますので、端折り気味でいきます。

IDE の支援を受けながら、ドキュメントとの反復横跳びをしなくても書ける、ということはとても大きいです。昨今であれば「AI で書けるじゃん?」という議論もあると思いますが、結局そのコードのオーナーシップを持つのは自分です。誰が書いたものであれコードの内容は把握しながらマージ & リリースしますし、誰が書こうが使っているインタフェースやパラメータについては一通り確認します。必要に応じて自分で書き換えたりもします。そういった普段の開発シーンにおいて、型定義は画面の往復をすることなく実装や仕様の理解を助けてくれます。特に IaC の実装はパラメータの厳密さが問われますし、型定義と補完によって保証できる領域があることは大きな利点と考えています。

適切な抽象化

これを説明するには、grant メソッドの存在が最もわかりやすいかと思います。

Lambda(にくっつける IAM Role)に、S3 に対する Read を許可する実装を想像してください。terraform や cfn に馴染んでいる方であれば特にハードルもなく、Function, Role, Policy, Bucket の関係性を描けるでしょう。でも、いくらモジュール化して構造化したところで、そのわかりやすさには限界があると(私は)思っています。

適切に抽象化されたソフトウェアが少ない行数でいとも簡単に複雑な「意図」を表現してくれるように、CDK が IaC の世界で同じ体験を提供してくれます。今挙げた s3 & lambda の例であれば、パーミッション追加の実装は次の1行で表現できます。

declare const myBucket: s3.Bucket;
declare const myFunction: lambda.Function;
  
// ↓この1行で、Function に紐づく IAM Role に S3 バケットの read 権限が付与できる。
myBucket.grantRead(myFunction);

上記の書き方は、英文表現として語順そのままに

myBucket grants read permission to myFunction.

と解釈ができます。この1行が何をしているのかは容易に推測できます。私は、これこそソフトウェアの、そして CDK の「適切な抽象化」がもたらす推測容易性(つまり読みやすさ)の利点だと考えます。もし詳細な値レベルまで確認したくなったら、それはユニットテストや snapshot で、最悪 synth 結果を確認する、などなど複数の手段で補完できます。このあたりの感覚は普通にアプリケーション実装のコードリーディングをしている場合と変わりません。

複数モジュールの横断あるいは yaml ファイルの上下往復をして確認するより、こちらの方がより簡単に、その実装内容と意図を推測できると思いませんか。

デプロイ前に動かせるバリデーションやテスト

度々引用させてもらっていますが、具体的にどのようなことができるのか?については以下の記事が詳しいのでそちらに譲ります。

aws.amazon.com

IaC 実装で達成したいことのひとつは「堅牢に作りたい」ということだと思います。

CDK の本質は cfn を抽象化するツールですから、CDK に抵抗感のある方は、おそらく「抽象化されては結局何が作られるのか人間が把握しづらくなる。ブラックボックスな IaC 実装なんて怖くて使えないだろう」と不安に思われるのではないかと思います。ブラックボックスな状態でデプロイすることが良くないという認識や、そうなることに対して懸念を抱くこと自体は、私もまったく同意見です。

他にも敬遠する理由はあろうかと思いますが*2、いったんこの観点から私の所感を述べます。

通常のアプリケーション開発における一般論として、「堅牢」に作るために実装側でどんな工夫をするかというと、おそらく静的解析ベースのツールの導入やバリデーションロジック・ユニットテストの充実化、回帰テストの導入、あたりが最も手近でかつバリューが出るところではないかと思います*3。CDK であれば、それらはほぼすべて組み込みの機能で満たすことができます。

実際の Stack のデプロイメントを行わずとも、不正な値や意図しない回帰、重要なシステムコンポーネントに焦点をあてた社内ポリシーへの準拠、などなどを検出できる方法が、CDK には用意されています。例えば、cdk-nag を使えば、Security Hub がデプロイ済リソースに対して発見的統制の枠組みでやっているような話をデプロイ前に検出できるようにもなります。そして、それらは容易に使い始めることができます。

この観点において CDK を使っていて最も嬉しかったのはデグレ確認の容易さです。terraform との対比ではないのが恐縮ですが、実例を補足します。

そのプロジェクトでは Serverless Framework を使っている、長期間塩漬け状態のシステムがありました。改修要望が出ており、前任者も離れていたため私が受け取ったのですが、改修に先立ち、まずは Serverless Framework の依存関係の更新、次いで古いランタイムの入れ替えを行うなどの前工程が必要でした。このとき、インフラ定義やアプリロジックの実装はほぼ変化させる必要がありませんので、更新デプロイされる Stack の差分は少ない、あるいは生じないはずです。しかし、IaC 側で使っているプラグイン自体も古く、外部的・内部的な仕様が変わっている箇所があり、依存関係の更新に伴って Stack の更新差分がそれなりの量生じることになりました。このときの差分確認の方法は、現行のデプロイ済み Stack と、手元の Serverless Framework のビルド結果のテンプレートを Raw JSON (or yaml) で人力レビューすることでした*4。なお、当時の Serverless Framework には ChangeSet 作成まででストップできるデプロイオプションは存在しませんでした*5

正直、かなり面倒な作業でした。CDK を使っていたのであれば、これは cdk diff のレビュー、そして Snapshot testing の枠組みによってかなりわかりやすい形で視覚化できていました*6。おそらく、もっと更新は楽にできていただろうと思いますし、社内のユーザーを(100%開発側の都合によって)無駄に待たせてしまうこともなかったはずだと思います。そうした保守の苦労があったので、そこに対して回答を示してくれた CDK が私には刺さりました。

私なりの立場で、CDK の良さを総括

インフラ定義とアプリ実装の兼任をしている私のような立場からすると、上記のような CDK の特徴が非常にマッチしていると感じる場合が多いです。

ほとんどの場合、私の仕事の「価値」の本命は、業務上の用事を達成するロジックの方にあります。そうなると、インフラ定義の方にはできるだけ時間を取られたくないですし、実際の業務上の困りごとを対話し、本質的課題を明らかにしていく方向に多くの時間を充てたい、という意識が強く働きます。AWS 流に表現するなら、インフラ定義の部分は私にとっては "Undifferentiated heavy lifting" な性質に寄ったタスクとして捉えられる場合が多い、ということです。

Stop spending money on undifferentiated heavy lifting: AWS does the heavy lifting of data center operations like racking, stacking, and powering servers. It also removes the operational burden of managing operating systems and applications with managed services. This permits you to focus on your customers and business projects rather than on IT infrastructure.

AWS Document - AWS Well-Architected Framework - Design principles より https://docs.aws.amazon.com/wellarchitected/latest/framework/cost-dp.html

デプロイメントやリリースの観点までひっくるめてインフラ定義が整備されることは、私の仕事にとって本命の価値創出のリードタイムにダイレクトに寄与する成果と言えます。したがって、それらの技術領域を軽く見ているということは一切ありません。むしろ SRE 的な活動として、私の仕事範囲の中でも大変に重要なものであるという認識を持っています。

...とはいえ、全部をこなすには手が足りないので、じゃあどこに一番集中するべき?という話を考えるとき、IaC は相対的に順位を下げざるを得ないケースが多い、というニュアンスです。

terraform (aws provider) や Cloud Formation は AWS API の生の仕様に近い粒度を意識させる作りになっています。上記のような立場や事情を前提として、私の感覚としては「そんな細かいところまで、こちらに意識させないでほしい...」とも思うのです。

適切に抽象化され、少ない行数でその実装の意図を明瞭に表現できる CDK が、豊富なバリデーション・テストの手段を備え、厳密さ・透明さを確保しながら使えるのであれば、私がやりたいこと・ありたい姿を、それなりに堅牢なやり方実現できるじゃん?と考えています。私が CDK を使う動機はこういったところにあります。

感想

terraform や Cloud Formation は DSL のアプローチを採用したツールであり、CDK とは考え方がほぼ対極にあるツールと考えています。「TypeScript などの汎用言語で書ける=自由度の高さ」とも言えますし、それは DSL とは全く反対の考え方であろうと思います。おそらく、思想が合わない人にはとことん合わないだろうな、とも思います。

DSL ベースのツールが開発者の自由を意図的に狭め、ガードレールとして機能してくれることは大きな利点と認識していますし、その良さに共感している人からすると、CDK が思想として受け容れづらく映るのは自然なことだと思います。実際、私も(少ない経験値からの印象で恐縮ですが)terraform で書かれたソースは具体的に何がどうなるのかが明白なので、厳密さの観点では CDK よりも優れていると思います。CDK でもそのへんは頑張れなくもないと思いますが、とはいえ実装の自由度が高いツールであるがゆえ個々人の実装者の力量や個性という変数に影響されてしまう、という側面があります。

記述自由度の高さこそが良くも悪くも CDK の最大の特徴であり、ここに共感できるかどうか、というのが多くのみなさんにとっての CDK への印象を決定づける大きなファクターなのではないか...と、私なりには整理しています。

他の IaC ツールを否定する意図はありません。必要があれば使いますし、何よりいちエンジニアとしても様々なツールの様々な思想・アプローチに触れるのは楽しいですので。

私の観測範囲内では CDK を敬遠気味に見ている方も一定数いらっしゃるような印象がありましたので、この記事でそうした見方が少しでも(たとえ読者のチームで採用されなかったとしても) 興味を持つ方向に振れてくれたらいいなと思い、この記事を書きました。

そして、願わくばどなたか私に terraform の世界観を教えてください...。個人的興味はあるものの、まだ私の趣味キューにスタックしているものがたくさんあり、全然手を出せていないのです...。私も対価として CDK のことを喋りますので、何卒。terraform 推しの方が見ている世界観を、私も知ってみたいです。

*1:私の個人的な印象です。公式が一言一句違わずこう言っている、ということではありませんのであしからず

*2:代表的なのは、terraform ユーザーからの「でも AWS 専用なんでしょ?」という意見かなと思っています。ここは私も反論の余地ありません

*3:ほかにもデプロイメント・リリースの方法論だとか、エンドツーエンドでのテストや監視だとか、多くの切り口があるということは認識しております

*4:念の為申し上げますが、私自身は Serverless Framework を愛用していましたし、今でも好きなツールの一つです。根本的な問題は Serverless Framework の採用是非というよりも、メンテナンスを放置してしまったことで苦労の利息が膨れ上がってしまったことに根ざしている、という認識を明言しておきます

*5:コミュニティプラグインには ChangeSet に対応するのものが存在しましたが、当時は不使用でした

*6:terraform であれば、おそらく plan と test が対応するでしょうか? snapshot test に対応するものは存在しない認識で、おそらく plan が近い立ち位置になるかと思います。もし私の誤認であれば、ご指摘いただけると幸いです

橋本 拓弥(記事一覧)

マネージドサービス部

内製開発中心にやってます。普段はサーバーレス関連や CDK を触ることが多いです