1. Home
  2. DataAnalyticsInfrastructure
  3. TROCCO
  4. TROCCO 構成を Terraform で管理する

TROCCO 構成を Terraform で管理する

  • 公開日
  • カテゴリ:TROCCO
  • タグ:TROCCO
TROCCO 構成を Terraform で管理する

TROCCO の設定を Terraform でコード管理してみました。

GUI での設定操作も便利ですが、環境が増えると差分の把握や再現が難しくなります。Terraform を使えば、設定をコードとして管理し、レビューや環境の再構築も簡単に行えます。

今回は、ラベル・データマート・ワークフローといった TROCCO の構成を Terraform 化してみます。

contents

  1. プロジェクトのセットアップ
    1. 01. Provider 定義ファイルを作成
    2. 02. TROCCO API キーを発行する
    3. 03. 環境変数を設定する
    4. 04. Terraform を初期化する
  2. ラベルを作成する
  3. データマート定義を作成する
    1. 01. モジュール追加と変数の設定
    2. 02. 基本的な定義
    3. 03. 複雑な SQL を外部ファイルに分離
    4. 出力定義
  4. ワークフローを作成する
    1. 01. モジュール追加と変数の設定
    2. 02. ワークフロー定義を作成する
    3. 03. plan / apply の実行
    4. 補足:並列実行の仕組み

プロジェクトのセットアップ

01. Provider 定義ファイルを作成

まずは TROCCO Provider を利用できるようにします。

Terraform のバージョンと provider の情報を定義するファイルを2つ作成します。

versions.tf

terraform {
  required_version = ">= 1.13.0"

  required_providers {
    trocco = {
      source  = "trocco-io/trocco"
      version = "~> 0.20"
    }
  }
}

provider.tf

provider "trocco" {}

02. TROCCO API キーを発行する

TROCCO の管理画面から API キーを発行します。

メニューの「チーム管理」→「APIキー」から新しいキーを作成してください。

03. 環境変数を設定する

Terraform から TROCCO にアクセスするため、API キーを環境変数に設定します。

.envrc ファイルを作成

# .envrc
export TROCCO_API_KEY="YOUR_TROCCO_API_KEY"

direnv を使ってロードします。

direnv allow .

.envrc には秘密情報を含むため、.gitignore に追記しておきます。

# .gitignore
.envrc
.direnv/
.terraform/
terraform.tfstate
terraform.tfstate.backup

04. Terraform を初期化する

準備ができたら初期化コマンドを実行します。

terraform init

これで TROCCO Provider がインストールされ、準備完了です。

ラベルを作成する

TROCCO では、ジョブやデータマートにラベルを付けて整理できます。

まずは modules/labels を作り、3つのラベルを定義します。

# modules/labels/main.tf
resource "trocco_label" "label_a" {
  name        = "ラベルA"
  description = "ラベルAの説明"
  color       = "#FF6B6B"
}

resource "trocco_label" "label_b" {
  name        = "ラベルB"
  description = "ラベルBの説明"
  color       = "#4ECDC4"
}

resource "trocco_label" "label_c" {
  name        = "ラベルC"
  description = "ラベルCの説明"
  color       = "#95E1D3"
}

作成したラベルを他のモジュールで参照できるよう、outputs も定義します。

# modules/labels/outputs.tf
output "label_a_name" {
  description = "Name of label A"
  value       = trocco_label.label_a.name
}
output "label_b_name" {
  description = "Name of label B"
  value       = trocco_label.label_b.name
}
output "label_c_name" {
  description = "Name of label C"
  value       = trocco_label.label_c.name
}

モジュール内で使用する Provider の指定を行います。これにより、モジュール単体でも Terraform 実行が可能になります。

# modules/labels/versions.tf
terraform {
  required_providers {
    trocco = {
      source = "trocco-io/trocco"
    }
  }
}

作成したラベルモジュールをルート main.tf から呼び出します。

# main.tf
# ラベル定義モジュールを読み込み、Terraform 管理下に追加する
module "labels" {
  source = "./modules/labels"
}

このモジュールの出力値(label_a_name など)は、後でデータマートやワークフロー定義に渡して使います。

plan で反映内容を確認し、apply で TROCCO に反映します。

# 実行内容確認
terraform plan

# TROCCO に反映
terraform apply

> Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

apply に成功すると、TROCCO にラベルが追加されたことを確認できました。

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

次に、BigQuery のデータマート定義を Terraform で管理してみます。

