[PYTHON] [AWS] Play with Step Functions (SAM + Lambda) Part.2 (Parameter)

Review of Part.1

In Part1, we mainly did the following.

--Create a Lambda function (SAM) --Deploy Lambda functions (SAM) --Configure a state machine --Call a Lambda function (only) --Deploy a state machine (SAM) --Run the state machine (Management Console)

This time, I will start from the continuation. If you start from here, https://github.com/hito-psv/sam-demo-004 It's okay to have the code of `git clone``, or you can try it from Part1.

This time's target

--Try passing fixed arguments to Lambda --Try passing an external argument to Lambda --Try passing a context object to Lambda --Try passing the return value of Lambda to the argument of another Task

I would like to target. Regarding the Lambda part, I would like to play around with the "Hello World" function created in Part1 and try various things.

Preparation

Modify the Lambda function

It's basically Hello World, but to check the contents of the arguments, let's add only the description that outputs the contents of the arguments to CloudWatch. hello_world / app.py is still the default created from the template, so try the following, including refactoring.

hello_world/app.py


import json
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    logger.info(event)
    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "hello world",
        })
    }

Build / deploy

In this state, execute sam build, sam deploy --guided to deploy the Lambda function.

Try passing fixed arguments to Lambda

Modify state machine definition

First, it's a fixed parameter, but you need to change the definition of the state machine. The change is to add Parameters.

step_functions/state_machine.json


{
    "StartAt": "hello world",
    "States": {
      "hello world": {
        "Type": "Task",
        "Resource": "${HelloWorldFunction}",
        "Parameters": {
          "p1": 100,
          "p2": "0123",
          "p3": {
            "p3-1": 20,
            "p3-2": "xyz"
          }
        },
        "End": true
      }
    }
  }

Try running a state machine

Let's run the state machine from the management console. This time, the parameters to be passed to the state machine definition are fixedly set, so the input is fine.

sf1.png

Check out CloudWatch Logs

You can transition from the state machine to CloudWatch Logs of the executed Lambda function, so let's check the contents of the log from there.

cw1.png

You can see that the parameters set in the state machine definition have been passed to the first argument ʻevents` of the Lambda function.

Try passing an external argument to Lambda

Modify state machine definition

Then modify the state machine definition to use the input value to the state machine for the parameter. The point is

--The input value can be used only if the Key part ends with ". " --Specify the Key name of the input parameter after "." In the Value part. --If you enter "$" in the Value part of the Key that passes the input value, you can pass all the input values as parameters.

is. Now, let's fix it in consideration of these.

step_functions/state_machine.json


{
    "StartAt": "hello world",
    "States": {
      "hello world": {
        "Type": "Task",
        "Resource": "${HelloWorldFunction}",
        "Parameters": {
          "p1.$": $.p1,
          "p2.$": "$.p2",
          "p3": {
            "p3-1": 20,
            "p3-2": "xyz"
          },
          "all.$": "$"
        },
        "End": true
      }
    }
  }

Try running a state machine

Let's run the state machine from the management console. This time, we will use p1 and p2, so specify the input orchid as follows.

sf2.png

--Specify a 9999 value for p1 --Specify the string "p2 strings." For p2

Check out CloudWatch Logs

Now let's take a look at the CloudWatch Logs for Lambda functions.

--The number 9999 in p1 --The string "p2 strings." In p2 --All input values to all

You can see that is set. The order has been changed, but there is no problem with the reference as Json data.

cw2.png

What happens if no parameter is specified for the input value?

When running the state machine

{
    "Comment": "Insert your JSON here"
}

What happens if there is no "p1" or "p2" required in the definition of the state machine, but the execution of the state machine fails. In this case, the state machine will fail before calling the Lambda function.

{
  "error": "States.Runtime",
  "cause": "An error occurred while executing the state 'hello world' (entered at the event id #2). The JSONPath '$.p1' specified for the field 'p1.$' could not be found in the input '{\n    \"Comment\": \"Insert your JSON here\"\n}'"
}

Try passing a context object to Lambda

Modify state machine definition

Modify the state machine in the same way, but before that, what is a context object? There is a question. A context object is information about a state machine and execution. Specifically, Role information, execution time, task name, etc. To pass a context object to your Lambda function

--The input value can be used only if the Key part ends with ". " --Specify "$" in the Value part of the Key that passes the input value

is. Now, let's fix it in consideration of these.

step_functions/state_machine.json


{
    "StartAt": "hello world",
    "States": {
      "hello world": {
        "Type": "Task",
        "Resource": "${HelloWorldFunction}",
        "Parameters": {
          "p1.$": $.p1,
          "p2.$": "$.p2",
          "p3": {
            "p3-1": 20,
            "p3-2": "xyz"
          },
          "all.$": "$",
          "context.$": "$$"
        },
        "End": true
      }
    }
  }

Try running a state machine

Let's run the state machine from the management console. Specify "p1" and "p2" and execute.

Check out CloudWatch Logs

Now let's take a look at the CloudWatch Logs for Lambda functions.

--In context, a context object (what you think)

You can see that is set.

cw3.png

Try passing the Lambda return value to another Task argument

Finally, this is it. This time, I would like to use HelloWorld's Lambda function.

Modify Lambda function

First, the current Hello World Lambda function outputs the following result.

{
  "statusCode": 200,
  "body": "{\"message\": \"hello world\"}"
}

Actually, this is a little troublesome, and the result of the body part has become character string data. So let's tweak the Lambda function a bit so that we can return it in Json structure. Simply remove the extra stringing process when returning the result.

hello_world/app.py


import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    logger.info(event)
    return {
        "statusCode": 200,
        "body": {
            "message": "hello world",
        }
    }

Modify state machine definition

This time, I'll call the HelloWorld Lambda function twice. The major changes this time are as follows.

--Changed the state name to "hello world 1 | 2" format --Along with that, change the first state name to hello world 1 with StartAt --Added ResultPath and ʻOutputPath to hello world 1 --Specifyhello world 2 for Nextofhello world 1 --Addedhello world 2`

