オブジェクトの広場はオージス総研グループのエンジニアによる技術発表サイトです

クラウド/Webサービス

もっとじっくり AWS CDK のコンセプト

第1回 AWS CDK とは:アプリの開発キット
オージス総研
樋口 匡俊
2023年7月27日

この連載では AWS CDK について、その基礎となる概念やものの見方・考え方を中心に解説していきます。『Concepts』など公式ドキュメントやソースコードの情報を整理して紹介するとともに、それでは足りない点やあいまいな点は、筆者の解釈で補いながら説明します。
前提となるのは、AWS とプログラミングの基礎的な知識だけです。AWS CDK の経験がなくとも読めるような説明を心がけますが、あらかじめ公式ワークショップなど何か一つチュートリアルをこなしておくと、より読みやすくなると思います。
今回は AWS CDK をアプリの開発キットととらえて、その概要を説明します。

AWS CDK のバージョン

はじめに、この連載であつかう AWS CDK のバージョンについて説明しておきます。

AWS CDK は Amazon Web Services (AWS) のオープンソースソフトウェア (OSS) です。 Apache License 2.0 のもと、GitHub でソースコードが公開されています。

公開されたのは今から 5 年前、2018 年 8 月のことです。 当初は開発者プレビューという位置づけでしたが、翌 2019 年 7 月には一般提供 (GA) が開始されました。 このときのバージョンは v1 という古いバージョンで、今年 6 月にサポート期間が終了しています。

筆者は v1 をほとんど使ったことがありません。 v1 のころは代わりに AWS CloudFormation や AWS Serverless Application Model (SAM) を使っていました。

AWS CDK を使いはじめたのは、2021 年 4 月に公開された v2 開発者プレビュー版からです。 主に技術開発で必要な環境構築に活用しています。 v2 は 2021 年 12 月に一般提供が開始され、2023 年現在も活発に開発が行われています。

本連載はこの v2 にもとづいて説明していきます。

シンプルなアイデアをこえて

AWS CDK の基本的なアイデアはとてもシンプルです。 CloudFormation のテンプレートを書くかわりにソースコードを書く。 ソースコードをもとにテンプレートを生成する。 それを可能にするのが AWS CDK です。

AWS CDK の基本的なアイデア

CloudFormation テンプレートは、EC2 インスタンスや S3 バケットなど、管理したい AWS のリソースを定義できる JSON/YAML 形式のファイルです。 テンプレートの定義にしたがい、CloudFormation はリソースを作成したり削除したりしてくれます。

CloudFormation は CDK とは独立したサービスです。 たいへん便利で、10 年以上の実績もあり、使ったことがある人も多いと思います。 けれども使い込んでいくと、テンプレートは長大で複雑であつかいづらいものになりがちです。

AWS CDK を生みだした Elad Ben-Israel 氏のチームも、やはりテンプレートに悩まされていたといいます。 はじめのころ、AWS Lambda 関数をいくつか作るぐらいならよかったのですが、プロジェクトの進行とともに AWS を利用する規模は大きくなり、テンプレートの管理も難しくなっていったのだそうです。

また、そもそもテンプレートが YAML 形式なのも問題でした。 表現できるのはリソースの設定だけで、自分たちが開発しているものの背後にある意図や考え方を表現することは困難でした。

しかし彼らはすぐに AWS CDK の開発に着手したわけではありません。 当時すでに troposphereGoFormation など、テンプレートのかわりにコードを書けるツールはいくつかあったので、まずはそれら既存のツールを試してみたのだそうです。

試してはみたものの、どのツールも満足のいくものではありませんでした。 AWS CDK は、コードからテンプレートを生成する以上のものを求めて開発されたのです。

抽象化とコンポーザビリティ

