🏭
TerraformでStepFunctionsのState定義をYAMLで管理
概要
Step FunctionsのState定義は通常JSONで記述しますが、可読性や保守性の観点からYAMLで管理したいことがあります。
TerraformでStepFunctionsのState定義をYAMLで管理する方法を記載します。
一般的なディレクトリ構成例
project-root/
└── terraform/
├── step_functions.tf
└── state_machine.template.asl.yml
-
step_functions.tf
: Terraformの設定ファイル -
state_machine.template.asl.yml
: Step FunctionsのYAMLテンプレート
.asl.yml
にする理由
補足:拡張子を YAMLテンプレートファイルの拡張子を .asl.yml
としているのは、VSCodeのStep Functions拡張機能(AWS Step Functions extension for VSCode)でシンタックスハイライトやバリデーションが有効になるためです。これを使うことで、マネジメントコンソールで設定するような操作感でState定義することが可能になります。
1. State定義をYAMLで作成する
state_machine.template.asl.yml
にStepFunctionsの定義をYAMLで記述します。
テンプレート内でTerraformの変数を ${...}
形式で埋め込むことができます。
title=state_machine.template.asl.yml(一例)
StartAt: FirstState
States:
FirstState:
Type: Task
Resource: ${first_lambda_arn}
Next: SecondState
SecondState:
Type: Pass
Result: "done"
End: true
-
${first_lambda_arn}
のように、Terraformから値を埋め込めます。
Resource:
と Resource.$:
の違い
補足:-
Resource:
は静的な値(文字列)を指定します。 -
Resource.$:
は動的な値(入力データやStates関数の結果など)を指定します。
例
# 静的なLambda ARNを指定
Resource: arn:aws:lambda:ap-northeast-1:123456789012:function:my-function
# 入力データからLambda ARNを動的に取得
Resource.$: $.lambda_arn
# ランダムな値やStates関数の結果を使う場合も必ず .$ を使う
Parameters:
RandomId.$: States.UUID()
Resource.$: States.Format('arn:aws:lambda:ap-northeast-1:123456789012:function:my-func-{}', States.UUID())
-
Resource: ...
→ そのまま書いた値が使われます。 -
Resource.$: ...
→ 実行時に入力データやStates関数の結果など、動的な値を参照します。
ポイント: ランダムな値や動的な値(States関数、入力データ、JSONPath式など)を使いたい場合は、必ず
.$
記法を使う必要があります。
補足:短いランダム文字列を生成したい場合
States.ArrayGetItem(States.StringSplit(States.UUID(), '-'), 0)
のように書くことで、UUIDの先頭部分だけを抜き出して短いランダム文字列として使うことができます。
Parameters:
ShortRandom.$: States.ArrayGetItem(States.StringSplit(States.UUID(), '-'), 0)
2. TerraformでYAMLテンプレートを利用する
step_functions.tf
で、YAMLテンプレートに変数を埋め込み、最終的にJSONへ変換してStepFunctionsに渡します。
title=step_functions.tf(一例)
locals {
# テンプレートファイルに変数を埋め込む
sf_template = templatefile("${path.module}/state_machine.template.asl.yml", {
first_lambda_arn = aws_lambda_function.first.arn
})
# YAML→JSON変換
sf_template_yml = yamldecode(local.sf_template)
step_function_definition = jsonencode(local.sf_template_yml)
}
resource "aws_sfn_state_machine" "example" {
name = "example-state-machine"
role_arn = aws_iam_role.step_function.arn
definition = local.step_function_definition
}
補足:デバッグしたい値単位でlocalsで変数を定義する
- 必要な値だけ
terraform console
ですぐ確認可能 - 例:
terraform console
を起動し、local.<変数名>
で値を確認できます
$ terraform console
> local.sf_template_yml
> local.step_function_definition
3. ポイント・注意点
-
テンプレート変数:YAMLテンプレート内で
${...}
形式で変数を記述し、templatefile
関数で値を埋め込む。 -
YAML→JSON変換:
yamldecode
→jsonencode
でYAMLをJSONに変換し、StepFunctionsに渡す。
Discussion