The ResultPath of hello_world_1 holds the result of the Lambda function with the Key name hello_world_result. The contents are reflected in the entire input contents with ʻOutput Path. In hello_world_2, by specifying" $ "in ʻInputPath, the entire input value to hello world 1 including hello_world_result is passed to the Lambda function.

step_functions/state_machine.json


{
  "StartAt": "hello world 1",
  "States": {
    "hello world 1": {
      "Type": "Task",
      "Resource": "${HelloWorldFunction}",
      "Parameters": {
        "p1.$": $.p1,
        "p2.$": "$.p2",
        "p3": {
          "p3-1": 20,
          "p3-2": "xyz"
        },
        "all.$": "$"
      },
      "ResultPath": "$.hello_world_result",
      "OutputPath": "$",
      "Next": "hello world 2"
    },
    "hello world 2": {
      "Type": "Task",
      "Resource": "${HelloWorldFunction}",
      "InputPath": "$",
      "End": true
    }
  }
}

Try running a state machine

Let's run the state machine from the management console. Specify "p1" and "p2" and execute.

First, make sure you are called twice, hello world 1 and hello world 2.

sf5.png

Check out CloudWatch Logs

Now let's take a look at the CloudWatch Logs for Lambda functions.

--In hello world 1 (red frame), the parameters are the same as before. --In hello_world_2 (blue frame), in addition to the parameter of hello world 1, the response of hello world 1 (hello_world_result) is added.

You can see that is set.

cw5.png

Summary

This time, I tried to verify how to pass parameters and how to pass results. If you learn how to use "$", it will not be so difficult.

Next time, I would like to examine the branching due to the result.

Sample code repository

https://github.com/hito-psv/sam-demo-005

Recommended Posts

[AWS] Play with Step Functions (SAM + Lambda) Part.2 (Parameter)
[AWS] Play with Step Functions (SAM + Lambda) Part.3 (Branch)
[AWS] Play with Step Functions (SAM + Lambda) Part.1 (Basic)
[AWS SAM] Create API with DynamoDB + Lambda + API Gateway
Regular serverless scraping with AWS lambda + scrapy Part 1.8
Serverless scraping using selenium with [AWS Lambda] -Part 1-
Serverless application with AWS SAM! (APIGATEWAY + Lambda (Python))
AWS Step Functions to learn with a sample
Delete DynamoDB data after 5 minutes with AWS Step Functions
AWS Lambda with PyTorch [Lambda import]
[AWS] Try adding Python library to Layer with SAM + Lambda (Python)
Create API with Python, lambda, API Gateway quickly using AWS SAM
[AWS] Create API with API Gateway + Lambda
Using Lambda with AWS Amplify with Go
Serverless scraping on a regular basis with AWS lambda + scrapy Part 1
[AWS] Using ini files with Lambda [Python]
Play handwritten numbers with python Part 2 (identify)
I want to play with aws with python
[AWS] Link Lambda and S3 with boto3
Connect to s3 with AWS Lambda Python
[AWS] Do SSI-like things with S3 / Lambda
Python + Selenium + Headless Chromium with aws lambda
I just did FizzBuzz with AWS Lambda
Play with Lambda layer (python) for about 5 minutes
LINE BOT with Python + AWS Lambda + API Gateway
I tried connecting AWS Lambda with other services
Infrastructure construction automation with CloudFromation + troposphere + AWS Lambda
I wanted to operate google spread sheet with AWS lambda, so I tried it [Part 2]