はじめまして。AWS Step Functions のフローを理解する

この記事は個人ブログと同じ内容です

www.ritolab.com


AWS Step Functions の「フロー」を触って挙動を確認します。

AWS Step Functions

様々なアプリケーションのワークフローを一連の処理として定義し実行できるサービス。Lambda invokeSNS Publish, ECS Run task など、AWS 上に構築した処理を一つのシナリオにまとめて、順番に実行したり、条件によってそれらの実行を決定したり、並列実行や反復実行なども行える。

フロー

Step Functions における「フロー」は、ステートマシンを定義する上で、処理実行の流れや有無、どう実行するかを決める根幹の部分。

大きく以下 3 つフローを用いて処理の流れを定義する。

  • Choice
  • Parallel
  • Map

最もシンプルなフロー

最もシンプルなフローは、上から順番に実行していくフロー。パラータや状態の評価による処理の分岐がない場合は、シンプルに実行順に各処理を並べていけばよく、上記の Choice, Parallel, Map も使用しない。

Choice

Choice は、パラメータや状態によって処理を分岐できるフロー。if 文のような挙動をする。

// Choice のイメージ

if (...) {

} elseif (...) {

} elseif (...) {

} else {

}

Choice には複数の Rule が指定できるが、上から定義した Rule が評価され、合致した時点でその処理に遷移し Choice フローは終了する。つまり、必ずどれか 1 つだけの処理に移行する。(条件に合う全てのフローが実行されるような動作はしない)

ASL (Amazon States Language)

{
  "Comment": "A Hello World example demonstrating various state types of the Amazon States Language. It is composed of flow control states only, so it does not need resources to run.",
  "StartAt": "Pass",
  "States": {
    "Pass": {
      "Comment": "A Pass state passes its input to its output, without performing work. They can also generate static JSON output, or transform JSON input using filters and pass the transformed data to the next state. Pass states are useful when constructing and debugging state machines.",
      "Type": "Pass",
      "Result": {
        "selectA": true,
        "selectB": true,
        "IsHelloWorldExample": true
      },
      "Next": "Hello World example?"
    },
    "Hello World example?": {
      "Comment": "A Choice state adds branching logic to a state machine. Choice rules can implement many different comparison operators, and rules can be combined using And, Or, and Not",
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.IsHelloWorldExample",
          "BooleanEquals": true,
          "Next": "Selected A"
        },
        {
          "Variable": "$.IsHelloWorldExample",
          "BooleanEquals": false,
          "Next": "No"
        },
        {
          "Variable": "$.IsHelloWorldExample",
          "BooleanEquals": true,
          "Next": "Wait"
        }
      ],
      "Default": "Selected A"
    },
    "Wait": {
      "Type": "Wait",
      "Seconds": 5,
      "Next": "Yes"
    },
    "Yes": {
      "Type": "Pass",
      "Next": "Success (1)"
    },
    "Success (1)": {
      "Type": "Succeed"
    },
    "No": {
      "Type": "Fail",
      "Cause": "Not Hello World"
    },
    "Wait 3 sec": {
      "Comment": "A Wait state delays the state machine from continuing for a specified time.",
      "Type": "Wait",
      "Seconds": 3,
      "Next": "Parallel State"
    },
    "Parallel State": {
      "Comment": "A Parallel state can be used to create parallel branches of execution in your state machine.",
      "Type": "Parallel",
      "Next": "Hello World",
      "Branches": [
        {
          "StartAt": "Hello",
          "States": {
            "Hello": {
              "Type": "Pass",
              "End": true
            }
          }
        },
        {
          "StartAt": "World",
          "States": {
            "World": {
              "Type": "Pass",
              "End": true
            }
          }
        }
      ]
    },
    "Hello World": {
      "Type": "Pass",
      "Next": "Success"
    },
    "Success": {
      "Type": "Succeed"
    },
    "Selected A": {
      "Type": "Pass",
      "Next": "Wait 3 sec"
    }
  }
}

