created: 2023-09-06T01:58:23.263Z

GCP のリソースを cdktf で管理しようとしてみる

ツールのインストール

$ npm install -g cdktf-cli
$ cdktf --version
0.18.0
$ asdf install terraform latest
# latestで1.5.6が入った
$ echo 'terraform 1.5.6' > .tool-versions
$ terraform --version
Terraform v1.5.6
on darwin_arm64

cdktf init

空っぽのディレクトリで実行する必要がある。

$ cdktf init --template=typescript

こんなファイルが生成される。

$ ll
drwxr-xr-x user staff 512 B  Wed Sep  6 09:23:05 2023  .
drwxr-xr-x user staff 288 B  Wed Sep  6 09:18:08 2023  ..
.rw-r--r-- user staff 129 B  Wed Sep  6 09:19:47 2023  .gitignore
.rw-r--r-- user staff  18 B  Wed Sep  6 09:19:47 2023  .npmrc
.rw-r--r-- user staff  16 B  Wed Sep  6 09:18:28 2023  .tool-versions
.rw-r--r-- user staff 223 B  Wed Sep  6 09:19:47 2023  cdktf.json
.rw-r--r-- user staff  53 B  Wed Sep  6 09:22:34 2023  default.code-workspace
.rw-r--r-- user staff 1.9 KB Wed Sep  6 09:19:47 2023  help
.rw-r--r-- user staff 6.4 KB Wed Sep  6 09:23:53 2023  jest.config.js
.rw-r--r-- user staff 2.7 KB Wed Sep  6 09:23:17 2023  main.test.ts
.rw-r--r-- user staff 343 B  Wed Sep  6 09:26:47 2023  main.ts
drwxr-xr-x user staff 6.8 KB Wed Sep  6 09:25:56 2023  node_modules
.rw-r--r-- user staff 279 KB Wed Sep  6 09:26:00 2023  package-lock.json
.rw-r--r-- user staff 787 B  Wed Sep  6 09:26:00 2023  package.json
.rw-r--r-- user staff  59 B  Wed Sep  6 09:19:47 2023  setup.js
.rw-r--r-- user staff 761 B  Wed Sep  6 09:19:47 2023  tsconfig.json

今回は GCP のリソースを管理する積り。

$ npm install @cdktf/provider-google

.gitignore は gibo を使って生成する。

$ echo '!.tool-versions' >> .gitignore
$ gibo dump Terraform >> .gitignore
$ gibo dump Node >> .gitignore

cdktf.json

プロバイダーを追加

diff --git a/terraform/cdktf/cdktf.json b/terraform/cdktf/cdktf.json
index 255924c..5dba582 100644
--- a/terraform/cdktf/cdktf.json
+++ b/terraform/cdktf/cdktf.json
@@ -3,7 +3,7 @@
   "app": "npx ts-node main.ts",
   "projectId": "33b4527a-5545-411f-bbda-6fe03a5a0ec2",
   "sendCrashReports": "true",
-  "terraformProviders": [],
+  "terraformProviders": ["hashicorp/google"],
   "terraformModules": [],
   "context": {
 

npm run get

npm run get を実行して、必要なファイルをダウンロードしてくる必要がある。

$ cat help | grep 'npm run get' npm run get Import/update Terraform providers and modules (you should check-in this directory)

.gen というディレクトリに色々ダウンロードされる。you should check-in this directory とあるが、かなりファイルの数があるのでけっこう嫌である。REAEMD.md とかコミットしたくないけれども。

$ tree .gen/ | tail
│       │   └── index.ts
│       ├── vpc-access-connector
│       │   ├── README.md
│       │   └── index.ts
│       └── workflows-workflow
│           ├── README.md
│           └── index.ts
└── versions.json

907 directories, 1814 files

実装

cdktf init の時点で main.ts がセットアップされている。 先ほど生成した .gen 配下から use して実装する。

import { Construct } from "constructs";
import { App, TerraformStack, GcsBackend } from "cdktf";
import { provider } from "@cdktf/provider-google"
import { LoggingMetric } from "./.gen/providers/google/logging-metric"

class MyStack extends TerraformStack {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    new GcsBackend(this, {
      bucket: "mcsk-cdk-tfstate",
      prefix: "prod",
    });

    new provider.GoogleProvider(this, "cdktf-google", {
      region: process.env["GCP_DEFAULT_REGION"],
      project: process.env["GCP_PROJECT_ID"],
    });

    new LoggingMetric(this, "sample-metrics", {
      ...
    })

    // define resources here
  }
}

const app = new App();
new MyStack(app, "cdktf");
app.synth();

中止

このあたりで cdktf の試用を中止。そんなに複雑なことをしないのであれば、まだ HCL を普通に書く方が楽そうである。 テストが書けるのはとてもよさそうなので、5年後くらいに大規模なインフラを構築することがあれば使ってみたい。

枯れていない

まだAPIや環境構築手順が安定していないかもしれない。去年の記事だと今とは手順や実装がけっこう違ったので参考情報を探す時には時期に気をつけた方がよさそうだった。

公式のリポジトリにサンプルコードが載っているのでこれを読むのがよさそうではある。

公式ドキュメントもまだそこまで痒いところに手が届く感じでもないが、これが頼みの綱。

アプリケーションコードで使うライブラリなら多少枯れてなくても問題ないのだが、SaaSやクラウドプロバイダのリソースを預けるライブラリが非互換な変更をたくさんしてくるとくたびれてしまいそうである。

ちなみに 2018年に aws-cdk を触った時も同様に「枯れてないなぁ」ということで試用でとめていた。cdk ってなんかモダンな印象だけどあれはもう5年前ですか。

リソースに毎度 this を渡すところとか、クラスを new するけどオブジェクトは使わないことが多いのとか、当時は驚いてたけどそのうちそういうのなくなるのかなと思ってたけど、そのへんのアレはそのままだった。

その他

cdktf が asdf が渡す terraform のパスを見ていないようで、こんなエラーになった。

$ cat .tool-versions
terraform 1.5.6
$ npm run get

> cdktf@1.0.0 get
> cdktf get

⠹ downloading and generating modules and providers...
No version is set for command terraform
Consider adding one of the following versions in your config file at
Error: non-zero exit code 126
    at ChildProcess.<anonymous> (/Users/sakamossan/.nodebrew/node/v18.13.0/lib/node_modules/cdktf-cli/bundle/bin/cmds/handlers.js:45:2141)
    at Object.onceWrapper (node:events:628:26)
    at ChildProcess.emit (node:events:513:28)
    at ChildProcess.emit (node:domain:489:12)
    at maybeClose (node:internal/child_process:1091:16)
    at ChildProcess._handle.onexit (node:internal/child_process:302:5) {
  stderr: 'No version is set for command terraform\n' +
    'Consider adding one of the following versions in your config file at \n' +
    'terraform 1.5.6\n'
}
⠹ downloading and generating modules and providers...
Error: non-zero exit code 126

原因はしらべていないが .envrc に以下の定義をしてパスを通してみた。

source_up
PATH_add ~/.asdf/installs/terraform/1.5.6/bin

ruby だと issue になっていたようだが、terraform もツール越しに触ろうとするとダメなことがあるようだ。

失敗から学ぶユーザインタフェース 世界はBADUI(バッド・ユーアイ)であふれている
[ad] 失敗から学ぶユーザインタフェース 世界はBADUI(バッド・ユーアイ)であふれている
中村 聡史 (大型本)