TROCCO を Terraform で構築してみた

AWS

2025.11.4

Topics

概要

Terraform は、HashiCorp 社が開発した IaC(Infrastructure as Code)ツールです。
AWS や Google Cloud などのインフラ環境をコードで管理している方も多いのではないでしょうか。

TROCCO では、Free プランまたは Advanced プラン以上の契約アカウントで TROCCO API をご利用いただけます。
この API を利用することで、TROCCO の設定や運用も Terraform を使ってコードベースで管理することが可能になります。

プラン上の制約
TROCCO API は、Free プランまたは Advanced プラン以上の契約アカウントでのみ、ご利用いただけます。
TROCCO API リファレンス

これにより、インフラ環境とデータパイプラインを統合的に管理し、より効率的で再現性の高い運用を実現できます。
それでは、実際に TROCCO を Terraform で構築してみます。

今回の構成

TROCCO を使って S3 のデータを BigQuery に転送する設定を Terraform で構築します。

TROCCO_Terraformの構成図

以下の手順で構築していきます。

  1. TROCCO で API Key を発行
  2. Terraform コードを作成
  3. Terraform apply を実行
  4. 動作確認

今回は、TROCCO にフォーカスするため、S3 や BigQuery はすでに作成済みの状態としています。

S3 にあるファイルは生成 AI を使って作成したサンプルの売上データです。

order_id,tenant_id,company_name,user_id,user_name,product_name,category,quantity,unit_price,total_amount,order_date,region,status
ORD001,tenant_a,株式会社Alpha,user_a1,田中太郎,ノートPC,Electronics,2,80000,160000,2024-01-15,東京,完了
ORD002,tenant_a,株式会社Alpha,user_a2,佐藤花子,マウス,Electronics,5,3000,15000,2024-01-16,東京,完了
ORD003,tenant_b,Beta商事,user_b1,鈴木一郎,デスク,Furniture,1,50000,50000,2024-01-17,大阪,処理中
ORD004,tenant_b,Beta商事,user_b2,山田美咲,チェア,Furniture,3,25000,75000,2024-01-18,大阪,完了

1. TROCCO で API Key を発行

まずは、TROCCO で API Key を発行します。

TROCCOダッシュボード

右上の「新規作成」を選択します。

API Keyの作成画面

名前を入力して「保存」を押します。

API Key の設定画面

作成されると、API Key が表示されます。
注意 : この画面から移動すると API Key を再度確認できなくなるため、必ず控えておいてください。

API Key作成後の画面

2. Terraform コードを作成

次は、Terraform コードを作成します。

プロバイダー設定

プロバイダーは以下のように定義します。

Terraform の設定ブロックで TROCCO プロバイダーを定義し、API Key とリージョンを指定して TROCCO サービスとの接続を確立します。
API Key は、後述の変数を参照する形としています。

terraform {
  required_providers {
    trocco = {
      source = "registry.terraform.io/trocco-io/trocco"
    }
  }
}
provider "trocco" {
  api_key = var.trocco_api_key
  region  = "japan"
}

変数の設定

variables.tfは以下のように定義します。

  • trocco_api_key:TROCCO API Key の変数
  • service_account_json_key:Google Cloud のサービスアカウントの JSON の変数

service_account_json_key は JSON 形式のため、ヒアドキュメントを使用してダブルクォーテーションを含む文字列を適切に扱えるよう変数化しています。

注意 : セキュリティの観点から、本番環境では環境変数等を使用することを強く推奨します。

variable "trocco_api_key" {
  type      = string
  sensitive = true
  default   = "tra_Mkt*******************************************************"
}

variable "service_account_json_key" {
  type      = string
  sensitive = true
  default   = <<-JSON
{
  "type": "service_account"
}
  JSON
}

接続情報の設定

接続情報は以下のように定義します。

接続情報では、S3 は IAM ロール認証、BigQuery はサービスアカウント認証を設定します。
[XXX]の内容は環境に応じて編集してください。

編集項目

  • account_id
  • role_name
  • project_id
