【AWS】Step FunctionsでLambdaを繋ぐワークフローを実装する方法

当ページのリンクには広告が含まれています。
いずみ

こんな悩みを解決できる記事を書きました!

僕は現役フリーランスエンジニア(歴年)で、資格は個保有しています。

Step Functionsで複数のLambdaを順番に実行するワークフローを組みたい」と考えていませんか?

Lambda関数が増えてくると、関数から次の関数を直接呼び出す作りは全体の流れが見えづらくなります。

Step Functionsを使うと、処理の順序とエラー時の挙動をJSONで宣言的に定義できます。

いずみ

僕も複数のLambdaをつなぐ処理はStep Functionsに寄せることが多いです。

コード側の見通しが良くなるのでおすすめです。

ということで、本記事ではStep FunctionsでLambdaを繋ぐワークフローを実装する方法を解説します。

いずみ

すぐ読み終わるので、ぜひ最後まで読んでください。

スクロールできます
【当サイト】おすすめフリーランスエージェント3選
エージェント評価ポイント公式サイト
レバテックフリーランス

5.0
業界最大級のエージェント。
高単価案件が豊富。
公式
Midworks

4.8
満足度調査で
3年連続3冠を達成。
公式
ITプロパートナーズ

4.6
週2〜3向けの案件が豊富。公式
執筆者/監修者
  • フリーランスエンジニア(保有資格個、企業と直接契約
  • ブログ・アフィリエイト歴7年(2018年〜)
  • ブランドせどりで月利50万円⇨脱サラ
  • 投資(仮想通貨・FX)歴7年(2018年〜)
  • X(旧Twitter)フォロワー約1,900人
  • 運営者情報はこちら
いずみです
目次

【AWS】Step FunctionsでLambdaを繋ぐワークフローを実装する方法

早速、Step FunctionsでLambdaを繋ぐワークフローを実装していきます。

Step Functionsとは

Step Functionsは、複数のLambda関数やAWSサービスの呼び出しを状態遷移としてつなげられるマネージドのオーケストレーションサービスです。

ワークフローはAmazon States Language(ASL)というJSON形式で記述します。

ステートごとに、成功時の遷移先・リトライ回数・失敗時のフォールバックを宣言的に書けます。

実行状況はマネジメントコンソール上でグラフとして可視化され、どのステートで失敗したか一目で分かります。

いずみ

リトライ処理をLambdaのコードから追い出せるのが地味に嬉しいポイントです。

今回作るワークフローの構成

題材として、注文を検証するLambdaと決済するLambdaを直列でつなぐワークフローを作ります。

各ステートは一時的なエラーに備えてリトライを設定し、リトライ上限を超えた場合は失敗ステートへ遷移させます。

ステートマシンを定義する

ステートマシンの作成手順を順番に見ていきます。

STEP
Lambda関数を2つ用意する

validate-orderとprocess-paymentの2つのLambda関数をデプロイしておきます。

validate-orderは、注文明細が空なら例外を投げ、問題なければ合計金額を返すだけの関数です。

def handler(event, context):
    order = event.get("order", {})
    if not order.get("items"):
        raise ValueError("注文明細が空です")
    return {
        "order_id": order["id"],
        "amount": sum(i["price"] for i in order["items"]),
    }

例外を投げるとStep Functions側ではStates.TaskFailedとして扱われ、リトライ対象になります。

STEP
Amazon States Languageでワークフロー定義を書く

workflow.asl.jsonというファイルにワークフロー全体を記述します。

{
  "Comment": "注文を検証してから決済するワークフロー",
  "StartAt": "ValidateOrder",
  "States": {
    "ValidateOrder": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:validate-order",
      "Retry": [
        {
          "ErrorEquals": ["States.TaskFailed"],
          "IntervalSeconds": 2,
          "MaxAttempts": 3,
          "BackoffRate": 2.0
        }
      ],
      "Catch": [
        { "ErrorEquals": ["States.ALL"], "Next": "NotifyFailure" }
      ],
      "Next": "ProcessPayment"
    },
    "ProcessPayment": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:process-payment",
      "Retry": [
        {
          "ErrorEquals": ["States.TaskFailed"],
          "IntervalSeconds": 2,
          "MaxAttempts": 2,
          "BackoffRate": 2.0
        }
      ],
      "Catch": [
        { "ErrorEquals": ["States.ALL"], "Next": "NotifyFailure" }
      ],
      "End": true
    },
    "NotifyFailure": {
      "Type": "Fail",
      "Error": "WorkflowFailed",
      "Cause": "注文処理に失敗しました"
    }
  }
}

