見出し画像

AWS_Step Functionsのステップ間で値を受け渡す(lambda_handler) #492

Step Functionsの基本的な使い方と、ステップ間でデータをどのように受け渡すかをまとめてみたいと思います。今回、受け渡された値はlambda_handlerで処理する前提で記述しています。

Step Functionsとは

AWS Step Functionsでは、状態機械(State Machine)を定義し、それぞれのステップ(状態)が実行されるたびに結果を次のステップに渡すことができます。状態機械は、JSONベースの構成ファイルで定義されるAmazon States Language (ASL)で記述します。

主要なステートタイプは以下の通りです。

  • Taskステート: Lambdaや他のAWSサービスを呼び出す

  • Choiceステート: 条件分岐を処理する

  • Parallelステート: 複数のステップを並列に実行

  • Mapステート: 繰り返し処理を行う

Step Functionsの基本構造

まずシンプルなLambda関数を使って、状態機械を定義する基本構造を見ていきます。ここでは、2つのLambda関数を実行するステートマシンを作成し、それらの間でデータを受け渡します。

↓Lambdaを呼び出すStep Functions

{
  "Comment": "Lambda関数を2つ呼び出す例",
  "StartAt": "FirstLambda",
  "States": {
    "FirstLambda": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:FirstLambda",
      "Next": "SecondLambda"
    },
    "SecondLambda": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:SecondLambda",
      "End": true
    }
  }
}

ステップ間での値の受け渡し

Step Functionsでは、各ステップの出力を次のステップに渡すことができます。受け渡しの方法はデフォルト、ResultPath、InputPath、OutputPathなど複数あり、柔軟に制御可能です。

デフォルトの例

デフォルトではステップの出力がそのまま次のステップの入力になります。

{
  "StartAt": "FirstLambda",
  "States": {
    "FirstLambda": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:FirstLambda",
      "Next": "SecondLambda"
    },
    "SecondLambda": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:SecondLambda",
      "End": true
    }
  }
}

この時、まずFirstLambdaから以下のように出力されます。

{
  "message": "Hello from FirstLambda",
  "statusCode": 200
}

この出力はそのまま次のステップである SecondLambda に渡され、 SecondLambdaのlambda_handlerで次のように使用できます。

import json

def lambda_handler(event, context):
    # eventはFirstLambdaから渡されたデータ
    message = event.get('message')
    status_code = event.get('statusCode')

    return {
        'statusCode': 200,
        'body': json.dumps(f"Received: {message}, with status {status_code}")
    }


ResultPathの使用例

ResultPath を使用すると、前のステップの結果を入力の一部にマージしたり、特定のパスに結果を格納できます。

{
  "StartAt": "FirstLambda",
  "States": {
    "FirstLambda": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:FirstLambda",
      "ResultPath": "$.lambdaResult",  // 結果を$.lambdaResultに格納
      "Next": "SecondLambda"
    },
    "SecondLambda": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:SecondLambda",
      "End": true
    }
  }
}

この場合、FirstLambdaの出力は次のステップの入力全体ではなく、$.lambdaResultに格納され、元の入力データが保持されます。

{
  "lambdaResult": {
    "message": "Hello from FirstLambda",
    "statusCode": 200
  }
}

この出力はSecondLambdaのlambda_handlerで次のように使用できます。

import json

def lambda_handler(event, context):
    # eventからlambdaResult内のデータを取得
    result = event.get('lambdaResult', {})
    message = result.get('message')
    status_code = result.get('statusCode')

    return {
        'statusCode': 200,
        'body': json.dumps(f"Received: {message}, with status {status_code}")
    }


InputPathの使用例

InputPath を使用して、前のステップの出力の一部だけを次のステップに渡すことができます。

{
  "StartAt": "FirstLambda",
  "States": {
    "FirstLambda": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:FirstLambda",
      "Next": "SecondLambda"
    },
    "SecondLambda": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:SecondLambda",
      "InputPath": "$.lambdaResult",  // lambdaResultだけを次のステップに渡す
      "End": true
    }
  }
}

この設定では、FirstLambda の出力全体ではなく、 lambdaResult の部分だけが次のステップに渡されます。例えばFirstLamdaで以下のように複数の出力がある場合、lambdaResultだけ渡される形です。

{
  "lambdaResult": {
    "message": "Hello from FirstLambda",
    "statusCode": 200
  },
  "extraInfo": "This part is not passed"
}

この時、SecondLambdaには以下の形式で渡されます。

{
  "message": "Hello from FirstLambda",
  "statusCode": 200
}

この出力はSecondLambdaのlambda_handlerで次のように使用できます。

import json

def lambda_handler(event, context):
    # 受け取ったeventはlambdaResult内のデータ
    message = event.get('message')
    status_code = event.get('statusCode')

    return {
        'statusCode': 200,
        'body': json.dumps(f"Received: {message}, with status {status_code}")
    }


OutputPathの使用例

OutputPath を使うと、ステップの出力の一部を次のステップに渡すことができます。これにより、ステップの結果全体ではなく、特定のフィールドのみを出力できます。

{
  "StartAt": "FirstLambda",
  "States": {
    "FirstLambda": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:FirstLambda",
      "OutputPath": "$.lambdaResult",  // 結果の一部だけを出力
      "Next": "SecondLambda"
    },
    "SecondLambda": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:SecondLambda",
      "End": true
    }
  }
}

先ほどのInputPathとほぼ同じで、FirstLambdaで定義するかSecondLambdaで定義するかだけが違いです。出力例や使用方法は割愛します。


値の受け渡しをマスターすると、StepFunctionsを本当の意味で使いこなせているような感じがしますね。

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

参考


この記事が気に入ったらサポートをしてみませんか?