

# Developing workflows with Step Functions
<a name="developing-workflows"></a>

We recommend starting to build workflows in the Step Functions console and Workflow Studio visual editor. You can start from a blank canvas or choose starter templates for common scenarios.

Building your workflows require the following tasks:
+ Defining your workflow
+ Running and debugging your workflow
+ Deploying your workflow

You define a state machine in Amazon States Language. You can manually create your Amazon States Language definitions, but Workflow Studio will be featured in tutorials. With Workflow Studio, you can define, your machine definition, visualize and edit the steps, run and debug your workflow, and view the results all from within the Step Functions console.

**Working with Workflow Studio in Visual Studio Code**  
With the AWS toolkit, you can use Workflow Studio from within VS Code to visualize, build, and even test individual states in your state machines. You provide state inputs and set variables, start the test, then you can see how your data is transformed. You can adjust the workflow and re-test. When finished, you can apply the changes to update the state machine. For more information, see [Working with Workflow Studio](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/stepfunctions-workflowstudio.html) in the AWS Toolkit for Visual Studio Code. 

You can also use many Step Functions features from the AWS Command Line Interface (AWS CLI). For example, you can create a state machine and list your existing state machines. You can use Step Functions commands in the AWS CLI to start and manage executions, poll for activities, record task heartbeats, and more. For a complete list of Step Functions commands, descriptions of the available arguments, and examples showing their use, see the *AWS CLI Command Reference*. [AWS CLI Command Reference](https://docs.aws.amazon.com/cli/latest/reference/)

AWS CLI commands follow the Amazon States Language closely, so you can use the AWS CLI to learn about the Step Functions API actions. You can also use your existing API knowledge to prototype code or perform Step Functions actions from the command line.

**Validating state machine definitions**  
You can use the API to **validate** state machines and find potential problems before creating your workflow.  
To learn more about validating workflows, see [ValidateStateMachineDefinition](https://docs.aws.amazon.com/step-functions/latest/apireference/API_ValidateStateMachineDefinition.html) in the Step Functions API Reference.

To get started with minimal setup, you can follow the [Creating a Lambda State Machine](tutorial-creating-lambda-state-machine.md) tutorial, which shows you how to define a workflow with a single step that calls a Lambda function, then run the workflow, and view the results.

## Defining your workflow
<a name="development-define"></a>

The first step in developing your workflow is defining the steps in Amazon States Language. Depending on your preference and tool, you can define your Step Functions state machines in JSON, YAML, or as a stringified Amazon States Language (ASL) definition.

The following table shows ASL-based definition format support by tool. 


| AWS Tool | Supported format(s) | 
| --- | --- | 
| Step Functions Console | JSON | 
| HTTPS Service API | Stringified ASL | 
| AWS CLI | Stringified ASL | 
| Step Functions Local | Stringified ASL | 
| AWS Toolkit for Visual Studio Code | JSON, YAML | 
| AWS SAM | JSON, YAML | 
| CloudFormation | JSON, YAML, Stringified ASL | 

YAML single line comments in the state machine definition of a template will not be carried forward into the created resource’s definition. If you need to persist a comment, you should use the `Comment` property within the state machine definition. For information, see [State machine structure](statemachine-structure.md).

With CloudFormation and AWS SAM, you can upload your state machine definitions to Amazon S3 (JSON or YAML format) and provide the definition's Amazon S3 location in the template. For information see the [AWS::StepFunctions::StateMachine S3Location](https://docs.aws.amazon.com//AWSCloudFormation/latest/UserGuide/aws-properties-stepfunctions-statemachine-s3location.html) page. 

The following example CloudFormation templates show how you can provide the same state machine definition using different input formats. 

------
#### [ JSON with Definition ]

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "AWS Step Functions sample template.",
  "Resources": {
    "MyStateMachine": {
      "Type": "AWS::StepFunctions::StateMachine",
      "Properties": {
        "RoleArn": {
          "Fn::GetAtt": [ "StateMachineRole", "Arn" ]
        },
        "TracingConfiguration": {
          "Enabled": true
        },
        "Definition": {
          "StartAt": "HelloWorld",
          "States": {
            "HelloWorld": {
              "Type": "Pass",
              "End": true
            }
          }
        }
      }
    },
    "StateMachineRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",		 	 	 
          "Statement": [
            {
              "Action": [
                "sts:AssumeRole"
              ],
              "Effect": "Allow",
              "Principal": {
                "Service": [
                  "states.amazonaws.com"
                ]
              }
            }
          ]
        },
        "ManagedPolicyArns": [],
        "Policies": [
          {
            "PolicyName": "StateMachineRolePolicy",
            "PolicyDocument": {
              "Statement": [
                {
                  "Action": [
                    "lambda:InvokeFunction"
                  ],
                  "Resource": "*",
                  "Effect": "Allow"
                }
              ]
            }
          }
        ]
      }
    }
  },
  "Outputs": {
    "StateMachineArn": {
      "Value": {
        "Ref": "MyStateMachine"
      }
    }
  }
}
```

------
#### [ JSON with DefinitionString ]

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "AWS Step Functions sample template.",
  "Resources": {
    "MyStateMachine": {
      "Type": "AWS::StepFunctions::StateMachine",
      "Properties": {
        "RoleArn": {
          "Fn::GetAtt": [ "StateMachineRole", "Arn" ]
        },
        "TracingConfiguration": {
          "Enabled": true
        },
        "DefinitionString": "{\n  \"StartAt\": \"HelloWorld\",\n  \"States\": {\n    \"HelloWorld\": {\n      \"Type\": \"Pass\",\n      \"End\": true\n    }\n  }\n}"
      }
    },
    "StateMachineRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",		 	 	 
          "Statement": [
            {
              "Action": [
                "sts:AssumeRole"
              ],
              "Effect": "Allow",
              "Principal": {
                "Service": [
                  "states.amazonaws.com"
                ]
              }
            }
          ]
        },
        "ManagedPolicyArns": [],
        "Policies": [
          {
            "PolicyName": "StateMachineRolePolicy",
            "PolicyDocument": {
              "Statement": [
                {
                  "Action": [
                    "lambda:InvokeFunction"
                  ],
                  "Resource": "*",
                  "Effect": "Allow"
                }
              ]
            }
          }
        ]
      }
    }
  },
  "Outputs": {
    "StateMachineArn": {
      "Value": {
        "Ref": "MyStateMachine"
      }
    }
  }
}
```

------
#### [ YAML with Definition ]

```
AWSTemplateFormatVersion: 2010-09-09
Description: AWS Step Functions sample template.
Resources:
  MyStateMachine:
    Type: 'AWS::StepFunctions::StateMachine'
    Properties:
      RoleArn: !GetAtt
        - StateMachineRole
        - Arn
      TracingConfiguration:
        Enabled: true
      Definition:
        # This is a YAML comment. This will not be preserved in the state machine resource's definition.
        Comment: This is an ASL comment. This will be preserved in the state machine resource's definition.
        StartAt: HelloWorld
        States:
          HelloWorld:
            Type: Pass
            End: true
  StateMachineRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Action:
              - 'sts:AssumeRole'
            Effect: Allow
            Principal:
              Service:
                - states.amazonaws.com
      ManagedPolicyArns: []
      Policies:
        - PolicyName: StateMachineRolePolicy
          PolicyDocument:
            Statement:
              - Action:
                  - 'lambda:InvokeFunction'
                Resource: "*"
                Effect: Allow

Outputs:
  StateMachineArn:
    Value:
      Ref: MyStateMachine
```

------
#### [ YAML with DefinitionString ]

```
AWSTemplateFormatVersion: 2010-09-09
Description: AWS Step Functions sample template.
Resources:
  MyStateMachine:
    Type: 'AWS::StepFunctions::StateMachine'
    Properties:
      RoleArn: !GetAtt
        - StateMachineRole
        - Arn
      TracingConfiguration:
        Enabled: true
      DefinitionString: |
        {
            "StartAt": "HelloWorld",
            "States": {
                "HelloWorld": {
                    "Type": "Pass",
                    "End": true
                }
            }
        }
  StateMachineRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Action:
              - 'sts:AssumeRole'
            Effect: Allow
            Principal:
              Service:
                - states.amazonaws.com
      ManagedPolicyArns: []
      Policies:
        - PolicyName: StateMachineRolePolicy
          PolicyDocument:
            Statement:
              - Action:
                  - 'lambda:InvokeFunction'
                Resource: "*"
                Effect: Allow

Outputs:
  StateMachineArn:
    Value:
      Ref: MyStateMachinele
```

------