TaskステートのResourceにはLambda関数のARNを指定します。

Retryで再試行の間隔と回数を、Catchでリトライ枯渇後の遷移先を指定しています。

最後のステートにEndをtrueで付けると、ワークフローが正常終了します。

いずみ

BackoffRateを2にしておくと、リトライのたびに待ち時間が倍になります。

STEP
実行用のIAMロールを作成する

Step FunctionsがLambdaを呼び出せるよう、信頼ポリシーとアクセス許可を持つIAMロールを用意します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Service": "states.amazonaws.com" },
      "Action": "sts:AssumeRole"
    }
  ]
}

信頼ポリシーのプリンシパルにstates.amazonaws.comを指定します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "lambda:InvokeFunction",
      "Resource": [
        "arn:aws:lambda:ap-northeast-1:123456789012:function:validate-order",
        "arn:aws:lambda:ap-northeast-1:123456789012:function:process-payment"
      ]
    }
  ]
}

アクセス許可ポリシーでは、呼び出す2つのLambda関数に対してlambda:InvokeFunctionを許可します。

boto3でステートマシンを作成する

作成したIAMロールとASLファイルを使い、boto3のcreate_state_machineでステートマシンを登録します。

import boto3

sfn = boto3.client("stepfunctions", region_name="ap-northeast-1")

with open("workflow.asl.json") as f:
    definition = f.read()

response = sfn.create_state_machine(
    name="order-workflow",
    definition=definition,
    roleArn="arn:aws:iam::123456789012:role/StepFunctionsOrderRole",
    type="STANDARD",
)
print(response["stateMachineArn"])

戻り値のstateMachineArnは、実行時に必要になるので控えておきます。

定義を修正したい場合はupdate_state_machineで同じARNのまま更新できます。

ワークフローを実行して結果を取得する

start_executionで実行を開始し、describe_executionでステータスを確認します。

import json
import time

execution = sfn.start_execution(
    stateMachineArn="arn:aws:states:ap-northeast-1:123456789012:stateMachine:order-workflow",
    input=json.dumps({"order": {"id": "A-1001", "items": [{"price": 1200}]}}),
)

execution_arn = execution["executionArn"]

while True:
    result = sfn.describe_execution(executionArn=execution_arn)
    status = result["status"]
    if status != "RUNNING":
        break
    time.sleep(2)

print(status)
if status == "SUCCEEDED":
    print(json.loads(result["output"]))

statusはRUNNINGから始まり、SUCCEEDED・FAILED・TIMED_OUT・ABORTEDのいずれかで確定します。

SUCCEEDEDのとき、outputに最後のLambdaが返したJSONが文字列で入っています。

いずみ

短時間で終わる処理なら数秒のポーリングで十分ですが、長い処理はEventBridge経由で完了通知を受け取る作りが楽です。

コンソールで実行結果を確認する

Step Functionsのコンソールを開くと、実行ごとにワークフローのグラフが表示されます。

成功したステートは緑、失敗したステートは赤で色分けされ、各ステートの入力と出力のJSONも確認できます。

リトライが発生した回数も履歴に残るため、どこで詰まっているか調査しやすくなっています。

スクロールできます
【当サイト】おすすめフリーランスエージェント3選
エージェント評価ポイント公式サイト
レバテックフリーランス

5.0
業界最大級のエージェント。
高単価案件が豊富。
公式
Midworks

4.8
満足度調査で
3年連続3冠を達成。
公式
ITプロパートナーズ

4.6
週2〜3向けの案件が豊富。公式

【厳選】フリーランスエンジニアにおすすめなエージェント3選

フリーランスエンジニアになるにはエージェントから案件をもらう必要があります。

僕が実際に利用しているおすすめエージェントを紹介しますね。

いずみ

エージェントは必ず複数登録してください。

担当者によっては「全然案件紹介してくれない…」みたいなこともあるので…

僕は実際に5つのエージェントを使い回していますよ。

フリーランスを始めるなら「

