AWS Serverless Application Model Supports Step Functions State Machines

The AWS Serverless Application Model (AWS SAM) recently gained support for AWS Step Functions state machines. The new AWS::Serverless::StateMachine resource type enables developers to define state machines within a SAM template or in a separate file so that they can provision workflow orchestration as an integrated part of serverless applications.

The AWS Serverless Application Model (AWS SAM) is an open-source framework that provides a "simple and clean" shorthand syntax extending AWS's infrastructure as code service CloudFormation to ease building serverless applications (previous coverage). It is accompanied by the AWS SAM CLI, which has just become generally available and provides "local tooling to create, develop, debug, and deploy serverless applications".

AWS Step Functions is a serverless workflow orchestration service that allows to "sequence AWS Lambda functions and multiple AWS services into business-critical applications". A Step Functions state machine execution can run for up to one year while automatically managing state, error handling, and retry logic (previous coverage).

As outlined by Rob Sutter in his introductory blog post, the new AWS SAM support for Step Functions via the AWS::Serverless::StateMachine resource type simplifies the definition of workflows in serverless applications. Besides providing a shorthand syntax for configuration options like logging or event-based triggering of workflow executions, this also enables the use of SAM policy templates to scope down the workflow permissions to just those resources used by the application at hand. In turn this allows to forego customer acknowledgments for unscoped IAM permissions when deploying an application from the AWS Serverless Application Repository (previous coverage).

His sample template provisions a DynamoDB table, which is then referenced from the Step Functions state machine via a service integration to the PutItem API action to store information about the workflow execution, and also from a policy template so that all resources can be provisioned together as a single application:

 Resources:    SAMTable:      Type: AWS::Serverless::SimpleTable      SimpleStateMachine:      Type: AWS::Serverless::StateMachine      Properties:        Definition:          StartAt: FirstState          States:            FirstState:              Type: Pass              Next: Write to DynamoDB            Write to DynamoDB:              Type: Task              Resource: arn:aws:states:::dynamodb:putItem              Parameters:                TableName: !Ref SAMTable                Item:                  id:                    S.$: $$.Execution.Id              ResultPath: $.DynamoDB              End: true        Policies:          - DynamoDBWritePolicy:               TableName: !Ref SAMTable

Notably, the state machine can be defined inline via the Definition property in the JSON or YAML based SAM template as in the preceding example, but also via the DefinitionUri property from an Amazon S3 URI or local file path as illustrated below. Regardless, the DefinitionSubstitutions property allows to specify a map of key-value pairs that will substitute matching variable definitions in ${dollar_sign_brace} notation within the state machine:

 StockTraderStateMachine:    Type: AWS::Serverless::StateMachine    Properties:      DefinitionUri: statemachine/stockTrader.asl.json      DefinitionSubstitutions:        StockCheckerFunctionArn: !GetAtt StockCheckerFunction.Arn        StockSellerFunctionArn: !GetAtt StockSellerFunction.Arn        StockBuyerFunctionArn: !GetAtt StockBuyerFunction.Arn        DDBPutItem: !Sub arn:${AWS::Partition}:states:::dynamodb:putItem        DDBTable: !Ref TransactionTable

AWS community hero Ben Kehoe embraced this architectural choice in a tweet:

Listen up, everyone, this is how DSL-deploying APIs (CodeBuild, CodePipeline, SSM Automation docs, …) should work: you define your content in its own file, and use substitution to inject references from your template. I am super excited for this release!

Additional simplifications provided by AWS::Serverless::StateMachine cover the configuration of event sources that can start workflow executions, and the configuration of log destinations that capture the workflow execution history. Both work conceptually similar to how these properties are implemented for other resource types.

In related news, the AWS team has recently added support to "define, visualize, and create" Step Functions workflows via Visual Studio Code. The AWS Toolkit for Visual Studio Code also just gained the ability to debug SAM applications via launch configurations. AWS Step Functions itself has recently gained a new service integration with AWS CodeBuild, which has been complemented by a new action type for AWS CodePipeline to support complex release processes via Step Functions. Together these updates enable developers to automate and customize their software development workflows with fine-grained continuous delivery capabilities, not unlike Microsoft's GitHub Actions.

Developers who prefer the Serverless Framework over AWS SAM can resort to the Serverless Step Functions plugin. Microsoft Azure also offers a designer-first declarative developer experience to create and manage Azure Logic Apps workflow definitions in Visual Studio Code. In contrast, Azure Durable Functions provides code-first imperative orchestration for stateful workflows. Google Cloud Platform's workflow orchestration service Cloud Composer is built atop the open-source Apache Airflow engine and uses imperative workflow definitions via Python based configuration as code.

The AWS Serverless Application Model documentation features a developer guide, including references for the AWS SAM specification, the SAM CLI command reference, and the SAM policy templates. Support is provided via its GitHub repository and a Slack channel. AWS SAM is provided at no additional charge beyond the regular usage-based pricing for provisioned AWS services.