Cloud Workflows を Terraform で扱います。以下はリファレンスのページ。
以下は公式チートシート。ぼーと眺めている。
Cloud Workflows - Syntax cheat sheet
以下のリポジトリは、Google の中の人が push してくれている Cloud Workflows のサンプルリポジトリ。マニュアル読んでも分からず困ったことがある場合、ここを見に行くとおおよそ解決します。
環境
- Terraform v1.3.5
- registry.terraform.io/hashicorp/google v4.43.1
ファイル一覧
Terraform のテンプレートファイルと Workflows 向けの YAML ファイルたちです。指定した URL に HTTP アクセスして、Response の Body を表示するだけの処理を作ります。
ファイル構造
. ├── main.tf └── yaml ├── custom_predicate.yaml ├── subwf_http_get.yaml └── wf_main.yaml
./main.tf
Terraform のテンプレートファイル。
variable "project_id" {} variable "region" {} terraform { required_version = "1.3.5" required_providers { google = { source = "hashicorp/google" version = "4.43.1" } } } provider "google" { project = var.project_id region = var.region } # Create a service account for Workflows # https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_service_account resource "google_service_account" "workflows_service_account" { account_id = "workflows-service-account" display_name = "Workflows Service Account" project = var.project_id } # Grant privileges to a service account # https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_service_account_iam#google_service_account_iam_member resource "google_project_iam_member" "workflows_service_account" { role = "roles/logging.logWriter" member = "serviceAccount:${google_service_account.workflows_service_account.email}" project = var.project_id } # Define and deploy a workflow # https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/workflows_workflow resource "google_workflows_workflow" "workflows_example" { name = "sample-workflow" project = var.project_id region = var.region description = "A sample workflow" labels = { "key1" = "value1" } service_account = google_service_account.workflows_service_account.id source_contents = join("", [ templatefile("${path.module}/yaml/wf_main.yaml", {}), templatefile("${path.module}/yaml/subwf_http_get.yaml", {}), templatefile("${path.module}/yaml/custom_predicate.yaml", {}) ]) }
wf_main.yaml
main workflow となる YAML ファイル。実際の処理は sub workflow 側で記述しています。
main: params: [args] steps: - assignment: assign: - host: $${args.host} - path: $${args.path} - call_subworkflow: call: subwf_http_get args: host: $${host} path: $${path} result: output - return_message: return: $${output}
subwf_http_get.yaml
main workflow から呼び出される sub workflow となる YAML ファイル。http.get
関数の処理を実行するものです。
subwf_http_get: params: [host, path] steps: - assignment: assign: - URL: '$${"https://" + host + "/" + path}' - get_message: try: call: http.get args: url: $${URL} timeout: 60.0 headers: Content-Type: "text/plain" result: response retry: predicate: $${custom_predicate} max_retries: 5 backoff: initial_delay: 1.0 max_delay: 60 multiplier: 1.25 except: as: e steps: - logging_error: call: sys.log args: data: '$${"Could not get from " + URL + "."}' severity: "ERROR" - raise_exception: raise: $${e} - logging_info: call: sys.log args: data: '$${"Could get from" + URL + "."}' severity: "INFO" - return_value: return: $${response.body}
custom_predicate.yaml
http.get
関数のリトライ制御で利用される predication の YAML ファイル。
custom_predicate: params: [e] steps: - repeat: switch: - condition: $${"ConnectionError" in e.tags} return: true - condition: $${e.code == 429} return: true - condition: $${e.code == 502} return: true - condition: $${e.code == 503} return: true - condition: $${e.code == 504} return: true - otherwise: return: false
デプロイ・実行
デプロイして、実行します。
Workflows のデプロイ
デプロイ。
$ terraform apply -auto-approve \ -var="project_id=123456789012" \ -var="region=us-central1"
Workflows の実行
デプロイした Workflows の実行。https://ipinfo.io/ip
という、アクセス元 IP アドレスを返してくれる Public API にアクセスしています。
$ gcloud workflows run sample-workflow --location=us-central1 --data='{"host":"ipinfo.io", "path":"ip"}' Waiting for execution [dfe385de-1a0d-411d-8e1a-b4751776a984] to complete...done. argument: '{"host":"ipinfo.io","path":"ip"}' endTime: '2022-11-21T05:35:42.099667275Z' name: projects/123456789012/locations/us-central1/workflows/sample-workflow/executions/dfe385de-1a0d-411d-8e1a-b4751776a984 result: '"64.233.172.168"' startTime: '2022-11-21T05:35:41.581584119Z' state: SUCCEEDED status: currentSteps: - routine: main step: return_message workflowRevisionId: 000005-60a
メモたち
Workflow 定義ファイルを分ける
main workflow は処理のフローを記述するレベルに抑え、実際の処理は個別の sub workflow で記述します。sub workflow で利用する引数を管理することで、sub workflow の処理をある種の関数やメソッドのように利用できるようなります。以下の公式の紹介記事が詳しいです。
Terraform で複数の YAML ワークフロー定義をデプロイする
変数の設定
Cloud Workflows の YAML ファイルで利用する変数は、$${variable_name}
と記述します。Cloud Workflows 本来の変数の記法は ${variable_name}
とドルマーク 1 つですが、そのままでは Terraform の変数として扱われてしまうため、ドルマークを 2 つ付けてエスケープしてあげます。
エラーハンドリングとリトライの制御
try-except 構文と try-retry 構文を利用して、エラーハンドリングします。
各関数で発生する例外は、関数のマニュアルページに記載あるので、そこで確認します。
拾われなかった例外は発生した場合、ワークフロー全体の処理が終了するため、処理を停止したいステップを作る時には明示的に raise してあげます。