案件数マージン率単価
約88,000件非公開
初心者福利厚生申し込み
無料
Good Point
  • 業界最大級の案件数。
  • 業界トップクラスの高単価報酬、低マージン(平均年収862万円)。
  • 案件参画中のフォローの充実。

※詳細は「【業界最大手】レバテックフリーランスとは?メリットや利用手順を解説!」を参照。

は業界最大手のフリーランスエージェントです。

とにかく案件数が多いので、とりあえず登録しておけば間違いないエージェントです!

いずみ

僕もはじめてフリーランスの案件を貰ったのはです。

保有している案件数が多いので、業務経験がなくても何かしらの案件は紹介してもらえますよ(僕はJavaの経験3年でも案件を貰えました)。

手厚い保障を重視したいなら「

案件数マージン率単価
約10,000件非公開
初心者福利厚生申し込み
無料
Good Point
  • 手厚い保障で正社員並みの安心感。
  • 還元率60%超え&単価公開でクリアな契約。
  • 給与保障制度(審査あり)。

は手厚い保障が特徴のフリーランスエージェントです。

フリーランスを目指しているけど不安な方や保障を重視したい方におすすめです。

いずみ

僕も何度か案件を紹介してもらいました。

自分のスキルに合った案件を紹介してもらえましたし、電話のやり取りも非常に丁寧でした。

週2〜3日の案件探しなら「

案件数マージン率単価
約5,000件非公開
初心者福利厚生申し込み
経験者向け無料
Good Point
  • IT案件に特化したフリーランスエージェント。
  • 週2〜3日の案件が豊富。
  • リモート案件が多く、直エンドなので単価も高い。

※詳細は「【週2・3案件】ITプロパートナーズとは?メリットや利用手順を解説!」を参照。

はIT案件に特化したフリーランスエージェントです。

週2〜3日から参画できる案件が豊富なので、起業したい人にもおすすめです。

いずみ

週2〜3日の案件はある程度スキルがないと紹介してもらえない印象です。

とはいえ、週5の案件ももちろんありますし、僕が利用した時は迅速・丁寧に対応していただきました!

よくある質問

StandardワークフローとExpressワークフローの違いは何ですか?

Standardは実行履歴が残り、最長1年間の実行に対応するため、確実性が求められる業務処理に向いています。

Expressは大量かつ短時間のイベント処理向けで、料金は実行回数と実行時間から算出されます。

ワークフロー定義を変更したら実行中の処理はどうなりますか?

update_state_machineによる更新は、更新後に開始される実行から反映されます。

すでに動いている実行は、開始時点の定義のまま最後まで処理されます。

ローカルで動作確認する方法はありますか?

AWSが配布するStep Functions Localのdockerイメージを使うと、手元でステートマシンを実行できます。

Lambda呼び出し部分はモックのエンドポイントに差し替えて検証します。

まとめ

今回は、Step FunctionsでLambdaを繋ぐワークフローを実装する方法について解説しました。

以下が本記事のまとめになります。

まとめ
  • Step FunctionsはAmazon States LanguageのJSONで、処理順序とエラー時の挙動を宣言的に定義できる。
  • TaskステートのResourceにLambdaのARNを指定し、RetryとCatchでリトライとフォールバックを組み込める。
  • boto3のcreate_state_machineで登録し、start_executionとdescribe_executionで実行と結果取得ができる。
まとめ
いずみ

最後までお読みいただき、ありがとうございました!

スクロールできます
【当サイト】おすすめフリーランスエージェント3選
エージェント評価ポイント公式サイト
レバテックフリーランス

5.0
業界最大級のエージェント。
高単価案件が豊富。
公式
Midworks

4.8
満足度調査で
3年連続3冠を達成。
公式
ITプロパートナーズ

4.6
週2〜3向けの案件が豊富。公式
  • クソおすすめ本
¥4,480 (2024/06/01 23:28時点 | Amazon調べ)
\楽天ポイント4倍セール!/
楽天市場
いずみ

海外のエンジニアがどういった思考で働いているかが理解できます。

海外に行く気はないけど海外エンジニアの動向が気になる雑魚エンジニアにおすすめです(本当におすすめな本しか紹介しないのでご安心を)。

この記事が気に入ったら
フォローしてね!

シェアしてね!
  • URLをコピーしました!
目次