CDK for TerraformをCIに組み込む実践手順|TypeScriptでインフラ定義する流れ

運営:リナックスマスター.JP(代表 宮崎智広)
HOME > Linux技術 リナックスマスター.JP(Linuxマスター.JP) > Terraform > CDK for TerraformをCIに組み込む実践手順|TypeScriptでインフラ定義する流れ
「CDK for Terraformって概念はわかったが、実際のCIにどう組み込むのか分からない」「TypeScriptでインフラを書けると聞いたが、既存のHCL資産とどう共存させるか迷っている」
こうした疑問は、CDKTFを調べ始めたエンジニアが必ず直面する壁です。公式ドキュメントは基本的な使い方を説明していますが、GitHub ActionsへのCI組み込みやHCLとの設計使い分けまで踏み込んだ情報が少なく、導入検討が止まるケースが典型的です。

この記事では、Node.js 18以降・cdktf-cli 0.20系を想定環境として、CDK for Terraform(CDKTF)の仕組みから始め、TypeScriptによるAWSリソース定義、GitHub ActionsへのCI組み込み、HCLとの使い分け判断まで解説します。

この記事のポイント

・cdktf synthでTerraform JSONへ変換できる
・cdktf deployでCI/CDから自動適用が可能
・ロジックが複雑な構成にCDKTFは向く
・GitHub ActionsはNode.js+cdktf-cliで動く


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

CDK for Terraform(CDKTF)とは何か

CDK for Terraform(CDKTF)は、HashiCorpとAWSが共同開発したオープンソースのフレームワークです。TypeScript・Python・Go・Javaなどのプログラミング言語からTerraformの設定ファイル(JSON形式)を生成します。AWS CDKがCloudFormationのテンプレートを出力するのと同じ仕組みで、出力先がTerraform JSONになっています。

通常のTerraformはHCL(HashiCorp Configuration Language)で記述しますが、CDKTFを使うとTypeScriptのクラスとしてリソースを定義できます。ループ・条件分岐・型チェックがそのまま利用でき、数十台以上のサーバー設定を繰り返し記述する手間がなくなります。

CDKTFの動作の流れ

・TypeScript(またはPython/Go等)でリソースを定義する
・cdktf synth コマンドでTerraform JSON(cdktf.out/配下)を生成する
・生成されたJSONを terraform apply またはcdktf deployで適用する

CDKTFは「コード→Terraform JSON変換器」であり、Terraform自体のステート管理・プロバイダーエコシステムはそのまま活用できます。既存のtfstateやS3バックエンドとも互換があります。

TypeScriptでAWSリソースを定義する基本手順

1. cdktf-cliのインストールとプロジェクト初期化

まずNode.js 18以降がインストールされていることを確認します。

# Node.jsバージョン確認 node -v # 出力例(環境により異なります) # v20.17.0 # cdktf-cliをグローバルインストール npm install -g cdktf-cli@latest # バージョン確認 cdktf --version # 0.20.x

インストール後、新規プロジェクトを初期化します。--local フラグで初期状態はローカルバックエンドを使用します。

# TypeScriptテンプレートでプロジェクトを初期化(ローカルバックエンド) cdktf init --template=typescript --local # ディレクトリ構成(出力例、環境により異なります) # . # ├── cdktf.json ← プロバイダーとスタック設定 # ├── main.ts ← リソース定義の主ファイル # ├── package.json # └── tsconfig.json

cdktf.json にAWSプロバイダーを追記します。

{ "language": "typescript", "app": "npx ts-node main.ts", "terraformProviders": [ "aws@~> 5.0" ], "terraformModules": [] }

プロバイダーを追記したら cdktf get でTypeScript用のバインディングを生成します。

# プロバイダーバインディングを生成(初回は数分かかります) cdktf get # 生成後の確認(出力例、環境により異なります) ls .gen/providers/aws/ # instance/ provider/ s3-bucket/ vpc/ ...

2. TypeScriptでEC2インスタンスを定義する

.gen/ 配下の型定義を使って main.ts を編集します。

// main.ts import { App, TerraformStack, TerraformOutput } from "cdktf"; import { AwsProvider } from "./.gen/providers/aws/provider"; import { Instance } from "./.gen/providers/aws/instance"; class MyStack extends TerraformStack { constructor(scope: App, id: string) { super(scope, id); // AWSプロバイダーの設定 new AwsProvider(this, "aws", { region: "ap-northeast-1", }); // EC2インスタンスの定義 const instance = new Instance(this, "web-server", { ami: "ami-0d52744d6551d851e", // Amazon Linux 2023 instanceType: "t3.micro", tags: { Name: "cdktf-web-server", Env: "dev", }, }); // outputでパブリックIPを出力 new TerraformOutput(this, "public_ip", { value: instance.publicIp, }); } } const app = new App(); new MyStack(app, "my-stack"); app.synth();