ここでは、TROCCO の BigQuery データマート定義(trocco_bigquery_datamart_definition をコード化します。

まずは、モジュールの準備と main.tf への追加から進めます。

01. モジュール追加と変数の設定

ラベル作成モジュールと同様に、データマート用のモジュールを作成します。

# main.tf
module "datamarts" {
  source                    = "./modules/datamarts"
  bigquery_connection_id    = # 接続情報のID 123456 etc
  write_disposition_default = "truncate"
  label_a_name              = module.labels.label_a_name
  label_b_name              = module.labels.label_b_name
  label_c_name              = module.labels.label_c_name
}

ここでは、BigQuery の接続情報(bigquery_connection_id)やラベルの参照を渡しています。

このように、main.tf からモジュールに値を渡すことで、環境ごとの設定差分を簡単に吸収できます。

変数定義ファイルを用意する

モジュール側では、受け取る値を variables.tf で定義します。

# modules/datamarts/variables.tf
variable "bigquery_connection_id" {
  type = number
}

# よく使う共通のデフォルト値(必要に応じて変更可)
variable "write_disposition_default" {
  type = string
}

# ラベル名を受け取る変数
variable "label_a_name" {
  type = string
}
variable "label_b_name" {
  type = string
}
variable "label_c_name" {
  type = string
}

これで main.tf → モジュール間の変数受け渡しができるようになります。

Provider の指定

モジュール単体で terraform planterraform validate を実行する場合に、Provider 情報が無いとエラーになるため、versions.tf にも指定しておきます。

# modules/datamarts/versions.tf
terraform {
  required_providers {
    trocco = {
      source = "trocco-io/trocco"
    }
  }
}

02. 基本的な定義

ここまで準備ができたら、データマート定義を実際に作成してみます。

以下は最もシンプルな構成です。

# modules/datamarts/example_datamart.tf
resource "trocco_bigquery_datamart_definition" "example_datamart" {
  name                     = "example_datamart"
  is_runnable_concurrently = false
  bigquery_connection_id   = var.bigquery_connection_id
  query                    = "SELECT 1 AS x"
  query_mode               = "insert"
  destination_dataset      = "test"
  destination_table        = "tf_example_min"
  write_disposition        = var.write_disposition_default
}

ここでは最小構成の SELECT 1 クエリを定義しています。

write_disposition には "truncate"(上書き)や "append"(追記)などを指定できます。

03. 複雑な SQL を外部ファイルに分離

SQL が長くても、ファイルとして外出しできるため、tf ファイルをシンプルに保てます。

# modules/datamarts/sample_ice_cream__item_gender_sales_ratio.tf
resource "trocco_bigquery_datamart_definition" "sample_ice_cream__item_gender_sales_ratio" {
  name                     = "sample_ice_cream__item_gender_sales_ratio_2"
  is_runnable_concurrently = false
  bigquery_connection_id   = var.bigquery_connection_id
  query_mode               = "insert"
  destination_dataset      = "sample_ice_cream"
  destination_table        = "item_gender_sales_ratio_2"
  write_disposition        = var.write_disposition_default
  query                    = file("${path.module}/queries/item_gender_sales_ratio.sql")

  labels = [
    { name = var.label_a_name },
    { name = var.label_b_name },
    { name = var.label_c_name },
  ]
}

SQL ファイルは次のように配置します。

modules/
  datamarts/
    queries/
      item_gender_sales_ratio.sql
-- modules/datamarts/queries/item_gender_sales_ratio.sql
WITH t1 AS (
    SELECT
        item_name,
        gender
    FROM `sample_ice_cream.ice_cream_sales` sales
             INNER JOIN `sample_ice_cream.members` members ON sales.member_id=members.id
    WHERE gender in ('男', '女')
)
   , t2 AS (
    SELECT
        item_name,
        SUM(CASE WHEN gender='男' THEN 1 ELSE 0 END) as male,
        SUM(CASE WHEN gender='女' THEN 1 ELSE 0 END) as female
    FROM t1
    GROUP BY item_name
)
SELECT
    item_name,
    male + female as total_sales,
    ROUND(male / (male + female), 2) as male_ratio,
    ROUND(female / (male + female), 2) as female_ratio,
FROM t2;

このようにすると Terraform で SQL ファイルを読み込み、TROCCO に反映されます。

出力定義

他モジュール(ワークフロー)で参照できるよう、ID を出力します。

# modules/datamarts/outputs.tf
output "sample_ice_cream_datamart_id" {
  description = "ID of sample_ice_cream__item_gender_sales_ratio datamart definition"
  value       = trocco_bigquery_datamart_definition.sample_ice_cream__item_gender_sales_ratio.id
}

output "example_datamart_datamart_id" {
  description = "ID of example_datamart datamart definition"
  value       = trocco_bigquery_datamart_definition.example_datamart.id
}

plan と apply を実行して反映させます。

terraform plan
terraform apply

Terraform がデータマート定義を作成し、TROCCO の画面上で確認できるようになります。

ワークフローを作成する

最後に、TROCCO 上のデータマートを実行する「ワークフロー(パイプライン)」を作成してみます。

ワークフローは複数のデータマートをまとめて実行したり、スケジュールを設定したりできる機能です。Terraform では trocco_pipeline_definition リソースを使って定義します。

01. モジュール追加と変数の設定

まずは main.tf にワークフローモジュールを追加します。

# main.tf
module "workflows" {
  source                       = "./modules/workflows"
  sample_ice_cream_datamart_id = module.datamarts.sample_ice_cream_datamart_id
  example_datamart_datamart_id  = module.datamarts.example_datamart_datamart_id
  label_a_name                 = module.labels.label_a_name
  label_b_name                 = module.labels.label_b_name
  label_c_name                 = module.labels.label_c_name
}

ここでは、前章で作成したデータマートの ID と、ラベルモジュールの出力値を参照しています。これにより、ワークフロー定義でそれらを再利用できるようになります。

変数定義ファイルを用意する

モジュール内で受け取る値を variables.tf に定義します。

# modules/workflows/variables.tf
variable "sample_ice_cream_datamart_id" {
  description = "ID of sample_ice_cream__item_gender_sales_ratio datamart definition"
  type        = number
}

variable "example_datamart_datamart_id" {
  description = "ID of example_datamart datamart definition"
  type        = number
}

# ラベル名を受け取る変数
variable "label_a_name" {
  type = string
}
variable "label_b_name" {
  type = string
}
variable "label_c_name" {
  type = string
}

これで、データマートとラベルの情報をワークフローモジュール内で参照できるようになります。

Provider の指定

モジュール単体でも Terraform が動作できるよう、Provider 情報を記述します。

# modules/workflows/versions.tf
terraform {
  required_providers {
    trocco = {
      source = "trocco-io/trocco"
    }
  }
}

02. ワークフロー定義を作成する

続いて、実際のワークフローリソースを定義します。

# modules/workflows/example_workflow.tf
resource "trocco_pipeline_definition" "example_workflow" {
  name        = "example_workflow"
  description = "Sample workflow executing two datamarts in parallel"

  # 並列実行設定
  max_task_parallelism = 2
  is_stopped_on_errors = true

  # スケジュール設定(毎日 09:00 JST)
  schedules = [
    {
      frequency = "daily"
      hour      = 9
      minute    = 0
      time_zone = "Asia/Tokyo"
    }
  ]

  # タスク定義
  tasks = [
    {
      key  = "sample_ice_cream__item_gender_sales_ratio"
      type = "trocco_bigquery_datamart"
      trocco_bigquery_datamart_config = {
        definition_id = var.sample_ice_cream_datamart_id
      }
    },
    {
      key  = "example_datamart"
      type = "trocco_bigquery_datamart"
      trocco_bigquery_datamart_config = {
        definition_id = var.example_datamart_datamart_id
      }
    }
  ]

  # ラベル設定
  labels = [
    { name = var.label_a_name },
    { name = var.label_b_name },
    { name = var.label_c_name },
  ]
}

この設定では、2つのデータマートを並列実行するワークフローを作成しています。スケジュール設定により、毎日 9:00 に自動で実行されます。

03. plan / apply の実行

ここまで準備ができたら、Terraform を実行して TROCCO に反映します。

terraform plan
terraform apply

apply が完了すると、TROCCO の管理画面上に「example_workflow」が表示されます。

補足:並列実行の仕組み

この例では max_task_parallelism = 2 としており、2つのデータマートタスクを 依存関係なしで同時実行 する設定になっています。

もしタスクの依存順序を制御したい場合は、
task_dependencies パラメータを使用して明示的に順序を指定できます。

# 例:タスクBをタスクAの後に実行
task_dependencies = [
  { before = "sample_ice_cream__item_gender_sales_ratio", after = "example_datamart" }
]

このようにワークフローをコードで管理することで、TROCCO の実行パイプラインを再現性高く構築・更新できるようになります。

まとめ

今回は、Terraform による TROCCO の設定をコード管理を試してみました。

結果として、ラベル・データマート・ワークフローといった構成要素をコードから定義・更新できることが確認できました。

Terraform のモジュール構成をうまく切り分ければ、TROCCO の運用設定もインフラ構成管理の一部として扱えそうです。

データパイプラインの構成をコードとして git 管理し、差分を追ったりレビューできるのも安心感があります。

興味があればぜひ試してみてください。

Author

rito

  • Backend Engineer
  • Tokyo, Japan
  • PHP 5 技術者認定上級試験 認定者
  • 統計検定 3 級