TROCCO®のTerraform Provider（β版）ができたので最速で触ってみる

# はじめに

:::note
Terraformが使えるようになりました！！！（心の底からの叫び）
:::

TROCCO®はデータ基盤の総合支援SaaSとして提供されてきて、これまでその設定をコード管理したいという要望は何度もお伺いしてきました。Git連携の機能はあったものの、リソースを変更する機能はなく、上手くお応えできないことに申し訳なく思っていました。

しかし、ついに、待ちに待った、Terraform Provider（β版）がリリースされました！！！！！（大拍手）

https://x.com/kekekenta/status/1821851040888521179

嬉しすぎて泣きそうになってしまったので、最速で触ってみた記事を書くことにした次第です！！！！！


:::note warn

- Advancedプランから利用できる、TROCCO APIの利用が前提になります。
- 現時点ではBigQueryのデータマート定義のみに対応しています。
- β版ですので、今後仕様が変更になる可能性があります。
- 以下の記載はWindows環境のものになるので、Macの方は適宜読み替えてください。

:::


# 事前準備


## Terraformのインストール

Terraformをインストールし、PATHを通して実行可能にしておきます。

https://developer.hashicorp.com/terraform/install?product_intent=terraform


## TROCCO API KEYを発行する

TROCCO®にログインし、外部連携 > TROCCO API KEYからAPI KEYを発行しておきます。


# Terraform Providerを使ってみる

[TROCCO®のTerraform Provider](https://registry.terraform.io/providers/trocco-io/trocco/0.1.1)にアクセスします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/bcf3ee07-b409-62d8-e769-9455247a698d.png)

※Terraformの命名規則でtroccoが小文字になっています（笑）


## Terraformの初期設定をする

利用するディレクトリでmain.tfファイルを作成し、以下のファイルを作成します。

```terraform main.tf
terraform {
  required_providers {
    trocco = {
      source = "registry.terraform.io/trocco-io/trocco"
    }
  }
}

provider "trocco" {
  region  = "japan"
}
```

コマンドプロンプトを起動し、`set TROCCO_API_KEY={TROCCO_API_KEY}`で環境変数にTROCCO API KEYを設定します。

続いて、`terraform init`でTerraformを初期化します。

```
Initializing the backend...
Initializing provider plugins...
- Finding latest version of trocco-io/trocco...
- Installing trocco-io/trocco v0.1.1...
- Installed trocco-io/trocco v0.1.1 (self-signed, key ID 4AD358D3E1334E66)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
```

これで初期設定は完了です。

なお、VSCodeで作業をする場合、HashiCorp Terraformの拡張機能を入れておくと便利です。

https://marketplace.visualstudio.com/items?itemName=HashiCorp.terraform


## データマート定義を作成する

はじめに、[Documentation](https://registry.terraform.io/providers/trocco-io/trocco/latest/docs/resources/bigquery_datamart_definition)を参考に、データマート定義を作成してみましょう。

Example UsageにあるMinimumでリソースを作成しましょう。記載の値をコピーし、先ほどのmain.tfファイルに追記します。このとき、`bigquery_connection_id`は自身の環境で有効なものを利用します。接続情報の編集画面を開き、URLに表示されるものがIDになります。

```terraform main.tf
terraform {
  required_providers {
    trocco = {
      source = "registry.terraform.io/trocco-io/trocco"
    }
  }
}

provider "trocco" {
  region  = "japan"
}

resource "trocco_bigquery_datamart_definition" "minimum" {
  name                     = "example_minimum"
  is_runnable_concurrently = false
  bigquery_connection_id   = {BIGQUERY_CONNECTION_ID}
  query                    = "SELECT * FROM tables"
  query_mode               = "insert"
  destination_dataset      = "dist_datasets"
  destination_table        = "dist_tables"
  write_disposition        = "append"
}
```

保存して、`terraform apply`のコマンドを実行します。新しいリソースを作成するとなっている！！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/e13b6831-fd1a-17a4-8665-d420cc4c2bfa.png)

`yes`と記入してEnterを押すと・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/3ce003d1-a13a-4e0f-bf12-9b94c2299627.png)

できている！！！まじか！！！最高！！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/20b3bc21-4ef4-6ed1-af26-d05a0d9837b6.png)


## データマート定義を変更する

先ほどの設定情報を変更してみます。

```terraform main.tf
terraform {
  required_providers {
    trocco = {
      source = "registry.terraform.io/trocco-io/trocco"
    }
  }
}

provider "trocco" {
  region = "japan"
}

resource "trocco_bigquery_datamart_definition" "minimum" {
  name                     = "example_minimum_hoge" # _hogeを追記する
  is_runnable_concurrently = false
  bigquery_connection_id   = 919
  query                    = "SELECT * FROM tables WHERE fuga = null" # WHERE fuga = nullを追記する
  query_mode               = "insert"
  destination_dataset      = "dist_datasets"
  destination_table        = "dist_tables"
  write_disposition        = "truncate" # truncateに変更
}
```

`terraform apply`を実行します。

どこがどう変更されるよ、ということが表示されます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/2f3d9051-a6a0-918c-a82c-a0ce769345d5.png)

`yes`で実行されます！1 changedで変更されたのが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/0dcb57e8-9c05-c3ef-7da8-e71062057b20.png)

確かに変更されています！すごい。クエリまでキャプチャが届かなかったのはご愛嬌ということで（笑）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/360ea54a-9564-3799-9b37-f6a5fe7104c0.png)


