Step Functions Workflow Studio with Serverless Framework
Tags: serverless, aws, tutorial, cloud
Published: 2021-08-11 07:02:06

The [serverless-step-functions plugin](https://www.serverless.com/plugins/serverless-step-functions) is a nifty [Serverless Framework](https://github.com/serverless/serverless) extension that allows you to define step functions directly within the `serverless.yml`. However, the definitions for step functions tend to get messy fast and it's hard to visualize how a workflow actually looks and flows just from looking at the YAML. The [Step Functions Workflow Studio](https://aws.amazon.com/blogs/aws/new-aws-step-functions-workflow-studio-a-low-code-visual-tool-for-building-state-machines/) helps you with exactly this by allowing you to interactively sketch out your state machine. In this post, I'll give you a brief walkthrough of how we can use the Workflow Studio together with the Step Functions plugin.

## Creating a State Machine

To get started, navigate to the [Step Functions](console.aws.amazon.com/states/) page in the AWS Console and press "**Create state machine**".

![image-20210716221315868](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrou3d3cevtvwxhjwex0.png)

Next, choose "**Design your workflow visually**", then go to **Next**.

![image-20210716221446618](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qhz8uwx9rugwt8gxo05f.png)

From here, you can drag and drop *Actions* and *Flows*, tinker with the properties, flow, and error handling until you're happy with the design.

![image-20210716221527803](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5xdounm9kcb24jtrjdr1.png)



Set any resources that you want to eventually define in your serverless app to refer to a made-up value in the meantime - setting the Lambda *Function name* to just a string name for example. Once you're done, click "**Next**".

![image-20210811082837045](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k45mi92v2fkiwxljuse6.png)

At last, we have our generated JSON schema for the state machine! But wait. Our Serverless template is in YAML, not JSON - how do we translate this into something that we can actually use? 

![image-20210716221635101](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhrgz7numjjne5bujv7g.png)


As it turns out, [YAML is just a superset of JSON](https://www.geeksforgeeks.org/what-is-the-difference-between-yaml-and-json/), meaning all JSON is valid YAML. The JSON that was generated is in the form of [Amazon State Languages spec](https://states-language.net/spec.html), and that same spec is used by our serverless-step-functions plugin. This means that we can translate our JSON snippet to YAML using an online tool, such as [Code Beatify](https://codebeautify.org/json-to-yaml), or a CLI tool such as [yq](https://mikefarah.gitbook.io/yq/usage/convert).

![image-20210716221957330](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qeoq7f9h7giuu206p9nz.png)


Now that we've got the state machine defined in YAML, all we need to do is actually use it in the `serverless.yml`. 

## Putting it together

> If you don't already have a serverless project set up, check out my [guide to a simple esbuild setup](https://dev.to/aws-builders/lightning-fast-simple-typescript-serverless-builds-33ed) or just run `serverless` in your terminal to choose from one of the boilerplates.

The serverless-step-functions plugin extends the `serverless.yml` format with a root `stepFunctions` property. We'll use that to define our step function by pasting in our YAML snippet as the definition of the state machine.

```yaml
// serverless.yml
[...]

stepFunctions:
  stateMachines:
    myStateMachine:
    	name: MyStateMachine
    	[your generated state machine goes here]
```

Keep in mind that any references to Lambda functions or other services that we used placeholder references for needs to be updated to refer to the actual resources we want them to point to. As an example, a Lambda definition might look like this when generated:

```yaml
FirstFunction:
  Type: Task
  Resource: arn:aws:states:::lambda:invoke
  OutputPath: $.Payload
  Parameters:
    Payload.$: $
    FunctionName: firstFunction

```

and we can change that to instead refer to a `firstFunction` Lambda defined in our stack by changing it to:

```yaml
FirstFunction:
  Type: Task
  Resource: !GetAtt firstFunction.Arn
  OutputPath: "$.Payload"
  Parameters:
		Payload.$: "$"
```



For the workflow from the examples above, this is what the full `serverless.yml` might look like.

```yaml
service: step-functions-demo

plugins:
  - serverless-step-functions

provider:
  name: aws
  runtime: nodejs14.x

stepFunctions:
  stateMachines:
    myStateMachine:
      name: MyStateMachine
      definition:
        Comment: This is your state machine
        StartAt: First function
        States:
          First function:
            Type: Task
            Resource: !GetAtt firstFunction.Arn
            OutputPath: "$.Payload"
            Parameters:
              Payload.$: "$"
            Retry:
            - ErrorEquals:
              - Lambda.ServiceException
              - Lambda.AWSLambdaException
              - Lambda.SdkClientException
              IntervalSeconds: 2
              MaxAttempts: 6
              BackoffRate: 2
            Next: Wait
          Wait:
            Type: Wait
            Seconds: 5
            Next: Second function
          Second function:
            Type: Task
            Resource: !GetAtt secondFunction.Arn
            OutputPath: "$.Payload"
            Parameters:
              Payload.$: "$"
            Retry:
            - ErrorEquals:
              - Lambda.ServiceException
              - Lambda.AWSLambdaException
              - Lambda.SdkClientException
              IntervalSeconds: 2
              MaxAttempts: 6
              BackoffRate: 2
            End: true

functions:
  firstFunction:
    handler: src/functions/first.handler
  secondFunction:
    handler: src/functions/second.handler
```



------

**If you enjoyed this post and want to see more**, follow me on Twitter at [@TastefulElk](https://twitter.com/tastefulelk) where I frequently write about serverless tech, AWS, and developer productivity! 👋