今日はなにの日。

気になったこと勉強になったことのメモ。

今日は、TerraformのCDKで無残に散った話の日。

目次

とある日

TerraformでCDKがあるのでそれを利用してDockerをいい感じにしたかったが、全然うまくいかなかった話。

はじめに

公式のチュートリアルを参考にしてもできそうになかったので諦めた話です。

WindowsでWSL2上にDockerを構築していて、それに対してTerraformを実行していました。

  • Terraform v1.0.3 on windows_amd64
  • go version go1.16.3 windows/amd64
  • Docker Engine - Community Engine: Version: 20.10.7

Terraformの構築の話は一切行いません。

CDK for Terraform

Terraform用のCDK(Cloud Development Kit)を使用すると、開発者は使い慣れたプログラミング言語を使用してクラウドインフラストラクチャを定義し、HashiCorpTerraformを介してプロビジョニングできます。

Go言語を、選択して開発を行いました。(できませんでしたが)

チュートリアル

やはり、触ったことのない技術はチュートリアルからやるのがいいので、はじめにチュートリアルを触りました。

チュートリアルは、TypeScriptのコードしかTerraformの公式ページでは見つからなかった。

GitHubで、調べるとGoのコードが出てきたのでそれで実験。

github.com

github.com

package main

import (
    "github.com/hashicorp/terraform-cdk/examples/go/docker/generated/kreuzwerker/docker"

    "github.com/aws/constructs-go/constructs/v3"
    "github.com/aws/jsii-runtime-go"
    "github.com/hashicorp/terraform-cdk-go/cdktf"
)

func NewExampleCdktfGoDockerStack(scope constructs.Construct, id string) cdktf.TerraformStack {
    stack := cdktf.NewTerraformStack(scope, &id)

    docker.NewDockerProvider(stack, jsii.String("provider"), &docker.DockerProviderConfig{})

    dockerImage := docker.NewImage(stack, jsii.String("nginxImage"), &docker.ImageConfig{
        Name:        jsii.String("nginx:latest"),
        KeepLocally: jsii.Bool(false),
    })

    docker.NewContainer(stack, jsii.String("nginxContainer"), &docker.ContainerConfig{
        Image: dockerImage.Latest(),
        Name:  jsii.String("tutorial"),
        Ports: &[]*docker.ContainerPorts{{
            Internal: jsii.Number(80), External: jsii.Number(8000),
        }},
    })

    return stack
}

func main() {
    app := cdktf.NewApp(nil)

    NewExampleCdktfGoDockerStack(app, "ExampleCdktfGoDockerStack")

    app.Synth()
}

チュートリアルにそって必要なパッケージやらはインストール済み。

なので、上記のコードを実行。

第一の関門 : うまくいかないimport

"github.com/hashicorp/terraform-cdk/examples/go/docker/generated/kreuzwerker/docker"

上記のパッケージがないとエラーが出力される。

試しに、GitHubで該当ファイルを探すとgenerated/kreuzwerker/dockerが無いことが判明する。

docker以下はGoのプログラムのソースしかない。

対処法

色々と試行錯誤した結果cdktf getを実行しました。

該当importは下記のように変更。

import (
    "cdk.tf/go/stack/generated/kreuzwerker/docker"
    "github.com/aws/constructs-go/constructs/v3"
    "github.com/aws/jsii-runtime-go"
    "github.com/hashicorp/terraform-cdk-go/cdktf"
)

cdktf getコマンドについて。

 cdktf get [OPTIONS]              Generate CDK Constructs for Terraform providers and modules.
 cdktf get [OPTIONS] TerraformプロバイダーおよびモジュールのCDKコンストラクトを生成します。

cdktf.jsonに則ってパッケージが作成される。

すると、うまくいかないimport問題は解決される。

ただ、importの先をたどってみても該当のものは見つからない。

ちょっと状況が読めない。

が、当初の問題は解決した。

しかしつぎなる関門が登場する。

第二の関門 : 消えるprovider.docker

第一の関門が無事解決できたので、cdktf synthコマンド実行して次に進もうとしたところ。

cdktf deployを実行すると下記のエラーが出力される。

⠧ planning hello-terraform...
╷
│ Error: Error initializing Docker client: protocol not available
│
│   with provider["registry.terraform.io/kreuzwerker/docker"],
│   on cdk.tf.json line 18, in provider.docker[0]:
│   18:       {}
│
⠇ planning hello-terraform...
non-zero exit code 1

cdk.tf.jsonのファイルを確認すると下記のようになっていました。

一部だけ抜粋しています。

  "provider": {
    "docker": [
      {}
    ]
  },

うん、なにもない。

エラーメッセージを見ても原因がわからない。

Getting Started with Goを見ても、何も書かれていない状態のためなにがだめなのかがわからない。

試しに、該当行に適当に文字列を入力してもcdktf deployを実行すると書き込んだ行が削除される。

2時間ぐらい試行錯誤したけど無理だったので諦めました。

公式のチュートリアルもまともに動かないのでTerraformでDockerをIaCをしようとしないほうがいいと思います。

自分のやり方が悪い可能性もありますが、如何せん情報がなさすぎて判断ができなかったです。

TerraformのDockerの記事自体が少な過ぎて、さらにエラーの原因が不明すぎて諦めました。

本来の目的は、Dockerをコード化すればよかったのでおとなしくDockerfileを書こうと思います。

初めての、Terraform冒険は無残に散りました。