🏭

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変換yamldecodejsonencodeでYAMLをJSONに変換し、StepFunctionsに渡す。

参考

Discussion