彼らが求めたものをたった一つのキーワードで表すとしたら、それは抽象化 (abstraction) だと思います。 ここでいう抽象化とは、オブジェクト指向のプログラミング言語で実現できるようなもののことを指します。 細かい処理や条件分岐、ベストプラクティス、頭の中にあるものの見方・考え方などをモデル化し、再利用しやすい形でまとめあげ、問題解決に役立てていく。 そうしたソフトウエア・エンジニアが長年培ってきた抽象化のスキルやセンスを、AWS のようなインフラにおいても存分に活かせるようなものが求められたわけです。

Elad Ben-Israel 氏によると、ソフトウェアの抽象化にとって鍵となる基本的な要素はコンポーザビリティ (composability) です。 コンポーザビリティは、近年 CDK にかかわらず注目をあつめている言葉です。 説明の仕方はいろいろありますが、氏によると、それは問題を小さく分割し解決できるようにしてくれるものであり、既存のツールに不足していたものであり、AWS CDK に求められたものでした。

AWS CDK とは:公式 README の説明

そんな AWS CDK を短く一文で説明するとどうなるでしょうか。 AWS CDK の README を見てみましょう。

The AWS Cloud Development Kit (AWS CDK) is an open-source software development framework to define cloud infrastructure in code and provision it through AWS CloudFormation.

AWS Cloud Development Kit (AWS CDK) とは、クラウドのインフラストラクチャーを、ソースコードで定義して AWS CloudFormation でプロビジョニングする、オープンソースのソフトウェア開発フレームワークである。

コードを書くことと CloudFormation を使うこと。 基本的なアイデアが端的に述べられていますね。 けっして間違った説明ではありません。 さっと読み流して、すぐにチュートリアルにとりかかる方が、てっとり早く AWS CDK を習得できるかもしれません。

しかしこの説明、あらためて読むと気になる点が二つあります。

一つは、CloudFormation を使うことがはっきり示されていることです。 実際、AWS CDK と CloudFormation は切っても切れない関係にあります。 けれども AWS CDK において CloudFormation は抽象化して利用するものです。 CloudFormation にふれるのは二文目、三文目にして、必要以上に CloudFormation を前面に出さない方がよいと思います。

もう一つは、AWS CDK をフレームワークと呼んでいることです。 CDK の「DK」は「Development Kit」つまり開発に使うさまざまな道具一式を意味します。 ならば素直に CDK は開発キットであり、フレームワークは数ある道具の一つとみなす方がよいと思います。 実際そのように説明している AWS の資料もいくつかあります1

AWS CDK とは:筆者の説明

それをふまえて、筆者が短く一文で説明すると「AWS CDK とは AWS CDK アプリの開発キットである。」となります。 AWS CDK アプリってなに??という感じですが、このあとじっくり説明します。

キットの主な要素は次の三つです。

  1. AWS CDK ツールキット (AWS CDK Toolkit)
  2. AWS コンストラクトライブラリ (AWS Construct Library)
  3. コアフレームワーク (Core Framework)

以下、くわしく見ていきましょう。

AWS CDK アプリ

AWS CDK アプリ (AWS CDK app) は、その名のとおりアプリケーションです。 AWS CDK では、アプリとして AWS のリソースを定義します。

