Table of Contents
SAM - Combining Lambda and Step Functions in AWS Toolkit for VS Code
This this page is the follow up from awstoolkitforvscode, in which we used the AWS Toolkit for VS Code to deploy a Step Functions State Machine and also created a Serverless Application to deploy Lambda functions. Now that approach was very functional, but not the most efficient. We still had to do some stuff manually, mainly adding the Lambdas ARNs to the Step Function State Machine. On this page we are going to combine these two in one Serverless Application.
Note that we are still doing the 10 minute tutorial for Step Functions
Note that we continue this story in SAM - Creating a WebApp in AWS Toolkit for VS Code
Create a new SAM
To start fresh we'll copy the SAM-CallCenterLambdas folder to a new one and call it SAM-CallCenterApp. Create an extra folder called “statemachines” and copy the CallCenterStateMachine.asl.json to this folder. Once you've done this we created all the files we need, all we need to do now is to modify them.
Step Function State Machine
The first file we'll edit is the state machine. In here we need to replace the Lambdas ARNs with variables so that upon deployment the variables can be filled with the ARNs automatically. The name of the variables can be random as we'll be referencing them from the template file later on. You could so something like this:
- | CallCenterStateMachine.asl.json
{ "Comment": "A simple AWS Step Functions state machine that automates a call center support session.", "StartAt": "Open Case", "States": { "Open Case": { "Type": "Task", "Resource": "${OpenCaseFunctionArn}", "Next": "Assign Case" }, "Assign Case": { "Type": "Task", "Resource": "${AssignCaseFunctionArn}", "Next": "Work on Case" }, "Work on Case": { "Type": "Task", "Resource": "${WorkOnCaseFunctionArn}", "Next": "Is Case Resolved" }, "Is Case Resolved": { "Type" : "Choice", "Choices": [ { "Variable": "$.Status", "NumericEquals": 1, "Next": "Close Case" }, { "Variable": "$.Status", "NumericEquals": 0, "Next": "Escalate Case" } ] }, "Close Case": { "Type": "Task", "Resource": "${CloseCaseFunctionArn}", "End": true }, "Escalate Case": { "Type": "Task", "Resource": "${EscalateCaseFunctionArn}", "Next": "Fail" }, "Fail": { "Type": "Fail", "Cause": "Engage Tier 2 Support." } } }
Template
Now we need to add the StepFunction to the SAM template file:
- | template.yaml
AWSTemplateFormatVersion: "2010-09-09" Transform: AWS::Serverless-2016-10-31 Description: > SAM-CallCenterApp SAM to deploy Lambda Functions and Step Functions State Machine as described in https://aws.amazon.com/getting-started/hands-on/create-a-serverless-workflow-step-functions-lambda/ Resources: CallCenterStateMachine: Type: AWS::Serverless::StateMachine # More info about State Machine Resource: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-statemachine.html Properties: DefinitionUri: statemachines/CallCenterStateMachine.asl.json DefinitionSubstitutions: OpenCaseFunctionArn: !GetAtt OpenCaseFunction.Arn AssignCaseFunctionArn: !GetAtt AssignCaseFunction.Arn WorkOnCaseFunctionArn: !GetAtt WorkOnCaseFunction.Arn CloseCaseFunctionArn: !GetAtt CloseCaseFunction.Arn EscalateCaseFunctionArn: !GetAtt EscalateCaseFunction.Arn Policies: # Find out more about SAM policy templates: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-policy-templates.html - LambdaInvokePolicy: FunctionName: !Ref OpenCaseFunction - LambdaInvokePolicy: FunctionName: !Ref AssignCaseFunction - LambdaInvokePolicy: FunctionName: !Ref WorkOnCaseFunction - LambdaInvokePolicy: FunctionName: !Ref CloseCaseFunctionp - LambdaInvokePolicy: FunctionName: !Ref EscalateCaseFunction OpenCaseFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html Properties: CodeUri: functions/open-case/ Handler: app.handler #app.lambdaHandler Runtime: nodejs12.x Role: arn:aws:iam::952941930635:role/service-role/OpenCaseFunction-role-53xmbdiv AssignCaseFunction: Type: AWS::Serverless::Function Properties: CodeUri: functions/assign-case/ Handler: app.handler #app.lambdaHandler Runtime: nodejs12.x Role: arn:aws:iam::952941930635:role/service-role/OpenCaseFunction-role-53xmbdiv WorkOnCaseFunction: Type: AWS::Serverless::Function Properties: CodeUri: functions/work-on-case/ Handler: app.handler #app.lambdaHandler Runtime: nodejs12.x Role: arn:aws:iam::952941930635:role/service-role/OpenCaseFunction-role-53xmbdiv CloseCaseFunction: Type: AWS::Serverless::Function Properties: CodeUri: functions/close-case/ Handler: app.handler #app.lambdaHandler Runtime: nodejs12.x Role: arn:aws:iam::952941930635:role/service-role/OpenCaseFunction-role-53xmbdiv EscalateCaseFunction: Type: AWS::Serverless::Function Properties: CodeUri: functions/escalate-case/ Handler: app.handler #app.lambdaHandler Runtime: nodejs12.x Role: arn:aws:iam::952941930635:role/service-role/OpenCaseFunction-role-53xmbdiv # Outputs: # # https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-generated-resources.html # CallCenterStateMachineArn: # Description: "Call Center state machine ARN" # Value: !Ref CallCenterStateMachine # CallCenterStateMachineRole: # Description: "IAM Role created for Call Center state machine based on the specified SAM Policy Templates" # Value: !GetAtt CallCenterStateMachineRole.Arn
Notice:
- That the variables used in the callcenterstatemachine.asl.json file are being referenced in the DefinitionSubstitutions section
- I'm using policies here to automatically create a role. I could also use a pre-defined role as used in the Lambda functions
- I've outcommented the Ouputs, as I don't know yet what they are for and it works without
Deploy
We can now deploy our newly created Serverless Application like this:
- Open the command palette and search for AWS and select AWS: Deploy Serverless Application
- Select the just created template.yaml from the list
- Select the region to deploy to: Europe (Ireland) - eu-west-1
- Provide the name of the S3 bucket we created earlier: vscode-awstoolkitsam
- Provide the name of the (CloudFormation) stack. Notice that all lambda resources will be created with this name as a prefix (not the step function), so keep the name short and simple: sam-callcenterapp
Test
Now everything should work, and to test:
- In the AWS Explorer, navigate to the CallCenterStateMachine
- Right click the state machine and select Start Execution
- As explained in the tutorial, provide the json input below and click Execute
{ "inputCaseID": "001" }
Unfortunately, in the output you can only see that the execution started, not the result, and as the State Machine is also not configured for CloudWatch logging we can only check in the AWS Console what the result is. You could check the CloudWatch Lambda loggroup, but that lacks the overview of the entire Step Function:
- In the AWS Console, go to the Step Functions console
- Click on the CallCenterStateMachine
- You can now check the status of the executions, and click on the execution to go to the Graph Inspector to get a visual overview.
To check the individual Lambda Cloudwatch logs check in AWS Explorer the Cloudwatch Logs. Notice that it could take a while for the logs to show.