実際の実行結果

Parallel

並行処理を実施するフロー。複数の処理を並行で実施できる。

ASL (Amazon States Language)

{
  "Comment": "A description of my state machine",
  "StartAt": "Pass",
  "States": {
    "Pass": {
      "Type": "Pass",
      "Next": "Parallel"
    },
    "Parallel": {
      "Type": "Parallel",
      "End": true,
      "Branches": [
        {
          "StartAt": "Choice run A",
          "States": {
            "Choice run A": {
              "Type": "Choice",
              "Choices": [
                {
                  "Variable": "$.runA",
                  "BooleanEquals": true,
                  "Next": "run A"
                }
              ],
              "Default": "not run A"
            },
            "run A": {
              "Type": "Pass",
              "Next": "Success run A"
            },
            "Success run A": {
              "Type": "Succeed"
            },
            "not run A": {
              "Type": "Pass",
              "End": true
            }
          }
        },
        {
          "StartAt": "Choice run B",
          "States": {
            "Choice run B": {
              "Type": "Choice",
              "Choices": [
                {
                  "Variable": "$.runB",
                  "BooleanEquals": true,
                  "Next": "run B"
                }
              ],
              "Default": "not run B"
            },
            "run B": {
              "Type": "Pass",
              "Next": "Success run B"
            },
            "Success run B": {
              "Type": "Succeed"
            },
            "not run B": {
              "Type": "Pass",
              "End": true
            }
          }
        }
      ]
    }
  }
}

実際の実行結果

Map

反復処理を実施するフロー。配列で受け取ったパラメータに対して、item 文、処理をループ実行できる。

ASL (Amazon States Language)

{
  "Comment": "A description of my state machine",
  "StartAt": "Pass",
  "States": {
    "Pass": {
      "Type": "Pass",
      "Next": "Map",
      "Result": {
        "foo": "bar",
        "colors": [
          "red",
          "green",
          "blue",
          "yellow",
          "white"
        ]
      }
    },
    "Map": {
      "Type": "Map",
      "ItemProcessor": {
        "ProcessorConfig": {
          "Mode": "INLINE"
        },
        "StartAt": "exec 01",
        "States": {
          "exec 01": {
            "Type": "Pass",
            "Next": "exec 02"
          },
          "exec 02": {
            "Type": "Pass",
            "End": true
          }
        }
      },
      "End": true,
      "ItemsPath": "$.colors",
      "ItemSelector": {
        "uuid.$": "States.UUID()"
      },
      "ResultPath": "$.uuid"
    }
  }
}

実際の実行結果

{
  "output": {
    "foo": "bar",
    "colors": [
      "red",
      "green",
      "blue",
      "yellow",
      "white"
    ],
    "uuid": [
      {
        "uuid": "8272efe6-80e5-4530-aa7d-fad0fb8d9eb8"
      },
      {
        "uuid": "067ccf0c-85aa-4086-9dc4-7537f6729c7c"
      },
      {
        "uuid": "51e0f5d2-25a2-4f39-a3c7-4bc101e353ef"
      },
      {
        "uuid": "18c85a40-15da-405d-ae02-8c7c3bc5c8e2"
      },
      {
        "uuid": "bd902850-51f1-4857-9232-bc0348c29a22"
      }
    ]
  },
  "outputDetails": {
    "truncated": false
  }
}

使ってみればシンプルで強力なサービス

Choice, Parallel, Map と、名前から挙動を想像しやすく分かりやすかったですが、Choice の挙動が択一であることは留意しておきたい点。

パラメータ $isRunA = true, $isRunB = true で Choice の Rule から A と B の実行判断は行えないため、こういった判断は Parallel → Choice で実現する必要がある。

基本のフローが理解できたので今回はここまで。


現在 back check 開発チームでは一緒に働く仲間を募集中です。 herp.careers