こんにちは~ 浮田です。
前回の記事との違い:
前回が「何者で・いつ使い・何から学ぶか」を俯瞰する地図なら、本記事は最初の1歩目です。
基本用語は手早く復習しつつ、前回の記事では触れない ASL(実物の JSON)とデータの流れをコードで追って深掘りします。
前回の記事を読んだ人は前半(1〜4章)を復習として流し読みでOKです。
Step Functions は、複数の処理の「段取り」(順番・分岐・並列・リトライ・待機)をまるごと引き受けるサービス。
実際の仕事は Lambda 等に任せ、自分は流れの管理に徹します。 最大の強みは「流れが図として見え、どこで失敗したか実行履歴に残る」こと。
入門の天王山は「ステート間のデータの流れ」。ここだけは手を動かして越える必要があります。
コードを暗記する記事ではありません。「なぜこれが必要か」を一緒に追っていきます。
1. なぜ「関数が関数を呼ぶ」とつらいのか
2. Step Functions とは
3. 基本の用語を4つだけ
4. ステートの種類
5. 最小のサンプルを読んでみる
6. 最大の難所「データの流れ」を、実際に追いかける
7. 失敗したらどうする(エラー処理)
8. 似たサービスとの違い
9. 2つのタイプ: Standard と Express
10. どんなときに使う?(ユースケース)
たとえば、あなたがオンラインショップの裏側を作っているとします。
注文が入ったら、こういう流れを動かしたい。
3つの処理は、それぞれ AWS Lambda(サーバー不要で動く小さな関数)で書きました。
動かすために、関数の中から次の関数を呼ぶようにします。
在庫確認が決済を呼び、決済がメール送信を呼ぶ。シンプルですね。
このシステムをリリースしてから数日後以下の連絡が来るとします。
「お客様から『決済されたのにメールが来ない』と問い合わせが来ています」
あなたは飛び起きてログを漁ります。
が、ログは3つの関数にバラバラに散らばっていて、どの注文が、どこまで進んで、なぜ止まったのかが分からない。
決済は通っている。でもメールは飛んでいない。その間で何が起きたのか、誰も知らない。
これが、開発者が一度は通る「Lambda 呼び出し地獄」です。
そしてこの記事の主役 AWS Step Functions は、まさにこのあるあるから抜け出すための道具です。
この記事では、AWS の Step Functions というサービスを、ゼロから紹介します。
ひとことで言うと「いくつもの処理を、決まった順番でうまく動かしてくれる仕組み」。
…と言われてもピンと来ないと思うので、まずは"あるある"な困りごとから始めましょう。
Step Functions が「ないと、どう困るのか」。
絵にすると一直線で平和そのもの。でも現実は、ここに次々と地雷が埋まっています。
ここで大事な気づきがあります。これらは「処理そのもの(在庫を確認する、決済する)」の問題ではありません。「処理の段取り(どの順で、失敗したらどうするか、いつ待つか)」の問題です。
各 Lambda は、与えられた仕事をこなすことはできます。でも、「自分の次は誰か」「失敗したらどうするか」という全体の段取りを知っているものが、どこにもいない。各処理が「次は誰だっけ」と手探りで次を呼んでいる——これが、つらさの正体です。
(補足: そもそも「関数の中から次の関数を同期的に呼ぶ」のは AWS でも推奨されない書き方で、間に SQS をはさむなどの逃げ道もあります。ただ、いずれの方法でも"段取り"の問題は形を変えて残ります。)
そして、この"段取り役"をまるごと引き受けてくれるのが Step Functions です。
AWS Step Functions は、複数の処理を「ワークフロー(作業の流れ)」として組み立て、順番・分岐・並列・リトライ・待機までまるごと管理してくれるサービスです。
最大の特徴は、処理の流れを図(ビジュアルワークフロー)として定義でき、実行状況も図で見られること。
※在庫確認→決済の後に「金額で分岐」し、1万円以上のお客様にはVIP向けの通知を送る、という分岐をStepFunctionsで表現しています。
冒頭の地獄が、Step Functions ではこう解決されます。
|
困りごと |
Step Functions での解決 |
|
リトライを自前で書くのが大変 |
設定を数行書くだけで自動リトライ |
|
どこまで進んだか分からない |
1回ごとの実行履歴が、どこで止まったか図で残る |
|
途中で長時間待ちたい |
「待つ」専用の仕組みがあり、最大1年まで待てる |
|
流れがコードに埋もれる |
流れは独立した設計図として見える化 |
ポイントは、Step Functions 自身は実際の仕事をしないこと。
在庫確認も決済も、相変わらず Lambda(や他のサービス)がやります。
Step Functions は「次は決済、失敗したら在庫戻し」と指揮するだけ。
だからStep Functions を使っていれば、コンソールを開いて該当の注文の実行履歴を見るだけで「決済までは緑、メール送信が赤で止まっている」と一目で分かったはずなのです。
Step Functions を語るうえで最低限おさえたい言葉です。
前回の記事ではこの3語を「設計図・箱・製品」のたとえでつかみました。ここでは次章以降で実物の ASL(JSON)を読むための語彙として押さえ直し、4つ目に ASL そのものを足します。
ワークフロー全体の設計図そのもの。「在庫確認 → 決済 → メール」という流れ全体を1つのステートマシンとして定義します。作るのは設計図1個、というイメージ。
ワークフローを構成する1つ1つの箱(工程)。「在庫確認」も「決済」も、それぞれが1つのステートです。種類がいくつかあります(次章)。
設計図(ステートマシン)を実際に動かした1回分の処理。同じ設計図に対して、注文Aの実行・注文Bの実行…と何回でも並行して走らせられます。レシピ(設計図)に対して、実際に作る各回が実行、という関係。
ステートマシンを記述する JSON 形式の言語。コンソールの画面でドラッグして作れますが、最終的にはこの JSON に落ちます。読めるようになると一気に世界が広がります。
この4つの関係を一文で: 「ASL で書いた設計図(ステートマシン)は、たくさんの箱(ステート)でできていて、動かすたびに実行が1回生まれる」。
ステート(箱)には種類があります。主なものは以下の8種類です。
|
種類 |
役割 |
ひとことで |
|
Task |
実際の仕事をする |
Lambda を呼ぶ、DB に書く等。主役 |
|
Choice |
条件分岐 |
「金額が1万円以上なら承認へ」 |
|
Parallel |
並列実行 |
複数の処理を同時に走らせる |
|
Map |
繰り返し |
配列の各要素に同じ処理(例: 注文100件) |
|
Pass |
データを通すだけ |
値の整形やテスト用 |
|
Wait |
待つ |
「10秒待つ」「指定時刻まで待つ」 |
|
Succeed |
成功で終了 |
ここに来たら正常終了 |
|
Fail |
失敗で終了 |
ここに来たらエラー終了 |
最初は Task / Choice / Parallel / Map の4つを知っていれば十分。
とくに Task が圧倒的な主役で、「実際の仕事を呼び出す箱」はだいたい Task です。
💡 Task は Lambda 専用ではありません。AWS のほぼ全サービス(S3、DynamoDB、SNS、ECS など220以上)を直接呼べます。「ファイルを保存」「通知を送る」程度なら、Lambda を1個も書かずにStep Functions から直接サービスを叩けることも多いんです。
百聞は一見にしかず。「Lambda を1つ呼ぶだけ」を ASL で書くとこうです。
身構えなくて大丈夫。読み方はこれだけです。
3工程つなげるのも簡単。Next で「次の箱の名前」を指すだけ。
StartAt で始点、各ステートが Next で次を指し、最後が End: true。この数珠つなぎがワークフローの基本形です。あとはここに分岐(Choice)や並列(Parallel)が足されていくだけ、と思って構いません。
基本ルールはたった一つ。
あるステートの「出力」が、次のステートの「入力」になる。
バケツリレーです。最初に渡したデータが、箱を通るたびに姿を変えながら次へ手渡されていく。
注文処理の実行を1回、頭から最後まで追います。
▶ スタート: 実行を開始するとき、こんな JSON を渡したとします。
この出力が、そのまま次の箱「決済」の入力になります。バケツが手渡された瞬間です。
ここで一つ技術的な注意があります。← 在庫確認が付け足した という矢印注釈は、厳密にはJSONとして正しくない記法です(JSONにコメントは書けません)。
▶ ステート②「決済」
決済 Lambda は金額を計算して決済し、決済IDを付けて返します。
これが「メール送信」への入力に。
▶ ステート③「メール送信」
メール送信 Lambda は、お客様の email 宛に確認メールを出します。必要なのは email と orderId と金額 くらい。
注文明細(items)の全データは要りません。
「前の出力を"そのまま全部"渡したいわけじゃない」
メール送信に items の中身までドサッと渡すのは無駄だし、危なっかしい。「必要な項目だけ取り出して、形を整えてから渡したい」。この"データの加工"こそ、Step Functions でいちばん奥が深いテーマです。
歴史的に、Step Functions にはデータ加工のやり方が2つあります。
① 旧来の流派: JSONPath InputPath / Parameters / ResultSelector / ResultPath / OutputPath という 5つの設定を組み合わせて加工していました。
強力なのですが、5つの役割の違いが分かりにくく、Step Functions 学習における最大の難所として知られています。
② 新しい流派: 2024年11月、Step Functions JSONata(ジェイソネイタ) という新しいクエリ言語が追加されました。データ加工が、直感的になります。
⚠️ Step Functions のデフォルトは今も JSONPath です。
JSONata を使うには、ステートマシン(またはステート)に "QueryLanguage": "JSONata" を明示する必要があります。これを書き忘れると、以下のような JSONata 式は評価されず「動かない」とハマります。あるあるなので覚えておいてください。
たとえば「メール送信に必要な3項目だけ」を組み立てるなら、こう書けます。
$states.input が「この箱への入力」を指す決まり文句。そこから .customer.email のようにドットで掘っていくだけ。さっきのゴテゴテした5項目が、これ1つで済みます。
評価するとこうなります。
{
"to": "yamada@example.com",
"orderId": "A-001",
"amount": 3200
}
スッキリ。これがそのままメール送信 Lambda への入力になります。
なお JSONata モードでは「同じ式の結果を後のステートで使い回したい」というときに Variables(変数) で値を保存しておけます。
本記事では深入りしませんが、「変数も使える」とだけ頭の隅に置いてください。
これから新しく作るなら、JSONata で書くのがおすすめです。
ただし注意点がひとつ。AWS 公式ドキュメントやネット上の既存サンプルは、まだ JSONPath で書かれたものが多いです。
本記事ではデータ加工は「こういうものがある」程度に留めますが、これは読むだけでは身につきません。手を動かして覚えるのが近道です。
冒頭の悲劇——「決済は通ったのにメールが飛ばない」。Step Functions なら、こうした失敗への備えを設定だけで組み込めます。各 Task に2つの仕掛けを足せます。
一時的な不調(通信の瞬断など)は、これだけで勝手に回復します。自前のリトライコードはもう要りません。
リトライしても最終的にダメなら、Catch で「在庫を戻す」へ逃がして後始末。
States.ALL は「あらゆるエラー」の意味。
この Retry(粘る)+ Catch(諦めて後始末) が、堅牢なワークフローパターンです。
「処理をつなぐ」系の AWS サービスは他にもあります。初心者がいちばん混乱するのがこの区別。違いをハッキリさせておくと、Step Functions を正しく使えます。
宅配便に例えると分かりやすいです。
|
サービス |
役割 |
宅配便でいうと |
|
Lambda 単体 |
単発の仕事を1つこなす |
1件の配達作業そのもの |
|
SQS(キュー) |
仕事をためて順番待ちさせる |
荷物を置く集荷棚。誰かが取りに来るまで待つ |
|
EventBridge |
「○○が起きた」を関係者に知らせる |
「荷物が届きました」の通知メール(pub/sub) |
|
Step Functions |
一連の流れを順序立てて指揮する |
配送全体を管理する配送センター |
もう少し噛み砕くと——
そして大事なのは、よく一緒に使われること。
たとえば「EventBridge が注文イベントを受け取って Step Functions を起動し、その中の重い処理を SQS 経由でさばき、各ステップは Lambda」——というふうに、役割分担して組み合わせるのが王道です。
迷ったときの合言葉: 「流れを管理したい? なら Step Functions」。
ステートマシンを作るとき、Standard か Express を選びます。
最初は「Standard で無難」でOKですが、違いは以下の通りです。
|
|
Standard |
Express |
|
最大実行時間 |
1年 |
5分 |
|
向く用途 |
長い業務、人の承認待ち、バッチ |
大量・高頻度・短時間(IoT、APIの裏側) |
|
実行履歴 |
1件ずつ詳細に残る |
コンソールには残らない(CloudWatchにログ出力は可能) |
|
料金体系 |
状態遷移の回数で課金 |
実行回数+実行時間で課金 |
|
超大量実行時 |
割高になりがち |
安い |
ざっくり、
本記事がずっと推してきた「実行履歴が図で残り、どこで止まったか後から追える」という Step Functions 最大の強みは、Standard の特権です。
Express は1件ごとの履歴を残さない(必要ならログに出す)ので、入門段階では迷わず Standard を選んでください。「回数が爆発してコストが気になる」と分かってから Express を検討、で十分です。
Step Functions は、ワークフローのステップが実行されるたびに状態遷移をカウントします。
再試行など、すべての状態マシンのステート遷移の合計数に基づいて請求されます。
USD 0.025/1,000 回
4,000 回の状態遷移の無料枠(最初の1年だけでなく、ずっと毎月)
個人で試す・社内の小さな自動化レベルなら、料金を過度に心配する必要はまずありません。
正確な額は変動するので必ず公式の料金ページで確認してください。
「うちの業務に出番ある?」の判断材料に、典型例を。
共通点は「複数ステップ+順番・分岐・並列・失敗処理が絡む」こと。逆に単発処理なら Lambda 単体で十分です。
SFn が分かると、「Lambda をどう呼び合わせるか」で消耗していた問題が、設計図を描く問題に変わります。流れが見える化され、失敗にも強くなる。
もう、決済とメールの"あいだ"で迷子になることはありません。