**Develop workflows with AWS SDKs**  
Step Functions is supported by the AWS SDKs for Java, .NET, Ruby, PHP, Python (Boto 3), JavaScript, Go, and C\$1\$1. These SDKs provide a convenient way to use the Step Functions HTTPS API actions in multiple programming languages. You can develop state machines, activities, or state machine starters using the API actions exposed by these SDK libraries. You can also access visibility operations using these libraries to develop your own Step Functions monitoring and reporting tools. See the reference documentation for the current AWS SDKs and [Tools for Amazon Web Services](http://aws.amazon.com/tools/).

**Develop workflows through HTTPS requests**  
Step Functions provides service operations that are accessible through HTTPS requests. You can use these operations to communicate directly with Step Functions from your own libraries. You can develop state machines, workers, or state machine starters using the service API actions. You can also access visibility operations through the API actions to develop your own monitoring and reporting tools. For details see the [AWS Step Functions API Reference](https://docs.aws.amazon.com/step-functions/latest/apireference/).

**Develop workflows with the AWS Step Functions Data Science SDK**  
Data scientists can create workflows that process and publish machine learning models using SageMaker AI and Step Functions. You can also create multi-step machine learning workflows in Python that orchestrate AWS infrastructure at scale. The AWS Step Functions Data Science SDK provides a Python API that can create and invoke Step Functions workflows. You can manage and execute these workflows directly in Python, as well as Jupyter notebooks. For more information, see: [AWS Step Functions Data Science Project on Github](https://github.com/aws/aws-step-functions-data-science-sdk-python), [data science SDK documentation](https://aws-step-functions-data-science-sdk.readthedocs.io/), and [example Jupyter notebooks](https://docs.aws.amazon.com/sagemaker/latest/dg/howitworks-nbexamples.html) and [SageMaker AI examples on GitHub](https://github.com/awslabs/amazon-sagemaker-examples/tree/master/step-functions-data-science-sdk).

## Running and debugging your workflows
<a name="development-run-debug"></a>

You can start workflows in a number of ways, including from the console, an API call (for example, from a Lambda function), from Amazon EventBridge and EventBridge Scheduler, from another Step Functions state machine. Running workflows can connect to third party services, use AWS SDKs, and manipulate data while running. Various tools exist to both run and debug the execution steps and data flowing through your state machine. The following sections provide additional resources for running and debugging your workflows. 

To learn more about the ways to start state machine executions, see [Starting state machine executions in Step Functions](statemachine-starting.md).

**Choose an endpoint to run your workflows**  
To reduce latency and store data in a location that meets your requirements, Step Functions provides endpoints in different AWS Regions. Each endpoint in Step Functions is completely independent. A state machine or activity exists only within the Region where it was created. Any state machines and activities that you create in one Region do not share any data or attributes with those created in another Region. For example, you can register a state machine named `STATES-Flows-1` in two different Regions. The `STATES-Flows-1` state machine in one region won't share data or attributes with the `STATES-Flow-1` state machine in the other region. For a list of Step Functions endpoints, see [AWS Step Functions Regions and Endpoints](https://docs.aws.amazon.com/general/latest/gr/step-functions.html) in the *AWS General Reference*.

**Development with VS Code**  
With the AWS toolkit, you can use Workflow Studio from within VS Code to visualize, build, and even test individual states in your state machines. You can also use your SAM and CloudFormation definition substitutions. You provide state inputs and set variables, start the test, then you can see how your data is transformed. In the State definition tab, you can adjust the workflow and re-test. When finished, you can apply the changes to update the state machine. For more information, see [Working with Step Functions](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/bulding-stepfunctions.html) and [Working with Workflow Studio](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/stepfunctions-workflowstudio.html) in the AWS Toolkit for Visual Studio Code. 

## Deploying your workflows
<a name="development-deploy"></a>

After you have defined and debugged your workflows, you'll probably want to deploy using Infrastructure as Code frameworks. You can choose to deploy your state machines using a variety of IaC options, including: AWS Serverless Application Model, CloudFormation, AWS CDK, and Terraform.

**AWS Serverless Application Model**  
You can use AWS Serverless Application Model with Step Functions to build workflows and deploy the infrastructure you need, including Lambda functions, APIs and events, to create serverless applications. You can also use the AWS SAM CLI in conjunction with the AWS Toolkit for Visual Studio Code as part of an integrated experience.  
For more information, see [Using AWS SAM to build Step Functions workflows](concepts-sam-sfn.md).

**CloudFormation**  
You can use your state machine definitions directly in CloudFormation templates.  
For more information, see [Using CloudFormation to create a workflow in Step Functions](tutorial-lambda-state-machine-cloudformation.md).

**AWS CDK**  
You can build Standard and Express state machines with AWS CDK.  
To build a Standard workflow, see [Using CDK to create a Standard workflow](tutorial-lambda-state-machine-cdk.md).  
To build an Express workflow, see [Using CDK to create an Express workflow](tutorial-step-functions-rest-api-integration-cdk.md).

**Terraform**  
[Terraform](https://www.terraform.io/intro/) by HashiCorp is a framework for building applications using infrastructure as code (IaC). With Terraform, you can create state machines and use features, such as previewing infrastructure deployments and creating reusable templates. Terraform templates help you maintain and reuse the code by breaking it down into smaller chunks.  
For more information, see [Using Terraform to deploy state machines in Step Functions](terraform-sfn.md).

# Developing workflows in Step Functions Workflow Studio
<a name="workflow-studio"></a>

When editing a workflow in the AWS Step Functions console, you'll use a visual tool called Workflow Studio. With Workflow Studio, you can drag-and-drop states onto a canvas to build your workflows. You can add, edit, and configure states, set input and output filters, transform results, and set up error handling.

As you modify states in your workflow, Workflow Studio will validate and auto-generate the state machine definition. You can review the generated code, edit the configuration, and even modify the text definition with the built-in code editor. When you're finished, you can save your workflow, run it, and then examine the results.

You can access Workflow Studio from the Step Functions console, when you create or edit a workflow. 

You can also use Workflow Studio from **within** AWS Infrastructure Composer, a visual designer to create infrastructure as code with AWS Serverless Application Model and AWS CloudFormation. To discover the benefits of this approach, see [Using Workflow Studio in Infrastructure Composer](use-wfs-in-app-composer.md).

Workflow Studio has three modes: **Design**, **Code**, and **Config**. In *Design mode*, you can drag-and-drop states onto the canvas. *Code mode* provides a built-in code editor for editing your workflow definitions within the console. In *Config mode*, you can manage your workflow configuration.

**Working with Workflow Studio in Visual Studio Code**  
With the AWS toolkit, you can use Workflow Studio from within VS Code to visualize, build, and even test individual states in your state machines. You provide state inputs and set variables, start the test, then you can see how your data is transformed. You can adjust the workflow and re-test. When finished, you can apply the changes to update the state machine. For more information, see [Working with Workflow Studio](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/stepfunctions-workflowstudio.html) in the AWS Toolkit for Visual Studio Code. 

## Design mode
<a name="wfs-interface-design-mode"></a>

Design mode provides a graphical interface to visualize your workflows as you build their prototypes. The following image shows the states browser, workflow canvas, inspector, and contextual help panels in the **Design** mode of Workflow Studio.

![\[Screenshot of Design mode, showing states browser, workflow canvas, inspector, and help panels.\]](http://docs.aws.amazon.com/step-functions/latest/dg/images/wfs_main_01.png)


1. Mode buttons switch between the three modes. You cannot switch modes if your ASL workflow definition is invalid.

1. The [States browser](#workflow-studio-components-states) contains the following three tabs:
   + The **Actions** tab provides a list of AWS APIs that you can drag and drop into your workflow graph in the canvas. Each action represents a [Task workflow state](state-task.md) state.
   + The **Flow** tab provides a list of flow states that you can drag and drop into your workflow graph in the canvas.
   + The **Patterns** tab provides several ready-to-use, reusable building blocks that you can use for a variety of use cases. For example, you can use these patterns to iteratively process data in an Amazon S3 bucket.

1. The [Canvas and workflow graph](#workflow-studio-components-grapheditor) is where you drag and drop states into your workflow graph, change the order of states, and select states to configure or view.

1. The [Inspector panel](#workflow-studio-components-formdefinition) panel is where you can view and edit the properties of any state you've selected on the canvas. Turn on the **Definition** toggle to view the Amazon States Language code for your workflow, with the currently selected state highlighted. 

1. **Info** links open a panel with contextual information when you need help. These panels also include links to related topics in the Step Functions documentation. 

1. Design toolbar – Contains a set of buttons to perform common actions, such as undo, delete, and zoom in.

1. Utility buttons – A set of buttons to perform tasks, such as saving your workflows or exporting their ASL definitions in a JSON or YAML file.

### States browser
<a name="workflow-studio-components-states"></a>

From the States browser, you can select states to drag and drop on to your workflow canvas. The **Actions** tab provides a list of task states that connect to 3rd party HTTP endpoints and AWS APIs. The **Flow** tab provides a list of states with which you can direct and control your workflow. Flow states include: Choice, Parallel, Map, Pass, Wait, Success, and Fail. The **Patterns** tab provides ready-to-use, reusable pre-defined building blocks. You can search among all state types with the search box at the top of the panel.

![\[Illustrative collection of screen shots showing Actions, Flow, Patterns, and search.\]](http://docs.aws.amazon.com/step-functions/latest/dg/images/wfe-states-browser-01.png)


### Canvas and workflow graph
<a name="workflow-studio-components-grapheditor"></a>

After you choose a state to add to your workflow, you can drag it to the canvas and drop it into your workflow graph. You can also drag and drop states to move them within your workflow. If your workflow is large, you can zoom in or out to view different parts of your workflow graph in the canvas. 

### Inspector panel
<a name="workflow-studio-components-formdefinition"></a>

You can configure any states that you add to your workflow from the **Inspector** panel on the right. Choose the state you want to configure, and you will see its configuration options in the **Inspector** panel. To see the auto-generated [ASL definition](concepts-amazon-states-language.md) for your workflow code, turn on the **Definition** toggle. The ASL definition associated with the state you've selected will appear highlighted.

![\[Illustrative screenshot of Workflow Studio inspector showing configuration panel\]](http://docs.aws.amazon.com/step-functions/latest/dg/images/wfe-forms-definitions-01.png)


![\[Illustrative screenshot of Workflow Studio inspector panel showing code definition\]](http://docs.aws.amazon.com/step-functions/latest/dg/images/wfe-forms-definitions-02.png)


## Code mode
<a name="wfs-interface-code-mode"></a>

In **Code** mode of Workflow Studio, you can use an integrated code editor to view, write, and edit the [Using Amazon States Language to define Step Functions workflows](concepts-amazon-states-language.md) (ASL) definition of your workflows within the Step Functions console. The following screenshot shows the components in the **Code** mode.

![\[Illustrative screenshot of editing a workflow definition in Code mode.\]](http://docs.aws.amazon.com/step-functions/latest/dg/images/wfs-code-mode.png)


1. Mode buttons switch between the three modes. You cannot switch modes if your ASL workflow definition is invalid.

1. The [Code editor](#wfs-interface-code-editor) is where you write and edit the [ASL definition](concepts-amazon-states-language.md) of your workflows within the Workflow Studio. The code editor also provides features, such as syntax highlighting and auto-completion.

1. [Graph visualization](#wfs-interface-code-graph-viz) – Shows a real-time graphical visualization of your workflow.

1. Utility buttons – A set of buttons to perform tasks, such as saving your workflows or exporting their ASL definitions in a JSON or YAML file.

1. Code toolbar – Contains a set of buttons to perform common actions, such as undoing an action or formatting the code.

1. Graph toolbar – Contains a set of buttons to perform common actions, such as zooming in and zooming out the workflow graph.

### Code editor
<a name="wfs-interface-code-editor"></a>

The code editor provides an IDE-like experience to write and edit your workflow definitions using JSON within the Workflow Studio. The code editor includes several features, such as syntax highlighting, auto-complete suggestions, [ASL definition](concepts-amazon-states-language.md) validation, and context-sensitive help display. As you update your workflow definition, the [Graph visualization](#wfs-interface-code-graph-viz) renders a real-time graph of your workflow. You can also see the updated workflow graph in the [Design mode](#wfs-interface-design-mode).

If you select a state in the [Design mode](#wfs-interface-design-mode) or the graph visualization pane, the ASL definition of that state appears highlighted in the code editor. The ASL definition of your workflow is automatically updated if you reorder, delete, or add a state in the **Design** mode or the graph visualization pane.

The code editor can make suggestions to auto-complete fields and states.
+ To see a list of fields you can include within a specific state, press **Ctrl\$1Space**.
+ To generate a code snippet for a new state in your workflow press **Ctrl\$1Space** after the current state's definition.
+ To display a list of all available commands and **keyboard shortcuts**, press **F1**.

### Graph visualization
<a name="wfs-interface-code-graph-viz"></a>

The graph visualization panel shows your workflow in a graphical format. When you write your workflow definitions in the [Code editor](#wfs-interface-code-editor) of Workflow Studio, the graph visualization pane renders a real-time graph of your workflow. 

As you reorder, delete, or duplicate a state in the graph visualization pane, the workflow definition in the Code editor is automatically updated. Similarly, as you update your workflow definitions, reorder, delete, or add a state in the Code editor, the visualization is automatically updated.

If the JSON in the ASL definition of your workflow is invalid, the graph visualization panel pauses the rendering and displays a status message at the bottom of the pane.

## Config mode
<a name="wfs-interface-config-mode"></a>

In the **Config** mode of Workflow Studio, you can manage the general configuration of your state machines. In this mode, you can specify settings, such as the following:
+ **Details**: Set the workflow **name** and **type**. Note that both **cannot** be changed after you create the state machine.
+ **Permissions **: you can create a new role (recommended), choose an existing role, or enter an ARN for a specific role. If you select the option to create a new role, Step Functions creates an execution role for your state machines using least privileges. The generated IAM roles are valid for the AWS Region in which you create the state machine. Prior to creation, you can review the permissions that Step Functions will automatically generate for your state machine.
+ **Logging**: You can enable and set a log level for your state machine. Step Functions logs the execution history events based on your selection. You can optionally use a customer managed key to encrypt your logs. For more information about log levels, see [Log levels for Step Functions execution events](cw-logs.md#cloudwatch-log-level).

In **Additional configuration**, you can set one or more of the following **optional** configuration options:
+ **Enable X-Ray tracing**: You can send traces to X-Ray for state machine executions, even when a trace ID is not passed by an upstream service. For more information, see [Trace Step Functions request data in AWS X-Ray](concepts-xray-tracing.md).
+ **Publish version on creation**: A *version* is a numbered, immutable snapshot of a state machine that you can run. Choose this option to publish a version of your state machine while creating the state machine. Step Functions publishes version 1 as the first revision of the state machine. For more information about versions, see [State machine versions in Step Functions workflows](concepts-state-machine-version.md).
+ **Encrypt with customer managed key **: You can provide a key that you mange directly to encrypt your data. For information, see [Data at rest encryption](encryption-at-rest.md)
+ **Tags**: Choose this box to add tags that can help you track and manage the costs associated with your resources, and provide better security in your IAM policies. For more information about tags, see [Tagging state machines and activities in Step Functions](sfn-best-practices.md#concepts-tagging).

# Creating a workflow with Workflow Studio in Step Functions
<a name="workflow-studio-create"></a>

Learn to create, edit, and run workflows using Step Functions Workflow Studio. After your workflow is ready, you can save, run, and export it. 

**Topics**
+ [

## Create a state machine
](#workflow-studio-components-create)
+ [

## Design a workflow
](#workflow-studio-build)
+ [

## Run your workflow
](#workflow-studio-components-create-run)
+ [

## Edit your workflow
](#workflow-studio-components-create-edit)
+ [

## Export your workflow
](#workflow-studio-components-create-export)
+ [

## Creating a workflow prototype with placeholders
](#workflow-studio-components-create-prototype)

## Create a state machine
<a name="workflow-studio-components-create"></a>

In Workflow Studio, you can either choose a starter template or a blank template to create a workflow.

A starter template is a ready-to-run sample project that automatically creates the workflow prototype and definition, and deploys all the related AWS resources that your project needs to your AWS account. You can use these starter templates to deploy and run them as is, or use the workflow prototypes to build on them. For more information about starter templates, see [Deploy a state machine using a starter template for Step Functions](starter-templates.md).

With a blank template, you use the [Design](workflow-studio.md#wfs-interface-design-mode) or [Code](workflow-studio.md#wfs-interface-code-mode) mode to create your custom workflow.

### Create a state machine using a starter template
<a name="wfs-create-workflow-templates"></a>

1. Open the [Step Functions console](https://console.aws.amazon.com/states/home?region=us-east-1#/) and choose **Create state machine**.

1. In the **Choose a template** dialog box, do one of the following to choose a sample project:
   + Type **Task Timer** in the Search by keyword box, and then choose **Task Timer** from the search results.
   + Browse through the sample projects listed under **All** on the right pane, and then choose **Task Timer**.

1. Choose **Next** to continue.

1. Choose how to use the template:

1. Choose **Use template** to continue with your selection.

1. **Run a demo** – creates a read-only state machine. After review, you can create the workflow and all related resources.

1. **Build on it** – provides an editable workflow definition that you can review, customize, and deploy with your own resources. (Related resources, such as functions or queues, will **not** be created automatically.)

### Create a workflow using a blank template
<a name="wfs-create-workflow-blank"></a>

When you want to start from a clean canvas, create a workflow from the blank template.

1. Open the [Step Functions console](https://console.aws.amazon.com/states/home?region=us-east-1#/).

1. Choose **Create state machine**.

1. Choose **Create from blank**.

1. Name your state machine, then choose **Continue** to edit your state machine in Workflow Studio.

   You can now start designing your workflow in [Design mode](workflow-studio.md#wfs-interface-design-mode) or writing your workflow definition in [Code mode](workflow-studio.md#wfs-interface-code-mode).

1. Choose **Config** to manage the configuration of your workflow in the [Config mode](workflow-studio.md#wfs-interface-config-mode). For example, provide a name for your workflow and choose its type.

## Design a workflow
<a name="workflow-studio-build"></a>

When you know the name of the state you want to add, use the search box at the top of the [States browser](workflow-studio.md#workflow-studio-components-states) to find it. Otherwise, look for the state you need in the browser and add it onto the canvas. 

You can reorder states in your workflow by dragging them to a different location in your workflow. As you drag a state onto the canvas, a line appears to show where the state will be inserted into your workflow, as shown in the following screenshot: 

![\[Illustrative screenshot showing the blue line that indicates the destination for a state.\]](http://docs.aws.amazon.com/step-functions/latest/dg/images/wfe-design-02.png)


After a state is dropped onto the canvas, its code is auto-generated and added inside the workflow definition. To see the definition, turn on the **Definition** toggle on the [Inspector panel](workflow-studio.md#workflow-studio-components-formdefinition). You can choose [Code mode](workflow-studio.md#wfs-interface-code-mode) to edit the definition with the built-in code editor.

After you drop a state onto the canvas, you can configure it in the [Inspector panel](workflow-studio.md#workflow-studio-components-formdefinition) panel on the right. This panel contains the **Configuration**, **Input**, **Output**, and **Error Handling** tabs for each of the state or API action that you place on the canvas. You configure the states you include in your workflows in the **Configuration** tab. 

For example, the **Configuration** tab for Lambda Invoke API action provides the following options:
+ **State name**: You can identify the state with a custom name or accept the default generated name.
+ **API** shows which API action is used by the state. 
+ **Integration type**: You can choose the service integration type used to call API actions on other services.
+ **Function name** provides options to:
  +  **Enter a function name**: You can enter your function name or its ARN. 
  +  **Get function name at runtime from state input**: You can use this option to dynamically get the function name from the state input based on the path you specify. 
  +  **Select function name**: You can directly select from the functions available in your account and region. 
+ **Payload** : you can choose to use the state input, a JSON object, or no payload to pass as the payload to your Lambda function. If you choose JSON, you can include both static values and values selected from the state input.
+ (Optional) Some states will have an option to select **Wait for task to complete** or **Wait for callback**. When available, you can choose one of the following [service integration patterns](connect-to-resource.md): 
  + **No option selected**: Step Functions will use the [Request Response](connect-to-resource.md#connect-default) integration pattern. Step Functions will wait for an HTTP response and then progress to the next state. Step Functions will not wait for a job to complete. When no options are available, the state will use this pattern. 
  + **Wait for task to complete**: Step Functions will use the [Run a Job (.sync)](connect-to-resource.md#connect-sync) integration pattern.
  + **Wait for callback**: Step Functions will use the [Wait for a Callback with Task Token](connect-to-resource.md#connect-wait-token) integration pattern.
+ (Optional) To access resources configured in different AWS accounts within your workflows, Step Functions provides [cross-account access](concepts-access-cross-acct-resources.md). **IAM role for cross-account access** provides options to:
  + **Provide IAM role ARN**: Specify the IAM role that contains appropriate resource access permissions. These resources are available in a target account, which is an AWS account to which you make cross-account calls.
  + **Get IAM role ARN at runtime from state input**: Specify a reference path to an existing key-value pair in the state’s JSON input which contains the IAM role.
+ **Next state** lets you to select the state you want to transition to next. 
+ (Optional) **Comment** field will not affect the workflow, but you can be use it to annotate your workflow.

Some states will have additional generic configuration options. For example, the Amazon ECS `RunTask` state configuration contains an `API Parameters` field populated with placeholder values. For these states, you can replace the placeholder values with configurations that are suited to your needs.

**To delete a state**

You can press backspace, right-click and choose **Delete state**, or choose **Delete** on the [Design toolbar](workflow-studio.md#wfs-interface-design-mode).

## Run your workflow
<a name="workflow-studio-components-create-run"></a>

When your workflow is ready to go, you can run it and view its execution from the [Step Functions console](https://console.aws.amazon.com/states/home).

**To run a workflow in Workflow Studio**

1. In the **Design**, **Code**, or **Config** mode, choose **Execute.**

   The **Start execution** dialog box opens in a new tab.

1. In the **Start execution** dialog box, do the following:

   1. (Optional) Enter a custom execution name to override the generated default.
**Non-ASCII names and logging**  
Step Functions accepts names for state machines, executions, activities, and labels that contain non-ASCII characters. Because such characters will prevent Amazon CloudWatch from logging data, we recommend using only ASCII characters so you can track Step Functions metrics.

   1. (Optional) In the **Input** box, enter input values in JSON format to run your workflow.

   1. Choose **Start execution**.

   1. The Step Functions console directs you to a page that's titled with your execution ID, known as the *Execution Details* page. You can review the execution results as the workflow progresses and after it completes.

      To review the execution results, choose individual states on the **Graph view**, and then choose the individual tabs on the [Step details](concepts-view-execution-details.md#exec-details-intf-step-details) pane to view each state's details including input, output, and definition respectively. For details about the execution information you can view on the *Execution Details* page, see [Execution details overview](concepts-view-execution-details.md#exec-details-interface-overview).

## Edit your workflow
<a name="workflow-studio-components-create-edit"></a>

You can edit an existing workflow visually in the [Design mode](workflow-studio.md#wfs-interface-design-mode) of Workflow Studio. 

In the [Step Functions console](https://console.aws.amazon.com/states/home), choose the workflow you want to edit from the **State machines** page. The workflow opens in **Design** mode of Workflow Studio.

You can also edit the workflow definition in [Code mode](workflow-studio.md#wfs-interface-code-mode). Choose the **Code** button to view or edit the workflow definition in Workflow Studio.

**Note**  
If you see errors in your workflow, you must fix them in **Design** mode. You can't switch to the **Code** or **Config** mode if any errors exist in your workflow.

When you save changes to your workflow, you have the option to also publish a new **version**. With versions, you can choose to run the original or alternate versions of your workflow. To learn more about managing workflows with versions, see [State machine versions in Step Functions workflows](concepts-state-machine-version.md)

## Export your workflow
<a name="workflow-studio-components-create-export"></a>

You can export your workflow's [Amazon States Language](concepts-amazon-states-language.md) (ASL) definition and your workflow graph:

1. Choose your workflow in the [Step Functions console](https://console.aws.amazon.com/states/home).

1. On the *State machine detail* page, choose **Edit**.

1. Choose the **Actions** dropdown button, and then do one or both of the following:
   + To export the workflow graph to an SVG or PNG file, under **Export graph**, select the format you want.
   + To export the workflow definition as a JSON or YAML file, under **Export definition**, select the format you want.

## Creating a workflow prototype with placeholders
<a name="workflow-studio-components-create-prototype"></a>

You can use Workflow Studio or [Workflow Studio in Infrastructure Composer](use-wfs-in-app-composer.md) to create prototypes of new workflows that contain *placeholder resources* which are named resources that do not exist yet.

To create a workflow prototype:

1. Sign in to the [Step Functions console](https://console.aws.amazon.com/states/home?region=us-east-1#/).

1. Choose **Create state machine**.

1. Choose **Create from blank**.

1. Name your state machine, then choose **Continue** to edit your state machine in Workflow Studio.

1. The [Design mode](workflow-studio.md#wfs-interface-design-mode) of Workflow Studio opens. Design your workflow in Workflow Studio. To include placeholder resources:

   1. Choose the state for which you want to include a placeholder resource, and then in **Configuration**:
      + For Lambda Invoke states, choose **Function name**, then choose **Enter function name**. You can also enter a custom name for your function.
      + For Amazon SQS Send Message states, choose **Queue URL**, then choose **Enter queue URL**. Enter a placeholder queue URL.
      + For Amazon SNS Publish states, from **Topic**, choose a topic ARN.
      + For all other states listed under **Actions**, you can use the default configuration.
**Note**  
If you see errors in your workflow, you must fix them in **Design** mode. You can't switch to the **Code** or **Config** mode if any errors exist in your workflow.

   1. (Optional) To view the auto-generated ASL definition of your workflow, choose **Definition**.

   1. (Optional) To update the workflow definition in Workflow Studio, choose the **Code** button.
**Note**  
If you see errors in your workflow definition, you must fix them in **Code** mode. You can't switch to the **Design** or **Config** mode if any errors exist in your workflow definition.

1. (Optional) To edit the state machine name, choose the edit icon next to the default state machine name of **MyStateMachine** and specify a name in the **State machine name** box.

   You can also switch to the [Config mode](workflow-studio.md#wfs-interface-config-mode) to edit the default state machine name.

1. Specify your workflow settings, such as state machine type and its execution role.

1. Choose **Create**.

You've now created a new workflow with placeholder resources that can be used to prototype. You can [export](#workflow-studio-components-create-export) your workflow definition and the workflow graph.
+ To export your workflow definition as a JSON or YAML file, in the **Design** or **Code** mode, choose the **Actions** dropdown button. Then, under **Export definition**, select the format you want to export. You can use this exported definition as the starting point for local development with the [AWS Toolkit for Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/building-stepfunctions.html).
+ To export your workflow graph to an SVG or PNG file, in the **Design** or **Code** mode, choose the **Actions** dropdown button. Then, under **Export definition**, select the format you want.

# Configure states inputs and outputs with Workflow Studio in Step Functions
<a name="workflow-studio-process"></a>

**Managing state and transforming data**  
Learn about [Passing data between states with variables](workflow-variables.md) and [Transforming data with JSONata](transforming-data.md).

Each state makes a decision or performs an action based on input that it receives. In most cases, it then passes output to other states. In Workflow Studio, you can configure how a state filters and manipulates its input and output data in the **Input** and **Output** tabs of the [Inspector panel](workflow-studio.md#workflow-studio-components-formdefinition) panel. Use the **Info** links to access contextual help when configuring inputs and outputs. 

![\[Illustrative screenshot showing state inputs, outputs, and the info help panel\]](http://docs.aws.amazon.com/step-functions/latest/dg/images/wfs_input_output_01.png)


For detailed information about how Step Functions processes input and output, see [Processing input and output in Step Functions](concepts-input-output-filtering.md). 

## Configure input to a state
<a name="workflow-studio-process-input"></a>

Each state receives input from the previous state as JSON. If you want to filter the input, you can use the `InputPath` filter under the **Input** tab in the [Inspector panel](workflow-studio.md#workflow-studio-components-formdefinition) panel. The `InputPath` is a string, beginning with `$`, that identifies a specific JSON node. These are called [reference paths](amazon-states-language-paths.md), and they follow JsonPath syntax. 

To filter the input:
+ Choose **Filter input with InputPath**.
+ Enter a valid [JsonPath](https://datatracker.ietf.org/wg/jsonpath/about/) for the `InputPath` filter. For example, **\$1.data**.

Your `InputPath` filter will be added to your workflow.

**Example 1: Use InputPath filter in Workflow Studio**  
Say the input to your state includes the following JSON data.  

```
{
  "comment": "Example for InputPath",
  "dataset1": {
    "val1": 1,
    "val2": 2,
    "val3": 3
  },
  "dataset2": {
    "val1": "a",
    "val2": "b",
    "val3": "c"
  }
}
```
To apply the `InputPath` filter, choose **Filter input with InputPath**, then enter an appropriate reference path. If you enter **\$1.dataset2.val1**, the following JSON is passed as input to the state.  

```
{"a"}
```
A reference path can also have a selection of values. If the data you reference is `{ "a": [1, 2, 3, 4] }` and you apply the reference path `$.a[0:2]` as the `InputPath` filter, the following is the result.  

```
[ 1, 2 ]
```

[Parallel workflow state](state-parallel.md), [Map workflow state](state-map.md), and [Pass workflow state](state-pass.md) flow states have an additional input filtering option called `Parameters` under their **Input** tab. This filter takes effect after the InputPath filter and can be used to construct a custom JSON object consisting of one or more key-value pairs. The values of each pair can either be static values, can be selected from the input, or can be selected from the [Accessing execution data from the Context object in Step Functions](input-output-contextobject.md) with a path. 

**Note**  
To specify that a parameter uses a reference path to point to a JSON node in the input, the parameter name must end with `.$`.

**Example 2: Create custom JSON input for Parallel state**  
Say the following JSON data is the input to a Parallel state.  

```
{
  "comment": "Example for Parameters",
  "product": {
    "details": {
      "color": "blue",
      "size": "small",
      "material": "cotton"
    },
    "availability": "in stock",
    "sku": "2317",
    "cost": "$23"
  }
}
```

To select part of this input and pass additional key-value pairs with a static value, you can specify the following in the **Parameters** field, under the **Parallel** state’s **Input** tab.

```
{
 "comment": "Selecting what I care about.",
 "MyDetails": {
    "size.$": "$.product.details.size",
    "exists.$": "$.product.availability",
    "StaticValue": "foo"
    }
 }
```

The following JSON data will be the result.

```
{
  "comment": "Selecting what I care about.",
  "MyDetails": {
    "size": "small",
    "exists": "in stock",
    "StaticValue": "foo"
  }
}
```

## Configure output of a state
<a name="workflow-studio-process-output"></a>

Each state produces JSON output that can be filtered before it is passed to the next state. There are several filters available, and each affects the output in a different way. Output filters available for each state are listed under the **Output** tab in the **Inspector** panel. For [Task workflow state](state-task.md) states, any output filters you select are processed in this order: 

1.  `ResultSelector`: Use this filter to manipulate the state’s result. You can construct a new JSON object with parts of the result. 

1.  `Specifying state output using ResultPath in Step Functions`: Use this filter to select a combination of the state input and the task result to pass to the output. 

1.  `Filtering state output using OutputPath`: Use this filter to filter the JSON output to choose which information from the result will be passed to the next state. 

### Use ResultSelector
<a name="workflow-studio-process-output-resultselector"></a>

`ResultSelector` is an optional output filter for the following states:
+  [Task workflow state](state-task.md) states, which are all states listed in the **Actions** tab of the [States browser](workflow-studio.md#workflow-studio-components-states). 
+  [Map workflow state](state-map.md) states, in the **Flow** tab of the States browser. 
+  [Parallel workflow state](state-parallel.md) states, in the **Flow** tab of the States browser. 

`ResultSelector` can be used to construct a custom JSON object consisting of one or more key-value pairs. The values of each pair can either be static values or selected from the state's result with a path. 

**Note**  
To specify that a parameter uses a path to reference a JSON node in the result, the parameter name must end with `.$`.

**Example to use ResultSelector filter**  
In this example, you use `ResultSelector` to manipulate the response from the Amazon EMR CreateCluster API call for an Amazon EMR `CreateCluster` state. The following is the result from the Amazon EMR `CreateCluster` API call.  

```
{
  "resourceType": "elasticmapreduce",
  "resource": "createCluster.sync",
  "output": {
    "SdkHttpMetadata": {
      "HttpHeaders": {
        "Content-Length": "1112",
        "Content-Type": "application/x-amz-JSON-1.1",
        "Date": "Mon, 25 Nov 2019 19:41:29 GMT",
        "x-amzn-RequestId": "1234-5678-9012"
      },
      "HttpStatusCode": 200
    },
    "SdkResponseMetadata": {
      "RequestId": "1234-5678-9012"
    },
    "ClusterId": "AKIAIOSFODNN7EXAMPLE"
  }
}
```
To select part of this information and pass an additional key-value pair with a static value, specify the following in the **ResultSelector** field, under the state’s **Output** tab.  

```
{
 "result": "found",
 "ClusterId.$": "$.output.ClusterId", 
 "ResourceType.$": "$.resourceType"
 }
```
Using `ResultSelector` produces the following result.  

```
{
 "result": "found",
 "ClusterId": "AKIAIOSFODNN7EXAMPLE",
 "ResourceType": "elasticmapreduce"
}
```

### Use ResultPath
<a name="workflow-studio-process-output-resultpath"></a>

The output of a state can be a copy of its input, the result it produces, or a combination of its input and result. Use `ResultPath` to control which combination of these is passed to the state output. For more use cases of `ResultPath`, see [Specifying state output using ResultPath in Step Functions](input-output-resultpath.md).

`ResultPath` is an optional output filter for the following states:
+  [Task workflow state](state-task.md) states, which are all states listed in the **Actions** tab of the States browser. 
+  [Map workflow state](state-map.md) states, in the **Flow** tab of the States browser. 
+  [Parallel workflow state](state-parallel.md) states, in the **Flow** tab of the States browser. 
+  [Pass workflow state](state-pass.md) states, in the **Flow** tab of the States browser. 

`ResultPath` can be used to add the result into the original state input. The specified path indicates where to add the result.

**Example to use ResultPath filter**  
Say the following is the input to a Task state.  

```
{
  "details": "Default example",
  "who": "AWS Step Functions"
}
```
The result of the Task state is the following.  

```
Hello, AWS Step Functions
```
You can add this result to the state’s input by applying `ResultPath` and entering a reference [path](amazon-states-language-paths.md) that indicates where to add the result, such as `$.taskresult`:  
With this `ResultPath`, the following is the JSON that is passed as the state’s output.  

```
{
  "details": "Default example",
  "who": "AWS Step Functions",
  "taskresult": "Hello, AWS Step Functions!"
}
```

### Use OutputPath
<a name="workflow-studio-process-output-resultselector"></a>

The `OutputPath` filter lets you filter out unwanted information, and pass only the portion of JSON that you need. The `OutputPath` is a string, beginning with `$`, that identifies nodes within JSON text.

**Example to use OutputPath filter**  
Imagine a Lambda Invoke API call returns metadata in addition to the Lambda function’s result.  

```
{
  "ExecutedVersion": "$LATEST",
  "Payload": {
     "foo": "bar",
     "colors": [
          "red",
          "blue",
          "green"    
     ],
     "car": {
          "year": 2008,
          "make": "Toyota",
          "model": "Matrix"
     }
   },
"SdkHttpMetadata": {
  "AllHttpHeaders": {
    "X-Amz-Executed-Version": ["$LATEST"]
...
```
You can use `OutputPath` to filter out the additional metadata. By default, the value of **OutputPath** filter for Lambda Invoke states created through the Workflow Studio is `$.Payload`. This default value removes the additional metadata and returns an output equivalent to running the Lambda function directly.  
The Lambda Invoke task result example and the value of `$.Payload` for the **Output** filter pass the following JSON data as the output.  

```
{
 "foo": "bar",
 "colors": [
      "red",
      "blue",
      "green"    
 ],
 "car": {
      "year": 2008,
      "make": "Toyota",
      "model": "Matrix"
 }
}
```
The `OutputPath` filter is the last output filter to take effect, so if you use additional output filters such as `ResultSelector` or `ResultPath`, you should modify the default value of `$.Payload` for the `OutputPath` filter accordingly. 

# Set up execution roles with Workflow Studio in Step Functions
<a name="manage-state-machine-permissions"></a>

You can use Workflow Studio to set up execution roles for your workflows. Every Step Functions state machine requires an AWS Identity and Access Management (IAM) role which grants the state machine permission to perform actions on AWS services and resources or call HTTPS APIs. This role is called an *execution role*. 

The execution role must contain IAM policies for each action, for example, policies that allow the state machine to invoke an AWS Lambda function, run an AWS Batch job, or call the Stripe API. Step Functions requires you to provide an execution role in the following cases:
+ You create a state machine in the console, AWS SDKs or AWS CLI using the [CreateStateMachine](https://docs.aws.amazon.com/step-functions/latest/apireference/API_CreateStateMachine.html) API.
+ You [test](test-state-isolation.md) a state in the console, AWS SDKs, or AWS CLI using the [TestState](https://docs.aws.amazon.com/step-functions/latest/apireference/API_TestState.html) API.

**Topics**
+ [

## About auto-generated roles
](#wfs-auto-gen-roles)
+ [

## Automatically generating roles
](#auto-generating-roles)
+ [

## Resolving role generation problems
](#resolve-role-gen-problem)
+ [

## Role for testing HTTP Tasks in Workflow Studio
](#test-state-role-http)
+ [

## Role for testing an optimized service integration in Workflow Studio
](#test-state-role-optimized)
+ [

## Role for testing an AWS SDK service integration in Workflow Studio
](#test-state-role-aws-sdk)
+ [

## Role for testing flow states in Workflow Studio
](#test-state-role-flow)

## About auto-generated roles
<a name="wfs-auto-gen-roles"></a>

When you create a state machine in the Step Functions console, [Workflow Studio](workflow-studio.md) can automatically create an execution role for you which contains the necessary IAM policies. Workflow Studio analyzes your state machine definition and generates policies with the least privileges necessary to execute your workflow.

Workflow Studio can generate IAM policies for the following:
+ [HTTP Tasks](call-https-apis.md) that call HTTPS APIs.
+ Task states that call other AWS services using [optimized integrations](integrate-optimized.md), such as [Lambda Invoke](connect-lambda.md), [DynamoDB GetItem](connect-batch.md), or [AWS Glue StartJobRun](connect-glue.md).
+ Task states that run [nested workflows](connect-stepfunctions.md).
+ [Distributed Map states](state-map-distributed.md), including [policies](iam-policies-eg-dist-map.md) to start child workflow executions, list Amazon S3 buckets, and read or write S3 objects.
+ [X-Ray](concepts-xray-tracing.md) tracing. Every role that is auto-generated in Workflow Studio contains a [policy](concepts-xray-tracing.md#xray-iam) which grants permissions for the state machine to send traces to X-Ray.
+ [Using CloudWatch Logs to log execution history in Step Functions](cw-logs.md) when logging is enabled on the state machine.

Workflow Studio can't generate IAM policies for Task states that call other AWS services using [AWS SDK integrations](supported-services-awssdk.md).

## Automatically generating roles
<a name="auto-generating-roles"></a>

1. Open the [Step Functions console](https://console.aws.amazon.com/states/home), choose **State machines** from the menu, then choose **Create state machine**.

   You can also update an existing state machine. Refer Step 4 if you're updating a state machine.

1. Choose **Create from blank**.

1. Name your state machine, then choose **Continue** to edit your state machine in Workflow Studio.

1. Choose the **Config** tab.

1. Scroll down to the **Permissions** section, and do the following:

   1. For **Execution role**, make sure you keep the default selection of **Create new role**.

      Workflow Studio automatically generates all the required IAM policies for every valid state in your state machine definition. It displays a banner in with the message, **An execution role will be created with full permissions.**  
![\[Illustrative screenshot of the Config tab with preview of auto-generated permissions.\]](http://docs.aws.amazon.com/step-functions/latest/dg/images/wfs-full-permissions-role.png)
**Tip**  
To review the permissions that Workflow Studio automatically generates for your state machine, choose **Review auto-generated permissions**.
**Note**  
If you delete the IAM role that Step Functions creates, Step Functions can't recreate it later. Similarly, if you modify the role (for example, by removing Step Functions from the principals in the IAM policy), Step Functions can't restore its original settings later. 

      If Workflow Studio can't generate all the required IAM policies, it displays a banner with the message **Permissions for certain actions cannot be auto-generated. An IAM role will be created with partial permissions only.** For information about how to add the missing permissions, see [Resolving role generation problems](#resolve-role-gen-problem).

   1. Choose **Create** if you're creating a state machine. Otherwise, choose **Save**.

   1. Choose **Confirm** in the dialog box that appears.

      Workflow Studio saves your state machine and creates the new execution role.

## Resolving role generation problems
<a name="resolve-role-gen-problem"></a>

Workflow Studio can't automatically generate an execution role with all the required permissions in the following cases:
+ There are errors in your state machine. Make sure to resolve all validation errors in Workflow Studio. Also, make sure that you address any server-side errors you encounter in the course of saving.
+ Your state machine contains tasks use AWS SDK integrations. Workflow Studio can't [auto-generate](#auto-generating-roles) IAM policies in this case. Workflow Studio displays a banner with the message, **Permissions for certain actions cannot be auto-generated. An IAM role will be created with partial permissions only.** In the **Review auto-generated permissions** table, choose the content in **Status** for more information about the policies your execution role is missing. Workflow Studio can still generate an execution role, but this role will not contain IAM policies for all actions. See the links under **Documentation links** to write your own policies and add them to the role after it is generated. These links are available even after you save the state machine.

## Role for testing HTTP Tasks in Workflow Studio
<a name="test-state-role-http"></a>

[Testing](call-https-apis.md#http-task-test) an HTTP Task state requires an execution role. If you don’t have a role with sufficient permissions, use one of the following options to create a role:
+ **Auto-generate a role with Workflow Studio (recommended)** – This is the secure option. Close the **Test state** dialog box and follow the instructions in [Automatically generating roles](#auto-generating-roles). This will require you to create or update your state machine first, then go back into Workflow Studio to test your state.
+ **Use a role with Administrator access** – If you have permissions to create a role with full access to all services and resources in AWS, you can use that role to test any type of state in your workflow. To do this, you can create a Step Functions service role and add the [AdministratorAccess policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#jf_administrator) to it in the IAM console [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

## Role for testing an optimized service integration in Workflow Studio
<a name="test-state-role-optimized"></a>

Task states that call [optimized service integrations](integrate-optimized.md) require an execution role. If you don’t have a role with sufficient permissions, use one of the following options to create a role:
+ **Auto-generate a role with Workflow Studio (recommended)** – This is the secure option. Close the **Test state** dialog box and follow the instructions in [Automatically generating roles](#auto-generating-roles). This will require you to create or update your state machine first, then go back into Workflow Studio to test your state.
+ **Use a role with Administrator access** – If you have permissions to create a role with full access to all services and resources in AWS, you can use that role to test any type of state in your workflow. To do this, you can create a Step Functions service role and add the [AdministratorAccess policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#jf_administrator) to it in the IAM console [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

## Role for testing an AWS SDK service integration in Workflow Studio
<a name="test-state-role-aws-sdk"></a>

Task states that call [AWS SDK integrations](supported-services-awssdk.md) require an execution role. If you don’t have a role with sufficient permissions, use one of the following options to create a role:
+ **Auto-generate a role with Workflow Studio (recommended)** – This is the secure option. Close the **Test state** dialog box and follow the instructions in [Automatically generating roles](#auto-generating-roles). This will require you to create or update your state machine first, then go back into Workflow Studio to test your state. Do the following:

  1. Close the **Test state** dialog box

  1. Choose the **Config** tab to view the Config mode.

  1. Scroll down to the **Permissions** section.

  1. Workflow Studio displays a banner with the message, **Permissions for certain actions cannot be auto-generated. An IAM role will be created with partial permissions only.** Choose **Review auto-generated permissions**.

  1. The **Review auto-generated permissions** table displays a row that shows the action corresponding to the task state you want to test. See the links under **Documentation links** to write your own IAM policies into a custom role.
+ **Use a role with Administrator access** – If you have permissions to create a role with full access to all services and resources in AWS, you can use that role to test any type of state in your workflow. To do this, you can create a Step Functions service role and add the [AdministratorAccess policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#jf_administrator) to it in the IAM console [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

## Role for testing flow states in Workflow Studio
<a name="test-state-role-flow"></a>

You require an execution role to test flow states in Workflow Studio. Flow states are those states that direct execution flow, such as [Choice workflow state](state-choice.md), [Parallel workflow state](state-parallel.md), [Map workflow state](state-map.md), [Pass workflow state](state-pass.md), [Wait workflow state](state-wait.md), [Succeed workflow state](state-succeed.md), or [Fail workflow state](state-fail.md). The [TestState](https://docs.aws.amazon.com/step-functions/latest/apireference/API_TestState.html) API doesn't work with Map or Parallel states. Use one of the following options to create a role for testing a flow state:
+ **Use any role in your AWS account (recommended)** – Flow states do not require any specific IAM policies, because they don’t call AWS actions or resources. Therefore, you can use any IAM role in your AWS account. 

  1. In the **Test state** dialog box, select any role from the **Execution role** dropdown list.

  1. If no roles appear in the dropdown list, do the following:

     1. In the IAM console [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/), choose **Roles**.

     1. Choose a role from the list, and copy its ARN from the role details page. You will need to provide this ARN in the **Test state** dialog box.

     1. In the **Test state** dialog box, select **Enter a role ARN** from the **Execution role** dropdown list.

     1. Paste the ARN in **Role ARN**.
+ **Use a role with Administrator access** – If you have permissions to create a role with full access to all services and resources in AWS, you can use that role to test any type of state in your workflow. To do this, you can create a Step Functions service role and add the [AdministratorAccess policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#jf_administrator) to it in the IAM console [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

# Configure error handling with Workflow Studio in Step Functions
<a name="workflow-studio-process-error"></a>

**Managing state and transforming data**  
Learn about [Passing data between states with variables](workflow-variables.md) and [Transforming data with JSONata](transforming-data.md).

You can configure error handling within the Workflow Studio visual editor. By default, when a state reports an error, Step Functions causes the workflow execution to fail entirely. For actions and some flow states, you can configure how Step Functions handles errors. 

Even if you have configured error handling, some errors may still cause a workflow execution to fail. For more information, see [Handling errors in Step Functions workflows](concepts-error-handling.md). In Workflow Studio, configure error handling in the **Error handling** tab of the [Inspector panel](workflow-studio.md#workflow-studio-components-formdefinition). 

## Retry on errors
<a name="workflow-studio-process-error-retry"></a>

You can add one or more rules to action states and the [Parallel workflow state](state-parallel.md) flow state to retry the task when an error occurs. These rules are called *retriers*. To add a retrier, choose the edit icon in **Retrier \$11** box, then configure its options:
+ (Optional) In the **Comment** field, add your comment. It will not affect the workflow, but can be used to annotate your workflow. 
+ Place the cursor in the **Errors** field and choose an error that will trigger the retrier, or enter a custom error name. You can choose or add multiple errors.
+ (Optional) Set an **Interval**. This is the time in seconds before Step Functions make its first retry. Additional retries will follow at intervals that you can configure with **Max attempts** and **Backoff rate**.
+ (Optional) Set **Max attempts**. This is the maximum number of retries before Step Functions will cause the execution to fail.
+ (Optional) Set the **Backoff rate**. This is a multiplier that determines by how much the retry interval will increase with each attempt.

**Note**  
Not all error handling options are available for all states. Lambda Invoke has one retrier configured by default.

## Catch errors
<a name="workflow-studio-process-error-catch"></a>

You can add one or more rules to action states and to the [Parallel workflow state](state-parallel.md) and [Map workflow state](state-map.md) flow states to catch an error. These rules are called *catchers*. To add a catcher, choose **Add new catcher**, then configure its options:
+ (Optional) In the **Comment** field, add your comment. It will not affect the workflow, but can be used to annotate your workflow. 
+ Place the cursor in **Errors** field and choose an error that will trigger the catcher, or enter a custom error name. You can choose or add multiple errors.
+ In the **Fallback state** field, choose a [fallback state](concepts-error-handling.md#error-handling-fallback-states). This is the state that the workflow will move to next, after an error is caught.
+ (Optional) In the **ResultPath** field, add a `ResultPath` filter to add the error to the original state input. The [`ResultPath`](input-output-resultpath.md) must be a valid [JsonPath](https://datatracker.ietf.org/wg/jsonpath/about/). This will be sent to the fallback state.

## Timeouts
<a name="workflow-studio-process-error-timeout"></a>

You can configure a timeout for action states to set the maximum number of seconds your state can run before it fails. Use timeouts to prevent stuck executions. To configure a timeout, enter the number of seconds your state should wait before the execution fails. For more information about timeouts, see `TimeoutSeconds` in [Task workflow state](state-task.md) state.

## HeartbeatSeconds
<a name="workflow-studio-process-error-heartbeat"></a>

You can configure a *Heartbeat* or periodic notification sent by your task. If you set a heartbeat interval, and your state doesn't send heartbeat notifications in the configured intervals, the task is marked as failed. To configure a heartbeat, set a positive, non-zero integer number of seconds. For more information, see `HeartBeatSeconds` in [Task workflow state](state-task.md) state. 

# Using Workflow Studio in Infrastructure Composer to build Step Functions workflows
<a name="use-wfs-in-app-composer"></a>

Workflow Studio is available in Infrastructure Composer to help you design and build your workflows. Workflow Studio in Infrastructure Composer provides a visual infrastructure as code (IaC) environment that makes it easy for you to incorporate workflows in your serverless applications built using IaC tools, such as CloudFormation templates. 

AWS Infrastructure Composer is a visual builder that helps you develop AWS SAM and AWS CloudFormation templates using a simple graphical interface. With Infrastructure Composer, you design an application architecture by dragging, grouping, and connecting AWS services in a visual canvas. Infrastructure Composer then creates an IaC template from your design that you can use to deploy your application with the AWS SAM Command Line Interface (AWS SAM CLI) or CloudFormation. To learn more about Infrastructure Composer, see [What is Infrastructure Composer](https://docs.aws.amazon.com/application-composer/latest/dg/what-is-composer.html).

When you use Workflow Studio in Infrastructure Composer, Infrastructure Composer connects the individual workflow steps to AWS resources and generates the resource configurations in an AWS SAM template. Infrastructure Composer also adds the IAM permissions required for your workflow to run. Using Workflow Studio in Infrastructure Composer, you can create prototypes of your applications and turn them into production-ready applications.

When you use Workflow Studio in Infrastructure Composer, you can switch back and forth between the Infrastructure Composer canvas and Workflow Studio.

**Topics**
+ [Using Workflow Studio in Infrastructure Composer](#procedure-use-wfs-in-app-composer)
+ [Dynamically reference resources using CloudFormation definition substitutions](#use-cfn-sub-edit-state-machine-resource)
+ [

## Connect service integration tasks to enhanced component cards
](#connect-service-integrations-enhanced-cards)
+ [

## Import existing projects and sync them locally
](#import-projects-local-sync)
+ [

## Export Step Functions workflows directly into AWS Infrastructure Composer
](#export-wsf-projects-into-app-composer)
+ [

## Unavailable Workflow Studio features in AWS Infrastructure Composer
](#wfs-features-unavailable-app-composer)

## Using Workflow Studio in Infrastructure Composer to build a serverless workflow
<a name="procedure-use-wfs-in-app-composer"></a>

1. Open the [Infrastructure Composer console](https://console.aws.amazon.com/composer/home) and choose **Create project** to create a project.

1. In the search field in the **Resources** palette, enter **state machine**.

1. Drag the **Step Functions State machine** resource onto the canvas. 

1. Choose **Edit in Workflow Studio** to edit your state machine resource.

   The following animation shows how you can switch to the Workflow Studio for editing your state machine definition.  
![\[An animation that illustrates how you can use Workflow Studio in Infrastructure Composer.\]](http://docs.aws.amazon.com/step-functions/latest/dg/images/use-wfs-in-app-composer.gif)

   The integration with Workflow Studio to edit state machines resources created in Infrastructure Composer is only available for [https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-statemachine.html](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-statemachine.html) resource. This integration is not available for templates that use the [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html) resource.

## Dynamically reference resources using CloudFormation definition substitutions in Workflow Studio
<a name="use-cfn-sub-edit-state-machine-resource"></a>

In Workflow Studio, you can use CloudFormation definition substitutions in your workflow definition to dynamically reference resources that you've defined in your IaC template. You can add placeholder substitutions to your workflow definition using the `${dollar_sign_brace}` notation and they are replaced with actual values during the CloudFormation stack creation process. For more information about definition substitutions, see [DefinitionSubstitutions in AWS SAM templates](concepts-sam-sfn.md#sam-definition-substitution-eg).

The following animation shows how you can add placeholder substitutions for the resources in your state machine definition.

![\[Animation showing how to add placeholder substitutions for resources in your state machine.\]](http://docs.aws.amazon.com/step-functions/latest/dg/images/use-def-sub-wfs-app-composer.gif)


## Connect service integration tasks to enhanced component cards
<a name="connect-service-integrations-enhanced-cards"></a>

You can connect the tasks that call [optimized service integrations](integrate-optimized.md) to [enhanced component cards](https://docs.aws.amazon.com/application-composer/latest/dg/reference-cards.html#reference-cards-enhanced-components) in Infrastructure Composer canvas. Doing this automatically maps any placeholder substitutions specified by the `${dollar_sign_brace}` notation in your workflow definition and the `DefinitionSubstitution` property for your `StateMachine` resource. It also adds the appropriate AWS SAM policies for the state machine.

If you map optimized service integration tasks with [standard component cards](https://docs.aws.amazon.com/application-composer/latest/dg/using-composer-cards.html#using-composer-cards-component-intro), the connection line doesn't appear on the Infrastructure Composer canvas.

The following animation shows how you can connect an optimized task to an enhanced component card and view the changes in [https://docs.aws.amazon.com/application-composer/latest/dg/using-change-inspector.html](https://docs.aws.amazon.com/application-composer/latest/dg/using-change-inspector.html).

![\[Animation showing how to connect tasks and optimized service integrations.\]](http://docs.aws.amazon.com/step-functions/latest/dg/images/make-connections-wfs-app-composer.gif)


You can't connect [AWS SDK integrations](supported-services-awssdk.md) in your Task state with enhanced component cards or optimized service integrations with standard component cards. For these tasks, you can map the substitutions in the **Resource properties** panel in Infrastructure Composer canvas, and add policies in the AWS SAM template.

**Tip**  
Alternatively, you can also map placeholder substitutions for your state machine under **Definition Substitutions** in the **Resource properties** panel. When you do this, you must add the required permissions for the AWS service your Task state calls in the state machine execution role. For information about permissions your execution role might need, see [Set up execution roles with Workflow Studio in Step Functions](manage-state-machine-permissions.md).

The following animation shows how you can manually update the placeholder substitution mapping in the **Resource properties** panel.

![\[Animation showing how to update placeholder substitution mapping in the resource properties panel.\]](http://docs.aws.amazon.com/step-functions/latest/dg/images/manual-update-placeholder-mapping.gif)


## Import existing projects and sync them locally
<a name="import-projects-local-sync"></a>

You can open existing CloudFormation and AWS SAM projects in Infrastructure Composer to visualize them for better understanding and modify their designs. Using Infrastructure Composer's [local sync](https://docs.aws.amazon.com/application-composer/latest/dg/reference-features-local-sync.html) feature, you can automatically sync and save your template and code files to your local build machine. Using the local sync mode can compliment your existing development flows. Make sure that your browser supports the [File System Access API](https://docs.aws.amazon.com/application-composer/latest/dg/reference-fsa.html), which allows web applications to read, write, and save files in your local file system. We recommend using either Google Chrome or Microsoft Edge.

## Export Step Functions workflows directly into AWS Infrastructure Composer
<a name="export-wsf-projects-into-app-composer"></a>

The AWS Step Functions console provides the ability to export a saved state machine workflow as a template that's recognized as an advanced IaC resource by Infrastructure Composer. This feature creates an IaC template as an AWS SAM schema and navigates you to Infrastructure Composer. For more information, see [Exporting your workflow to IaC templates](exporting-iac-templates.md).

## Unavailable Workflow Studio features in AWS Infrastructure Composer
<a name="wfs-features-unavailable-app-composer"></a>

When you use Workflow Studio in Infrastructure Composer, some of the Workflow Studio features are unavailable. In addition, the **API Parameters** section available in the [Inspector panel](workflow-studio.md#workflow-studio-components-formdefinition) panel supports CloudFormation definition substitutions. You can add the substitutions in the [Code mode](workflow-studio.md#wfs-interface-code-mode) using the `${dollar_sign_brace}` notation. For more information about this notation, see [DefinitionSubstitutions in AWS SAM templates](concepts-sam-sfn.md#sam-definition-substitution-eg).

The following list describes the Workflow Studio features that are unavailable when you use Workflow Studio in Infrastructure Composer:
+ [Starter templates](starter-templates.md) – Starter templates are ready-to-run sample projects that automatically create the workflow prototypes and definitions. These templates deploys all the related AWS resources that your project needs to your AWS account.
+ [Config mode](workflow-studio.md#wfs-interface-config-mode) – This mode lets you manage the configuration of your state machines. You can update your state machine configurations in your IaC templates or use the **Resource properties** panel in Infrastructure Composer canvas. For information about updating configurations in the **Resource properties** panel, see [Connect service integration tasks to enhanced component cards](#connect-service-integrations-enhanced-cards).
+ [TestState](test-state-isolation.md) API
+ Option to import or export workflow definitions from the **Actions** dropdown button in Workflow Studio. Instead, from the Infrastructure Composer **menu**, select **Open** > **Project folder**. Make sure that you've enabled the [local sync](https://docs.aws.amazon.com/application-composer/latest/dg/reference-features-local-sync.html) mode to automatically save your changes in the Infrastructure Composer canvas directly to your local machine.
+ **Execute** button. When you use Workflow Studio in Infrastructure Composer, Infrastructure Composer generates the IaC code for your workflow. Therefore, you must first deploy the template. Then, run the workflow in the console or through the AWS Command Line Interface (AWS CLI).

# Using AWS SAM to build Step Functions workflows
<a name="concepts-sam-sfn"></a>

You can use AWS Serverless Application Model with Step Functions to build workflows and deploy the infrastructure you need, including Lambda functions, APIs and events, to create serverless applications.

You can also use the AWS Serverless Application Model CLI in conjunction with the AWS Toolkit for Visual Studio Code as part of an integrated experience to build and deploy AWS Step Functions state machines. You can build a serverless application with AWS SAM, then build out your state machine in the VS Code IDE. Then you can validate, package, and deploy your resources. 

**Tip**  
To deploy a sample serverless application that starts a Step Functions workflow using AWS SAM, see [Deploy with AWS SAM](https://catalog.workshops.aws/stepfunctions/iac/deploy-with-sam) in *The AWS Step Functions Workshop*.

## Why use Step Functions with AWS SAM?
<a name="concepts-sam-sfn-integration"></a>

When you use Step Functions with AWS SAM you can:
+ Get started using a AWS SAM sample template.
+ Build your state machine into your serverless application.
+ Use variable substitution to substitute ARNs into your state machine at the time of deployment.

   AWS CloudFormation supports [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-definitionsubstitutions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-definitionsubstitutions) that let you add dynamic references in your workflow definition to a value that you provide in your CloudFormation template. You can add dynamic references by adding substitutions to your workflow definition using the `${dollar_sign_brace}` notation. You also need to define these dynamic references in the `DefinitionSubstitutions` property for the StateMachine resource in your CloudFormation template. These substitutions are replaced with actual values during the CloudFormation stack creation process. For more information, see [DefinitionSubstitutions in AWS SAM templates](#sam-definition-substitution-eg). 
+ Specify your state machine's role using AWS SAM policy templates.
+ Initiate state machine executions with API Gateway, EventBridge events, or on a schedule within your AWS SAM template. 

## Step Functions integration with the AWS SAM specification
<a name="concepts-sam-sfn-ots2"></a>

You can use the [AWS SAM Policy Templates](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-policy-templates.html) to add permissions to your state machine. With these permissions, you can orchestrate Lambda functions and other AWS resources to form complex and robust workflows. 

## Step Functions integration with the SAM CLI
<a name="concepts-sam-sfn-ots3"></a>

Step Functions is integrated with the AWS SAM CLI. Use this to quickly develop a state machine into your serverless application.

Try the [Create a Step Functions state machine using AWS SAM](tutorial-state-machine-using-sam.md) tutorial to learn how to use AWS SAM to create state machines.

Supported AWS SAM CLI functions include: 


| CLI Command | Description | 
| --- | --- | 
| sam init |  Initializes a Serverless Application with an AWS SAM template. Can be used with a SAM template for Step Functions.  | 
| sam validate | Validates an AWS SAM template. | 
| sam package |  Packages an AWS SAM application. It creates a ZIP file of your code and dependencies, and then uploads it to Amazon S3. It then returns a copy of your AWS SAM template, replacing references to local artifacts with the Amazon S3 location where the command uploaded the artifacts.  | 
| sam deploy | Deploys an AWS SAM application. | 
| sam publish |  Publish an AWS SAM application to the AWS Serverless Application Repository. This command takes a packaged AWS SAM template and publishes the application to the specified region.  | 

**Note**  
When using AWS SAM local, you can emulate Lambda and API Gateway locally. However, you can't emulate Step Functions locally using AWS SAM.

## DefinitionSubstitutions in AWS SAM templates
<a name="sam-definition-substitution-eg"></a>

You can define state machines using CloudFormation templates with AWS SAM. Using AWS SAM, you can define the state machine inline in the template or in a separate file. The following AWS SAM template includes a state machine that simulates a stock trading workflow. This state machine invokes three Lambda functions to check the price of a stock and determine whether to buy or sell the stock. This transaction is then recorded in an Amazon DynamoDB table. The ARNs for the Lambda functions and DynamoDB table in the following template are specified using [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-definitionsubstitutions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html#cfn-stepfunctions-statemachine-definitionsubstitutions).

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: |
  step-functions-stock-trader
  Sample SAM Template for step-functions-stock-trader
Resources:
  StockTradingStateMachine:
    Type: AWS::Serverless::StateMachine
    Properties:
      DefinitionSubstitutions:
        StockCheckerFunctionArn: !GetAtt StockCheckerFunction.Arn
        StockSellerFunctionArn: !GetAtt StockSellerFunction.Arn
        StockBuyerFunctionArn: !GetAtt StockBuyerFunction.Arn
        DDBPutItem: !Sub arn:${AWS::Partition}:states:::dynamodb:putItem
        DDBTable: !Ref TransactionTable
      Policies:
        - DynamoDBWritePolicy:
            TableName: !Ref TransactionTable
        - LambdaInvokePolicy:
            FunctionName: !Ref StockCheckerFunction
        - LambdaInvokePolicy:
            FunctionName: !Ref StockBuyerFunction
        - LambdaInvokePolicy:
            FunctionName: !Ref StockSellerFunction
      DefinitionUri: statemachine/stock_trader.asl.json
  StockCheckerFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: functions/stock-checker/
      Handler: app.lambdaHandler
      Runtime: nodejs18.x
      Architectures:
        - x86_64
  StockSellerFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: functions/stock-seller/
      Handler: app.lambdaHandler
      Runtime: nodejs18.x
      Architectures:
        - x86_64
  StockBuyerFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: functions/stock-buyer/
      Handler: app.lambdaHandler
      Runtime: nodejs18.x
      Architectures:
        - x86_64
  TransactionTable:
    Type: AWS::DynamoDB::Table
    Properties:
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
```

The following code is the state machine definition in the file `stock_trader.asl.json` which is used in the [Create a Step Functions state machine using AWS SAM](tutorial-state-machine-using-sam.md) tutorial.This state machine definition contains several `DefinitionSubstitutions` denoted by the `${dollar_sign_brace}` notation. For example, instead of specifying a static Lambda function ARN for the `Check Stock Value` task, the substitution `${StockCheckerFunctionArn}` is used. This substitution is defined in the [DefinitionSubstitutions](#sam-template-def-substitution) property of the template. `DefinitionSubstitutions` is a map of key-value pairs for the state machine resource. In `DefinitionSubstitutions`, \$1\$1StockCheckerFunctionArn\$1 maps to the ARN of the `StockCheckerFunction` resource using the CloudFormation intrinsic function [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html). When you deploy the AWS SAM template, the `DefinitionSubstitutions` in the template are replaced with the actual values.

```
{
    "Comment": "A state machine that does mock stock trading.",
    "StartAt": "Check Stock Value",
    "States": {
        "Check Stock Value": {
            "Type": "Task",
            "Resource": "arn:aws:states:::lambda:invoke",
            "OutputPath": "$.Payload",
            "Parameters": {
                "Payload.$": "$",
                "FunctionName": "${StockCheckerFunctionArn}"
            },
            "Next": "Buy or Sell?"
        },
        "Buy or Sell?": {
            "Type": "Choice",
            "Choices": [
                {
                    "Variable": "$.stock_price",
                    "NumericLessThanEquals": 50,
                    "Next": "Buy Stock"
                }
            ],
            "Default": "Sell Stock"
        },
        "Buy Stock": {
            "Type": "Task",
            "Resource": "arn:aws:states:::lambda:invoke",
            "OutputPath": "$.Payload",
            "Parameters": {
                "Payload.$": "$",
                "FunctionName": "${StockBuyerFunctionArn}"
            },
            "Retry": [
                {
                    "ErrorEquals": [
                        "Lambda.ServiceException",
                        "Lambda.AWSLambdaException",
                        "Lambda.SdkClientException",
                        "Lambda.TooManyRequestsException"
                    ],
                    "IntervalSeconds": 1,
                    "MaxAttempts": 3,
                    "BackoffRate": 2
                }
            ],
            "Next": "Record Transaction"
        },
        "Sell Stock": {
            "Type": "Task",
            "Resource": "arn:aws:states:::lambda:invoke",
            "OutputPath": "$.Payload",
            "Parameters": {
                "Payload.$": "$",
                "FunctionName": "${StockSellerFunctionArn}"
            },
            "Next": "Record Transaction"
        },
        "Record Transaction": {
            "Type": "Task",
            "Resource": "arn:aws:states:::dynamodb:putItem",
            "Parameters": {
                "TableName": "${DDBTable}",
                "Item": {
                    "Id": {
                        "S.$": "$.id"
                    },
                    "Type": {
                        "S.$": "$.type"
                    },
                    "Price": {
                        "N.$": "$.price"
                    },
                    "Quantity": {
                        "N.$": "$.qty"
                    },
                    "Timestamp": {
                        "S.$": "$.timestamp"
                    }
                }
            },
            "End": true
        }
    }
}
```

## Next steps
<a name="concepts-sam-sfn-next-steps"></a>

You can learn more about using Step Functions with AWS SAM with the following resources:
+ Complete the [Create a Step Functions state machine using AWS SAM](tutorial-state-machine-using-sam.md) tutorial to create a state machine with AWS SAM.
+ Specify a [AWS::Serverless::StateMachine](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-statemachine.html) resource.
+ Find [AWS SAM Policy Templates](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-policy-templates.html) to use.
+ Use [AWS Toolkit for Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/stepfunctions.html) with Step Functions. 
+ Review the [AWS SAM CLI reference](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-command-reference.html) to learn more about the features available in AWS SAM.

You can also design and build your workflows in infrastructure as code (IaC) using visual builders, such as Workflow Studio in Infrastructure Composer. For more information, see [Using Workflow Studio in Infrastructure Composer to build Step Functions workflows](use-wfs-in-app-composer.md).

# Using CloudFormation to create a workflow in Step Functions
<a name="tutorial-lambda-state-machine-cloudformation"></a>

In this tutorial, you will create a AWS Lambda function using AWS CloudFormation. You'll use the CloudFormation console and a YAML template to create a *stack* (IAM roles, the Lambda function, and the state machine). Then, you'll use the Step Functions console to start the state machine execution.

For more information, see [Working with CloudFormation Templates](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-guide.html) and the `[AWS::StepFunctions::StateMachine](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html)` resource in the *AWS CloudFormation User Guide*.

## Step 1: Set up your CloudFormation template
<a name="lambda-state-machine-cfn-step-1"></a>

Before you use the [example templates](#lambda-state-machine-cfn-step-2), you should understand how to declare the different parts of an CloudFormation template.

### To create an IAM role for Lambda
<a name="lambda-state-machine-cfn-procedure-create-iam-role"></a>

Define the trust policy associated with the IAM role for the Lambda function. The following examples define a trust policy using either YAML or JSON.

------
#### [ YAML ]

```
LambdaExecutionRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"		 	 	 
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: "sts:AssumeRole"
```

------
#### [ JSON ]

```
          "LambdaExecutionRole": {
              "Type": "AWS::IAM::Role",
              "Properties": {
                  "AssumeRolePolicyDocument": {
                      "Version": "2012-10-17",		 	 	 
                      "Statement": [
                          {
                              "Effect": "Allow",
                              "Principal": {
                                  "Service": "lambda.amazonaws.com"
                              },
                              "Action": "sts:AssumeRole"
                          }
                      ]
                  }
              }
```

------

### To create a Lambda function
<a name="lambda-state-machine-cfn-create-function"></a>

Define the following properties for a Lambda function that will print the message `Hello World`.

**Important**  
Ensure that your Lambda function is under the same AWS account and AWS Region as your state machine.

------
#### [ YAML ]

```
MyLambdaFunction:
    Type: "AWS::Lambda::Function"
    Properties:
      Handler: "index.handler"
      Role: !GetAtt [ LambdaExecutionRole, Arn ]
      Code:
        ZipFile: |
          exports.handler = (event, context, callback) => {
              callback(null, "Hello World!");
          };
      Runtime: "nodejs12.x"
      Timeout: "25"
```

------
#### [ JSON ]

```
        "MyLambdaFunction": {
              "Type": "AWS::Lambda::Function",
              "Properties": {
                  "Handler": "index.handler",
                  "Role": {
                      "Fn::GetAtt": [
                          "LambdaExecutionRole",
                          "Arn"
                      ]
                  },
                  "Code": {
                      "ZipFile": "exports.handler = (event, context, callback) => {\n    callback(null, \"Hello World!\");\n};\n"
                  },
                  "Runtime": "nodejs12.x",
                  "Timeout": "25"
              }
          },
```

------

### To create an IAM role for the state machine execution
<a name="lambda-state-machine-cfn-create-role"></a>

Define the trust policy associated with the IAM role for the state machine execution.

------
#### [ YAML ]

```
StatesExecutionRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"		 	 	 
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - !Sub states.${AWS::Region}.amazonaws.com
            Action: "sts:AssumeRole"
      Path: "/"
      Policies:
        - PolicyName: StatesExecutionPolicy
          PolicyDocument:
            Version: "2012-10-17"		 	 	 
            Statement:
              - Effect: Allow
                Action:
                  - "lambda:InvokeFunction"
                Resource: "*"
```

------
#### [ JSON ]

```
        "StatesExecutionRole": {
              "Type": "AWS::IAM::Role",
              "Properties": {
                  "AssumeRolePolicyDocument": {
                      "Version": "2012-10-17",		 	 	 
                      "Statement": [
                          {
                              "Effect": "Allow",
                              "Principal": {
                                  "Service": [
                                      {
                                          "Fn::Sub": "states.${AWS::Region}.amazonaws.com"
                                      }
                                  ]
                              },
                              "Action": "sts:AssumeRole"
                          }
                      ]
                  },
                  "Path": "/",
                  "Policies": [
                      {
                          "PolicyName": "StatesExecutionPolicy",
                          "PolicyDocument": {
                              "Version": "2012-10-17",		 	 	 
                              "Statement": [
                                  {
                                      "Effect": "Allow",
                                      "Action": [
                                          "lambda:InvokeFunction"
                                      ],
                                      "Resource": "*"
                                  }
                              ]
                          }
                      }
                  ]
              }
          },
```

------

### To create a Lambda state machine
<a name="lambda-state-machine-cfn-create"></a>

Define the Lambda state machine.

------
#### [ YAML ]

```
MyStateMachine:
    Type: "AWS::StepFunctions::StateMachine"
    Properties:
      DefinitionString:
        !Sub
          - |-
            {
              "Comment": "A Hello World example using an AWS Lambda function",
              "StartAt": "HelloWorld",
              "States": {
                "HelloWorld": {
                  "Type": "Task",
                  "Resource": "${lambdaArn}",
                  "End": true
                }
              }
            }
          - {lambdaArn: !GetAtt [ MyLambdaFunction, Arn ]}
      RoleArn: !GetAtt [ StatesExecutionRole, Arn ]
```

------
#### [ JSON ]

```
        "MyStateMachine": {
              "Type": "AWS::StepFunctions::StateMachine",
              "Properties": {
                  "DefinitionString": {
                      "Fn::Sub": [
                          "{\n  \"Comment\": \"A Hello World example using an AWS Lambda function\",\n  \"StartAt\": \"HelloWorld\",\n  \"States\": {\n    \"HelloWorld\": {\n      \"Type\": \"Task\",\n      \"Resource\": \"${lambdaArn}\",\n      \"End\": true\n    }\n  }\n}",
                          {
                              "lambdaArn": {
                                  "Fn::GetAtt": [
                                      "MyLambdaFunction",
                                      "Arn"
                                  ]
                              }
                          }
                      ]
                  },
                  "RoleArn": {
                      "Fn::GetAtt": [
                          "StatesExecutionRole",
                          "Arn"
                      ]
                  }
              }
          }
```

------

## Step 2: Use the CloudFormation template to create a Lambda State Machine
<a name="lambda-state-machine-cfn-step-2"></a>

Once you understand the components of the CloudFormation template, you can put them together and use the template to create an CloudFormation stack.

### To create the Lambda state machine
<a name="to-create-the-lam-state-machine"></a>

1. Copy the following example data to a file named `MyStateMachine.yaml` for the YAML example, or `MyStateMachine.json` for JSON.

------
#### [ YAML ]

   ```
   AWSTemplateFormatVersion: "2010-09-09"
     Description: "An example template with an IAM role for a Lambda state machine."
     Resources:
       LambdaExecutionRole:
         Type: "AWS::IAM::Role"
         Properties:
           AssumeRolePolicyDocument:
             Version: "2012-10-17"		 	 	 
             Statement:
               - Effect: Allow
                 Principal:
                   Service: lambda.amazonaws.com
                 Action: "sts:AssumeRole"
     
       MyLambdaFunction:
         Type: "AWS::Lambda::Function"
         Properties:
           Handler: "index.handler"
           Role: !GetAtt [ LambdaExecutionRole, Arn ]
           Code:
             ZipFile: |
               exports.handler = (event, context, callback) => {
                   callback(null, "Hello World!");
               };
           Runtime: "nodejs12.x"
           Timeout: "25"
     
       StatesExecutionRole:
         Type: "AWS::IAM::Role"
         Properties:
           AssumeRolePolicyDocument:
             Version: "2012-10-17"		 	 	 
             Statement:
               - Effect: "Allow"
                 Principal:
                   Service:
                     - !Sub states.${AWS::Region}.amazonaws.com
                 Action: "sts:AssumeRole"
           Path: "/"
           Policies:
             - PolicyName: StatesExecutionPolicy
               PolicyDocument:
                 Version: "2012-10-17"		 	 	 
                 Statement:
                   - Effect: Allow
                     Action:
                       - "lambda:InvokeFunction"
                     Resource: "*"
     
       MyStateMachine:
         Type: "AWS::StepFunctions::StateMachine"
         Properties:
           DefinitionString:
             !Sub
               - |-
                 {
                   "Comment": "A Hello World example using an AWS Lambda function",
                   "StartAt": "HelloWorld",
                   "States": {
                     "HelloWorld": {
                       "Type": "Task",
                       "Resource": "${lambdaArn}",
                       "End": true
                     }
                   }
                 }
               - {lambdaArn: !GetAtt [ MyLambdaFunction, Arn ]}
           RoleArn: !GetAtt [ StatesExecutionRole, Arn ]
   ```

------
#### [ JSON ]

   ```
   {
         "AWSTemplateFormatVersion": "2010-09-09",
         "Description": "An example template with an IAM role for a Lambda state machine.",
         "Resources": {
             "LambdaExecutionRole": {
                 "Type": "AWS::IAM::Role",
                 "Properties": {
                     "AssumeRolePolicyDocument": {
                         "Version": "2012-10-17",		 	 	 
                         "Statement": [
                             {
                                 "Effect": "Allow",
                                 "Principal": {
                                     "Service": "lambda.amazonaws.com"
                                 },
                                 "Action": "sts:AssumeRole"
                             }
                         ]
                     }
                 }
             },
             "MyLambdaFunction": {
                 "Type": "AWS::Lambda::Function",
                 "Properties": {
                     "Handler": "index.handler",
                     "Role": {
                         "Fn::GetAtt": [
                             "LambdaExecutionRole",
                             "Arn"
                         ]
                     },
                     "Code": {
                         "ZipFile": "exports.handler = (event, context, callback) => {\n    callback(null, \"Hello World!\");\n};\n"
                     },
                     "Runtime": "nodejs12.x",
                     "Timeout": "25"
                 }
             },
             "StatesExecutionRole": {
                 "Type": "AWS::IAM::Role",
                 "Properties": {
                     "AssumeRolePolicyDocument": {
                         "Version": "2012-10-17",		 	 	 
                         "Statement": [
                             {
                                 "Effect": "Allow",
                                 "Principal": {
                                     "Service": [
                                         {
                                             "Fn::Sub": "states.${AWS::Region}.amazonaws.com"
                                         }
                                     ]
                                 },
                                 "Action": "sts:AssumeRole"
                             }
                         ]
                     },
                     "Path": "/",
                     "Policies": [
                         {
                             "PolicyName": "StatesExecutionPolicy",
                             "PolicyDocument": {
                                 "Version": "2012-10-17",		 	 	 
                                 "Statement": [
                                     {
                                         "Effect": "Allow",
                                         "Action": [
                                             "lambda:InvokeFunction"
                                         ],
                                         "Resource": "*"
                                     }
                                 ]
                             }
                         }
                     ]
                 }
             },
             "MyStateMachine": {
                 "Type": "AWS::StepFunctions::StateMachine",
                 "Properties": {
                     "DefinitionString": {
                         "Fn::Sub": [
                             "{\n  \"Comment\": \"A Hello World example using an AWS Lambda function\",\n  \"StartAt\": \"HelloWorld\",\n  \"States\": {\n    \"HelloWorld\": {\n      \"Type\": \"Task\",\n      \"Resource\": \"${lambdaArn}\",\n      \"End\": true\n    }\n  }\n}",
                             {
                                 "lambdaArn": {
                                     "Fn::GetAtt": [
                                         "MyLambdaFunction",
                                         "Arn"
                                     ]
                                 }
                             }
                         ]
                     },
                     "RoleArn": {
                         "Fn::GetAtt": [
                             "StatesExecutionRole",
                             "Arn"
                         ]
                     }
                 }
             }
         }
     }
   ```

------

1. Open the [CloudFormation console](https://console.aws.amazon.com/cloudformation/home) and choose **Create Stack**.

1. On the **Select Template** page, choose **Upload a template to Amazon S3**. Choose your `MyStateMachine` file, and then choose **Next**.

1. On the **Specify Details** page, for **Stack name**, enter `MyStateMachine`, and then choose **Next**.

1. On the **Options** page, choose **Next**.

1. On the **Review** page, choose **I acknowledge that CloudFormation might create IAM resources.** and then choose **Create**.

   CloudFormation begins to create the `MyStateMachine` stack and displays the **CREATE\$1IN\$1PROGRESS** status. When the process is complete, CloudFormation displays the **CREATE\$1COMPLETE** status.

1. (Optional) To display the resources in your stack, select the stack and choose the **Resources** tab.

## Step 3: Start a State Machine execution
<a name="lambda-state-machine-cfn-step-3"></a>

After you create your Lambda state machine, you can start its execution.

### To start the state machine execution
<a name="to-start-the-state-machine-execution"></a>

1. Open the [Step Functions console](https://console.aws.amazon.com/states/home) and choose the name of the state machine that you created using CloudFormation.

1. On the ***MyStateMachine-ABCDEFGHIJ1K*** page, choose **New execution**.

   The **New execution** page is displayed.

1. (Optional) Enter a custom execution name to override the generated default.
**Non-ASCII names and logging**  
Step Functions accepts names for state machines, executions, activities, and labels that contain non-ASCII characters. Because such characters will prevent Amazon CloudWatch from logging data, we recommend using only ASCII characters so you can track Step Functions metrics.

1. Choose **Start Execution**.

   A new execution of your state machine starts, and a new page showing your running execution is displayed.

1. (Optional) In the **Execution Details**, review the **Execution Status** and the **Started** and **Closed** timestamps.

1. To view the results of your execution, choose **Output**.

# Using AWS CDK to create a Standard workflow in Step Functions
<a name="tutorial-lambda-state-machine-cdk"></a>

You can use the AWS Cloud Development Kit (AWS CDK) Infrastructure as Code (IAC) framework, to create an AWS Step Functions state machine that contains an AWS Lambda function.

You will define AWS infrastructure using one of the CDK's supported languages. After you define your infrastructure, you will synthesize your app to an CloudFormation template and deploy it to your AWS account.

 You will use this method to define a Step Functions state machine containing a Lambda function, and then run the state machine from the use the Step Functions AWS Management Console. 

Before you begin this tutorial, you must set up your AWS CDK development environment as described in [Getting Started With the AWS CDK - Prerequisites](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_prerequisites) in the *AWS Cloud Development Kit (AWS CDK) Developer Guide*. Then, install the AWS CDK with the following command at the AWS CLI:

```
npm install -g aws-cdk
```

This tutorial produces the same result as [Using CloudFormation to create a workflow in Step Functions](tutorial-lambda-state-machine-cloudformation.md). However, in this tutorial, the AWS CDK doesn't require you to create any IAM roles; the AWS CDK does it for you. The AWS CDK version also includes a [Succeed workflow state](state-succeed.md) step to illustrate how to add additional steps to your state machine.

**Tip**  
To deploy a sample serverless application that starts a Step Functions workflow using AWS CDK with TypeScript, see [Deploy with AWS CDK](https://catalog.workshops.aws/stepfunctions/iac/deploy-with-cdk) in *The AWS Step Functions Workshop*.

## Step 1: Set up your AWS CDK project
<a name="lambda-state-machine-cdk-step-1"></a>

1. In your home directory, or another directory if you prefer, run the following command to create a directory for your new AWS CDK app.
**Important**  
Be sure to name the directory `step`. The AWS CDK application template uses the name of the directory to generate names for source files and classes. If you use a different name, your app will not match this tutorial.

------
#### [ TypeScript ]

   ```
   mkdir step && cd step
   ```

------
#### [ JavaScript ]

   ```
   mkdir step && cd step
   ```

------
#### [ Python ]

   ```
   mkdir step && cd step
   ```

------
#### [ Java ]

   ```
   mkdir step && cd step
   ```

------
#### [ C\$1 ]

   Make sure you've installed .NET version 6.0 or higher. For information, see [Supported versions](https://dotnet.microsoft.com/en-us/download/dotnet).

   ```
   mkdir step && cd step
   ```

------

1. Initialize the app by using the **cdk init** command. Specify the desired template ("app") and programming language as shown in the following examples.

------
#### [ TypeScript ]

   ```
   cdk init --language typescript
   ```

------
#### [ JavaScript ]

   ```
   cdk init --language javascript
   ```

------
#### [ Python ]

   ```
   cdk init --language python
   ```

   After the project is initialized, activate the project's virtual environment and install the AWS CDK's baseline dependencies.

   ```
   source .venv/bin/activate
   python -m pip install -r requirements.txt
   ```

------
#### [ Java ]

   ```
   cdk init --language java
   ```

------
#### [ C\$1 ]

   ```
   cdk init --language csharp
   ```

------

## Step 2: Use AWS CDK to create a state machine
<a name="lambda-state-machine-cdk-step-2"></a>

First, we'll present the individual pieces of code that define the Lambda function and the Step Functions state machine. Then, we'll explain how to put them together in your AWS CDK app. Finally, you'll see how to synthesize and deploy these resources.

### To create a Lambda function
<a name="lambda-state-machine-cdk-create-function"></a>

The following AWS CDK code defines the Lambda function, providing its source code inline.

------
#### [ TypeScript ]

```
const helloFunction = new lambda.Function(this, 'MyLambdaFunction', {
    code: lambda.Code.fromInline(`
          exports.handler = (event, context, callback) => {
              callback(null, "Hello World!");
          };
      `),
    runtime: lambda.Runtime.NODEJS_18_X,
    handler: "index.handler",
    timeout: cdk.Duration.seconds(3)
});
```

------
#### [ JavaScript ]

```
const helloFunction = new lambda.Function(this, 'MyLambdaFunction', {
    code: lambda.Code.fromInline(`
          exports.handler = (event, context, callback) => {
              callback(null, "Hello World!");
          };
      `),
    runtime: lambda.Runtime.NODEJS_18_X,
    handler: "index.handler",
    timeout: cdk.Duration.seconds(3)
});
```

------
#### [ Python ]

```
hello_function = lambda_.Function(
            self, "MyLambdaFunction",
            code=lambda_.Code.from_inline("""
            exports.handler = (event, context, callback) => {
                callback(null, "Hello World!");
                }"""),
                runtime=lambda_.Runtime.NODEJS_18_X,
                handler="index.handler",
                timeout=Duration.seconds(25))
```

------
#### [ Java ]

```
final Function helloFunction = Function.Builder.create(this, "MyLambdaFunction")
        .code(Code.fromInline(
                "exports.handler = (event, context, callback) => { callback(null, 'Hello World!' );}"))
        .runtime(Runtime.NODEJS_18_X)
        .handler("index.handler")
        .timeout(Duration.seconds(25))
        .build();
```

------
#### [ C\$1 ]

```
var helloFunction = new Function(this, "MyLambdaFunction", new FunctionProps
{
    Code = Code.FromInline(@"`
      exports.handler = (event, context, callback) => {
        callback(null, 'Hello World!');
      }"),
    Runtime = Runtime.NODEJS_12_X,
    Handler = "index.handler",
    Timeout = Duration.Seconds(25)
});
```

------

You can see in this short example code:
+ The function's logical name, `MyLambdaFunction`.
+ The source code for the function, embedded as a string in the source code of the AWS CDK app.
+ Other function attributes, such as the runtime to be used (Node 18.x), the function's entry point, and a timeout.

### To create a state machine
<a name="lambda-state-machine-cdk-create"></a>

Our state machine has two states: a Lambda function task, and a [Succeed workflow state](state-succeed.md) state. The function requires that we create a Step Functions [Task workflow state](state-task.md) that invokes our function. This Task state is used as the first step in the state machine. The success state is added to the state machine using the Task state's `next()` method. The following code first invokes the function named `MyLambdaTask`, then uses the `next()` method to define a success state named `GreetedWorld`.

------
#### [ TypeScript ]

```
const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', {
  definition: new tasks.LambdaInvoke(this, "MyLambdaTask", {
    lambdaFunction: helloFunction
  }).next(new sfn.Succeed(this, "GreetedWorld"))
});
```

------
#### [ JavaScript ]

```
const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', {
  definition: new tasks.LambdaInvoke(this, "MyLambdaTask", {
    lambdaFunction: helloFunction
  }).next(new sfn.Succeed(this, "GreetedWorld"))
});
```

------
#### [ Python ]

```
state_machine = sfn.StateMachine(
                                 self, "MyStateMachine",
                                 definition=tasks.LambdaInvoke(
                                 self, "MyLambdaTask",
                                 lambda_function=hello_function)
                                 .next(sfn.Succeed(self, "GreetedWorld")))
```

------
#### [ Java ]

```
final StateMachine stateMachine = StateMachine.Builder.create(this, "MyStateMachine")
        .definition(LambdaInvoke.Builder.create(this, "MyLambdaTask")
            .lambdaFunction(helloFunction)
            .build()
            .next(new Succeed(this, "GreetedWorld")))
        .build();
```

------
#### [ C\$1 ]

```
var stateMachine = new StateMachine(this, "MyStateMachine", new StateMachineProps {
    DefinitionBody = DefinitionBody.FromChainable(new LambdaInvoke(this, "MyLambdaTask", new LambdaInvokeProps
    {
        LambdaFunction = helloFunction
    })
    .Next(new Succeed(this, "GreetedWorld")))
});
```

------

### To build and deploy the AWS CDK app
<a name="lambda-state-machine-cdk-app"></a>

In your newly created AWS CDK project, edit the file that contains the stack's definition to look like the following example code. You'll recognize the definitions of the Lambda function and the Step Functions state machine from previous sections.

1. Update the stack as shown in the following examples.

------
#### [ TypeScript ]

   Update `lib/step-stack.ts` with the following code.

   ```
   import * as cdk from 'aws-cdk-lib';
   import * as lambda from 'aws-cdk-lib/aws-lambda';
   import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
   import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';
   
   export class StepStack extends cdk.Stack {
     constructor(app: cdk.App, id: string) {
       super(app, id);
   
       const helloFunction = new lambda.Function(this, 'MyLambdaFunction', {
         code: lambda.Code.fromInline(`
             exports.handler = (event, context, callback) => {
                 callback(null, "Hello World!");
             };
         `),
         runtime: lambda.Runtime.NODEJS_18_X,
         handler: "index.handler",
         timeout: cdk.Duration.seconds(3)
       });
   
       const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', {
         definition: new tasks.LambdaInvoke(this, "MyLambdaTask", {
           lambdaFunction: helloFunction
         }).next(new sfn.Succeed(this, "GreetedWorld"))
       });
     }
   }
   ```

------
#### [ JavaScript ]

   Update `lib/step-stack.js` with the following code.

   ```
   import * as cdk from 'aws-cdk-lib';
   import * as lambda from 'aws-cdk-lib/aws-lambda';
   import * as sfn from 'aws-cdk-lib/aws-stepfunctions';
   import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks';
   
   export class StepStack extends cdk.Stack {
     constructor(app, id) {
       super(app, id);
   
       const helloFunction = new lambda.Function(this, 'MyLambdaFunction', {
         code: lambda.Code.fromInline(`
             exports.handler = (event, context, callback) => {
                 callback(null, "Hello World!");
             };
         `),
         runtime: lambda.Runtime.NODEJS_18_X,
         handler: "index.handler",
         timeout: cdk.Duration.seconds(3)
       });
   
       const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', {
         definition: new tasks.LambdaInvoke(this, "MyLambdaTask", {
           lambdaFunction: helloFunction
         }).next(new sfn.Succeed(this, "GreetedWorld"))
       });
     }
   }
   ```

------
#### [ Python ]

   Update `step/step_stack.py` with the following code.

   ```
   from aws_cdk import (
       Duration,
       Stack,
       aws_stepfunctions as sfn,
       aws_stepfunctions_tasks as tasks,
       aws_lambda as lambda_
   )
   class StepStack(Stack):
   
       def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
           super().__init__(scope, construct_id, **kwargs)
   
           hello_function = lambda_.Function(
               self, "MyLambdaFunction",
               code=lambda_.Code.from_inline("""
               exports.handler = (event, context, callback) => {
                   callback(null, "Hello World!");
                   }"""),
                   runtime=lambda_.Runtime.NODEJS_18_X,
                   handler="index.handler",
                   timeout=Duration.seconds(25))
   
           state_machine = sfn.StateMachine(
               self, "MyStateMachine",
               definition=tasks.LambdaInvoke(
               self, "MyLambdaTask",
               lambda_function=hello_function)
               .next(sfn.Succeed(self, "GreetedWorld")))
   ```

------
#### [ Java ]

   Update `src/main/java/com.myorg/StepStack.java` with the following code.

   ```
   package com.myorg;
   
   import software.constructs.Construct;
   import software.amazon.awscdk.Stack;
   import software.amazon.awscdk.StackProps;
   import software.amazon.awscdk.Duration;
   import software.amazon.awscdk.services.lambda.Code;
   import software.amazon.awscdk.services.lambda.Function;
   import software.amazon.awscdk.services.lambda.Runtime;
   import software.amazon.awscdk.services.stepfunctions.StateMachine;
   import software.amazon.awscdk.services.stepfunctions.Succeed;
   import software.amazon.awscdk.services.stepfunctions.tasks.LambdaInvoke;
   
   public class StepStack extends Stack {
       public StepStack(final Construct scope, final String id) {
           this(scope, id, null);
       }
   
       public StepStack(final Construct scope, final String id, final StackProps props) {
           super(scope, id, props);
   
           final Function helloFunction = Function.Builder.create(this, "MyLambdaFunction")
                   .code(Code.fromInline(
                           "exports.handler = (event, context, callback) => { callback(null, 'Hello World!' );}"))
                   .runtime(Runtime.NODEJS_18_X)
                   .handler("index.handler")
                   .timeout(Duration.seconds(25))
                   .build();
   
           final StateMachine stateMachine = StateMachine.Builder.create(this, "MyStateMachine")
                   .definition(LambdaInvoke.Builder.create(this, "MyLambdaTask")
                           .lambdaFunction(helloFunction)
                           .build()
                           .next(new Succeed(this, "GreetedWorld")))
                   .build();
       }
   }
   ```

------
#### [ C\$1 ]

   Update `src/Step/StepStack.cs` with the following code.

   ```
   using Amazon.CDK;
   using Constructs;
   using Amazon.CDK.AWS.Lambda;
   using Amazon.CDK.AWS.StepFunctions;
   using Amazon.CDK.AWS.StepFunctions.Tasks;
   
   namespace Step
   {
       public class StepStack : Stack
       {
           internal StepStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
           {
               var helloFunction = new Function(this, "MyLambdaFunction", new FunctionProps
               {
                   Code = Code.FromInline(@"exports.handler = (event, context, callback) => {
                       callback(null, 'Hello World!');
                   }"),
                   Runtime = Runtime.NODEJS_18_X,
                   Handler = "index.handler",
                   Timeout = Duration.Seconds(25)
               });
   
               var stateMachine = new StateMachine(this, "MyStateMachine", new StateMachineProps
               {
                   DefinitionBody = DefinitionBody.FromChainable(new LambdaInvoke(this, "MyLambdaTask", new LambdaInvokeProps
                   {
                       LambdaFunction = helloFunction
                   })
                   .Next(new Succeed(this, "GreetedWorld")))
               });
           }
       }
   }
   ```

------

1. Save the source file, and then run the `cdk synth` command in the app's main directory.

   AWS CDK runs the app and synthesizes an CloudFormation template from it. AWS CDK then displays the template.
**Note**  
If you used TypeScript to create your AWS CDK project, running the `cdk synth` command may return the following error.  

   ```
   TSError: ⨯ Unable to compile TypeScript:
   bin/step.ts:7:33 - error TS2554: Expected 2 arguments, but got 3.
   ```
Modify the `bin/step.ts` file as shown in the following example to resolve this error.  

   ```
   #!/usr/bin/env node
   import 'source-map-support/register';
   import * as cdk from 'aws-cdk-lib';
   import { StepStack } from '../lib/step-stack';
   
   const app = new cdk.App();
   new StepStack(app, 'StepStack');
   app.synth();
   ```

1. To deploy the Lambda function and the Step Functions state machine to your AWS account, issue `cdk deploy`. You'll be asked to approve the IAM policies the AWS CDK has generated.

## Step 3: Start a state machine execution
<a name="lambda-state-machine-cdk-step-3"></a>

After you create your state machine, you can start its execution.

### To start the state machine execution
<a name="to-start-the-state-machine-execution"></a>

1. Open the [Step Functions console](https://console.aws.amazon.com/states/home) and choose the name of the state machine that you created using AWS CDK.

1. On the state machine page, choose **Start execution**.

   The **Start execution** dialog box is displayed.

1. (Optional) Enter a custom execution name to override the generated default.
**Non-ASCII names and logging**  
Step Functions accepts names for state machines, executions, activities, and labels that contain non-ASCII characters. Because such characters will prevent Amazon CloudWatch from logging data, we recommend using only ASCII characters so you can track Step Functions metrics.

1. Choose **Start Execution**.

   Your state machine's execution starts, and a new page showing your running execution is displayed.

1. The Step Functions console directs you to a page that's titled with your execution ID. This page is known as the *Execution Details* page. On this page, you can review the execution results as the execution progresses or after it's complete.

   To review the execution results, choose individual states on the **Graph view**, and then choose the individual tabs on the [Step details](concepts-view-execution-details.md#exec-details-intf-step-details) pane to view each state's details including input, output, and definition respectively. For details about the execution information you can view on the *Execution Details* page, see [Execution details overview](concepts-view-execution-details.md#exec-details-interface-overview).

## Step 4: Clean Up
<a name="lambda-state-machine-cdk-step-4"></a>

After you've tested your state machine, we recommend that you remove both your state machine and the related Lambda function to free up resources in your AWS account. Run the `cdk destroy` command in your app's main directory to remove your state machine.

## Next steps
<a name="lambda-state-machine-cdk-next-steps"></a>

To learn more about developing AWS infrastructure using AWS CDK, see the [AWS CDK Developer Guide](https://docs.aws.amazon.com/cdk/v2/guide/home.html).

For information about writing AWS CDK apps in your language of choice, see:

------
#### [ TypeScript ]

 [Working with AWS CDK in TypeScript](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-typescript.html) 

------
#### [ JavaScript ]

 [Working with AWS CDK in JavaScript](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-javascript.html) 

------
#### [ Python ]

 [Working with AWS CDK in Python](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-python.html) 

------
#### [ Java ]

 [Working with AWS CDK in Java](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-java.html) 

------
#### [ C\$1 ]

 [Working with AWS CDK in C\$1](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-csharp.html) 

------

For more information about the AWS Construct Library modules used in this tutorial, see the following AWS CDK API Reference overviews:
+  [aws-lambda](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html) 
+  [aws-stepfunctions](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_stepfunctions-readme.html) 
+  [aws-stepfunctions-tasks](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_stepfunctions_tasks-readme.html) 

# Using AWS CDK to create an Express workflow in Step Functions
<a name="tutorial-step-functions-rest-api-integration-cdk"></a>

In this tutorial, you learn how to create an API Gateway REST API with a synchronous express state machine as the backend integration, using the AWS Cloud Development Kit (AWS CDK) Infrastructure as Code (IAC) framework.

You will use the `StepFunctionsRestApi` construct to connect the State Machine to the API Gateway. The `StepFunctionsRestApi` construct will set up a default input/output mapping and the API Gateway REST API, with required permissions and an HTTP “ANY” method.

 With AWS CDK is an Infrastructure as Code (IAC) framework, you define AWS infrastructure using a programming language. You define an app in one of the CDK's supported languages, synthesize the code into an CloudFormation template, and then deploy the infrastructure to your AWS account.

 You will use CloudFormation to define an API Gateway REST API, which is integrated with Synchronous Express State Machine as the backend, then use the AWS Management Console to initiate execution. 

Before starting this tutorial, set up your AWS CDK development environment as described in [Getting Started With the AWS CDK - Prerequisites](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_prerequisites), then install the AWS CDK by issuing:

```
npm install -g aws-cdk
```

## Step 1: Set Up Your AWS CDK Project
<a name="step-functions-rest-api-integration-cdk-step-1"></a>

First, create a directory for your new AWS CDK app and initialize the project.

------
#### [ TypeScript ]

```
mkdir stepfunctions-rest-api
cd stepfunctions-rest-api
cdk init --language typescript
```

------
#### [ JavaScript ]

```
mkdir stepfunctions-rest-api
cd stepfunctions-rest-api
cdk init --language javascript
```

------
#### [ Python ]

```
mkdir stepfunctions-rest-api
cd stepfunctions-rest-api
cdk init --language python
```

After the project has been initialized, activate the project's virtual environment and install the AWS CDK's baseline dependencies.

```
source .venv/bin/activate
python -m pip install -r requirements.txt
```

------
#### [ Java ]

```
mkdir stepfunctions-rest-api
cd stepfunctions-rest-api
cdk init --language java
```

------
#### [ C\$1 ]

```
mkdir stepfunctions-rest-api
cd stepfunctions-rest-api
cdk init --language csharp
```

------
#### [ Go ]

```
mkdir stepfunctions-rest-api
cd stepfunctions-rest-api
cdk init --language go
```

------

**Note**  
Be sure to name the directory `stepfunctions-rest-api`. The AWS CDK application template uses the name of the directory to generate names for source files and classes. If you use a different name, your app will not match this tutorial.

Now install the construct library modules for AWS Step Functions and Amazon API Gateway.

------
#### [ TypeScript ]

```
npm install @aws-cdk/aws-stepfunctions @aws-cdk/aws-apigateway
```

------
#### [ JavaScript ]

```
npm install @aws-cdk/aws-stepfunctions @aws-cdk/aws-apigateway
```

------
#### [ Python ]

```
python -m pip install aws-cdk.aws-stepfunctions
python -m pip install aws-cdk.aws-apigateway
```

------
#### [ Java ]

Edit the project's `pom.xml` to add the following dependencies inside the existing `<dependencies>` container.

```
        <dependency>
            <groupId>software.amazon.awscdk</groupId>
            <artifactId>stepfunctions</artifactId>
            <version>${cdk.version}</version>
        </dependency>
        <dependency>
            <groupId>software.amazon.awscdk</groupId>
            <artifactId>apigateway</artifactId>
            <version>${cdk.version}</version>
        </dependency>
```

Maven automatically installs these dependencies the next time you build your app. To build, issue `mvn compile` or use your Java IDE's **Build** command.

------
#### [ C\$1 ]

```
dotnet add src/StepfunctionsRestApi package Amazon.CDK.AWS.Stepfunctions
dotnet add src/StepfunctionsRestApi package Amazon.CDK.AWS.APIGateway
```

You may also install the indicated packages using the Visual Studio NuGet GUI, available via **Tools** > **NuGet Package Manager** > **Manage NuGet Packages for Solution**.

------

Once you have installed the modules, you can use them in your AWS CDK app by importing the following packages.

------
#### [ TypeScript ]

```
@aws-cdk/aws-stepfunctions
@aws-cdk/aws-apigateway
```

------
#### [ JavaScript ]

```
@aws-cdk/aws-stepfunctions
@aws-cdk/aws-apigateway
```

------
#### [ Python ]

```
aws_cdk.aws_stepfunctions
aws_cdk.aws_apigateway
```

------
#### [ Java ]

```
software.amazon.awscdk.services.apigateway.StepFunctionsRestApi
software.amazon.awscdk.services.stepfunctions.Pass
software.amazon.awscdk.services.stepfunctions.StateMachine
software.amazon.awscdk.services.stepfunctions.StateMachineType
```

------
#### [ C\$1 ]

```
Amazon.CDK.AWS.StepFunctions
Amazon.CDK.AWS.APIGateway
```

------
#### [ Go ]

Add the following to `import` inside `stepfunctions-rest-api.go`.

```
"github.com/aws/aws-cdk-go/awscdk/awsapigateway"
"github.com/aws/aws-cdk-go/awscdk/awsstepfunctions"
```

------

## Step 2: Use the AWS CDK to create an API Gateway REST API with Synchronous Express State Machine backend integration
<a name="step-functions-rest-api-integration-cdk-step-2"></a>

First, we'll present the individual pieces of code that define the Synchronous Express State Machine and the API Gateway REST API, then explain how to put them together into your AWS CDK app. Then you'll see how to synthesize and deploy these resources.

**Note**  
The State Machine that we will show here will be a simple State Machine with a `Pass` state.

### To create an Express State Machine
<a name="step-functions-rest-api-integration-cdk-create-state-machine"></a>

This is the AWS CDK code that defines a simple state machine with a `Pass` state.

------
#### [ TypeScript ]

```
const machineDefinition = new stepfunctions.Pass(this, 'PassState', {
    result: {value:"Hello!"},
})

const stateMachine = new stepfunctions.StateMachine(this, 'MyStateMachine', {
    definition: machineDefinition,
    stateMachineType: stepfunctions.StateMachineType.EXPRESS,
});
```

------
#### [ JavaScript ]

```
const machineDefinition = new sfn.Pass(this, 'PassState', {
    result: {value:"Hello!"},
})

const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', {
    definition: machineDefinition,
    stateMachineType: stepfunctions.StateMachineType.EXPRESS,
});
```

------
#### [ Python ]

```
machine_definition = sfn.Pass(self,"PassState", 
                        result = sfn.Result("Hello"))
    
state_machine = sfn.StateMachine(self, 'MyStateMachine', 
        definition = machine_definition, 
        state_machine_type = sfn.StateMachineType.EXPRESS)
```

------
#### [ Java ]

```
Pass machineDefinition = Pass.Builder.create(this, "PassState")
                        .result(Result.fromString("Hello"))
                        .build();

StateMachine stateMachine = StateMachine.Builder.create(this, "MyStateMachine")
                            .definition(machineDefinition)
                            .stateMachineType(StateMachineType.EXPRESS)
                            .build();
```

------
#### [ C\$1 ]

```
var machineDefinition = new Pass(this, "PassState", new PassProps
{
    Result = Result.FromString("Hello")
});

var stateMachine = new StateMachine(this, "MyStateMachine", new StateMachineProps
{
    Definition = machineDefinition,
    StateMachineType = StateMachineType.EXPRESS
});
```

------
#### [ Go ]

```
var machineDefinition = awsstepfunctions.NewPass(stack, jsii.String("PassState"), &awsstepfunctions.PassProps
{
    Result: awsstepfunctions.NewResult(jsii.String("Hello")),
})

var stateMachine = awsstepfunctions.NewStateMachine(stack, jsii.String("StateMachine"), &awsstepfunctions.StateMachineProps
{    
    Definition: machineDefinition,
    StateMachineType: awsstepfunctions.StateMachineType_EXPRESS,
})
```

------

You can see in this short snippet:
+ The machine definition named `PassState`, which is a `Pass` State.
+ The State Machine’s logical name, `MyStateMachine`.
+ The machine definition is used as the State Machine definition.
+ The State Machine Type is set as `EXPRESS` because `StepFunctionsRestApi` will only allow a Synchronous Express state machine.

### To create the API Gateway REST API using `StepFunctionsRestApi` construct
<a name="step-functions-rest-api-integration-cdk-create-rest-api"></a>

We will use `StepFunctionsRestApi` construct to create the API Gateway REST API with required permissions and default input/output mapping.

------
#### [ TypeScript ]

```
const api = new apigateway.StepFunctionsRestApi(this, 
  'StepFunctionsRestApi', { stateMachine: stateMachine });
```

------
#### [ JavaScript ]

```
const api = new apigateway.StepFunctionsRestApi(this, 
  'StepFunctionsRestApi', { stateMachine: stateMachine });
```

------
#### [ Python ]

```
api = apigw.StepFunctionsRestApi(self, "StepFunctionsRestApi",
                            state_machine = state_machine)
```

------
#### [ Java ]

```
StepFunctionsRestApi api = StepFunctionsRestApi.Builder.create(this, "StepFunctionsRestApi")
                           .stateMachine(stateMachine)
                           .build();
```

------
#### [ C\$1 ]

```
var api = new StepFunctionsRestApi(this, "StepFunctionsRestApi", new StepFunctionsRestApiProps
{
    StateMachine = stateMachine
});
```

------
#### [ Go ]

```
awsapigateway.NewStepFunctionsRestApi(stack, jsii.String("StepFunctionsRestApi"), &awsapigateway.StepFunctionsRestApiProps
{
    StateMachine = stateMachine,
})
```

------

### To build and deploy the AWS CDK app
<a name="step-functions-rest-api-integration-cdk-app"></a>

In the AWS CDK project you created, edit the file containing the definition of the stack to look like the code below. You'll recognize the definitions of the Step Functions state machine and the API Gateway from above.

------
#### [ TypeScript ]

Update ` lib/stepfunctions-rest-api-stack.ts` to read as follows.

```
import * as cdk from 'aws-cdk-lib';
import * as stepfunctions from 'aws-cdk-lib/aws-stepfunctions' 
import * as apigateway from 'aws-cdk-lib/aws-apigateway';


export class StepfunctionsRestApiStack extends cdk.Stack {
    constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const machineDefinition = new stepfunctions.Pass(this, 'PassState', {
        result: {value:"Hello!"},
    });
    
    const stateMachine = new stepfunctions.StateMachine(this, 'MyStateMachine', {
        definition: machineDefinition,
        stateMachineType: stepfunctions.StateMachineType.EXPRESS,
    });
    
    const api = new apigateway.StepFunctionsRestApi(this, 
        'StepFunctionsRestApi', { stateMachine: stateMachine });
```

------
#### [ JavaScript ]

Update `lib/stepfunctions-rest-api-stack.js` to read as follows.

```
const cdk = require('@aws-cdk/core');
const stepfunctions = require('@aws-cdk/aws-stepfunctions');
const apigateway = require('@aws-cdk/aws-apigateway');


class StepfunctionsRestApiStack extends cdk.Stack {
    constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const machineDefinition = new stepfunctions.Pass(this, "PassState", {
        result: {value:"Hello!"},
    })
    
    const stateMachine = new sfn.StateMachine(this, 'MyStateMachine', {
        definition: machineDefinition,
        stateMachineType: stepfunctions.StateMachineType.EXPRESS,
    });
    
    const api = new apigateway.StepFunctionsRestApi(this, 
        'StepFunctionsRestApi', { stateMachine: stateMachine });

    }
}

module.exports = { StepStack }
```

------
#### [ Python ]

Update `stepfunctions_rest_api/stepfunctions_rest_api_stack.py` to read as follows.

```
from aws_cdk import App, Stack
from constructs import Construct
from aws_cdk import aws_stepfunctions as sfn
from aws_cdk import aws_apigateway as apigw

class StepfunctionsRestApiStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        
        
        machine_definition = sfn.Pass(self,"PassState", 
                                result = sfn.Result("Hello"))

        state_machine = sfn.StateMachine(self, 'MyStateMachine', 
                definition = machine_definition, 
                state_machine_type = sfn.StateMachineType.EXPRESS)

        api = apigw.StepFunctionsRestApi(self, 
                    "StepFunctionsRestApi",
                    state_machine = state_machine)
```

------
#### [ Java ]

Update `src/main/java/com.myorg/StepfunctionsRestApiStack.java` to read as follows.

```
package com.myorg;


import software.amazon.awscdk.core.Construct;
import software.amazon.awscdk.core.Stack;
import software.amazon.awscdk.core.StackProps;
import software.amazon.awscdk.services.stepfunctions.Pass;
import software.amazon.awscdk.services.stepfunctions.StateMachine;
import software.amazon.awscdk.services.stepfunctions.StateMachineType;
import software.amazon.awscdk.services.apigateway.StepFunctionsRestApi;

public class StepfunctionsRestApiStack extends Stack {
    public StepfunctionsRestApiStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public StepfunctionsRestApiStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        Pass machineDefinition = Pass.Builder.create(this, "PassState")
                                .result(Result.fromString("Hello"))
                                .build();
        
        StateMachine stateMachine = StateMachine.Builder.create(this, "MyStateMachine")
                                    .definition(machineDefinition)
                                    .stateMachineType(StateMachineType.EXPRESS)
                                    .build();
                                    
        StepFunctionsRestApi api = StepFunctionsRestApi.Builder.create(this, "StepFunctionsRestApi")
                                   .stateMachine(stateMachine)
                                   .build();
                                   
    }
}
```

------
#### [ C\$1 ]

Update `src/StepfunctionsRestApi/StepfunctionsRestApiStack.cs` to read as follows.

```
using Amazon.CDK;
using Amazon.CDK.AWS.StepFunctions;
using Amazon.CDK.AWS.APIGateway;

namespace StepfunctionsRestApi
{
    public class StepfunctionsRestApiStack : Stack
    {
        internal StepfunctionsRestApi(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            var machineDefinition = new Pass(this, "PassState", new PassProps
            {
                Result = Result.FromString("Hello")
            });

            var stateMachine = new StateMachine(this, "MyStateMachine", new StateMachineProps
            {
                Definition = machineDefinition,
                StateMachineType = StateMachineType.EXPRESS
            });
            
            var api = new StepFunctionsRestApi(this, "StepFunctionsRestApi", new StepFunctionsRestApiProps
            {
                StateMachine = stateMachine
            });

        }
    }
}
```

------
#### [ Go ]

Update `stepfunctions-rest-api.go` to read as follows.

```
package main
import (
    "github.com/aws/aws-cdk-go/awscdk"
    "github.com/aws/aws-cdk-go/awscdk/awsapigateway"
    "github.com/aws/aws-cdk-go/awscdk/awsstepfunctions"
    "github.com/aws/constructs-go/constructs/v3"
    "github.com/aws/jsii-runtime-go"
)


type StepfunctionsRestApiGoStackProps struct {
    awscdk.StackProps
}

func NewStepfunctionsRestApiGoStack(scope constructs.Construct, id string, props *StepfunctionsRestApiGoStackProps) awscdk.Stack {
    var sprops awscdk.StackProps
    if props != nil {
        sprops = props.StackProps
    }
    stack := awscdk.NewStack(scope, &id, &sprops)

    // The code that defines your stack goes here
    var machineDefinition = awsstepfunctions.NewPass(stack, jsii.String("PassState"), &awsstepfunctions.PassProps
    {
        Result: awsstepfunctions.NewResult(jsii.String("Hello")),
    })

    var stateMachine = awsstepfunctions.NewStateMachine(stack, jsii.String("StateMachine"), &awsstepfunctions.StateMachineProps{
        Definition: machineDefinition,
        StateMachineType: awsstepfunctions.StateMachineType_EXPRESS,
    });

    awsapigateway.NewStepFunctionsRestApi(stack, jsii.String("StepFunctionsRestApi"), &awsapigateway.StepFunctionsRestApiProps{
        StateMachine = stateMachine,
    })

    return stack
}

func main() {
    app := awscdk.NewApp(nil)

    NewStepfunctionsRestApiGoStack(app, "StepfunctionsRestApiGoStack", &StepfunctionsRestApiGoStackProps{
        awscdk.StackProps{
            Env: env(),
        },
    })

    app.Synth(nil)
}

// env determines the AWS environment (account+region) in which our stack is to
// be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html
func env() *awscdk.Environment {
    // If unspecified, this stack will be "environment-agnostic".
    // Account/Region-dependent features and context lookups will not work, but a
    // single synthesized template can be deployed anywhere.
    //---------------------------------------------------------------------------
    return nil

    // Uncomment if you know exactly what account and region you want to deploy
    // the stack to. This is the recommendation for production stacks.
    //---------------------------------------------------------------------------
    // return &awscdk.Environment{
    //  Account: jsii.String("account-id"),
    //  Region:  jsii.String("us-east-1"),
    // }

    // Uncomment to specialize this stack for the AWS Account and Region that are
    // implied by the current CLI configuration. This is recommended for dev
    // stacks.
    //---------------------------------------------------------------------------
    // return &awscdk.Environment{
    //  Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")),
    //  Region:  jsii.String(os.Getenv("CDK_DEFAULT_REGION")),
    // }
}
```

------

Save the source file, then issue `cdk synth` in the app's main directory. The AWS CDK runs the app and synthesizes an CloudFormation template from it, then displays the template.

To actually deploy the Amazon API Gateway and the AWS Step Functions state machine to your AWS account, issue `cdk deploy`. You'll be asked to approve the IAM policies the AWS CDK has generated.

## Step 3: Test the API Gateway
<a name="step-functions-rest-api-integration-cdk-step-3"></a>

After you create your API Gateway REST API with Synchronous Express State Machine as the backend integration, you can test the API Gateway.

### To test the deployed API Gateway using API Gateway console
<a name="to-test-the-deployed-api-gateway-using-console"></a>

1. Open the [Amazon API Gateway console](https://console.aws.amazon.com/apigateway/) and sign in.

1. Choose your REST API named `StepFunctionsRestApi`.

1. In the **Resources** pane, choose the `ANY` method.

1. Choose the **Test** tab. You might need to choose the right arrow button to show the tab. 

1. For **Method**, choose **POST**.

1. For **Request body**, copy the following request parameters.

   ```
   {
       "key": "Hello"
   }
   ```

1. Choose **Test**. The following information will be displayed:
   + **Request** is the resource's path that was called for the method. 
   + **Status** is the response's HTTP status code.
   + **Latency** is the time between the receipt of the request from the caller and the returned response.
   + **Response body** is the HTTP response body.
   + **Response headers** are the HTTP response headers.
   + **Log** shows the simulated Amazon CloudWatch Logs entries that would have been written if this method were called outside of the API Gateway console.
**Note**  
Although the CloudWatch Logs entries are simulated, the results of the method call are real.

The **Response body** output should be something like this:

```
"Hello"
```

**Tip**  
Try the API Gateway with different methods and an invalid input to see the error output. You may want to change the state machine to look for a particular key and during testing provide the wrong key to fail the State Machine execution and generate an error message in the **Response body** output.

### To test the deployed API using cURL
<a name="to-test-the-deployed-api-gateway-using-curl"></a>

1. Open a terminal window.

1. Copy the following cURL command and paste it into the terminal window, replacing `<api-id>` with your API's API ID and `<region>` with the region where your API is deployed. 

   ```
   curl -X POST\
    'https://<api-id>.execute-api.<region>.amazonaws.com/prod' \
    -d '{"key":"Hello"}' \
    -H 'Content-Type: application/json'
   ```

The **Response Body** output should be something like this:

```
"Hello"
```

**Tip**  
Try the API Gateway with different methods and an invalid input to see the error output. You may want to change the state machine to look for a particular key and during testing provide the wrong key to fail the State Machine execution and generate an error message in the **Response Body** output.

## Step 4: Clean Up
<a name="step-functions-rest-api-integration-cdk-step-4"></a>

When you're done trying out your API Gateway, you can tear down both the state machine and the API Gateway using the AWS CDK. Issue `cdk destroy` in your app's main directory.

# Using Terraform to deploy state machines in Step Functions
<a name="terraform-sfn"></a>

[Terraform](https://www.terraform.io/intro/) by HashiCorp is a framework for building applications using infrastructure as code (IaC). With Terraform, you can create state machines and use features, such as previewing infrastructure deployments and creating reusable templates. Terraform templates help you maintain and reuse the code by breaking it down into smaller chunks.

If you're familiar with Terraform, you can follow the development lifecycle described in this topic as a model for creating and deploying your state machines in Terraform. If you aren't familiar with Terraform, we recommend that you first complete the workshop [Introduction to Terraform on AWS](https://catalog.workshops.aws/terraform101/en-US) for getting acquainted with Terraform.

**Tip**  
To deploy an example of a state machine built using Terraform, see [Deploy with Terraform](https://catalog.workshops.aws/stepfunctions/iac/deploy-with-terraform) in *The AWS Step Functions Workshop*.

**Topics**
+ [

## Prerequisites
](#terraform-sfn-prerequisites)
+ [Development lifecycle with Terraform](#terraform-sfn-dev-lifecycle)
+ [

## IAM roles and policies for your state machine
](#terraform-sfn-iam-policy)

## Prerequisites
<a name="terraform-sfn-prerequisites"></a>

Before you get started, make sure you complete the following prerequisites:
+ Install Terraform on your machine. For information about installing Terraform, see [Install Terraform](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli).
+ Install Step Functions Local on your machine. We recommend that you install the Step Functions Local Docker image to use Step Functions Local. For more information, see [Testing state machines with Step Functions Local (unsupported)](sfn-local.md).
+ Install AWS SAM CLI. For installation information, see [Installing the AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html) in the *AWS Serverless Application Model Developer Guide*.
+ Install the AWS Toolkit for Visual Studio Code to view the workflow diagram of your state machines. For installation information, see [Installing the AWS Toolkit for Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/setup-toolkit.html) in the *AWS Toolkit for Visual Studio Code User Guide*.

## State machine development lifecycle with Terraform
<a name="terraform-sfn-dev-lifecycle"></a>

The following procedure explains how you can use a state machine prototype that you build using [Workflow Studio](workflow-studio.md) in the Step Functions console as a starting point for local development with Terraform and the [AWS Toolkit for Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/welcome.html).

To view the complete example that discusses the state machine development with Terraform and presents the best practices in detail, see [Best practices for writing Step Functions Terraform projects](https://aws.amazon.com/blogs/devops/best-practices-for-writing-step-functions-terraform-projects/).

**To start the development lifecycle of a state machine with Terraform**

1. Bootstrap a new Terraform project with the following command.

   ```
   terraform init
   ```

1. Open the [Step Functions console](https://console.aws.amazon.com/states/home?region=us-east-1#/) to create a prototype for your state machine.

1. In Workflow Studio, do the following:

   1. Create your workflow prototype.

   1. Export the [Amazon States Language (ASL)](concepts-amazon-states-language.md) definition of your workflow. To do this, choose the **Import/Export** dropdownlist, and then select **Export JSON definition**.

1. Save the exported ASL definition within your project directory.

   You pass the exported ASL definition as an input parameter to the [https://registry.terraform.io/modules/terraform-aws-modules/step-functions/aws/latest](https://registry.terraform.io/modules/terraform-aws-modules/step-functions/aws/latest) Terraform resource that uses the [https://developer.hashicorp.com/terraform/language/functions/templatefile](https://developer.hashicorp.com/terraform/language/functions/templatefile) function. This function is used inside the definition field that passes the exported ASL definition and any variable substitutions.
**Tip**  
Because the ASL definition file can contain lengthy blocks of text, we recommend you avoid the inline EOF method. This makes it easier to substitute parameters into your state machine definition.

1. (Optional) Update the ASL definition within your IDE and visualize your changes using the AWS Toolkit for Visual Studio Code.  
![\[Screenshot of the ASL definition of a workflow in Visual Studio Code and its visual representation.\]](http://docs.aws.amazon.com/step-functions/latest/dg/images/visualize-sm-terraform-iac.png)

   To avoid continuously exporting your definition and refactoring it into your project, we recommend that you make updates locally in you IDE and track these updates with [Git](https://git-scm.com/). 

1. Test your workflow using [Step Functions Local](sfn-local.md).
**Tip**  
You can also locally test service integrations with Lambda functions and API Gateway APIs in your state machine using [AWS SAM CLI Local](sfn-local-lambda.md).

1. Preview your state machine and other AWS resources before deploying the state machine. To do this, run the following command.

   ```
   terraform plan
   ```

1. Deploy your state machine from your local environment or through [CI/CD pipelines](https://aws.amazon.com/blogs/developer/build-infrastructure-ci-for-terraform-code-leveraging-aws-developer-tools-and-terratest/) using the following command.

   ```
   terraform apply
   ```

1. (Optional) Clean up your resources and delete the state machine using the following command.

   ```
   terraform destroy
   ```

## IAM roles and policies for your state machine
<a name="terraform-sfn-iam-policy"></a>

Use the [Terraform service integration policies](https://registry.terraform.io/modules/terraform-aws-modules/step-functions/aws/latest#service-integration-policies) to add necessary IAM permissions to your state machine, for example, permission to invoke Lambda functions. You can also define explicit roles and policies and associate them with your state machine.

The following IAM policy example grants your state machine access to invoke a Lambda function named `myFunction`.

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "lambda:InvokeFunction"
      ],
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:myFunction"
    }
  ]
}
```

We also recommend using the [https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) data source when defining IAM policies for your state machines in Terraform. This helps you check if your policy is malformed and substitute any resources with variables.

The following IAM policy example uses the `aws_iam_policy_document` data source and grants your state machine access to invoke a Lambda function named `myFunction`.

```
data "aws_iam_policy_document" "state_machine_role_policy" {
  
  statement {
    effect = "Allow"

    actions = [
      "lambda:InvokeFunction"
    ]

    resources = ["${aws_lambda_function.function-1.arn}:*"]
  }
  
}
```

**Tip**  
To view more advanced AWS architectural patterns deployed with Terraform, see [Terraform examples at Serverless Land Workflows Collection](https://serverlessland.com/workflows?framework=Terraform).

# Exporting your workflow to IaC templates
<a name="exporting-iac-templates"></a>

The AWS Step Functions console provides the ability to export and download saved workflows as AWS CloudFormation or AWS SAM (SAM) templates. For AWS Regions that support AWS Infrastructure Composer, it additionally provides the ability to export your workflows to Infrastructure Composer and navigates to the Infrastructure Composer console, where you can continue to work with the newly generated template.

## Template configuration options
<a name="exporting-iac-templates-config-options"></a>

The following options are available with this feature. If you select to export and download an IaC template file, the console displays the options that apply to your saved state machine for selection. If you’re exporting to Infrastructure Composer, the Step Functions console automatically implements the configurations that apply to your state machine.
+  **Include IAM role created by console on your behalf** – This option exports the execution role policies. It constructs an IAM role in the template and attaches it to the state machine resource. This option is only applicable if the state machine has an execution role that’s created by the console.
+  **Include CloudWatch Log Group** – Constructs a CloudWatch log group in the template and attaches it to the state machine resource. This option is only applicable if the state machine has a CloudWatch log group attached to it and the [log level](cw-logs.md#cloudwatch-log-level) is *not* set to `OFF`. 
+  **Replace resource references with DefinitionSubstitutions** – This option generates [DefinitionSubstitutions](concepts-sam-sfn.md#sam-definition-substitution-eg) for the following components: 
  + [Distributed Map](state-map-distributed.md) S3 fields.
  + `Activity` resources. The export includes `Activity` resources in the CloudFormation template for any `Run Activity` task. The export also provides `DefinitionSubstitutions` referencing the created `Activity` resources.
  + Any `ARN` or `S3URI` in the Payload field for all service integrations.
  + In addition to the `ARN` and `S3URI` fields, the export generates `DefinitionSubstitutions` for other frequently used service integration payload fields. The specific service integrations are the following: 
    + `athena:startQueryExecution`
    + `batch:submitJob`
    +  `dynamodb:getItem`, `dynamodb:updateItem`, `dynamodb:updateItem`, `dynamodb:deleteItem` 
    + `ecs:runTask`
    + `glue:startJobRun`
    + `http:invoke`
    + `lambda:invoke`
    + `sns:publish`
    + `sqs:sendMessage`
    + `states:startExecution`

## Export and download your workflow's IaC template
<a name="exporting-iac-templates-files-procedure"></a>

**To export your workflow into an IaC template file**

1. Open the [Step Functions console](https://console.aws.amazon.com/states/home?region=us-east-1#/) and select the state machine you want to work with. Make sure that any changes to the state machine are saved before you proceed to the next step.

1. Select **Export to CloudFormation or SAM template** from the **Actions** menu.

1. Select **Type** as either **SAM** or **CloudFormation** from the dialog box that appears.
   + If you selected the **CloudFormation** template, next choose either the **JSON** or **YAML** file format.
   + If you selected the **SAM** template, no formats choices are presented. The SAM template defaults to YAML file format.

1. Expand **Additional configurations**. By default all of the options are selected. Review and update the selection of options for your IaC template. The options are described in detail in the previous section titled [Template configuration options](#exporting-iac-templates-config-options). 

   If an option doesn't apply to your specific workflow, then it won't display in the dialogue box.

1. Choose **Download** to export and download your generated IaC template file.

## Export your workflow directly into AWS Infrastructure Composer
<a name="exporting-iac-templates-infra-composer-procedure"></a>

**To export your workflow into Infrastructure Composer**

1. Open the [Step Functions console](https://console.aws.amazon.com/states/home?region=us-east-1#/) and select the state machine you want to work with. Make sure that any changes to the state machine are saved before you proceed to the next step.

1. Select **Export to Infrastructure Composer** from the **Actions** menu.

1. The **Export to Infrastructure Composer** dialog box displays. You can use the default name that displays in the **Transfer bucket name** field or enter a new name. Amazon S3 bucket names must be globally unique and follow the [bucket naming rules](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html).

1. Choose the **Confirm and create project** to export your workflow to Infrastructure Composer.

1. To save your project and workflow definition in Infrastructure Composer, activate [local sync mode](https://docs.aws.amazon.com/application-composer/latest/dg/reference-features-local-sync.html).

**Note**  
If you've used the **Export to Infrastructure Composer** feature before and created an Amazon S3 bucket using the default name, Step Functions can re-use this bucket if it still exists. Accept the default bucket name in the dialog box to re-use the existing bucket.

### Amazon S3 transfer bucket configuration
<a name="export-appcomposer-bucket-info"></a>

The Amazon S3 bucket that Step Functions creates to transfer your workflow automatically encrypts objects using the AES 256 encryption standard. Step Functions also configures the bucket to use the [bucket owner condition](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-owner-condition.html) to ensure that only your AWS account is able to add objects to the bucket.

The default bucket name uses the prefix `states-templates`, a 10-digit alphanumeric string, and the AWS Region you created your workflow in: `states-templates-amzn-s3-demo-bucket-us-east-1`. To avoid additional charges being added to your AWS account, we recommend that you delete the Amazon S3 bucket as soon as you have finished exporting your workflow to Infrastructure Composer.

Standard [Amazon S3 pricing](https://aws.amazon.com/s3/pricing/) applies.

### Required permissions
<a name="export-appcomposer-permissions"></a>

To use this Step Functions export feature with Infrastructure Composer, you need certain permissions to download an AWS SAM template and to write your template configuration to Amazon S3.

To download an AWS SAM template, you must have permission to use the following API actions:
+ [iam:GetPolicy](https://docs.aws.amazon.com/IAM/latest/APIReference/API_GetPolicy.html)
+ [iam:GetPolicyVersion](https://docs.aws.amazon.com/IAM/latest/APIReference/API_GetPolicyVersion.html)
+ [iam:GetRole](https://docs.aws.amazon.com/IAM/latest/APIReference/API_GetRole.html)
+ [iam:GetRolePolicy](https://docs.aws.amazon.com/IAM/latest/APIReference/API_GetRolePolicy.html)
+ [iam:ListAttachedRolePolicies](https://docs.aws.amazon.com/IAM/latest/APIReference/API_ListAttachedRolePolicies.html)
+ [iam:ListRolePolicies](https://docs.aws.amazon.com/IAM/latest/APIReference/API_ListRolePolicies.html)
+ [iam:ListRoles](https://docs.aws.amazon.com/IAM/latest/APIReference/API_ListRoles.html)

For Step Functions to write your function's configuration to Amazon S3, you must have permission to use the following API actions:
+ [S3:PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html)
+ [S3:CreateBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html)
+ [S3:PutBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html)

If you are unable to export your function's configuration to Infrastructure Composer, check that your account has the required permissions for these operations. 