## 既存のデータマート定義を取り込む

これは現時点でまとめてやる方法がないのですが、既存の1つの設定は一応こういう手順で取込できるよ、ということでご紹介です。

事前にGUIから設定を作成しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/9d2cd971-d996-7d3a-ff01-7cc6f11f5989.png)

合わせて、main.tfにリソース名のみを追加しておきます。

```terraform main.tf
terraform {
  required_providers {
    trocco = {
      source = "registry.terraform.io/trocco-io/trocco"
    }
  }
}

provider "trocco" {
  region = "japan"
}

resource "trocco_bigquery_datamart_definition" "minimum" {
  name                     = "example_minimum_hoge" # _hogeを追記する
  is_runnable_concurrently = false
  bigquery_connection_id   = {BIGQUERY_CONNECTION_ID}
  query                    = "SELECT * FROM tables WHERE fuga = null" # WHERE fuga = nullを追記する
  query_mode               = "insert"
  destination_dataset      = "dist_datasets"
  destination_table        = "dist_tables"
  write_disposition        = "truncate" # truncateに変更
}

# 取り込みたい設定用のリソースを追記する
resource "trocco_bigquery_datamart_definition" "import_test" {
}
```

取り込みたいデータマート定義のID（URLの末尾）をもとに、取り込むためのコマンドを実行します。

`terraform import "trocco_bigquery_datamart_definition.import_test" 47661`

main.tfに記載するために、`terraform state show "{リソースID}"`で取り込んだ情報を取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/02f18d61-4062-d4ce-ed18-040ea50b899a.png)

この設定情報をmain.tfに転記し、`terraform apply`を実行すると・・・read-onlyの値が入力されているよと怒られます（笑）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492462/afa62a7e-d640-a0db-2b7b-49fe08436e54.png)

これは、main.tfにあるのは設定したい情報で、terraform.tfstateの過去の適用時の情報を見ながら新規作成するのか更新するのかといった判断をするのに対して、tfファイル内にIDまで振られてしまっているからになります。

そこで、怒られたIDを削除して`terraform apply`して`yes`とすると、既存の設定をTerraformの管理下におけるようになります！！！


## データマート定義の削除

main.tfから追加した設定を除外し、再度`terraform apply`します。

```
trocco_bigquery_datamart_definition.minimum: Refreshing state... [name=example_minimum_hoge]
trocco_bigquery_datamart_definition.import_test: Refreshing state... [name=import_test]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # trocco_bigquery_datamart_definition.import_test will be destroyed
  # (because trocco_bigquery_datamart_definition.import_test is not in configuration)
  - resource "trocco_bigquery_datamart_definition" "import_test" {
      - bigquery_connection_id   = 919 -> null
      - destination_dataset      = "import" -> null
      - destination_table        = "dest_table" -> null
      - id                       = 47661 -> null
      - is_runnable_concurrently = false -> null
      - name                     = "import_test" -> null
      - query                    = <<-EOT
            SELECT
              *
            FROM
              import.ref_table
        EOT -> null
      - query_mode               = "insert" -> null
      - resource_group_id        = 1142 -> null
      - write_disposition        = "truncate" -> null
    }

Plan: 0 to add, 0 to change, 1 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

trocco_bigquery_datamart_definition.import_test: Destroying... [name=import_test]
trocco_bigquery_datamart_definition.import_test: Destruction complete after 0s

Apply complete! Resources: 0 added, 0 changed, 1 destroyed.
```

これでdestroyされ、Terraformで管理されていた設定が削除されました！


## 細かい設定もできるよ！！！

詳細は[Terraform Provider](trocco_bigquery_datamart_definition (Resource))に記載されていますが、細かい設定も利用することができます！！！

カスタム変数も設定できます！

```terraform
  custom_variable_settings = [
    {
      name  = "$string$",
      type  = "string",
      value = "foo",
    },
    {
      name      = "$timestamp$",
      type      = "timestamp",
      quantity  = 1,
      unit      = "hour",
      direction = "ago",
      format    = "%Y-%m-%d %H:%M:%S",
      time_zone = "Asia/Tokyo",
    }
  ]

```

スケジュールも設定できます！！！

```terraform
  schedules = [
    {
      frequency = "hourly"
      minute    = 0
      time_zone = "Asia/Tokyo"
    },
    {
      frequency = "daily"
      hour      = 0
      minute    = 0
      time_zone = "Asia/Tokyo"
    },
    {
      frequency   = "weekly"
      day_of_week = 0
      hour        = 0
      minute      = 0
      time_zone   = "Asia/Tokyo"
    },
    {
      frequency = "monthly"
      day       = 1
      hour      = 0
      minute    = 0
      time_zone = "Asia/Tokyo"
    }
  ]
```

通知設定もできます！！！

```terraform
  notifications = [
    {
      destination_type  = "slack"
      slack_channel_id  = 1
      notification_type = "job"
      notify_when       = "finished"
      message           = "@here Job finished."
    },
    {
      destination_type  = "email"
      email_id          = 1
      notification_type = "record"
      record_count      = 100
      record_operator   = "below"
      message           = "Record count is below 100."
    }
  ]
```

ラベルも設定できます！！！
```terraform
  labels = [
    {
      name = "test_label_1"
    },
    {
      name = "test_label_2"
    }
  ]
```


# さいごに

これでTROCCO®のデータマート定義について、作成／変更／新規取込／削除の処理ができました。まだできてほやほやのTerraform Providerではありますが、今後の発展が期待されます・・・！！