💡
Cloud Workflows から外部の JSON データを読み込んでセットする方法
Google Cloud Platform Advent Calendar 2021 の 11日目の記事です。
前提
Google Cloud リソースは Terraform で管理している
課題
Cloud Workflow で利用する E2E データを JSON で管理したい
- E2E データの例
{
"animal-id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"animal-kind": "dog",
"options": {
"color": "brown",
"name": "sunndy"
},
"created-at": "",
"updated-at": ""
}
解決法
Terraform の external data source を利用しシェルスクリプト経由で JSON を読み込み
詳細
read-e2e-data.sh
- JSON データを一行の文字列で扱うために Base64 でエンコーディングを行う
#!/usr/bin/env bash
set -e
eval "$(jq -r '@sh "ENV=\(.env)"')"
printf '{"base64_encoded":"%s"}\n' $(cat ../../../workflow/e2e/data/${ENV}.json | base64 -w 0)
main.tf
- Base64 でエンコーディングしたデータを Terraform の
base64decode
関数でディコーディングを行いe2e_data
っていう変数にセットする
local {
prefix = "org-srv"
environment = "dev"
}
data "external" "e2e_data" {
program = ["bash", "${path.module}/../../../workflow/e2e/read-e2e-data.sh"]
query = {
env = local.environment
}
}
resource "google_service_account" "demo" {
account_id = "${local.prefix}-demo-workflow"
}
variable "demo_workflow_roles" {
default = [
"roles/logging.logWriter",
"roles/datastore.user"
]
}
resource "google_project_iam_member" "demo" {
for_each = toset(var.demo_workflow_roles)
role = each.value
member = "serviceAccount:${google_service_account.demo.email}"
}
resource "google_workflows_workflow" "demo" {
name = "${local.prefix}-demo-workflow"
region = "asia-southeast1"
service_account = google_service_account.demo.id
source_contents = templatefile("${path.module}/../../../workflow/demo.yaml", {
e2e_data = base64decode(data.external.e2e_data.result["base64_encoded"])
})
}
demo.yaml
-
e2e_data
を Cloud Workflow の変数にセットすることで内部で自由に参照できる - JSON に定義していないタイムスタンプ型(*1)は、先月の中旬にリリースされた
time.format
を活用
*1) created-at, updated-at
main:
params:
- args
steps:
- init:
assign:
- project_id: $${sys.get_env("GOOGLE_CLOUD_PROJECT_ID")}
- current_timestamp: $${time.format(sys.now(), "Asia/Tokyo")}
- e2e_data: ${e2e_data}
...
- register_animal_for_e2e:
call: googleapis.firestore.v1.projects.databases.documents.createDocument
args:
parent: $${"projects/" + project_id + "/databases/(default)/documents/zoo/v0"
collectionId: animals
documentId: $${e2e_data["animal-id"]}
body:
fields:
animal-id:
stringValue: $${e2e_data["animal-id"]}
animal-kind:
stringValue: $${e2e_data["animal-kind"]}
options:
mapValue:
fields:
color:
stringValue: $${e2e_data["options"]["color"]}
name:
stringValue: $${e2e_data["options"]["name"]}
created-at:
timestampValue: $${current_timestamp}
updated-at:
timestampValue: $${current_timestamp}
...
Discussion