3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

embulk の設定ファイルを共通化したい

Last updated at Posted at 2018-08-25

困っていること、やりたいこと

digdag + embulk の環境において、embulk の設定ファイルで共通部分を include で共有している。 → 参考
ディレクトリの構造上、複数のプロジェクトにまたがって同じ設定を利用したいが、
仕様上、include する設定ファイルより上の階層からは include できないため、
現状は、まったく同じ設定ファイルを各プロジェクトの中に配置しているため気持ちが悪い。

具体的には、embulk-input-bigquery, emublk-output-bigquery の設定が記載されている。
設定が変更になったときに、すべてのファイルを変えなければならないため管理上問題がある。
これをなんとかする方法を知りたい。

サービスDBから生データを BigQuery に入れ、そのデータを集計した結果を BigQuery にいれるというようなことをしている

ファイル構成

commons 配下の _in_bigquery.yml.liquid と _out_bigquery.yml.liquid がまったく同じファイル

parent.dig
project1/
  ├ project1_child.dig
  ├ project1_conf1.yml.liquid
  ├ project1_conf2.yml.liquid
  ├ commons/
  │  ├ _in_mongodb.yml.liquid
  │  ├ _in_bigquery.yml.liquid
  │  ├ _out_bigquery.yml.liquid
project2/
  ├ project2_child.dig
  ├ project2_conf1.yml.liquid
  ├ project2_conf2.yml.liquid
  ├ commons/
  │  ├ _in_mysql.yml.liquid
  │  ├ _in_bigquery.yml.liquid
  │  ├ _out_bigquery.yml.liquid
parent.dig
+daily:
  +project1:
    !include : 'project1/project1_child.dig'

  +project2:
    !include : 'project2/project2_child.dig'
project1_child.dig
+daily:
  _export:
    OUTPUT_DATASET_NAME: xxx

  +task1:
    _export:
      INPUT_TABLE_NAME: xxx
      OUTPUT_TABLE_NAME: xxx

    +embulk:
      sh>: embulk run project1_conf1.yml.liquid

  +task2:
    _export:
      INPUT_TABLE_NAME: xxx
      OUTPUT_TABLE_NAME: xxx

    +embulk:
      sh>: embulk run project1_conf2.yml.liquid
project1_conf1.yml.liquid
{% include 'commons/in_bigquery' %}
  # 実際には何らかの集計クエリ
  sql: SELECT * FROM {{ env.INPUT_TABLE_NAME }}

{% include 'commons/out_bigquery' %}
  dataset: {{ env.OUTPUT_DATASET_NAME }}
  table: {{ env.OUTPUT_TABLE_NAME }}
  auto_create_table: true

  mode: replace
  prevent_duplicate_insert: true
_in_bigquery.yml.liquid
in:
  type: bigquery
  keyfile: xxx.json
  project: xxx
_out_bigquery.yml.liquid
out:
  type: bigquery
  auth_method: json_key
  json_keyfile: xxx.json
  project: xxx

  gcs_bucket: xxx
  auto_create_gcs_bucket: true
  compression: GZIP

試したこと

@hiroysato さんにアドバイスを頂き、yaml_master を使い、
_in_bigquery.yml.liquid と _out_bigquery.yml.liquid をそれぞれのプロジェクト内に出力するようにしました。

yaml_master の仕様上、先頭に --- がつくので、実際に出来上がる project1_conf1.yml.liquid は以下のようになり、複数の yaml ファイルとみなされてしまい動きません。
というところで今、詰まっているところです。

master.yml
yaml_master:
  project1_in_bigquery: project1/commons/_in_bigquery.yml.liquid
  project2_in_bigquery: project2/commons/_in_bigquery.yml.liquid
  project1_out_bigquery: project1/commons/_out_bigquery.yml.liquid
  project2_out_bigquery: project2/commons/_out_bigquery.yml.liquid

data:
  project1_in_bigquery: !include _in_bigquery.yml.liquid
  project2_in_bigquery: !include _in_bigquery.yml.liquid
  project1_out_bigquery: !include _out_bigquery.yml.liquid
  project2_out_bigquery: !include _out_bigquery.yml.liquid

include している _in_bigquery.yml.liquid、_out_bigquery.yml.liquid は、少し上のものとまったく同じです。

yaml_master実行
$ yaml_master -m master.yml --all

実行した結果できあがったものが以下

_in_bigquery.yml.liquid
---
in:
  type: bigquery
  keyfile: xxx.json
  project: xxx
_out_bigquery.yml.liquid
---
out:
  type: bigquery
  auth_method: json_key
  json_keyfile: xxx.json
  project: xxx

  gcs_bucket: xxx
  auto_create_gcs_bucket: true
  compression: GZIP

それによって出来上がった project1_conf1.yml.liquid は以下

yaml_masterで出力したproject1_conf1.yml.liquid
---
in:
  type: bigquery
  keyfile: xxx.json
  project: xxx
  # 実際には何らかの集計クエリ
  sql: SELECT * FROM {{ env.INPUT_TABLE_NAME }}

---
out:
  type: bigquery
  auth_method: json_key
  json_keyfile: xxx.json
  project: xxx

  gcs_bucket: xxx
  auto_create_gcs_bucket: true
  compression: GZIP
  dataset: {{ env.OUTPUT_DATASET_NAME }}
  table: {{ env.OUTPUT_TABLE_NAME }}
  auto_create_table: true

  mode: replace
  prevent_duplicate_insert: true

本当に欲しいのはこれ

期待するproject1_conf1.yml.liquid
in:
  type: bigquery
  keyfile: xxx.json
  project: xxx
  # 実際には何らかの集計クエリ
  sql: SELECT * FROM {{ env.INPUT_TABLE_NAME }}

out:
  type: bigquery
  auth_method: json_key
  json_keyfile: xxx.json
  project: xxx

  gcs_bucket: xxx
  auto_create_gcs_bucket: true
  compression: GZIP
  dataset: {{ env.OUTPUT_DATASET_NAME }}
  table: {{ env.OUTPUT_TABLE_NAME }}
  auto_create_table: true

  mode: replace
  prevent_duplicate_insert: true

よくよく考えると、実質的に _in_bigquery.yml.liquid と _out_bigquery.yml.liquid を各プロジェクトにコピーしているだけなので
そういうシェルを書いて、変更があったときに修正して実行するだけか…?

そもそもプロジェクトまたがって1つで実行しようとしていることが間違っているのか
プロジェクトごとにディレクトリ分けずに1つに突っ込めとなるのか
こういうケースのベストプラクティスを知りたい。

結局どうしたか

Twitterで @hiroysato さん @joker1007 さんにアドバイスをいただき
今回のケースでは、共通部分の設定ファイルを上位におき、変更があったときにそこから各所にコピーするシェルを実行する、としました。
もし project1_conf1.yml.liquid をある程度共通化できるようなケースであれば yaml_master が最適かもしれません。

commons/
  ├ _in_bigquery.yml.liquid
  ├ _out_bigquery.yml.liquid
copy.sh
parent.dig
project1/
  ├ project1_child.dig
  ├ project1_conf1.yml.liquid
  ├ project1_conf2.yml.liquid
  ├ commons/
  │  ├ _in_mongodb.yml.liquid
  │  ├ _in_bigquery.yml.liquid
  │  ├ _out_bigquery.yml.liquid
project2/
  ├ project2_child.dig
  ├ project2_conf1.yml.liquid
  ├ project2_conf2.yml.liquid
  ├ commons/
  │  ├ _in_mysql.yml.liquid
  │  ├ _in_bigquery.yml.liquid
  │  ├ _out_bigquery.yml.liquid
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?