error codes

ソフトウェアエンジニアリングなど、学んだこと、思ったことの記録です。

BigQuery Data Transfer Service / S3 転送の設定を Terraform で書く

BigQuery Data Transfer Service というのがあって、この S3 転送 というのを使うと、ログなどのデータ転送をだいぶ楽に行えることを知った。

これまでは、embulk とかを使って転送していたわけだけど、どこで動かすかとかを考えると地味に面倒で、一方 Data Transfer Service を使うと転送設定を書いておくだけで良いので、とても楽。

今回転送したかったものは、ログデータで、 S3 に日付ごとのパスに配置されている。これを日次で BigQuery に転送したい。

また転送したいログはいくつかあって、手動で設定していると管理が難しいので Terraform で転送設定を書くことにする。

resource "google_bigquery_dataset" "logs" {
  dataset_id = "test_logs"
  location   = "asia-northeast1"
}

resource "google_bigquery_table" "logs_app_log1" {
  dataset_id = google_bigquery_dataset.logs.dataset_id
  table_id   = "app_log1"

  time_partitioning {
    type = "DAY"
  }

  schema = file("...")
}

resource "google_bigquery_data_transfer_config" "logs_app_log1" {
  display_name   = "app_log1"
  data_source_id = "amazon_s3"

  params = {
    data_path                       = "s3://logs-bucket/app_log1/{run_time-24h|\"%Y\"}/{run_time-24h|\"%m\"}/{run_time-24h|\"%d\"}/*"
    destination_table_name_template = "app_log1$${run_time-24h|\"%Y%m%d\"}"
    field_delimiter                 = ","
    file_format                     = "JSON"
    max_bad_records                 = "0"
    access_key_id                   = aws_iam_access_key.transfer_user.id
    secret_access_key               = aws_iam_access_key.transfer_user.secret
    skip_leading_rows               = "0"
  }

  schedule                 = "every day 06:35"
  data_refresh_window_days = 0

  destination_dataset_id = google_bigquery_dataset.logs.dataset_id
  location               = "asia-northeast1"

  lifecycle {
    ignore_changes = [params["secret_access_key"]]
  }
}

ランタイムパラメータ というのを使って、ジョブが実行される日付を元に S3 のパスを指定できるので、日付ごとにパスが切られているようなログの溜め方をしていると、転送が行いやすい。

過去分のデータの転送は、バックフィル実行というのを行えば良いようだ。 Cloud Console からも行えるし、APIもありそうなので、すでにS3にデータが溜まっている場合も過去分データを問題なく転送できそう。

もう少しちゃんと使ってみると、はまりどころなども出てくるかもしれないが、いったんうまく動いたように見える。