HCLと比較すると、forEach や map がそのまま使える点がCDKTFの強みです。同じ設定の複数台サーバーを作成する場合、HCLでは count や for_each の独自構文を覚える必要がありますが、CDKTFではTypeScriptの配列操作をそのまま利用できます。

3. cdktf synthでTerraform JSONに変換する

# TypeScriptをコンパイルしてTerraform JSONを生成 cdktf synth # 生成されたファイルを確認(出力例、環境により異なります) ls cdktf.out/stacks/my-stack/ # cdk.tf.json # 中身の確認(プレーンなTerraform JSONフォーマット) cat cdktf.out/stacks/my-stack/cdk.tf.json | python3 -m json.tool | head -20

生成された cdk.tf.json は標準的なTerraform JSONフォーマットです。terraform -chdir=cdktf.out/stacks/my-stack plan で内容を確認できます。cdktf deploy コマンドはsynth→applyを1ステップで実行します。

CDKTFをGitHub ActionsのCIに組み込む実践

CDKTFをCI/CDに組み込む際の基本方針は「synthまでをCI側で実行し、生成されたJSONをTerraformのapplyパイプラインに渡す」です。これにより、既存のTerraform CI(tflint・planレビュー・ポリシーチェックなど)をそのまま流用できます。

1. ワークフローファイルの基本構成

# .github/workflows/cdktf.yml name: CDKTF CI on: pull_request: branches: [main] push: branches: [main] jobs: cdktf-plan: name: CDKTF Synth and Terraform Plan runs-on: ubuntu-latest permissions: contents: read id-token: write # OIDC認証用 pull-requests: write # PRコメント書き込み用 steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20" cache: "npm" - name: Install cdktf-cli and dependencies run: | npm install -g cdktf-cli@latest npm ci - name: Generate provider bindings run: cdktf get - name: CDKTF Synth run: cdktf synth - name: Setup Terraform uses: hashicorp/setup-terraform@v3 with: terraform_version: "1.9.x" - name: Terraform Init and Plan working-directory: cdktf.out/stacks/my-stack run: | terraform init terraform plan -out=tfplan

2. PRにplanの差分をコメントする

PR上でplan結果を確認できるようにすると、レビュアーがインフラ変更の影響を把握しやすくなります。

# (cdktf-planジョブのstepsに追加) - name: Terraform Plan Output id: plan working-directory: cdktf.out/stacks/my-stack run: | terraform show -no-color tfplan > plan_output.txt { echo "plan_output<> "$GITHUB_OUTPUT" - name: Comment PR with Plan Result if: github.event_name == 'pull_request' uses: actions/github-script@v7 with: script: | const plan = `${{ steps.plan.outputs.plan_output }}`; github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: `## Terraform Plan\n\`\`\`\n${plan}\n\`\`\`` });

3. mainブランチへのマージでapplyを実行する

applyはPRマージ後のpushイベントで実行します。GitHub Environments の承認フローを利用すると、担当者のOKが出るまでapplyジョブが待機します。

cdktf-apply: name: CDKTF Apply runs-on: ubuntu-latest needs: cdktf-plan if: github.ref == 'refs/heads/main' && github.event_name == 'push' environment: production # GitHub Environmentsで承認者を設定 steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: "20" cache: "npm" - name: Install, Synth run: | npm install -g cdktf-cli@latest npm ci cdktf get cdktf synth - name: Setup Terraform uses: hashicorp/setup-terraform@v3 with: terraform_version: "1.9.x" - name: Terraform Apply working-directory: cdktf.out/stacks/my-stack run: | terraform init terraform apply -auto-approve

environment: production を設定するとGitHub Environmentsの保護ルールが適用され、指定した承認者がOKを出すまでapplyジョブが待機します。コードレビュー+インフラapply承認の2段構えで変更を管理できます。

Terraformの基礎的なIaC設計を体系的に学ぶには、Terraform学習ガイド(terraform.linuxmaster.jp)も参考にしてください。

S3バックエンドでチーム共有のtfstateを管理する

cdktf init --local で作成したプロジェクトはtfstateがローカルに保存されるため、チーム開発には適しません。S3バックエンドへの切り替えは main.ts にバックエンド設定を追加するだけです。

// main.ts(S3バックエンド設定を追加) import { App, TerraformStack, S3Backend } from "cdktf"; import { AwsProvider } from "./.gen/providers/aws/provider"; class MyStack extends TerraformStack { constructor(scope: App, id: string) { super(scope, id); // S3バックエンドの設定(コード内で宣言) new S3Backend(this, { bucket: "my-tfstate-bucket", key: "cdktf/my-stack/terraform.tfstate", region: "ap-northeast-1", encrypt: true, dynamodbTable: "terraform-lock", // ステートロック用 }); new AwsProvider(this, "aws", { region: "ap-northeast-1" }); // ... リソース定義は変わらない } }

