Skip to content

Lambdas deployed on Localstack

Christophe Bougère edited this page Jan 8, 2019 · 6 revisions

Test stepfunctions-local with Lambdas deployed on Localstack

Prerequesites

Some dependencies are required in order to use the test commands.

Start servers

You need to start stepfunctions-local + localstack servers:

# start stepfunctions-local server
DEBUG=stepfunctions-local:* stepfunctions-local start --lambda-endpoint http://localhost:4574 --lambda-region us-east-1

# start localstack server
SERVICES=lambda LAMBDA_EXECUTOR=docker localstack start

Create lambda functions

We will create three simple lambda functions:

  • Success: A lambda function that will succeed
  • InternalErrorNotHandled: A lambda function that will fail because of an internal error (error not handled)
  • InternalErrorHandled: A lambda function that will fail because of an internal error (error handled)
  • Timeout: A lambda function that will timeout
# create handlers file (handlers.json)
echo 'module.exports.successHandler = function (event, context, callback) { event.result = { key: { subkey: "value" }}; callback(null, event); };
module.exports.internalErrorNotHandledHandler = function (event, context, callback) { throw new Error("Internal Error"); };
module.exports.internalErrorHandledHandler = function (event, context, callback) { try { throw new Error("Internal Error"); } catch (e) { callback(e); } };
module.exports.timeoutHandler = function (event, context, callback) { setTimeout(function() { callback(null, event); }, (context.getRemainingTimeInMillis() + 1000)); };' > handlers.js

# create zipfile (handlers.zip)
zip handlers.zip handlers.js

# create the functions and export lambda arns
aws lambda --endpoint http://localhost:4574 create-function --function-name Success --runtime nodejs6.10 --role success-role --handler handlers.successHandler --zip-file fileb://handlers.zip | export SUCCESS_LAMBDA_ARN=`jq -r .FunctionArn`

aws lambda --endpoint http://localhost:4574 create-function --function-name InternalNotHandledError --runtime nodejs6.10 --role internal-error-role --handler handlers.internalErrorNotHandledHandler --zip-file fileb://handlers.zip | export INTERNAL_ERROR_NOT_HANDLED_LAMBDA_ARN=`jq -r .FunctionArn`

aws lambda --endpoint http://localhost:4574 create-function --function-name InternalHandledError --runtime nodejs6.10 --role internal-error-role --handler handlers.internalErrorHandledHandler --zip-file fileb://handlers.zip | export INTERNAL_ERROR_HANDLED_LAMBDA_ARN=`jq -r .FunctionArn`

aws lambda --endpoint http://localhost:4574 create-function --function-name Timeout --runtime nodejs6.10 --role timeout-role --handler handlers.timeoutHandler --zip-file fileb://handlers.zip | export TIMEOUT_LAMBDA_ARN=`jq -r .FunctionArn`

You now have $SUCCESS_LAMBDA_ARN, $INTERNAL_ERROR_NOT_HANDLED_LAMBDA_ARN, $INTERNAL_ERROR_HANDLED_LAMBDA_ARN and $TIMEOUT_LAMBDA_ARN as environment variables containing the corresponding lambda functions arn.

Create State Machine

We will now create a simple State Machine.

cat <<EOF | xargs -0 aws stepfunctions --endpoint http://localhost:4584 create-state-machine --name test-state-machine --role-arn arn:aws:iam::0123456789:role/service-role/MyRole --definition
{"Comment": "Test Step Function","StartAt": "StartState","States": {"StartState": {"Type": "Pass","Next": "ChoiceState"},"ChoiceState": {"Type": "Choice","Choices": [{"Variable": "$.lambda","StringEquals": "InternalErrorNotHandled","Next": "InternalErrorNotHandledLambda"},{"Variable": "$.lambda","StringEquals": "InternalErrorHandled","Next": "InternalErrorHandledLambda"},{"Variable": "$.lambda","StringEquals": "Success","Next": "SuccessLambda"},{"Variable": "$.lambda","StringEquals": "Timeout","Next": "TimeoutLambda"}],"Default": "FailState"},"FailState": {"Type": "Fail","Error": "NoLambdaError","Cause": "No Matches!"},"SuccessLambda": {"Type": "Task","Resource": "$SUCCESS_LAMBDA_ARN","Next": "EndState"},"InternalErrorNotHandledLambda": {"Type": "Task","Resource": "$INTERNAL_ERROR_NOT_HANDLED_LAMBDA_ARN","Next": "EndState"},"InternalErrorHandledLambda": {"Type": "Task","Resource": "$INTERNAL_ERROR_HANDLED_LAMBDA_ARN","Next": "EndState"},"TimeoutLambda": {"Type": "Task","Resource": "$TIMEOUT_LAMBDA_ARN","Next": "EndState"},"EndState": {"Type": "Pass","End": true}}}
EOF

aws stepfunctions --endpoint http://localhost:4584 list-state-machines | export STATE_MACHINE_ARN=`jq -r .stateMachines[0].stateMachineArn`

Execute state machine

We will now execute the state machine with different inputs in order to trigger the different lambdas.
The lambda key contained in the input will be used as a filter to trigger the different lambdas.
It can take the following values:

  • Success > will trigger Success lambda
  • Timeout > will trigger Timeout lambda
  • InternalErrorNotHandled > will trigger InternalErrorNotHandled lambda
  • InternalErrorHandled > will trigger InternalErrorHandled lambda
# Success lambda
aws stepfunctions --endpoint http://localhost:4584 start-execution --state-machine-arn $STATE_MACHINE_ARN --input '{"lambda":"Success"}' --name success-execution

# InternalErrorNotHandled lambda
aws stepfunctions --endpoint http://localhost:4584 start-execution --state-machine-arn $STATE_MACHINE_ARN --input '{"lambda":"InternalErrorNotHandled"}' --name internal-error-not-handled-execution

# InternalErrorHandled lambda
aws stepfunctions --endpoint http://localhost:4584 start-execution --state-machine-arn $STATE_MACHINE_ARN --input '{"lambda":"InternalErrorHandled"}' --name internal-error-handled-execution

# Timeout lambda
aws stepfunctions --endpoint http://localhost:4584 start-execution --state-machine-arn $STATE_MACHINE_ARN --input '{"lambda":"Timeout"}' --name timeout-execution

The listing of the state machine executions should return one success and three failures:

aws stepfunctions --endpoint http://localhost:4584 list-executions --state-machine-arn $STATE_MACHINE_ARN
Clone this wiki locally