地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【CDKTF】触ってみる

github.com

terraform-cdkとは

CDK for Terraform (CDKTF)を使えば、TypeScript、PythonJavaC#、Goといった馴染みのあるプログラミング言語クラウドインフラを定義し、Terraformを通じてプロビジョニングできます。これにより、HCLを学ぶ必要がなく、Terraformエコシステムを活用しながら既存のツールチェーン(テスト、依存管理など)の強みを生かせます。

対応しているProviders

github.com

AWSGoogle Cloudはもちろんその他にも結構対応している。

Usage

% cdktf --help
cdktf

コマンド:
  cdktf init                Create a new cdktf project from a template.
  cdktf get                 Generate CDK Constructs for Terraform providers and modules.
  cdktf convert             Converts a single file of HCL configuration to CDK for Terraform. Takes the file to be converted on stdin.
  cdktf deploy [stacks...]  Deploy the given stacks                                                                                                                   [エイリアス: apply]
  cdktf destroy [stacks..]  Destroy the given stacks
  cdktf diff [stack]        Perform a diff (terraform plan) for the given stack                                                                                        [エイリアス: plan]
  cdktf list                List stacks in app.
  cdktf login               Retrieves an API token to connect to Terraform Cloud or Terraform Enterprise.
  cdktf synth               Synthesizes Terraform code for the given app in a directory.                                                                         [エイリアス: synthesize]
  cdktf watch [stacks..]    [experimental] Watch for file changes and automatically trigger a deploy
  cdktf output [stacks..]   Prints the output of stacks                                                                                                             [エイリアス: outputs]
  cdktf debug               Get debug information about the current project and environment
  cdktf provider            A set of subcommands that facilitates provider management
  cdktf completion          generate completion script

initしてdeployすれば動く。個人的に便利だなと思ったのはconvert。以下のようなHCLがあるときに

provider "aws" {
  region = "us-east-1"
}

variable "read_replicas" {
  description = "List of read replica configurations"
  type        = map(object({
    instance_class = string
    engine         = string
  }))
  default = {
    replica1 = {
      instance_class = "db.t3.micro"
      engine         = "mysql"
    }
    replica2 = {
      instance_class = "db.t3.micro"
      engine         = "mysql"
    }
  }
}

resource "aws_db_instance" "primary" {
  identifier          = "primary-db"
  allocated_storage   = 20
  engine              = "mysql"
  engine_version      = "8.0"
  instance_class      = "db.t3.micro"
  username            = "admin"
  password            = "password"
  parameter_group_name = "default.mysql8.0"
  skip_final_snapshot = true
}

resource "aws_db_instance" "read_replica" {
  for_each            = var.read_replicas
  identifier          = "read-replica-${each.key}"
  instance_class      = each.value.instance_class
  engine              = each.value.engine
  source_db_instance_identifier = aws_db_instance.primary.id
}

convertを打つと以下のようなTypeScriptが生成される。

import { Construct } from "constructs";
import {
  VariableType,
  TerraformVariable,
  Token,
  TerraformIterator,
  Fn,
} from "cdktf";
/*
 * Provider bindings are generated by running `cdktf get`.
 * See https://cdk.tf/provider-generation for more details.
 */
import { DbInstance } from "./.gen/providers/aws/db-instance";
import { AwsProvider } from "./.gen/providers/aws/provider";
class MyConvertedCode extends Construct {
  constructor(scope: Construct, name: string) {
    super(scope, name);
    /*The following providers are missing schema information and might need manual adjustments to synthesize correctly: aws.
    For a more precise conversion please use the --provider flag in convert.*/
    /*Terraform Variables are not always the best fit for getting inputs in the context of Terraform CDK.
    You can read more about this at https://cdk.tf/variables*/
    new AwsProvider(this, "aws", {
      region: "us-east-1",
    });
    const readReplicas = new TerraformVariable(this, "read_replicas", {
      default: [
        {
          replica1: [
            {
              engine: "mysql",
              instance_class: "db.t3.micro",
            },
          ],
          replica2: [
            {
              engine: "mysql",
              instance_class: "db.t3.micro",
            },
          ],
        },
      ],
      description: "List of read replica configurations",
      type: VariableType.map(
        VariableType.object({
          engine: VariableType.STRING,
          instance_class: VariableType.STRING,
        })
      ),
    });
    const primary = new DbInstance(this, "primary", {
      allocated_storage: 20,
      engine: "mysql",
      engine_version: "8.0",
      identifier: "primary-db",
      instance_class: "db.t3.micro",
      parameter_group_name: "default.mysql8.0",
      password: "password",
      skip_final_snapshot: true,
      username: "admin",
    });
    /*In most cases loops should be handled in the programming language context and
    not inside of the Terraform context. If you are looping over something external, e.g. a variable or a file input
    you should consider using a for loop. If you are looping over something only known to Terraform, e.g. a result of a data source
    you need to keep this like it is.*/
    const readReplicaForEachIterator = TerraformIterator.fromList(
      Token.asAny(readReplicas.value)
    );
    new DbInstance(this, "read_replica", {
      engine: Fn.lookupNested(readReplicaForEachIterator.value, ["engine"]),
      identifier: "read-replica-${" + readReplicaForEachIterator.key + "}",
      instance_class: Fn.lookupNested(readReplicaForEachIterator.value, [
        "instance_class",
      ]),
      source_db_instance_identifier: primary.id,
      forEach: readReplicaForEachIterator,
    });
  }
}

