86. ワークフローは有限状態機械である — 状態と遷移を宣言するとコードから制御の流れが消える
Step Functionsの正体は「有限状態機械の実行系」です。ワークフローを状態と遷移の集まりとして宣言すると、なぜコードからif/for/try-catchが消え、コンソールが図を自動で描けるのか——その仕組みを図で追っていきます。
① Step Functionsは「状態機械」でできている
- 公式の言い回し: "Step Functions is based on state machines and tasks. In Step Functions, state machines are called workflows, which are a series of event-driven steps. Each step in a workflow is called a state."
- 公式の言い回し: "a Task state represents a unit of work that another AWS service performs, such as calling another AWS service or API"(welcome.html)
Step Functionsの語彙はたった数語で閉じている——ワークフローは「状態」の連なりで、各ステップが1つの状態、そのうち実際に仕事をするのがTask状態。この語彙の少なさ自体が「これは有限状態機械だ」というサインです。
② 設計図(定義)と実体(実行)は別物
- 公式の言い回し: "Instances of running workflows performing tasks are called executions in Step Functions."(welcome.html)
- 1つの定義から実行をいくつも起動でき、各実行は独立して進む。
定義は「設計図」、実行(execution)は「その設計図から起動された実体」。1枚の定義から実行はいくつも生まれます。これはコンテナ編のタスク定義とタスク、認証・暗号編のポリシー文書とその評価とまったく同じ構図——「宣言(定義)と実体」を分ける設計がここでも再登場します。
③ 制御の流れをコードの外へ: ASLという宣言
- ASLは "a JSON-based, structured language used to define your state machine, a collection of states"。
- トップレベルの最小構造: "StartAt"(どの状態から始めるか=開始状態の名前)と "States"(状態名→状態定義の辞書)。例: "First" が Type: Task で Lambda を呼び、"Next": "Second" で遷移、"Second" は "End": true で終端。
- 各状態の共通フィールド: Type(状態の種類)、任意の Comment、遷移は「Next(次の状態名)」か「End: true(終端)」。Succeed/Fail 以外の状態は Next が必要("Each state (except Succeed or Fail states) requires a Next field")。
- 状態名は state machine 全体の中で一意でなければならない("must be unique within the scope of the entire state machine")。だから Next は名前だけで行き先を一意に指せる。
- エラー処理の宣言化: 公式は "Error handling (Retry/Catch) – You can retry failed tasks, or catch failed tasks and automatically run alternative steps."
ASLがやっているのは「制御の流れ(どの順で・どこへ遷移し・どこで終わるか)を、コードのif/for/try-catchから取り出してJSONの宣言に置く」こと。状態名が全体で一意だからこそ、Next は名前を1つ書くだけで遷移先を確定できます。
④ 分岐すら「宣言」である — Choice状態
- Choice は各 Choice Rule ごとに Condition(条件)と Next(行き先)の対を並べる。公式サンプル(JSONata版)からの抜粋: { "Next": "FirstMatchState", "Condition": "{% $foo = 1 %}" } を "Choices" 配列に列挙し、"Default": "DefaultState" を添える。
- 公式の言い回し: "Choice states can actually have more than one Next within each Choice Rule." ——つまり複数の Next を持てる。他の状態の遷移宣言は単一の Next か End なので、複数の行き先を持てるのはChoiceだけ。
- {% $foo = 1 %} はJSONata構文。公式例ではトップレベルに "QueryLanguage": "JSONata" を宣言し、$foo は前段のTask状態が Assign で代入した変数。
if文が「条件→行き先」の宣言リストに姿を変えたのがChoice状態です。分岐という制御構造すらデータ(JSON)として外に出る——これが「制御の流れをコードから消す」の核心です。
⑤ 仕事をするTask + 流れを操る7つのフロー状態
- 公式の分類: "States are separated in Workflow Studio into Actions, also known as Task states, and seven Flow states."
- 公式一行説明: Task="Add a single unit of work to be performed by your state machine"、Choice="Add a choice between branches of execution"、Parallel="Add parallel branches of execution"、Map="Dynamically iterate steps for each element of an input array"(Parallelと違い、配列の複数要素に同じステップを実行)、Pass="Pass state input through to the output"、Wait="Pause your workflow for a certain amount of time or until a specified time or date"、Succeed/Fail="Stops your workflow with a success / failure"。
- Succeed/Fail は終端状態なので Next を持たない。Choice は複数の Next を持てる唯一の状態。
状態の種類は「実際に仕事をするTask」1種と、「流れを操る7つのフロー状態」だけ。順次・分岐・並列・反復・待機・終了——プログラムの制御構造がそのまま状態の型として並んでいます。
⑥ なぜ「宣言」だと図が描け、追跡できるのか
- 制御の流れがコード内の暗黙の分岐でなく「状態と遷移の明示的な宣言」になっているから、機械はそれを読んで図(グラフ)を描き、実行の現在地を追える。公式: コンソールで "visualize, edit, and debug your application's workflow"、"examine the state of each step"。
- Statelintは公式が案内するASL検証ツール("Statelint, a tool that validates Amazon States Language code")。
- 可観測性編のアラームFSM(OK / ALARM / INSUFFICIENT_DATA の3状態)で見た「状態と遷移で振る舞いを定義する」考え方が、今度はアラームではなくあなたのアプリケーションの制御フローそのものに適用されている——これが本編の土台の有限状態機械です。
「制御の流れを宣言として外に出す」ことの見返りが、自動で描かれる図と、機械による正確な実行追跡です。振る舞いがコードの中に隠れず、状態と遷移というデータになっているからこそ、人も機械も「今どこで何が起きているか」を一目で追えます。