I have a simple step function launching a lambda and I am looking for a way to pass parameters (event / context) to each of several consequent tasks. My step function looks like this:
{
"Comment": "A Hello World example of the Amazon States Language using an AWS Lambda function",
"StartAt": "HelloWorld",
"States": {
"HelloWorld": {
"Type": "Task",
"Parameters": {
"TableName": "table_example"
},
"Resource": "arn:aws:lambda:ap-southeast-2:XXXXXXX:function:fields_sync",
"End": true
}
}
}
In the lambda written with Python I am using a simple handler which is:
def lambda_handler(event, context):
#...
The event and context look like this (checking the logs):
START RequestId: f58140b8-9f04-47d7-9285-510b0357b4c2 Version: $LATEST
I cannot find a way to pass parameters to this lambda and to use them in the script. Essentially, what I am trying to do is to run the same lambda passing a few different values as a parameter.
Could anyone please point me in the right direction?
Based on what you said: "looking for a a way to pass parameters (event / context) to each of several consequent tasks" I assumed that you want to pass non-static values to lambdas.
There are two ways to pass arguments through state machine. Via InputPath
and Parameters
. For differences please look here.
If you do not have any static values that you want to pass to lambda, I would do the following. Passed all parameters to step function in json format.
Input JSON for state machine
{
"foo": 123,
"bar": ["a", "b", "c"],
"car": {
"cdr": true
}
"TableName": "table_example"
}
In step function you are passing entire JSON explicitly to lambda using "InputPath": "$"
, except for a first step where it is passed implicitly. For more about $
path syntax please look here. You also need to take care of task result, with one of multiple approaches using ResultPath
. For most of cases the safest solution is to keep task result in special variable "ResultPath": "$.taskresult"
{
"Comment": "A Hello World example of the Amazon States Language using an AWS Lambda function",
"StartAt": "HelloWorld",
"States": {
"HelloWorld": {
"Type": "Task",
"Resource": "arn:aws:lambda:ap-southeast-2:XXXXXXX:function:fields_sync",
"Next": "HelloWorld2"
},
"HelloWorld2": {
"Type": "Task",
"InputPath": "$",
"ResultPath": "$.taskresult"
"Resource": "arn:aws:lambda:ap-southeast-2:XXXXXXX:function:fields_sync_2",
"End": true
}
}
}
Which in lambda became event variable and can be access as python dictionary
def lambda_handler(event, context):
table_example = event["TableName"]
a = event["bar"][0]
cdr_value = event["car"]["cdr"]
# taskresult will not exist as event key
# only on lambda triggered by first state
# in the rest of subsequent states
# it will hold a task result of last executed state
taskresult = event["taskresult"]
With this approach you can use multiple step functions and different lambdas and still keep both of them clean and small by moving all the logic in lambdas.
Also it is easier to debug because all events variables will be the same in all lambdas, so via simple print(event)
you can see all parameters needed for entire state machine and what possibly went wrong.