感想

Terraformだけで済むならTerraformだけで済ませたいが動的にインフラをプロビジョニングしたいケースとかが出てくると確かに便利そうだなと思った。例えば開発者環境だったりホスティングサービスの会社とかだと結構便利に使えそう。そうじゃない場合はおそらく使うケースってあまりないかなぁと思った。IDEによる補完みたいなメリットはありそうだけど保守する際に開発者ごとに書き味が違うコードが大量生産されると再利用性とかが低くなって大変とかそういうイメージ。

2024年を振り返る

2024年も色々あったので振り返ります。

ryuichi1208.hateblo.jp

目次

仕事

転職した

楽しくやっています。

ryuichi1208.hateblo.jp

ryuichi1208.hateblo.jp

登壇記録

プロポーザル通す必要があるカンファレンスは5本登壇していた(YAPC、CNDT、Tech Ramen、ya8、CODT)。全体での登壇自体は13回。

speakerdeck.com

EOL対応にフォーカスした資料は13,000 viewを超えてるっぽくて嬉しいがどこに需要があるのかは不明w

入門EOL対応 - Speaker Deck

基調講演という枠で登壇依頼が来たのは初めてで良い経験となった。

ryuichi1208.hateblo.jp

技術書典で本を出した

MySQL 8.0の推し機能について書いてます。今の仕事では触ってないけどデータベースは好きなので触っていこうと思います。来年も何かしら書きたい。

techbookfest.org

技術色々入門してる

ECS、PythonPostgreSQL、DynamoDBなどなど触ったことない技術で構成されているサービスだったので楽しくやっています。ドメインも全く違って電話に向き合っています。

11月の転職直後あたりからの草の生え具合が面白い。(ペパボの時はGHESで働いていたのでサボっていたわけではないですw)

SRE NEXTでCo-Chairになった

やります。7月なので予定を空けておいてください!Road to SRE NEXTも2月に京都であるのでぜひ予定合う方来てください!

ブログを書いた

今年は165本書きました。来年もこのくらいのペースで短い記事から長文まで書いていきたいと思います。

12月からGoogleアナリティクスを始めてみました。大体月に2~3万くらいのViewはあるって感じっぽいです。

技術書を読んだ

ここからなので75冊読みました。

個人的に一番良かったなぁと思ったのはこの一冊です。シニアエンジニアという肩書きは今の会社だとないのですが自分が目指すべき方向はこちらだと強く思っています。

私生活

結婚した

ryuichi1208.hateblo.jp

遠い昔のように感じるのですが今年の5/1でした。長いこと同棲をしてたので特に何か変わるということもなく平和に過ごしています。

旅行

今年はたくさん行きました。一番良かったのはベタですが沖縄が段違いで良かったです。2025年も行きたいと思います。

  • 北海道 * 3
  • 東北各県 * いっぱい
  • 新潟 * 1
  • 栃木 * 1
  • 茨城 * 1
  • 東京 * いっぱい
  • 京都 * 1
  • 広島 * 2
  • 福岡 * 1
  • 沖縄 * 1

ryuichi1208.hateblo.jp

ryuichi1208.hateblo.jp

ベッド買った

ふらっと寄ったお店で良かったのでベッドを買った。30万円の衝動買いは多分最高価格のはず。

ryuichi1208.hateblo.jp

最後に

2025年もやっていきます。

過去の振り返り

【iTerm2】帰ってきた

ryuichi1208.hateblo.jp

という記事を書いて3日くらい使ってみた。画面綺麗だし設定もシンプルで良かったです。ただキーバインドzshとかtmuxとかに最適化してる中でGhosttyに撮られるのが慣れなくて専用の設定を書く必要が出てきて「あれ、iTerm2で良いのでは?」と思ったので戻ってきた。iTerm2は新卒から使っている非常に付き合いの長いツールでやはり長年連れ添ったツールの方が良いなぁとなって戻した。iTerm2はいいです。はい。

【Ghostty】使ってみた

www.publickey1.jp

この記事で楽しみにしていたやつの1.0がリリースされた。10月くらいから使えることは使えたらしいが1.0が出るのを待っていたので早速入れてみました。

github.com

最小の設定で使えて便利です。現在の設定は↓のようになっています。

github.com