resource "trocco_connection" "s3" {
  aws_assume_role = {
    account_id = "[AWS Account ID]"
    role_name  = "[IAM Role]"
  }
  aws_auth_type   = "assume_role"
  connection_type = "s3"
  name            = "trocco-s3-connection"
}

resource "trocco_connection" "bigquery" {
  connection_type          = "bigquery"
  description              = "sample"
  name                     = "trocco-bigquery-connection"
  project_id               = "[Google Cloud Project ID]"
  service_account_json_key = var.service_account_json_key
}

転送設定の設定

転送設定は以下のように定義します。

転送ジョブの詳細設定を定義し、S3 から BigQuery へのデータ転送時のカラム定義、CSV パース設定、接続 ID の参照を行います。

編集項目

  • bucket
  • path_prefix
  • dataset
  • table
resource "trocco_job_definition" "job" {
  filter_columns = [
    {
      json_expand_enabled          = false
      json_expand_keep_base_column = false
      name                         = "order_id"
      src                          = "order_id"
      type                         = "string"
    },
    {
      json_expand_enabled          = false
      json_expand_keep_base_column = false
      name                         = "tenant_id"
      src                          = "tenant_id"
      type                         = "string"
    },
    {
      json_expand_enabled          = false
      json_expand_keep_base_column = false
      name                         = "company_name"
      src                          = "company_name"
      type                         = "string"
    },
    {
      json_expand_enabled          = false
      json_expand_keep_base_column = false
      name                         = "user_id"
      src                          = "user_id"
      type                         = "string"
    },
    {
      json_expand_enabled          = false
      json_expand_keep_base_column = false
      name                         = "user_name"
      src                          = "user_name"
      type                         = "string"
    },
    {
      json_expand_enabled          = false
      json_expand_keep_base_column = false
      name                         = "product_name"
      src                          = "product_name"
      type                         = "string"
    },
    {
      json_expand_enabled          = false
      json_expand_keep_base_column = false
      name                         = "category"
      src                          = "category"
      type                         = "string"
    },
    {
      json_expand_enabled          = false
      json_expand_keep_base_column = false
      name                         = "quantity"
      src                          = "quantity"
      type                         = "long"
    },
    {
      json_expand_enabled          = false
      json_expand_keep_base_column = false
      name                         = "unit_price"
      src                          = "unit_price"
      type                         = "long"
    },
    {
      json_expand_enabled          = false
      json_expand_keep_base_column = false
      name                         = "total_amount"
      src                          = "total_amount"
      type                         = "long"
    },
    {
      format                       = "%Y-%m-%d"
      json_expand_enabled          = false
      json_expand_keep_base_column = false
      name                         = "order_date"
      src                          = "order_date"
      type                         = "timestamp"
    },
    {
      json_expand_enabled          = false
      json_expand_keep_base_column = false
      name                         = "region"
      src                          = "region"
      type                         = "string"
    },
    {
      json_expand_enabled          = false
      json_expand_keep_base_column = false
      name                         = "status"
      src                          = "status"
      type                         = "string"
    },
  ]

  input_option = {
    s3_input_option = {
      bucket = "[S3 Bucket Name]"
      csv_parser = {
        allow_extra_columns    = false
        allow_optional_columns = false
        charset                = "UTF-8"
        columns = [
          {
            name = "order_id"
            type = "string"
          },
          {
            name = "tenant_id"
            type = "string"
          },
          {
            name = "company_name"
            type = "string"
          },
          {
            name = "user_id"
            type = "string"
          },
          {
            name = "user_name"
            type = "string"
          },
          {
            name = "product_name"
            type = "string"
          },
          {
            name = "category"
            type = "string"
          },
          {
            name = "quantity"
            type = "long"
          },
          {
            name = "unit_price"
            type = "long"
          },
          {
            name = "total_amount"
            type = "long"
          },
          {
            format = "%Y-%m-%d"
            name   = "order_date"
            type   = "timestamp"
          },
          {
            name = "region"
            type = "string"
          },
          {
            name = "status"
            type = "string"
          },
        ]
        default_date            = "1970-01-01"
        default_time_zone       = "UTC"
        delimiter               = ","
        escape                  = "\""
        max_quoted_size_limit   = 131072
        newline                 = "CRLF"
        quote                   = "\""
        quotes_in_quoted_fields = "ACCEPT_ONLY_RFC4180_ESCAPED"
        skip_header_lines       = 1
        stop_on_invalid_record  = true
        trim_if_not_quoted      = false
      }
      decompression_type          = "default"
      incremental_loading_enabled = false
      is_skip_header_line         = false
      path_prefix                 = "[Prefix]"
      region                      = "us-east-1"
      s3_connection_id            = trocco_connection.s3.id
      stop_when_file_not_found    = false
    }
  }

  input_option_type        = "s3"
  is_runnable_concurrently = false
  name                     = "sample-s3-bigquery"
  output_option = {
    bigquery_output_option = {
      auto_create_dataset                      = true
      bigquery_connection_id                   = trocco_connection.bigquery.id
      bigquery_output_option_clustering_fields = []
      bigquery_output_option_column_options = [
      ]
      bigquery_output_option_merge_keys = []
      dataset                           = "[Dataset]"
      location                          = "asia-northeast1"
      mode                              = "append"
      open_timeout_sec                  = 300
      read_timeout_sec                  = 300
      retries                           = 5
      send_timeout_sec                  = 300
      table                             = "[Table]"
      timeout_sec                       = 300
    }
  }
  output_option_type   = "bigquery"
  resource_enhancement = "custom_spec"
  retry_limit          = 0
}

