目次
今回は Cloud Development Kit for Terraform (CDKTF) について解説します。CDKTFを使うと、TypeScript、Python、Javaといった普段使い慣れたプログラミング言語でクラウドインフラを定義できるようになります。
Infrastructure as Code (IaC) とは
Infrastructure as Code (IaC) は、インフラの構成を手作業ではなくコードで管理する DevOps の重要な手法です。物理的なハードウェア設定や GUI による設定ではなく、機械が読み取れる設定ファイルでインフラを管理・構築します。これにより、どの環境でも同じ構成を再現できるようになります。
IaC のメリット
- 一貫性: 毎回同じ構成が確実に適用されるため、ヒューマンエラーを大幅に減らせます。
- バージョン管理: インフラの構成をコードとして Git 管理できるので、ロールバックやチーム開発が簡単になります。
- スケーラビリティ: インフラの構築を自動化できるため、必要に応じてスケールアップ・ダウンが容易です。
主要クラウドサービスの IaC ツール
- AWS: CloudFormation や CDK (Cloud Development Kit) でインフラを定義・管理できます。
- Azure: ARM テンプレートや Azure Bicep でインフラを管理します。
- GCP: Deployment Manager や Terraform でクラウドリソースを管理できます。
CDKTF は、こうした Terraform の機能を拡張し、普段使っているプログラミング言語でインフラを定義できるようにしたツールです。AWS、Azure、GCP どれでも使えるため、マルチクラウド環境でも統一した開発体験が得られます。
HCL ではなく CDKTF を選ぶ理由
HashiCorp Configuration Language (HCL) は Terraform の標準言語で、強力かつ広く使われています。でも、CDKTF にはそれを超える魅力がいくつかあります。
学習コストが低い: TypeScript、Python、Java など、すでに慣れている言語が使えるので、新しい DSL を学ぶ必要がありません。チームの学習曲線も緩やかになります。
コードの再利用性: 関数、ループ、条件分岐など、プログラミング言語の機能をフル活用できます。モジュール化された再利用可能なコードが書きやすくなります。
IDE のサポート: 一般的なプログラミング言語なので、オートコンプリート、Lint、デバッガーといった IDE の恩恵を受けられます。開発体験と生産性が段違いです。
既存コードとの統合: 既存のコードベースやライブラリとシームレスに統合できます。インフラコードを既存のワークフローに自然に組み込めます。
テストが書きやすい: Jest や pytest など、使い慣れたテストフレームワークでユニットテストを書けます。インフラコードの品質を担保しやすくなります。
前提条件
始める前に、以下をインストールしておいてください。
- Node.js と npm
- Terraform
- CDKTF CLI
ステップ1: CDKTF CLI をインストール
まず、npm で CDKTF CLI をグローバルにインストールしましょう。
npm install --global cdktf-cli@latest
ステップ2: プロジェクトを初期化
プロジェクト用のディレクトリを作成して移動します。
mkdir my-cdktf-project
cd my-cdktf-project
次に、CDKTF プロジェクトを初期化します。
cdktf init --template="typescript"
これで TypeScript を使った CDKTF プロジェクトがセットアップされます。
ステップ3: インフラを定義してみよう
プロジェクトディレクトリの main.ts ファイルを開きます。ここにインフラの構成を書いていきます。試しに AWS S3 バケットを作成してみましょう。
import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";
import { AwsProvider, S3Bucket } from "@cdktf/provider-aws";
class MyStack extends TerraformStack {
constructor(scope: Construct, id: string) {
super(scope, id);
new AwsProvider(this, "AWS", {
region: "us-west-2",
});
new S3Bucket(this, "MyBucket", {
bucket: "my-cdktf-bucket",
});
}
}
const app = new App();
new MyStack(app, "my-stack");
app.synth();
ステップ4: デプロイしてみよう
インフラをデプロイするには、次のコマンドを実行します。
cdktf get
cdktf deploy
ネイティブ対応していないモジュールの使い方
Terraform モジュールの中には、まだ CDKTF でネイティブサポートされていないものもあります。でも大丈夫。cdktf.json にモジュールを追加すれば、必要なコードを自動生成できます。
例: 非対応モジュールを使う
例えば、AWS IAM ロールを管理する Terraform モジュールを使いたいけど、CDKTF のネイティブモジュールがないケースを考えてみましょう。以下の手順で対応できます。
cdktf.jsonにモジュールを追加cdktf.jsonを開いて、terraformModulesセクションにモジュールを追加します。{ "language": "typescript", "app": "npx ts-node main.ts", "terraformProviders": ["hashicorp/aws@~> 3.0"], "terraformModules": [ { "name": "iam-role", "source": "terraform-aws-modules/iam/aws//modules/iam-role", "version": "~> 4.0" } ] }コードを生成
次のコマンドで、モジュール用のコードを自動生成します。
cdktf getこれで選択した言語(今回は TypeScript)のコードが生成されます。
生成されたモジュールを使う
import { Construct } from "constructs"; import { App, TerraformStack } from "cdktf"; import { AwsProvider } from "@cdktf/provider-aws"; import { IamRole } from "./.gen/modules/iam-role"; class MyStack extends TerraformStack { constructor(scope: Construct, id: string) { super(scope, id); new AwsProvider(this, "AWS", { region: "us-west-2", }); new IamRole(this, "IAMRole", { name: "my-iam-role", // ここに他の必須変数を追加 }); } }main.tsを修正して、生成されたモジュールを使います。const app = new App(); new MyStack(app, "my-stack"); app.synth();あとは
cdktf getで必要なプロバイダーをインストールして、cdktf deployでインフラを AWS にデプロイするだけです。こうすることで、CDKTF のネイティブサポートがない Terraform モジュールでも活用できるようになります。
実践のヒント
公式ドキュメントでは、インフラをスタックに分割して、それぞれがレイヤー(ネットワーク、VM など)を表すようにすることを推奨しています。ただ、実際に使ってみると問題があります。
各スタックには独自の lock-state ファイルがあるため、すべてのスタックを一度にデプロイすると、1つでも失敗したら他のスタックも中断され、ロックファイルが残ったままになります。手動で削除するのは本当に面倒です。
個人的には、スタックではなくモジュールでインフラを分離し、アプリケーション全体は1つのスタックにまとめる方が良いと思います(HCL でやる場合と同じように)。
Aspects を使うと、複数のリソースを一括で変更して、一貫性を保つのがとても楽になります。
ドキュメント: Aspects参考文献
まとめ
お疲れさまでした。これで最初の CDKTF プロジェクトの作成とデプロイができました。CDKTF を使えば、使い慣れたプログラミング言語でクラウドインフラを定義・管理できます。ぜひ実際のプロジェクトで活用してみてください。