バックエンド設定を追加して cdktf synth を再実行すると、生成されたJSONにS3バックエンドの設定が含まれます。CIで terraform init を実行した際にS3から最新のtfstateが取得されるようになります。

HCL直書きのTerraformとCDKTFの使い分け基準

CDKTFがすべてのケースでHCLより優れているわけではありません。チームのスキルセットとコードの複雑さで判断するのが実務的な指針です。

判断軸 HCL(Terraform)が向く CDKTFが向く
チームスキル インフラエンジニア中心 アプリ開発者もインフラを書く
構成の複雑さ リソース数が少なくシンプル 条件分岐・ループが多い
型安全性 tflintで補完 TypeScriptの型システムで補完
既存資産 HCLモジュールが豊富 TypeScript・Python資産と共存したい
学習コスト HCL構文のみ覚えれば動く Node.js・npmのセットアップも必要
CDKTFは「プログラミング言語の強みをインフラ定義に持ち込む」ツールです。静的型チェックやIDEの補完が効くため、大規模な環境でのリファクタリングや、環境ごとに微妙に異なる設定を表現する際に強みを発揮します。一方、リソース数が20未満のシンプルな構成ではHCLの直書きが扱いやすいケースが多いです。

よくあるエラーと対処法

「cdktf get」でバインディング生成が遅い、または途中で止まる

CDKTFのプロバイダーバインディング生成はネットワークとディスクI/Oに依存します。初回生成は数分かかることがあります。CI環境では生成結果をキャッシュすることで時間を短縮できます。

# GitHub Actionsでのキャッシュ設定例 - name: Cache CDKTF provider bindings uses: actions/cache@v4 with: path: | node_modules/.gen .gen key: cdktf-${{ hashFiles('cdktf.json') }} restore-keys: | cdktf-

cdktf synthは成功するがterraform initでプロバイダーが見つからない

cdktf synth が成功しても、terraform init でTerraformプロバイダーのダウンロードが走ります。CI環境で毎回ダウンロードが発生して遅い場合は TF_PLUGIN_CACHE_DIR を設定するか、actions/cache で ~/.terraform.d/plugins をキャッシュしてください。

# Terraformプロバイダーのキャッシュを有効化 - name: Cache Terraform providers uses: actions/cache@v4 with: path: ~/.terraform.d/plugins key: terraform-providers-${{ hashFiles('**/.terraform.lock.hcl') }}

TypeScriptのコンパイルエラーで型が合わない

CDKTFのバインディングは厳格な型定義を持つため、HCLでは許容されていた曖昧な値の設定でもTypeScriptの型チェックで弾かれます。たとえばCPUコア数に数値型が期待される場所に文字列 "2" を渡すとコンパイルエラーになります。エラーメッセージが示す型定義(.gen/providers/ 配下の .d.ts ファイル)を確認し、型を合わせてください。

複数スタックを定義しているときのデプロイ指定

複数のStackを定義している場合、cdktf deploy はデプロイ対象を明示する必要があります。

# スタック名を明示してデプロイ cdktf deploy my-stack # 全スタックを依存関係の順にデプロイ cdktf deploy '*' # planのみ確認する場合 cdktf diff my-stack

本記事のまとめ

CDK for Terraform(CDKTF)の仕組みから実践まで解説しました。要点を整理します。

やりたいこと コマンド・設定
プロジェクト初期化 cdktf init --template=typescript --local
プロバイダーバインディング生成 cdktf get
Terraform JSONへ変換 cdktf synth
インフラ変更の確認 cdktf diff または terraform plan
インフラ適用 cdktf deploy または terraform apply
S3バックエンド設定 main.tsで S3Backend クラスを使用
CI/CDへの組み込み GitHub Actionsでsynth+terraform plan/apply
CDKTFは「TypeScriptの型安全性とTerraformのエコシステム」を両立させる選択肢です。チーム内にTypeScript経験者が多い場合や、環境差分の制御が複雑でHCLでは表現しにくい場合に導入を検討する価値があります。まずは開発環境だけをCDKTFで管理し、運用に慣れてから本番環境へ展開する段階的なアプローチが現実的です。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、TerraformやCDKTFを使ったIaC実務の学習コンテンツも用意しています。>>Terraform実践ガイドを確認する

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録

運営

リナックスマスター.JP(代表 宮崎智広)

株式会社イーネットマーキュリーが運営するLinux教育サイトです。代表の宮崎智広は現役のLinuxサーバー管理者として20年以上の実務経験を持ち、累計3,100名以上のエンジニアを指導してきました。実践型のLinuxセミナーや無料マニュアルの配布を通じてLinux人材の育成に取り組んでいます。