🦔

Workflowsで変数をオーバーライドしてDataformを実行する方法

2023/08/02に公開

今回はシンプルにworkflowsからDataformを実行するというだけでなく、workflowsから実行したCloud RunやDataflowからとある出力結果を受け取り、それを引数としてDataformの変数に代入して実行したい!みたいなケースを想定して、Workflowsで定義している変数をDataformに引数として実行することができるのか試してみました。

WorkflowsからDataformを実行する方法

サンプルのYamlファイルとして提供されているのは以下のようなコード
おそらく以下のコードをworkflowsから実行すると問題なくdataformは実行できそう。。。

このyamlファイルのポイントとしては、
① createCompilationResultでhttp.postでdataformのcompilie結果を作成している
② createWorkflowInvocationでhttp.postでcompileした結果を実行する
という流れのworkflowが書かれているということです。

main:
    steps:
    - init:
        assign:
        - repository: projects/PROJECT_ID/locations/REPOSITORY_LOCATION/repositories/REPOSITORY_ID
    - createCompilationResult:
        call: http.post
        args:
            url: ${"https://dataform.googleapis.com/v1beta1/" + repository + "/compilationResults"}
            auth:
                type: OAuth2
            body:
                gitCommitish: GIT_COMMITISH
        result: compilationResult
    - createWorkflowInvocation:
        call: http.post
        args:
            url: ${"https://dataform.googleapis.com/v1beta1/" + repository + "/workflowInvocations"}
            auth:
                type: OAuth2
            body:
                compilationResult: ${compilationResult.body.name}
        result: workflowInvocation
    - complete:
        return: ${workflowInvocation.body.name}

Yamlファイルの中の以下の変数は以下のガイドに従って変更する必要があります
PROJECT_ID: Google Cloud プロジェクトの ID。
REPOSITORY_LOCATION: Dataform リポジトリの場所。
REPOSITORY_ID: Dataform リポジトリの名前。
GIT_COMMITISH: Dataform コードの実行元となる Git ブランチ。新しく作成したリポジトリの場合は、main に置き換えます。

コードはこちらの公式ガイドから参照しております。
https://cloud.google.com/dataform/docs/schedule-executions-workflows?hl=ja

workflowsのSAにDataformの編集権限を付与しておく

前提条件としてworkflowsのSAにDataformの編集権限を付与しておく必要があります。

https://cloud.google.com/dataform/docs/schedule-executions-workflows?hl=ja#required_roles

Dataformの変数をworkflowsから渡す変数でオーバーライドする方法

上記はシンプルにworkflowsからDataformを実行するYamlファイルでしたが、例えばworkflowsから実行したCloud RunやDataflowからとある出力結果を受け取り、それを引数としてDataformの変数に代入して実行したい!みたいなケースを想定しています。

その際に使えそうなのが、コンパイル変数の値
(以下参考リンク)
https://cloud.google.com/dataform/docs/compilation-overrides?hl=ja#about_compilation_overrides

コンパイル変数の値とは

dataform.jsonというdataformで使用するデフォルトのproject IDやデフォルトで使用するデータセット等が定義されているファイルの中で以下のように変数として設定することのできるものです。

例えばdataform.jsonを以下のように設定することができます。

{
  "defaultSchema": "dataform",
  "assertionSchema": "dataform_assertions",
  "warehouse": "bigquery",
  "defaultDatabase": "myproject",
  "defaultLocation": "asia-northeast1"
   "vars": {
      "myVariableName": "myVariableValue" # この部分がコンパイル変数の値
}

コンパイル変数の値の呼び出し方

コンパイル変数はDataformのdefinitionsフォルダー配下のsqlxファイルの中で自由に呼び出すことができます。
コンパイル変数を呼び出す場合には少し法則があり、以下のように指定してあげます。

dataform.projectConfig.vars.<変数名>

なので例えば、シンプルにCTASをするsqlxファイルの中で使おうと思うと以下のように作成することができます。

config {
  type: "table",
  name: dataform.projectConfig.vars.myVariableName
}


SELECT * FROM dataset_tokyo.sample_table

テーブル参照をするときの${ref()}を使用するときは以下のように書くことが可能です。

config {
  type: "table",
  name: dataform.projectConfig.vars.myVariableName2
}


SELECT * FROM ${ref(dataform.projectConfig.vars.myVariableName)}

コンパイル変数をworkflowsから受け取った引数で代入する

ここからは上記のdataform.jsonで定義しているコンパイル変数をworkflows経由でオーバーライドするための方法を見ていきます。

公式ガイドによると
https://cloud.google.com/dataform/docs/compilation-overrides?hl=ja#compilation-variables

Dataform APIコンパイルリクエストのcodeCompilationConfigブロックを追加して、次の形式で YOUR_VARIABLEとVALUEのKey-Valueペアを設定することで可能です。

{
 "codeCompilationConfig": {
   "vars": {
     "YOUR_VARIABLE": "VALUE"
   }
 }
}

上記を実際のworkflowsのyamlファイルに組み込むと以下のようなファイルになります。

main:
    steps:
    - init:
        assign:
        - repository: projects/<project ID>/locations/asia-northeast1/repositories/<repository ID>
    - createCompilationResult:
        call: http.post
        args:
            url: ${"https://dataform.googleapis.com/v1beta1/" + repository + "/compilationResults"}
            auth:
                type: OAuth2
            body:
                gitCommitish: main
                codeCompilationConfig: {
                    vars: {
                        "YOUR_VARIABLE": "VALUE"
                    }
                }
        result: compilationResult
    - createWorkflowInvocation:
        call: http.post
        args:
            url: ${"https://dataform.googleapis.com/v1beta1/" + repository + "/workflowInvocations"}
            auth:
                type: OAuth2
            body:
                compilationResult: ${compilationResult.body.name}
        result: workflowInvocation
    - complete:
        return: ${workflowInvocation.body.name}

Discussion