3. Terraform apply を実行

準備が整ったので、terraform applyを実行します。

Plan: 3 to add, 0 to change, 0 to destroy.
trocco_connection.bigquery: Creating...
trocco_connection.s3: Creating...
trocco_connection.s3: Creation complete after 1s [name=trocco-s3-connection]
trocco_connection.bigquery: Creation complete after 1s [name=trocco-bigquery-connection]
trocco_job_definition.job: Creating...
trocco_job_definition.job: Creation complete after 0s [name=sample-s3-bigquery]
╷
│ Warning: Quoted references are deprecated
│
│   on main.tf line 31, in resource "trocco_connection" "bigquery":
│   31:       "service_account_json_key"
│
│ In this context, references are expected literally rather than in quotes. Terraform 0.11 and
│ earlier required quotes, but quoted references are now deprecated and will be removed in a
│ future version of Terraform. Remove the quotes surrounding this reference to silence this
│ warning.
╵

セキュリティに関する警告が表示されていますが、今回は対応を省略します。

デプロイ後、S3 コネクションに外部 ID が生成されるため、IAM ロールの外部 ID を更新する必要があります。

S3 のコネクションの外部 ID

TROCCO のコンソールから外部 ID をコピーして、IAM ロールの信頼ポリシーを更新してください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::545668264778:root"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                    "sts:ExternalId": "[生成された外部ID]"
                }
            }
        }
    ]
}

4. 動作確認

Terraform で作成した転送設定を開き、「実行」ボタンを押します。

新規転送ジョブ実行

実行時は特に設定を変更せず、そのまま実行します。

ジョブ設定画面

ジョブが完了しました。

転送ジョブ完了画面

BigQuery を確認するとサンプルデータが正常に転送されていることが確認できました。

BigQueryのプレビュー画面

まとめ

TROCCO を Terraform で管理することで、インフラストラクチャとしてのデータパイプラインの構築が可能になりました。
設定項目が多いため、最初はコンソールで作成してから Terraform にインポートするアプローチも有効だと思います。

参考資料

trocco-io/trocco | Terraform Registry
Docs overview | trocco-io/trocco | Terraform | Terraform Registry
TROCCO API リファレンス

NHN テコラスの採用情報はこちら

テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!

Cold-Airflow

2021年新卒入社。インフラエンジニアです。RDBが三度の飯より好きです。 主にデータベースやAWSのサーバレスについて書く予定です。あと寒いのは苦手です。

Recommends

こちらもおすすめ

Special Topics

注目記事はこちら