AWS CDK アプリは TypeScript や Python、.NET (C#) など現代の主だったプログラミング言語で実装できます。 CDK 固有の言語ではありません。 わざわざ新しい言語をおぼえることなく、使いなれた言語で開発できることは、CDK の大きな特徴です。

アプリというだけあって、テストコードを書いたり、コードの静的解析ツールを適用したりもできます。 たとえば TypeScript であれば Jest でテストを書き、ESLint でコードの問題点を検出できます。

AWS CDK で開発するのは CloudFormation テンプレートではないということに注意してください。 最終的にはアプリをもとにしてテンプレートが出力されます。 また、実践的にはどのようなテンプレートが出力されるか確認することもよくあります。 しかし開発するのはあくまで AWS CDK アプリです。

AWS CDK 公式のベストプラクティスは、次のように述べています。

Treat AWS CloudFormation as an implementation detail that the AWS CDK uses for robust cloud deployments, not as a language target. You’re not writing AWS CloudFormation templates in TypeScript or Python, you’re writing CDK code that happens to use CloudFormation for deployment.

AWS CloudFormation を、ロバストなクラウド・デプロイのために AWS CDK が使用する実装の詳細としてとらえてください。プログラミング言語のターゲットとしてではありません。あなたは AWS CloudFormation テンプレートを書いているのではありません。あなたは CDK のコードを書いていて、それがたまたまデプロイのために CloudFormation を使うのです。

AWS CDK の世界では、CloudFormation やテンプレートは具体的な実体であり、開発者が直接ふれるものではありません。 開発者は AWS CDK アプリという抽象化されたものを開発していくのです。

AWS CDK ツールキット

AWS CDK アプリはアプリケーションですので、いつものツールで実行できます。 たとえば TypeScript のアプリであれば ts-node、.NET であれば dotnet run で実行できます。 しかしいまのところ、そのように直接アプリを実行することは一般的ではありません2

かわりに AWS CDK が提供する AWS CDK ツールキット (AWS CDK Toolkit) を使います。 AWS CDK ツールキットとは、cdk という CLI の正式名です。 cdk は、アプリの実行だけでなく CloudFormation の操作など細かな処理を開発者にかわって整理し、cdk listcdk diff のようなサブコマンドとして提供してくれます。

AWS CDK ツールキットは呼び方が統一されておらず、「cdk コマンド」や「AWS CDK CLI」と呼ばれることもあります。 また、「ツールキット」という単語はコマンドを表すこともあればライブラリなどを表すこともあり、まぎらわしいように思います。 以下ではコマンドであることがはっきりわかるよう、AWS CDK ツールキットを「cdk コマンド」と呼ぶことにします。

クラウドアセンブリ:シンセサイズとデプロイ

いくつもある cdk コマンドの処理のうち、特に重要なのがシンセサイズ (synthesize) とデプロイ (deploy) です。 どちらもクラウドアセンブリ (Cloud Assembly) というファイル群にかかわる処理です。

シンセサイズとは、AWS CDK アプリをもとにクラウドアセンブリを出力する処理のことです。 コマンドは cdk synthesize で、たいていはエイリアスを使って短く cdk synth と書きます。

デプロイとは、出力したクラウドアセンブリをもとに CloudFormation を操作し、リソースを作成したり更新したりする処理のことです。 コマンドは cdk deploy です。

クラウドアセンブリは何種類かのファイルで構成されています。 そのうちの一つは CloudFormation テンプレートです。 他に CloudFormation 実行用の IAM ロールを記述したファイルなどもあります。

つまりクラウドアセンブリには、デプロイに必要な CloudFormation の情報などがつまっているのです。 その詳細は JSON Schema で定義されていますが、ふだんはそういう細かいことまで気にする必要はありません。 開発者はアプリを実装し cdk コマンドを操作するだけでよく、クラウドアセンブリやその先の CloudFormation に直接かかわらなくてもよいようになっているのです。

cdk コマンドと他の関係

このような仕組みは、コンパイラ言語にたとえて説明されることがあります。 AWS CDK アプリという “ソースコード” を cdk コマンドで “コンパイル” して (synthesize)、出力したクラウド “アセンブリ” を CloudFormation という “CPU” で実行する (deploy)、という感じです。 開発者は “アセンブリ” や “CPU” の詳細をよく知らなくても、ソースコードの書き方とコマンドの使い方を知っていればよいわけです。

AWS コンストラクトライブラリ

それではもう CloudFormation のことはあまり気にしないことにして、ここからは AWS CDK アプリの実装方法を見ていきましょう。

AWS CDK アプリを実装するには、AWS CDK が提供する AWS コンストラクトライブラリ (AWS Construct Library) というライブラリが必要です。 コンストラクトライブラリは TypeScript で実装されており、npm パッケージの aws-cdk-lib として配布されています。

コンストラクト (construct) については、今後さまざまな形で説明していきます。 いまのところは、CDK アプリの基礎となる高いコンポーザビリティをそなえた部品、とおぼえておいてください。

AWS コンストラクトライブラリはモジュール (module) と呼ばれるまとまりに分割されています。 その多くは aws-ec2aws-s3 のように「aws-」にサービス名がついたもので、それぞれ名前のとおり EC2 や S3 のためのコンストラクトがまとめられています。

コンストラクトは、自分で好きなものを作ることもできます。 AWS コンストラクトライブラリ同様、自作したコンストラクトは npm などふつうのパッケージ管理ツールを使って共有できます。 CloudFormation の registry や SAM の AWS Serverless Application Repository に相当するような CDK 専用の仕組みは要りません。 コードだけでなくパッケージの管理にも、いつもの慣れ親しんだツールが使えることは、CDK の大きな特徴です。

TypeScript の重要性

AWS CDK はさまざまな言語をサポートしています。 AWS コンストラクトライブラリも、TypeScript 版をはじめ Python や .NET (C#) などさまざまな言語で配布されています。

ただし TypeScript 版以外のコンストラクトライブラリは、TypeScript 版をもとに生成されたパッケージです。 そしてどの言語であれ、コンストラクトライブラリを利用するには Node.js が必要です。 じつは先ほどの cdk コマンドも TypeScript で実装されており、やはり Node.js が必要です。

CDK のサンプルコードも TypeScript が多いように感じます。 AWS 以外が公開しているコンストラクトも、TypeScript 版しかない場合がけっこうあります。

このように TypeScript は AWS CDK にとって最も重要な言語です。 そのため、他の言語を使いたいという方も、まずは TypeScript を使ってみることをおすすめします。 AWS CDK で使う TypeScript の機能は、クラスやインターフェースなど他の言語にもあるものなので、習得はそれほど難しくないと思います。

この連載でも、特に理由がないかぎり TypeScript 版のコンストラクトライブラリをもとに説明を進めていきます。

コアフレームワーク

AWS CDK アプリは、コアフレームワーク (Core Framework) に従い一定の枠組みの中で実装していきます。

コアフレームワークは、v1 のころはコアライブラリとして独立して配布されていました。 v2 からはコンストラクトライブラリとあわせて aws-cdk-lib としてまとめて配布されています。

コアフレームワークの枠組みは、次のようなツリー構造で表せます。

AWS CDK アプリのツリー構造

アプリというだけあって、ツリーのルートは「App」です。

「App」はその下にいくつかの「Stack」をもっています。 「Stack」は CloudFormation のスタックに相当します。

各「Stack」はいくつかの「Construct」をもっています。 「Construct」は CloudFormation のスタックに含める EC2 インスタンスや S3 バケットなどのリソースに相当します。

ソースコードの例を見てみましょう。

import * as core from 'aws-cdk-lib/core'
import * as s3 from 'aws-cdk-lib/aws-s3'

const app = new core.App()

const stack = new core.Stack(app)

// Construct
new s3.Bucket(stack, 'Bucket')

new で生成したインスタンスが、別のインスタンスを new するときに渡されていますね。 core.Appcore.Stack へ、core.Stacks3.Bucket へ渡されています。 s3.Bucket は S3 バケットを表す「Construct」です。 このように「App」→「Stack」→「Construct」と、親を子へ渡していくことでツリーを伸ばしていきます。

よく見ると s3.Bucket だけ new したのに変数に代入していません。 これは CDK ではよく出てくる書き方です。 一見、使わないインスタンスを生成しているようで無駄に見えますが、じつは見えないところでツリーを作っているのでこれでよいのです。

この例は単純化したものですが、実際のアプリでもインスタンスを生成しながらツリーを作っていくという基本は同じです。

コンストラクトツリー

これら core.Appcore.Stacks3.Bucket も、もとをたどると同じ Construct というクラスを拡張 (extends) したクラスです。 じつは「App」も「Stack」もコンストラクトの一種なのです。

したがって、先ほどの図はすべてを「Construct」として描きかえることができます。

コンストラクトツリー

このような構造は、コンストラクトツリー (construct tree) と呼ばれます。 AWS CDK のコアフレームワークは、「App」や「Stack」を追加して、コンストラクトツリーの仕組みを AWS 向けに拡張したものなわけです。

コンストラクトツリーを組み立てていくプログラミングを、コンストラクトプログラミングモデル (Construct Programming Model) 略して CPM といいます。 CPM は AWS CDK に限らず、「あるべき状態 (desired state)」を定義するソフトウェア全般に適用しうるものとされています。 AWS CDK アプリは、こうした高度に抽象化されたプログラミングモデルに支えられているのです。

“as” から “is” へ変わる IaC

以上のような AWS CDK の仕組みは、AWS をこえて広まりつつあります。 AWS CloudFormation とよく比較される Terraform は、2022 年 8 月に CDK for Terraform (CDKTF) の一般提供を開始しました。 その前年 2021 年 10 月 には、コンテナ・オーケストレーションの Kubernetes も CDK for Kubernetes (CDK8s) の一般提供を開始しています。

各 CDK はコンストラクトの考え方を共有しており、高いコンポーザビリティをそなえています。 それを活かして、CDK 同士のインターオペラビリティ(相互運用性)を向上させる取り組みも進んでいます。 たとえば AWS CDK のコンストラクトを CDKTF でも使えるようにする AWS Adapter はプレビュー版が開発中です。 また CDK8s は AWS CDK の EKS コンストラクトと組み合わせて使うことができます。

AWS CDK の登場により、これら Infrastructure as Code(IaC)の世界は新たな段階に入ったと言ってよいでしょう。 ふりかえれば AWS の年次イベント re:Invent 2018 において、AWS CDK が初公開されたときのセッションは『Infrastructure Is Code with the AWS Cloud Development Kit』でした。 Infrastructure as Code の “as” を “is” に変えたこのタイトルには、インフラとコードが同じようなもの (as) からそれそのもの (is) に一体化したという感覚、いわば真の IaC が CDK によって実現されたという自負が表れているように思います。

おわりに

AWS CDK の利点としてよく挙げられるのは、コードを書く量が減るということです。 統計をとったわけではありませんが、実感としてそれは正しいと思います。 AWS CDK アプリは、ほんの数行で何倍もの行数の CloudFormation テンプレートを出力してくれます。

しかし、行数のような量に注目しても、CDK の真価はいまひとつわからないと思います。 CDK の真価は、機械的に数えたり測ったりする量よりも、人間が考えたり感じたりする質の変化にあるからです。

質の変化をもたらしたのは、今回紹介した AWS CDK アプリという抽象化や、コンストラクトにそなわっているコンポーザビリティです。 IaC の新たな世界を切りひらきつつある、そうした AWS CDK のコンセプトについて、次回以降もじっくり紹介していきたいと思います。


参考資料

AWS CDK が開発された経緯については、『The CDK Book』の Elad Ben-Israel 氏による前書きが参考になります。 本文中の氏の話はこの前書きにもとづいています。 他に AWS のブログ記事『Working backwards』も参考になります。

従来のツールとの違いは、AWS CDK 初公開時の動画の冒頭数分で説明されています。 日本語では AWS Japan の Black Belt に同様の説明があります。

引用した英文の翻訳は筆者が行いました。


  1. たとえば AWS CDK が公開された翌年、2019 年の AWS Online Tech TalksAWS re:Invent の動画。 

  2. このあたりの課題や解決策については GitHub Issue #300 を参照