

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 Step Functions 开发工作流程
<a name="developing-workflows"></a>

我们建议在 Step Functions 控制台和工作流程工作室可视化编辑器中开始构建工作流程。可以从空白画布开始，也可以为常见场景选择初学者模板。

构建工作流程需要执行以下任务：
+ 定义工作流程
+ 运行和调试工作流程
+ 部署工作流程

您使用 Amazon States Language 定义状态机。可以手动创建 Amazon States Language 定义，但教程中将采用工作流程工作室。使用工作流程工作室，可以在 Step Functions 控制台中定义机器定义、可视化和编辑步骤、运行和调试工作流程以及查看结果。

**在 Visual Studio Code 中使用 Workflow Studio**  
借助该 AWS 工具包，您可以在 VS Code 中使用 Workflow Studio 来可视化、构建甚至测试状态机中的各个状态。提供状态输入和设置变量，开始测试，然后就可以看到如何转换数据。您可以调整工作流并重新测试。完成后可以应用更改来更新状态机。有关更多信息，请参阅 AWS Toolkit for Visual Studio Code中的 [Working with Workflow Studio](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/stepfunctions-workflowstudio.html)。

您还可以使用 AWS Command Line Interface (AWS CLI) 中的许多 Step Functions 功能。例如，可以创建状态机并列出现有的状态机。您可以使用中的 Step Functions 命令 AWS CLI 来启动和管理执行、轮询活动、记录任务心跳等。有关 Step Functions 命令的完整列表、可用参数的说明以及展示它们使用方法的示例，请参阅 *AWS CLI 命令参考*。[AWS CLI Command Reference](https://docs.aws.amazon.com/cli/latest/reference/)

AWS CLI 命令严格遵循亚马逊州立大学的语言，因此您可以使用 AWS CLI 来了解 Step Functions API 操作。您还可以使用现有 API 知识创建代码原型，或者从命令行执行 Step Functions 操作。

**验证状态机定义**  
在创建工作流程之前，可以使用 API 来**验证**状态机并发现潜在问题。  
要了解有关验证工作流程的更多信息，请参阅 Step Functions API 参考[ValidateStateMachineDefinition](https://docs.aws.amazon.com/step-functions/latest/apireference/API_ValidateStateMachineDefinition.html)中的。

要从最小的设置开始，可以按照[创建 Lambda 状态机](tutorial-creating-lambda-state-machine.md)教程进行操作，该教程向您展示了如何通过调用 Lambda 函数的单个步骤来定义工作流程，然后运行工作流程并查看结果。

## 定义工作流程
<a name="development-define"></a>

开发工作流程的第一步是使用 Amazon States Language 定义步骤。根据您的偏好和工具，可以使用 JSON、YAML 或字符串化的 Amazon States Language（ASL）定义来定义 Step Functions 状态机。

下表按工具显示了基于 ASL 的定义格式支持。


| AWS 工具 | 支持的格式 | 
| --- | --- | 
| Step Functions 控制台 | JSON | 
| HTTPS 服务 API | 字符串化的 ASL | 
| AWS CLI | 字符串化的 ASL | 
| Step Functions Local | 字符串化的 ASL | 
| AWS Toolkit for Visual Studio Code | JSON、YAML | 
| AWS SAM | JSON、YAML | 
| CloudFormation | JSON、YAML、字符串化的 ASL | 

模板的状态机定义中的 YAML 单行注释将不会延续到所创建资源的定义中。如果您需要保留注释，则应使用状态机定义中的 `Comment` 属性。有关信息，请参阅[状态机结构](statemachine-structure.md)。

使用 CloudFormation 和 AWS SAM，您可以将状态机定义上传到 Amazon S3（JSON 或 YAML 格式），并在模板中提供定义的 Amazon S3 位置。有关信息，请参阅 [AWS::StepFunctions::StateMachine S3Location 页面](https://docs.aws.amazon.com//AWSCloudFormation/latest/UserGuide/aws-properties-stepfunctions-statemachine-s3location.html)。

以下示例 CloudFormation 模板展示了如何使用不同的输入格式提供相同的状态机定义。

------
#### [ 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
```

------

**使用开发工作流程 AWS SDKs**  
 AWS SDKs 适用于 Java、.NET、Ruby、PHP、Python（Boto 3） JavaScript、Go 和 C\$1\$1 的 Step Functions 支持。它们 SDKs 提供了一种在多种编程语言中使用 Step Functions HTTPS API 操作的便捷方式。您可以利用这些开发工具包库提供的 API 操作开发状态机、活动或状态机启动器。您还可以使用这些库访问可见性操作，以开发您自己的 Step Functions 监控和报告工具。参阅最新版本的参考文档 AWS SDKs 和适用于 [Amazon Web Services 的工具](https://aws.amazon.com/tools/)。

**通过 HTTPS 请求开发工作流程**  
Step Functions 提供可通过 HTTPS 请求访问的服务操作。可以使用这些操作直接与您自己库中的 Step Functions 通信。您可以使用服务 API 操作开发状态机、工作线程或状态机启动器。您还可以通过 API 操作访问可见性操作，以开发您自己的监控和报告工具。有关详细信息，请参阅 [AWS Step Functions API Reference](https://docs.aws.amazon.com/step-functions/latest/apireference/)。

**使用 AWS Step Functions 数据科学 SDK 开发工作流程**  
数据科学家可以使用 SageMaker AI 和 Step Functions 创建处理和发布机器学习模型的工作流程。也可以在 Python 中创建多步骤机器学习工作流程，以便大规模地编排 AWS 基础设施。 AWS Step Functions 数据科学 SDK 提供了一个 Python API，可以创建和调用 Step Functions 工作流程。您可以直接在 Python 和 Jupyter 笔记本中管理和执行这些工作流。欲了解更多信息，请参阅：[Github 上的AWS Step Functions 数据科学项目](https://github.com/aws/aws-step-functions-data-science-sdk-python)[、数据科学 SDK 文档](https://aws-step-functions-data-science-sdk.readthedocs.io/)以及上的 [Jupyter 笔记本](https://docs.aws.amazon.com/sagemaker/latest/dg/howitworks-nbexamples.html)和[SageMaker 人工智能示例](https://github.com/awslabs/amazon-sagemaker-examples/tree/master/step-functions-data-science-sdk)。 GitHub

## 运行和调试工作流程
<a name="development-run-debug"></a>

您可以通过多种方式启动工作流程，包括从控制台、API 调用（例如，来自 Lambda 函数）、Amazon EventBridge 和 S EventBridge cheduler、从另一台 Step Functions 状态机启动工作流程。运行的工作流程可以在运行时连接到第三方服务 AWS SDKs、使用和操作数据。可以通过各种工具来运行和调试执行步骤和流经状态机的数据。以下各节提供了用于运行和调试工作流程的更多资源。

要了解有关启动状态机执行的方法的更多信息，请参阅[在 Step Functions 中启动状态机执行](statemachine-starting.md)。

**选择用于运行工作流程的端点**  
为了减少延迟并将数据存储在符合您要求的位置，Step Functions 提供了不同 AWS 区域的终端节点。Step Functions 中的每个端点都完全独立。一个状态机或活动仅存在于创建它的区域中。在一个区域中创建的任意状态机或活动，不会与在其它区域中创建的状态机或活动共享任何数据或属性。例如，您可以在两个不同区域中注册名为 `STATES-Flows-1` 的状态机。一个区域中的 `STATES-Flows-1` 状态机不会与另一个区域的 `STATES-Flow-1` 状态机共享数据或属性。有关 Step Functions 端点的列表，请参阅《AWS 一般参考》**中的[AWS Step Functions 区域和端点](https://docs.aws.amazon.com/general/latest/gr/step-functions.html)。

**使用 VS Code 进行开发**  
借助该 AWS 工具包，您可以在 VS Code 中使用 Workflow Studio 来可视化、构建甚至测试状态机中的各个状态。您也可以使用 SAM 和 CloudFormation 定义替换。提供状态输入和设置变量，开始测试，然后就可以看到如何转换数据。在“状态定义”选项卡中，您可以调整工作流并重新测试。完成后可以应用更改来更新状态机。有关更多信息，请参阅 AWS Toolkit for Visual Studio Code中的 [Working with Step Functions](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/bulding-stepfunctions.html) 和 [Working with Workflow Studio](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/stepfunctions-workflowstudio.html)。

## 部署工作流程
<a name="development-deploy"></a>

定义和调试工作流程后，可能需要使用“基础设施即代码”框架进行部署。您可以选择使用各种 IaC 选项来部署状态机，包括：、 AWS Serverless Application Model CloudFormation AWS CDK、和 Terraform。

**AWS Serverless Application Model**  
您可以 AWS Serverless Application Model 与 Step Functions 一起使用来构建工作流程和部署所需的基础架构，包括 Lambda 函数 APIs 和事件，以创建无服务器应用程序。您也可以将 AWS SAM CLI 与结合使用 AWS Toolkit for Visual Studio Code ，作为集成体验的一部分。  
有关更多信息，请参阅 [AWS SAM 用于构建 Step Functions 工作流程](concepts-sam-sfn.md)。

**CloudFormation**  
您可以直接在 CloudFormation 模板中使用状态机定义。  
有关更多信息，请参阅 [用于在 St CloudFormation ep Functions 中创建工作流程](tutorial-lambda-state-machine-cloudformation.md)。

**AWS CDK**  
您可以使用构建标准和快速状态机 AWS CDK。  
要构建标准工作流程，请参阅[使用 CDK 创建标准工作流程](tutorial-lambda-state-machine-cdk.md)。  
要构建快速工作流程，请参阅[使用 CDK 创建快速工作流程](tutorial-step-functions-rest-api-integration-cdk.md)。

**Terraform**  
[Terraform](https://www.terraform.io/intro/) by HashiCorp 是一个使用基础设施即代码 (IaC) 构建应用程序的框架。借助 Terraform，您可以创建状态机并使用特征，例如预览基础架构部署和创建可重复使用的模板。Terraform 模板通过将代码分解为多个较小的块来帮助您维护和重用代码。  
有关更多信息，请参阅 [使用 Terraform 在 Step Functions 中部署状态机](terraform-sfn.md)。

# 在 Step Functions 工作流程工作室中开发工作流程
<a name="workflow-studio"></a>

在 AWS Step Functions 控制台中编辑工作流程时，您将使用名为 Workflow Studio 的可视化工具。使用 Workflow Studio，你可以在画布上进行 drag-and-drop状态以构建工作流程。可以添加、编辑和配置状态，设置输入和输出筛选条件，转换结果以及设置错误处理。

在工作流程中修改状态时，工作流程工作室将验证并自动生成状态机定义。可以使用内置的代码编辑器来查看生成的代码、编辑配置甚至修改文本定义。完成后，可以保存并运行工作流程，然后检查结果。

创建或编辑工作流程时，可以通过 Step Functions 控制台访问工作流程工作室。

也可以从 AWS 基础架构编辑器**内部**使用工作流程工作室，这是一个可视化设计器，可使用 AWS Serverless Application Model 和 AWS CloudFormation 创建“基础设施即代码”。要了解这种方法的优点，请参阅[使用 Infrastructure Composer 中的 Workflow Studio](use-wfs-in-app-composer.md)。

工作流程工作室有三种模式：**设计**、**代码**和**配置**。在*设计模式下*，可以在画布上显示 drag-and-drop状态。*代码模式* 提供了一个内置的代码编辑器，用于在控制台中编辑工作流程定义。在*配置模式* 下，可以管理工作流程配置。

**在 Visual Studio Code 中使用 Workflow Studio**  
借助该 AWS 工具包，您可以在 VS Code 中使用 Workflow Studio 来可视化、构建甚至测试状态机中的各个状态。提供状态输入和设置变量，开始测试，然后就可以看到如何转换数据。您可以调整工作流并重新测试。完成后可以应用更改来更新状态机。有关更多信息，请参阅 AWS Toolkit for Visual Studio Code中的 [Working with Workflow Studio](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/stepfunctions-workflowstudio.html)。

## 设计模式
<a name="wfs-interface-design-mode"></a>

设计模式提供了一个图形界面，可在您构建工作流程的原型时对工作流程进行可视化。下图显示了工作流程工作室的**设计**模式下的状态浏览器、工作流程画布、检查器和上下文帮助面板。

![\[设计模式的屏幕截图，显示状态浏览器、工作流程画布、检查器和帮助面板。\]](http://docs.aws.amazon.com/zh_cn/step-functions/latest/dg/images/wfs_main_01.png)


1. 模式按钮在这三种模式之间切换。如果 ASL 工作流程定义无效，则无法切换模式。

1. [状态浏览器](#workflow-studio-components-states)包含以下三个选项卡：
   + “**操作**” 选项卡提供了一个列表 AWS APIs，您可以将其拖放到画布中的工作流程图中。每个操作都代表一个 [Task 工作流程状态](state-task.md) 状态。
   + **流**选项卡提供了流状态列表，您可以将这些状态拖放到画布中的工作流图中。
   + P **at** terns 选项卡提供了几个 ready-to-use可重复使用的构造块，您可以将其用于各种用例。例如，您可以使用这些模式以迭代方式处理 Amazon S3 存储桶中的数据。

1. 您可以在[画布和工作流程图](#workflow-studio-components-grapheditor)上将状态拖放到工作流图中，更改状态的顺序，并选择要配置或查看的状态。

1. 在[检查器面板](#workflow-studio-components-formdefinition)面板中，您可以查看和编辑画布上所选状态的属性。打开**定义**切换开关，可查看工作流的 Amazon States Language 代码，并突出显示当前选定的状态。

1. 需要帮助时，可以使用**信息**链接打开一个包含上下文信息的面板。这些面板还包括指向 Step Functions 文档中相关主题的链接。

1. 设计工具栏 – 包含一组用于执行常见操作的按钮，例如撤消、删除和放大。

1. 实用工具按钮 – 一组用于执行任务的按钮，例如保存工作流或将其 ASL 定义导出为 JSON 或 YAML 文件。

### 状态浏览器
<a name="workflow-studio-components-states"></a>

从状态浏览器中，可以选择要拖放到工作流程画布上的状态。“**操作**” 选项卡提供了连接到第三方 HTTP 端点的任务状态列表，以及 AWS APIs。**流程**选项卡提供了一个状态列表，可以使用这些状态来指导和控制工作流程。流程状态包括：Choice、Parallel、Map、Pass、Wait、Success 和 Fail。“**模式**” 选项卡提供了 ready-to-use可重复使用的预定义构造块。可以使用面板顶部的搜索框在所有状态类型中进行搜索。

![\[显示“操作”、“流程”、“模式”以及搜索的屏幕截图的图示集合。\]](http://docs.aws.amazon.com/zh_cn/step-functions/latest/dg/images/wfe-states-browser-01.png)


### 画布和工作流程图
<a name="workflow-studio-components-grapheditor"></a>

选择要添加到工作流程的状态后，可以将其拖到画布上，然后放到工作流程图中。还可以拖放状态，以便在工作流程中移动它们。如果工作流程较大，则可以放大或缩小，以便在画布中查看工作流程图的不同部分。

### 检查器面板
<a name="workflow-studio-components-formdefinition"></a>

可以通过右侧的**检查器**面板来配置您添加到工作流程中的任何状态。选择要配置的状态，即可在 **Inspector** 面板中看到其配置选项。要查看工作流代码自动生成的 [ASL 定义](concepts-amazon-states-language.md)，请打开**定义**切换开关。与您选择的状态关联的 ASL 定义将突出显示。

![\[显示配置面板的工作流程工作室检查器的说明性屏幕截图\]](http://docs.aws.amazon.com/zh_cn/step-functions/latest/dg/images/wfe-forms-definitions-01.png)


![\[显示代码定义的工作流程工作室检查器面板的说明性屏幕截图\]](http://docs.aws.amazon.com/zh_cn/step-functions/latest/dg/images/wfe-forms-definitions-02.png)


## 代码模式
<a name="wfs-interface-code-mode"></a>

在工作流程工作室的**代码**模式下，可以使用一个集成的代码编辑器，在 Step Functions 控制台中查看、编写和编辑工作流程的[使用 Amazon States Language 定义 Step Functions 工作流程](concepts-amazon-states-language.md)（ASL）定义。以下屏幕截图显示了**代码**模式下的组件。

![\[在“代码”模式下编辑工作流程定义的说明性屏幕截图。\]](http://docs.aws.amazon.com/zh_cn/step-functions/latest/dg/images/wfs-code-mode.png)


1. 模式按钮在这三种模式之间切换。如果 ASL 工作流程定义无效，则无法切换模式。

1. [代码编辑器](#wfs-interface-code-editor)是在 Workflow Studio 中编写和编辑工作流的 [ASL 定义](concepts-amazon-states-language.md)的地方。代码编辑器还提供语法突出显示和自动完成等特征。

1. [图形可视化](#wfs-interface-code-graph-viz) – 显示工作流的实时图形可视化。

1. 实用工具按钮 – 一组用于执行任务的按钮，例如保存工作流或将其 ASL 定义导出为 JSON 或 YAML 文件。

1. 代码工具栏 – 包含一组用于执行常见操作的按钮，例如撤消操作或格式化代码。

1. 图表工具栏 – 包含一组用于执行常见操作的按钮，例如放大和缩小工作流图表。

### 代码编辑器
<a name="wfs-interface-code-editor"></a>

代码编辑器提供了类似 IDE 的体验，让您可以在 Workflow Studio 中使用 JSON 编写和编辑工作流定义。代码编辑器包括多项特征，例如语法突出显示、自动完成建议、[ASL 定义](concepts-amazon-states-language.md)验证和上下文相关帮助显示。更新工作流定义时，[图形可视化](#wfs-interface-code-graph-viz)会呈现工作流的实时图表。您还可以在[设计模式](#wfs-interface-design-mode)中查看更新的工作流图。

如果在[设计模式](#wfs-interface-design-mode)或图表可视化窗格中选择一个状态，则该状态的 ASL 定义将在代码编辑器中突出显示。如果在**设计**模式或图表可视化窗格中重新排序、删除或添加状态，则工作流的 ASL 定义会自动更新。

代码编辑器可以提出自动填写字段和状态的建议。
+ 要查看可在特定状态下包含的字段列表，请按 **Ctrl\$1Space**。
+ 要为工作流程中的新状态生成代码段，请在当前状态的定义后按 **Ctrl\$1Space**。
+ 要显示所有可用命令和**键盘快捷键**的列表，请按 **F1**。

### 图形可视化
<a name="wfs-interface-code-graph-viz"></a>

图表可视化面板以图形格式显示您的工作流程。当在 Workflow Studio 的[代码编辑器](#wfs-interface-code-editor)中编写工作流定义时，图表可视化窗格会呈现工作流的实时图表。

当在图表可视化窗格中重新排序、删除或复制状态时，代码编辑器中的工作流定义会自动更新。同样，当您在代码编辑器中更新工作流定义、重新排序、删除或添加状态时，可视化窗格也会自动更新。

如果工作流程 ASL 定义中的 JSON 无效，则图形可视化面板会暂停渲染，并在窗格底部显示一则状态消息。

## 配置模式
<a name="wfs-interface-config-mode"></a>

在工作流程工作室的**配置**模式下，可以管理状态机的常规配置。在此模式下，可以指定设置，如下所示：
+ **详细信息**：设置工作流程**名称**和**类型**。请注意，创建状态机后，**无法**更改这两者。
+ **权限**：可以创建新角色（建议）、选择现有角色或输入特定角色的 ARN。如果您选择创建新角色的选项，Step Functions 将使用最低权限为您的状态机创建一个执行角色。所生成的 IAM 角色对您在其中创建状态机的 AWS 区域 有效。在创建之前，可以查看 Step Functions 将为状态机自动生成的权限。
+ **日志记录**：可以为状态机启用和设置日志级别。Step Functions 会根据您的选择记录执行历史事件。可以选择使用客户自主管理型密钥来加密日志。有关日志级别的更多信息，请参阅[Step Functions 执行事件的日志级别](cw-logs.md#cloudwatch-log-level)。

在**其它配置**中，可以设置以下一个或多个**可选**配置选项：
+ **启用 X-Ray 跟踪**：即使上游服务没有传递跟踪 ID，也可以将跟踪发送到 X-Ray 以实现状态机执行。有关更多信息，请参阅 [Trace Step Functions 请求数据 AWS X-Ray](concepts-xray-tracing.md)。
+ **创建时发布版本**：*版本*是您可以运行的状态机快照，带编号且不可变。选中此选项，以便在创建状态机时发布状态机的版本。Step Functions 将版本 1 作为状态机的第一个修订版发布。有关版本的更多信息，请参阅[Step Functions 工作流程中的状态机版本](concepts-state-machine-version.md)。
+ **使用客户自主管理型密钥加密**：可以提供一个由您直接管理的密钥来加密您的数据。有关信息，请参阅 [静态数据加密](encryption-at-rest.md)
+ **标签**：选中此框可添加标签，标签有助于您跟踪和管理与资源关联的成本，并增强 IAM 策略中的安全性。有关标签的更多信息，请参阅[在 Step Functions 中标记状态机和活动](sfn-best-practices.md#concepts-tagging)。

# 在 Step Functions 中使用工作流程工作室创建工作流程
<a name="workflow-studio-create"></a>

学习使用 Step Functions Workflow Studio 创建、编辑和运行工作流。工作流程准备就绪后，可以保存、运行或导出它。

**Topics**
+ [创建状态机](#workflow-studio-components-create)
+ [设计工作流](#workflow-studio-build)
+ [运行工作流](#workflow-studio-components-create-run)
+ [编辑工作流](#workflow-studio-components-create-edit)
+ [导出工作流](#workflow-studio-components-create-export)
+ [使用占位符创建工作流程原型](#workflow-studio-components-create-prototype)

## 创建状态机
<a name="workflow-studio-components-create"></a>

在工作流程工作室中，可以选择初学者模板或空白模板来创建工作流程。

入门模板是一个 ready-to-run示例项目，它会自动创建工作流程原型和定义，并将项目所需的所有相关 AWS 资源部署到您的 AWS 账户项目中。您可以使用这些初学者模板按原样部署和运行，也可以使用工作流原型在其基础上进行构建。有关初学者模板的更多信息，请参阅 [使用 Step Functions 的初学者模板部署状态机](starter-templates.md)。

借助空白模板，可以使用[设计](workflow-studio.md#wfs-interface-design-mode)或[代码](workflow-studio.md#wfs-interface-code-mode)模式来创建自定义工作流程。

### 使用初学者模板创建状态机
<a name="wfs-create-workflow-templates"></a>

1. 打开 [Step Functions 控制台](https://console.aws.amazon.com/states/home?region=us-east-1#/)，然后选择**创建状态机**。

1. 在**选择模板**对话框中，执行以下操作之一来选择示例项目：
   + 在“按关键字搜索”框中键入 **Task Timer**，然后从搜索结果中选择**任务计时器**。
   + 浏览右侧窗格中**全部**下列出的示例项目，然后选择**任务计时器**。

1. 选择**下一步**继续。

1. 选择模板使用方式：

1. 选择**使用模板**继续进行选择。

1. **运行演示** — 创建只读状态机。审核后，您可以创建工作流和所有相关资源。

1. **构建依据** — 提供可编辑的工作流定义，您可借助自有资源对其进行审核、定制并部署。（**不会**自动创建函数或队列等相关资源。）

### 使用空白模板创建工作流
<a name="wfs-create-workflow-blank"></a>

当您想要从干净的画布开始时，可以从空白模板创建一个工作流程。

1. 打开 [Step Functions 控制台](https://console.aws.amazon.com/states/home?region=us-east-1#/)。

1. 选择**创建状态机**。

1. 选择**从空白创建**。

1. 为状态机命名，然后选择**继续**，在 Workflow Studio 中编辑状态机。

   现在，您可以开始在[设计模式](workflow-studio.md#wfs-interface-design-mode)下设计工作流，或在[代码模式](workflow-studio.md#wfs-interface-code-mode)下编写工作流定义。

1. 选择**配置**可在[配置模式](workflow-studio.md#wfs-interface-config-mode)下管理工作流程的配置。例如，为工作流提供名称并选择其类型。

## 设计工作流
<a name="workflow-studio-build"></a>

如果您知道要添加的状态的名称，请使用[状态浏览器](workflow-studio.md#workflow-studio-components-states)顶部的搜索框来查找该状态。否则，请在浏览器中查找所需的状态，并将其添加到画布上。

可以通过将状态拖到工作流程中的其它位置，来对工作流程中的状态进行重新排序。将状态拖到画布上时，会出现一条线来显示该状态将插入工作流程中的位置，如以下屏幕截图所示：

![\[说明性屏幕截图显示了指示状态目的地的蓝线。\]](http://docs.aws.amazon.com/zh_cn/step-functions/latest/dg/images/wfe-design-02.png)


将状态拖放到画布上后，其代码会自动生成并添加到工作流程定义中。要查看定义，请打开 [Inspector](workflow-studio.md#workflow-studio-components-formdefinition) 面板上的**定义**切换开关。可以选择[代码模式](workflow-studio.md#wfs-interface-code-mode)，以便使用内置的代码编辑器来编辑定义。

将状态拖放到画布上后，可以在右侧的 [检查器面板](workflow-studio.md#workflow-studio-components-formdefinition) 面板中对其进行配置。此面板包含您在画布上放置的每个状态或 API 操作的**配置**、**输入**、**输出**和**错误处理**选项卡。您可以在**配置**选项卡中配置工作流中包含的状态。

例如，Lambda 调用 API 操作的**配置**选项卡提供以下选项：
+ **状态名称**：可以使用自定义名称标识状态，也可以接受生成的默认名称。
+ **API** 显示状态使用哪个 API 操作。
+ **集成类型**：可以选择用于对其他服务调用 API 操作的服务集成类型。
+ **函数名称**提供执行以下操作的选项：
  +  **输入函数名称**：您可以输入函数名称或其 ARN。
  +  **运行时从状态输入中获取函数名称**：您可以使用此选项根据指定的路径从状态输入中动态获取函数名称。
  +  **选择函数名称**：您可以直接从您的账户和区域的可用函数中进行选择。
+ **有效载荷**：可以选择使用状态输入、JSON 对象或无有效载荷，作为有效载荷传递给 Lambda 函数。如果选择 JSON，则可以同时包含静态值和从状态输入中选择的值。
+ （可选）某些状态可以选择**等待任务完成**或**等待回调**。如果可用，则可以选择以下[服务集成模式](connect-to-resource.md)之一：
  + **未选择任何选项**：Step Functions 将使用[请求响应](connect-to-resource.md#connect-default)集成模式。Step Functions 将等待 HTTP 响应，然后进入下一个状态。Step Functions 不会等待作业完成。当没有可用选项时，状态将使用此模式。
  + **等待任务完成**：Step Functions 将使用[运行作业 (.sync)](connect-to-resource.md#connect-sync) 集成模式。
  + **等待回调**：Step Functions 将使用[等待具有任务令牌的回调](connect-to-resource.md#connect-wait-token)集成模式。
+ （可选）为了访问工作流程 AWS 账户 中不同配置的资源，Step Functions 提供[跨账户访问权限](concepts-access-cross-acct-resources.md)。**用于跨账户存取的 IAM 角色**提供以下选项：
  + **提供 IAM 角色 ARN**：指定包含相应资源访问权限的 IAM 角色。这些资源可在目标账户中使用，您可以 AWS 账户 向该账户进行跨账户调用。
  + **在运行时从状态输入中获取 IAM 角色 ARN**：在包含 IAM 角色的状态 JSON 输入中指定一个指向现有键值对的引用路径。
+ **下一个状态**用于选择下一个要过渡的状态。
+ （可选）**注释**字段不会影响工作流程，但可以使用它为工作流程添加注释。

某些状态将有其它通用的配置选项。例如，Amazon ECS `RunTask` 状态配置包含一个填充了占位符值的 `API Parameters` 字段。对于此类状态，您可以将占位符值替换为适合您需求的配置。

**删除状态**

可以按退格键，右键单击并选择**删除状态**，或者在[设计工具栏](workflow-studio.md#wfs-interface-design-mode)上选择**删除**。

## 运行工作流
<a name="workflow-studio-components-create-run"></a>

工作流程准备就绪后，可以在 [Step Functions 控制台](https://console.aws.amazon.com/states/home)中运行该工作流程并查看执行情况。

**在 Workflow Studio 中运行工作流**

1. 在**设计**、**代码**或**配置**模式下，选择**执行**。

   **开始执行**对话框将在新选项卡中打开。

1. 在**启动执行**对话框中，执行以下操作：

   1. （可选）输入自定义执行名称，以便覆盖生成的默认执行名称。
**非 ASCII 名称和日志记录**  
Step Functions 对于状态机、执行、活动和标签接受包含非 ASCII 字符的名称。由于此类字符会 CloudWatch 阻止亚马逊记录数据，因此我们建议您仅使用 ASCII 字符，这样您就可以跟踪 Step Functions 的指标。

   1. （可选）在**输入**框中，以 JSON 格式输入输入值以便运行工作流。

   1. 选择**启动执行**。

   1. Step Functions 控制台会将您引导到一个以您的执行 ID 为标题的页面，即*执行详细信息*页面。您可以随着工作流的进展以及在工作流完成后查看执行结果。

      要查看执行结果，请在**图表视图**上选择各个状态，然后在[步骤详细信息](concepts-view-execution-details.md#exec-details-intf-step-details)窗格中选择各个选项卡，分别查看每个状态的详细信息，包括输入、输出和定义。有关可在*执行详细信息*页面上查看的执行信息的详细信息，请参阅[执行详细信息概览](concepts-view-execution-details.md#exec-details-interface-overview)。

## 编辑工作流
<a name="workflow-studio-components-create-edit"></a>

您可以在 Workflow Studio 的[设计模式](workflow-studio.md#wfs-interface-design-mode)中直观地编辑现有工作流。

在 [Step Functions 控制台](https://console.aws.amazon.com/states/home)中，从**状态机**页面中选择要编辑的工作流程。工作流程在 Workflow Studio 的**设计**模式下打开。

也可以在[代码模式](workflow-studio.md#wfs-interface-code-mode)下编辑工作流程定义。选择**代码**按钮，以便在工作流程工作室中查看或编辑工作流程定义。

**注意**  
如果您在工作流中发现错误，则必须在**设计**模式下进行修复。如果工作流中存在任何错误，则无法切换到**代码**或**配置**模式。

保存对工作流程的更改时，也可以选择发布新**版本**。使用版本，可以选择运行工作流程的原始版本或备用版本。要了解使用版本管理工作流程的更多信息，请参阅 [Step Functions 工作流程中的状态机版本](concepts-state-machine-version.md)

## 导出工作流
<a name="workflow-studio-components-create-export"></a>

您可以导出工作流程 [Amazon States Language](concepts-amazon-states-language.md) (ASL) 的定义和工作流图：

1. 在 [Step Functions 控制台](https://console.aws.amazon.com/states/home)中选择您的工作流。

1. 在*状态机详细信息*页面上，选择**编辑**。

1. 选择**操作**下拉按钮，然后执行以下一项或两项操作：
   + 要将工作流图表导出到 SVG 或 PNG 文件，请在**导出图表**下选择所需的格式。
   + 要将工作流定义导出为 JSON 或 YAML 文件，请在**导出定义**下选择所需的格式。

## 使用占位符创建工作流程原型
<a name="workflow-studio-components-create-prototype"></a>

可以使用工作流程工作室或[Infrastructure Composer中的工作流程工作室](use-wfs-in-app-composer.md)，来创建包含*占位符资源* 的新工作流程原型，这些占位符资源是尚未存在的命名资源。

要创建工作流程原型，请执行以下操作：

1. 登录 [Step Functions 控制台](https://console.aws.amazon.com/states/home?region=us-east-1#/)。

1. 选择**创建状态机**。

1. 选择**从空白创建**。

1. 为状态机命名，然后选择**继续**，在 Workflow Studio 中编辑状态机。

1. 打开 Workflow Studio 的[设计](workflow-studio.md#wfs-interface-design-mode)模式。在 Workflow Studio 中设计您的工作流。要包含占位符资源，请执行以下操作：

   1. 选择要为其添加占位符资源的状态，然后在**配置**中：
      + 对于 Lambda 调用状态，选择**函数名称**，然后选择**输入函数名称**。您也可以输入函数的自定义名称。
      + 对于“Amazon SQS 发送消息”状态，选择**队列 URL**，然后选择**输入队列 URL**。输入占位符队列 URL。
      + 对于“Amazon SNS 发布”状态，从**主题**中选择一个主题 ARN。
      + 对于**操作**下列出的所有其他状态，您可以使用默认配置。
**注意**  
如果您在工作流中发现错误，则必须在**设计**模式下进行修复。如果工作流中存在任何错误，则无法切换到**代码**或**配置**模式。

   1. （可选）要查看自动生成的工作流 ASL 定义，请选择**定义**。

   1. （可选）要在 Workflow Studio 中更新工作流定义，请选择**代码**按钮。
**注意**  
如果您在工作流定义中看到错误，则必须在**代码**模式下对其进行修复。如果工作流定义中存在任何错误，则无法切换到**设计**或**配置**模式。

1. （可选）要编辑状态机名称，请选择默认状态机名称旁边的编辑图标，**MyStateMachine**然后在**状态机名称框中指定名称**。

   您也可以切换到[配置模式](workflow-studio.md#wfs-interface-config-mode)编辑默认状态机名称。

1. 指定工作流设置，例如状态机类型及其执行角色。

1. 选择**创建**。

现在，您已经创建了一个新的工作流，其中包含可用于原型的占位符资源。您可以[导出](#workflow-studio-components-create-export)工作流定义和工作流图表。
+ 要将工作流定义导出为 JSON 或 YAML 文件，请在**设计**或**代码**模式下，选择**操作**下拉按钮。然后，在**导出定义**下，选择要导出的格式。您可以使用此导出的定义作为使用 [AWS Toolkit for Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/building-stepfunctions.html) 进行本地开发的起点。
+ 要将工作流图表导出为 SVG 或 PNG 文件，请在**设计**或**代码**模式下，选择**操作**下拉按钮。然后，在**导出定义**下，选择所需的格式。

# 在 Step Functions 中使用工作流程工作室配置状态输入和输出
<a name="workflow-studio-process"></a>

**管理状态和转换数据**  
了解有关[使用变量在状态之间传递数据](workflow-variables.md)和[使用转换数据](transforming-data.md)的信息 JSONata。

每个状态都根据接收的输入做出决定或执行操作。在大多数情况下，该状态会将输出传递到其他状态。在 Workflow Studio 中，可以在 [检查器面板](workflow-studio.md#workflow-studio-components-formdefinition) 面板的**输入**和**输出**选项卡中配置状态如何筛选和操作其输入和输出数据。配置输入和输出时，使用**信息**链接访问上下文帮助。

![\[显示状态输入、输出和信息帮助面板的说明性屏幕截图\]](http://docs.aws.amazon.com/zh_cn/step-functions/latest/dg/images/wfs_input_output_01.png)


有关 Step Functions 如何处理输入和输入的详细信息，请参阅 [在 Step Functions 中处理输入和输出](concepts-input-output-filtering.md)。

## 配置状态的输入
<a name="workflow-studio-process-input"></a>

每个状态都以 JSON 形式接收来自前一个状态的输入。如果要筛选输入，可以使用 [检查器面板](workflow-studio.md#workflow-studio-components-formdefinition) 面板中**输入**选项卡下的 `InputPath` 筛选条件。`InputPath` 是一个以 `$` 开头的字符串，用于标识特定 JSON 节点。它们被称为[引用路径](amazon-states-language-paths.md)，它们遵循 JsonPath 语法。

要筛选输入，请进行以下操作：
+ 选择 “**筛选输入**” InputPath。
+ [JsonPath](https://datatracker.ietf.org/wg/jsonpath/about/)为`InputPath`筛选器输入有效的值。例如 **\$1.data**。

`InputPath` 筛选条件将添加到您的工作流中。

**Example 示例 1：在工作流工作室中使用 InputPath 过滤器**  
假设状态的输入包含以下 JSON 数据。  

```
{
  "comment": "Example for InputPath",
  "dataset1": {
    "val1": 1,
    "val2": 2,
    "val3": 3
  },
  "dataset2": {
    "val1": "a",
    "val2": "b",
    "val3": "c"
  }
}
```
要应用`InputPath`过滤器，请选择 “**筛选输入**” InputPath，然后输入相应的参考路径。如果您输入 **\$1.dataset2.val1**，则以下 JSON 将作为输入传递给状态。  

```
{"a"}
```
参考路径也可以选择值。如果您引用的数据是 `{ "a": [1, 2, 3, 4] }`，并且您应用引用路径 `$.a[0:2]` 作为 `InputPath` 筛选条件，则结果如下。  

```
[ 1, 2 ]
```

[Parallel 工作流程状态](state-parallel.md)、[Map 状态工作流程。](state-map.md) 和 [Pass 工作流程状态](state-pass.md) 流状态在其**输入**选项卡下还有一个名为 `Parameters` 的输入筛选选项。此过滤器在过滤 InputPath 器之后生效，可用于构造由一个或多个键值对组成的自定义 JSON 对象。每对的值可以是静态值，可从输入中选择，也可通过路径从[在 Step Functions 中从上下文对象访问执行数据](input-output-contextobject.md)中选择。

**注意**  
要指定参数使用引用路径指向输入中的 JSON 节点，请使用 `.$` 作为参数名称的结尾。

**Example 示例 2：为 Parallel 状态创建自定义 JSON 输入**  
假设以下 JSON 数据是一个 Parallel 状态的输入。  

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

要选择该输入的一部分并传递带有静态值的附加键值对，可以在 **Parallel** 状态的**输入**选项卡下的**参数**字段中指定以下内容。

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

结果将是以下 JSON 数据。

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

## 配置状态的输出
<a name="workflow-studio-process-output"></a>

每个状态都会生成 JSON 输出，可以在将其传递到下一个状态之前对其进行筛选。有几个筛选条件可用，每个筛选条件对输出的影响都不一样。每种状态可用的输出筛选条件列在 **Inspector** 面板的**输出**选项卡下。对于 [Task 工作流程状态](state-task.md) 状态，您选择的任何输出筛选条件都将按以下顺序处理：

1.  `ResultSelector`：使用此筛选条件来操纵状态的结果。您可以使用部分结果构造一个新的 JSON 对象。

1.  `在 Step Functions ResultPath 中使用指定状态输出`：使用此筛选条件选择要传递到输出的状态输入和任务结果的组合。

1.  `使用 OutputPath 筛选状态输出`：使用此筛选条件筛选 JSON 输出，用于选择将结果中的哪些信息传递到下一个状态。

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

`ResultSelector` 是用于以下状态的可选输出筛选条件：
+  [Task 工作流程状态](state-task.md) 状态，即[状态浏览器](workflow-studio.md#workflow-studio-components-states)的**操作**选项卡中列出的所有状态。
+  [Map 状态工作流程。](state-map.md) 状态，在状态浏览器的**流**选项卡中。
+  [Parallel 工作流程状态](state-parallel.md) 状态，在状态浏览器的**流**选项卡中。

`ResultSelector` 可用于构造由一个或多个键值对组成的自定义 JSON 对象。每对值可以是静态值，也可以通过路径从状态的结果中选择。

**注意**  
要指定参数使用路径引用结果中的 JSON 节点，请使用 `.$` 作为参数名称的结尾。

**Example 使用 ResultSelector 过滤器的示例**  
在此示例中，您可以使用`ResultSelector`操作亚马逊 EMR CreateCluster API 调用对亚马逊 EMR 状态的响应。`CreateCluster`以下是 Amazon EMR `CreateCluster` API 调用的结果。  

```
{
  "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"
  }
}
```
要选择部分信息并传递带有静态值的附加键值对，请在状态的 “**输出**” 选项卡下的**ResultSelector**字段中指定以下内容。  

```
{
 "result": "found",
 "ClusterId.$": "$.output.ClusterId", 
 "ResourceType.$": "$.resourceType"
 }
```
使用 `ResultSelector` 会产生以下结果。  

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

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

状态的输出可以是状态输入的副本、状态生成的结果或状态输入和结果的组合。使用 `ResultPath` 可控制传递到状态输出的上述两种内容的组合。有关更多 `ResultPath` 的用例，请参阅 [在 Step Functions ResultPath 中使用指定状态输出](input-output-resultpath.md)。

`ResultPath` 是用于以下状态的可选输出筛选条件：
+  [Task 工作流程状态](state-task.md) 状态，即状态浏览器的**操作**选项卡中列出的所有状态。
+  [Map 状态工作流程。](state-map.md) 状态，在状态浏览器的**流**选项卡中。
+  [Parallel 工作流程状态](state-parallel.md) 状态，在状态浏览器的**流**选项卡中。
+  [Pass 工作流程状态](state-pass.md) 状态，在状态浏览器的**流**选项卡中。

`ResultPath` 可用于将结果添加到原始状态输入中。指定的路径表示添加结果的位置。

**Example 使用 ResultPath 过滤器的示例**  
假设以下是一个 Task 状态的输入。  

```
{
  "details": "Default example",
  "who": "AWS Step Functions"
}
```
该 Task 状态的结果为以下内容。  

```
Hello, AWS Step Functions
```
您可以通过应用 `ResultPath` 并输入指示在何处添加结果的参考[路径](amazon-states-language-paths.md)，来将此结果添加到该状态的输入中，例如 `$.taskresult`：  
借助此 `ResultPath`，以下是作为状态输出传递的 JSON。  

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

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

`OutputPath` 筛选条件可用于筛选掉不需要的信息，而仅传递您需要的这部分 JSON。`OutputPath` 是一个以 `$` 开头的字符串，用于标识 JSON 文本中的节点。

**Example 使用 OutputPath 过滤器的示例**  
假设一个 Lambda 调用 API 调用除了返回 Lambda 函数的结果之外，还返回元数据。  

```
{
  "ExecutedVersion": "$LATEST",
  "Payload": {
     "foo": "bar",
     "colors": [
          "red",
          "blue",
          "green"    
     ],
     "car": {
          "year": 2008,
          "make": "Toyota",
          "model": "Matrix"
     }
   },
"SdkHttpMetadata": {
  "AllHttpHeaders": {
    "X-Amz-Executed-Version": ["$LATEST"]
...
```
您可以使用 `OutputPath` 筛选掉其他元数据。默认情况下，通过 Workflow Studio 创建的 Lambda Invoke 状态**OutputPath**筛选器的值为。`$.Payload`此默认值会删除额外的元数据，并返回相当于直接运行 Lambda 函数的输出。  
Lambda 调用任务结果示例和**输出**筛选条件的 `$.Payload` 值将以下 JSON 数据作为输出传递。  

```
{
 "foo": "bar",
 "colors": [
      "red",
      "blue",
      "green"    
 ],
 "car": {
      "year": 2008,
      "make": "Toyota",
      "model": "Matrix"
 }
}
```
`OutputPath` 筛选条件是最后一个生效的输出筛选条件，因此，如果您使用诸如 `ResultSelector` 或 `ResultPath` 之类的其它输出筛选条件，则应相应地修改 `OutputPath` 筛选条件的 `$.Payload` 默认值。

# 在 Step Functions 中使用工作流程工作室设置执行角色
<a name="manage-state-machine-permissions"></a>

可以使用工作流程工作室设置工作流程的执行角色。每台 Step Functions 状态机都需要一个 AWS Identity and Access Management（IAM）角色，来向状态机授予对 AWS 服务和资源执行操作或调用 HTTPS API 的权限。此角色称为*执行角色*。

对于每个操作，此执行角色都必须包含 IAM 策略，例如，可让状态机调用 AWS Lambda 函数、运行 AWS Batch 任务或调用 Stripe API 的策略。在以下情况下，Step Functions 要求您提供执行角色：
+ 您在控制台、AWS SDK 或 AWS CLI 中使用 [CreateStateMachine](https://docs.aws.amazon.com/step-functions/latest/apireference/API_CreateStateMachine.html) API 创建状态机。
+ 您在控制台、AWS SDK 或 AWS CLI 中使用 [TestState](https://docs.aws.amazon.com/step-functions/latest/apireference/API_TestState.html) API [测试](test-state-isolation.md)状态。

**Topics**
+ [关于自动生成的角色](#wfs-auto-gen-roles)
+ [自动生成角色](#auto-generating-roles)
+ [解决角色生成问题](#resolve-role-gen-problem)
+ [在 Workflow Studio 中测试 HTTP 任务的角色](#test-state-role-http)
+ [在 Workflow Studio 中测试优化的服务集成的角色](#test-state-role-optimized)
+ [在 Workflow Studio 中测试 AWS SDK 服务集成的角色](#test-state-role-aws-sdk)
+ [在 Workflow Studio 中测试流状态的角色](#test-state-role-flow)

## 关于自动生成的角色
<a name="wfs-auto-gen-roles"></a>

当您在 Step Functions 控制台中创建状态机时，[Workflow Studio](workflow-studio.md) 可以自动为您创建一个包含必需 IAM 策略的执行角色。Workflow Studio 会分析您的状态机定义，并生成具有执行工作流所需的最低权限的策略。

Workflow Studio 可以为以下各项生成 IAM 策略：
+ 调用 HTTPS API 的 [HTTP 任务](call-https-apis.md)。
+ 使用[优化的集成](integrate-optimized.md)（例如 [Lambda Invoke](connect-lambda.md)、[DynamoDB GetItem](connect-batch.md) 或 [AWS Glue StartJobRun](connect-glue.md)）调用其他 AWS 服务的 Task 状态。
+ 运行[嵌套工作流](connect-stepfunctions.md)的 Task 状态。
+ [分布式 Map 状态](state-map-distributed.md)，包括用于启动子工作流执行、列出 Amazon S3 桶以及读取或写入 S3 对象的[策略](iam-policies-eg-dist-map.md)。
+ [X-Ray](concepts-xray-tracing.md) 跟踪。在 Workflow Studio 中自动生成的每个角色都包含一个[策略](concepts-xray-tracing.md#xray-iam)，该策略向状态机授予向 X-Ray 发送跟踪的权限。
+ [在 Step Functions 中使用 CloudWatch 日志记录执行历史记录](cw-logs.md)（当在状态机上启用日志记录时）。

Workflow Studio 无法为使用 [AWS SDK 集成](supported-services-awssdk.md)调用其他 AWS 服务的 Task 状态生成 IAM 策略。

## 自动生成角色
<a name="auto-generating-roles"></a>

1. 打开 [Step Functions 控制台](https://console.aws.amazon.com/states/home)，从菜单中选择**状态机**，然后选择**创建状态机**。

   您也可以更新现有状态机。如果您要更新状态机，请参阅步骤 4。

1. 选择**从空白创建**。

1. 为状态机命名，然后选择**继续**，在 Workflow Studio 中编辑状态机。

1. 选择**配置**选项卡。

1. 向下滚动到**权限**部分，然后执行以下操作：

   1. 对于**执行角色**，请确保保留默认选择**创建新角色**。

      Workflow Studio 会自动为状态机定义中的每个有效状态生成所有必需的 IAM 策略。它会显示一条横幅，指明**将创建具有完全权限的执行角色**。  
![\[“配置”选项卡的说明性屏幕截图，其中包含自动生成的权限的预览。\]](http://docs.aws.amazon.com/zh_cn/step-functions/latest/dg/images/wfs-full-permissions-role.png)
**提示**  
要查看 Workflow Studio 为状态机自动生成的权限，请选择**查看自动生成的权限**。
**注意**  
如果您删除了 Step Functions 创建的 IAM 角色，Step Functions 在以后无法重新创建该角色。同样，如果您修改了该角色（例如，通过在 IAM 策略中从主体中删除 Step Functions），Step Functions 在以后也无法还原其原始设置。

      如果 Workflow Studio 无法生成所有必需的 IAM 策略，则会显示一条横幅，指明**无法为某些操作自动生成权限。将创建仅具有部分权限的 IAM 角色**。有关如何添加缺失权限的信息，请参阅[解决角色生成问题](#resolve-role-gen-problem)。

   1. 如果要创建状态机，请选择**创建**。否则，请选择**保存**。

   1. 在出现的对话框中，选择**确认**。

      Workflow Studio 会保存您的状态机并创建新的执行角色。

## 解决角色生成问题
<a name="resolve-role-gen-problem"></a>

在以下情况下，Workflow Studio 无法自动生成具有所有必需权限的执行角色：
+ 状态机中出现错误。请务必在 Workflow Studio 中解决所有验证错误。另外，请务必解决在保存过程中遇到的任何服务器端错误。
+ 您的状态机包含使用 AWS SDK 集成的任务。在这种情况下，Workflow Studio 无法[自动生成](#auto-generating-roles) IAM 策略。Workflow Studio 会显示一条横幅，指明**无法为某些操作自动生成权限。将创建仅具有部分权限的 IAM 角色**。在**查看自动生成的权限**表中，选择**状态**中的内容，以了解有关您的执行角色缺少的策略的更多信息。Workflow Studio 仍然可以生成执行角色，但该角色不会包含所有操作的 IAM 策略。请参阅**文档链接**下的链接，编写您自己的策略，并在角色生成后将其添加到角色中。即使在保存状态机之后，这些链接也仍然可用。

## 在 Workflow Studio 中测试 HTTP 任务的角色
<a name="test-state-role-http"></a>

需要一个执行角色来[测试](call-https-apis.md#http-task-test) HTTP Task 状态。如果您没有具有足够权限的角色，请使用以下选项之一创建角色：
+ **通过 Workflow Studio 自动生成一个角色（推荐）**- 这是安全的选项。关闭**测试状态**对话框并按照[自动生成角色](#auto-generating-roles)中的说明操作。这需要您先创建或更新状态机，然后返回 Workflow Studio 测试状态。
+ **使用具有管理员权限的角色**：如果您有权创建对 AWS 中的所有服务和资源具有完全访问权限的角色，可以使用该角色来测试工作流中的任何状态类型。为此，您可以创建一个 Step Functions 服务角色，并在 IAM 控制台 [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) 中向其添加 [AdministratorAccess 策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#jf_administrator)。

## 在 Workflow Studio 中测试优化的服务集成的角色
<a name="test-state-role-optimized"></a>

调用[经优化的服务集成](integrate-optimized.md)的 Task 状态需要执行角色。如果您没有具有足够权限的角色，请使用以下选项之一创建角色：
+ **通过 Workflow Studio 自动生成一个角色（推荐）**- 这是安全的选项。关闭**测试状态**对话框并按照[自动生成角色](#auto-generating-roles)中的说明操作。这需要您先创建或更新状态机，然后返回 Workflow Studio 测试状态。
+ **使用具有管理员权限的角色**：如果您有权创建对 AWS 中的所有服务和资源具有完全访问权限的角色，可以使用该角色来测试工作流中的任何状态类型。为此，您可以创建一个 Step Functions 服务角色，并在 IAM 控制台 [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) 中向其添加 [AdministratorAccess 策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#jf_administrator)。

## 在 Workflow Studio 中测试 AWS SDK 服务集成的角色
<a name="test-state-role-aws-sdk"></a>

调用 [AWS SDK 集成](supported-services-awssdk.md)的 Task 状态执行角色。如果您没有具有足够权限的角色，请使用以下选项之一创建角色：
+ **通过 Workflow Studio 自动生成一个角色（推荐）**- 这是安全的选项。关闭**测试状态**对话框并按照[自动生成角色](#auto-generating-roles)中的说明操作。这需要您先创建或更新状态机，然后返回 Workflow Studio 测试状态。执行以下操作：

  1. 关闭**测试状态**对话框

  1. 选择**配置**选项卡以查看配置模式。

  1. 向下滚动到**权限**部分。

  1. Workflow Studio 会显示一条横幅，指明**无法为某些操作自动生成权限。将创建仅具有部分权限的 IAM 角色**。选择**查看自动生成的权限**。

  1. **查看自动生成的权限**表会显示一行，列出与您要测试的 Task 状态相对应的操作。请参阅**文档链接**下的链接，将您自己的 IAM 策略编写到自定义角色中。
+ **使用具有管理员权限的角色**：如果您有权创建对 AWS 中的所有服务和资源具有完全访问权限的角色，可以使用该角色来测试工作流中的任何状态类型。为此，您可以创建一个 Step Functions 服务角色，并在 IAM 控制台 [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) 中向其添加 [AdministratorAccess 策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#jf_administrator)。

## 在 Workflow Studio 中测试流状态的角色
<a name="test-state-role-flow"></a>

您需要一个执行角色，以在 Workflow Studio 中测试流状态。流状态是指定向执行流的状态，例如 [Choice 工作流程状态](state-choice.md)、[Parallel 工作流程状态](state-parallel.md)、[Map 状态工作流程。](state-map.md)、[Pass 工作流程状态](state-pass.md)、[Wait 工作流程状态](state-wait.md)、[Succeed 工作流程状态](state-succeed.md) 或 [Fail 工作流程状态](state-fail.md)。[TestState](https://docs.aws.amazon.com/step-functions/latest/apireference/API_TestState.html) API 不适用于 Map 或 Parallel 状态。您可以使用以下选项之一创建用于测试流状态的角色：
+ **使用 AWS 账户中的任何角色（推荐）**：流状态不需要任何特定的 IAM 策略，因为它们不调用 AWS 操作或资源。因此，您可以使用 AWS 账户中的任何 IAM 角色。

  1. 在**测试状态**对话框中，从**执行角色**下拉列表中选择任意角色。

  1. 如果下拉列表中没有显示任何角色，请执行以下操作：

     1. 在 IAM 控制台 [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) 中，选择**角色**。

     1. 从列表中选择一个角色，然后从角色详细信息页面复制其 ARN。您需要在**测试状态**对话框中提供此 ARN。

     1. 在**测试状态**对话框中，从**执行角色**下拉列表中选择**输入角色 ARN**。

     1. 将 ARN 粘贴到**角色 ARN** 中。
+ **使用具有管理员权限的角色**：如果您有权创建对 AWS 中的所有服务和资源具有完全访问权限的角色，可以使用该角色来测试工作流中的任何状态类型。为此，您可以创建一个 Step Functions 服务角色，并在 IAM 控制台 [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) 中向其添加 [AdministratorAccess 策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html#jf_administrator)。

# 在 Step Functions 中使用工作流程工作室配置错误处理
<a name="workflow-studio-process-error"></a>

**管理状态和转换数据**  
了解有关[使用变量在状态之间传递数据](workflow-variables.md)和[使用转换数据](transforming-data.md)的信息 JSONata。

可以在工作流程工作室可视化编辑器中配置错误处理。默认情况下，当某个状态报告错误时，Step Functions 会导致工作流执行完全失败。对于操作和某些流状态，您可以配置 Step Functions 处理错误的方式。

即使您配置了错误处理，某些错误仍可能导致工作流执行失败。有关更多信息，请参阅 [处理 Step Functions 工作流程中的错误](concepts-error-handling.md)。在工作流程工作室中，在[检查器面板](workflow-studio.md#workflow-studio-components-formdefinition)的**错误处理**选项卡中配置错误处理。

## 出错时重试
<a name="workflow-studio-process-error-retry"></a>

您可以向操作状态和 [Parallel 工作流程状态](state-parallel.md) 流状态添加一条或多条规则，以便在发生错误时重试任务。这些规则被称为*重试器*。要添加重试器，请选择**重试器 \$11** 框中的编辑图标，然后配置其选项：
+ （可选）在**注释**字段中，添加您的注释。它不会影响工作流，但可以用来为您的工作流添加注释。
+ 将光标置于**错误**字段中，选择将触发重试器的错误，或者输入自定义错误名称。您可以选择或添加多个错误。
+ （可选）设置**间隔**。这是 Step Functions 首次重试之前的时间（以秒为单位）。随后将按间隔进行其他重试，您可以根据**最大尝试次数**和**回退率**进行配置。
+ （可选）设置**最大尝试次数**。这是 Step Functions 导致执行失败之前的最大重试次数。
+ （可选）设置**回退率**。这是一个乘数，它决定每次尝试的重试间隔将增加多少。

**注意**  
并非所有错误处理选项都适用于所有状态。默认情况下，Lambda 调用会配置了一个重试器。

## 捕获错误
<a name="workflow-studio-process-error-catch"></a>

您可以向操作状态以及 [Parallel 工作流程状态](state-parallel.md) 和 [Map 状态工作流程。](state-map.md) 流状态添加一条或多条规则以捕获错误。这些规则被称为*捕获器*。要添加捕获器，请选择**添加捕获器手**，然后配置其选项：
+ （可选）在**注释**字段中，添加您的注释。它不会影响工作流，但可以用来为您的工作流添加注释。
+ 将光标置于**错误**字段中，选择将触发捕获器的错误，或者输入自定义错误名称。您可以选择或添加多个错误。
+ 在**回退状态**字段中，选择一种[回退状态](concepts-error-handling.md#error-handling-fallback-states)。这是捕获到错误后，工作流将移至的下一个状态。
+ （可选）在该**ResultPath**字段中，添加`ResultPath`过滤器以将错误添加到原始状态输入中。[`ResultPath`](input-output-resultpath.md)必须是有效的[JsonPath](https://datatracker.ietf.org/wg/jsonpath/about/)。这将被发送到回退状态。

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

您可以为操作状态配置一个超时，用于设置状态在失败之前可以运行的最大秒数。使用超时可避免执行卡顿。要配置超时，请输入状态在执行失败之前应等待的秒数。有关超时的更多信息，请参阅 [Task 工作流程状态](state-task.md) 状态中的 `TimeoutSeconds`。

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

您可以配置任务发送的*检测信号*或定期通知。如果设置了检测信号间隔，并且状态未在配置的时间间隔内发送检测信号通知，则该任务将被标记为失败。要配置检测信号，请设置一个秒数，该值需为非零正整数。有关更多信息，请参阅 [Task 工作流程状态](state-task.md) 状态中的 `HeartBeatSeconds`。

# 使用Infrastructure Composer中的工作流程工作室构建 Step Functions 工作流程
<a name="use-wfs-in-app-composer"></a>

Infrastructure Composer 中提供的 Workflow Studio 旨在帮助您设计和构建工作流。Infrastructure Composer中的工作流程工作室提供了一个可视化基础设施即代码（IaC）环境，可让您轻松地将工作流程整合到使用 CloudFormation 模板等 IaC 工具构建的无服务器应用程序中。

AWS 基础架构编辑器 是一个可视化生成器，可帮助您使用简单的图形界面开发 AWS SAM 和 AWS CloudFormation 模板。使用Infrastructure Composer，您可以通过在可视画布 AWS 服务 中拖动、分组和连接来设计应用程序架构。 Infrastructure Composer然后根据您的设计创建 IaC 模板，您可以使用该模板通过AWS SAM命令行界面 (AWS SAMCLI) 或CloudFormation。要了解有关 Infrastructure Composer 的更多信息，请参阅[什么是 Infrastructure Composer](https://docs.aws.amazon.com/application-composer/latest/dg/what-is-composer.html)。

当您在中使用 Workflow Studio 时Infrastructure Composer，Infrastructure Composer 会将各个工作流程步骤连接到 AWS 资源，并在AWS SAM模板中生成资源配置。 Infrastructure Composer还添加了工作流程运行所需的IAM权限。使用 Infrastructure Composer 中的 Workflow Studio，您可以创建应用程序原型，并将其转化为生产就绪的应用程序。

使用 Infrastructure Composer 中的 Workflow Studio 时，您可以在 Infrastructure Composer 画布和 Workflow Studio 之间来回切换。

**Topics**
+ [使用 Infrastructure Composer 中的 Workflow Studio](#procedure-use-wfs-in-app-composer)
+ [使用 CloudFormation 定义替换项动态引用资源](#use-cfn-sub-edit-state-machine-resource)
+ [将服务集成任务连接到增强型组件卡](#connect-service-integrations-enhanced-cards)
+ [导入现有项目并在本地同步它们](#import-projects-local-sync)
+ [将 Step Functions 工作流直接导出到 AWS 基础架构编辑器](#export-wsf-projects-into-app-composer)
+ [AWS 基础架构编辑器 中不可用的 Workflow Studio 功能](#wfs-features-unavailable-app-composer)

## 使用 Infrastructure Composer 中的 Workflow Studio 构建无服务器工作流
<a name="procedure-use-wfs-in-app-composer"></a>

1. 打开[基础架构编辑器控制台](https://console.aws.amazon.com/composer/home)，然后选择**创建项目**来创建项目。

1. 在**资源**选项板的搜索字段中输入 **state machine**。

1. 将 **Step Functions 状态机**资源拖到画布上。

1. 选择**在 Workflow Studio 中编辑**，以编辑状态机资源。

   以下动画显示了如何切换到 Workflow Studio 来编辑状态机定义。  
![\[演示如何使用 Infrastructure Composer 中的 Workflow Studio 的动画。\]](http://docs.aws.amazon.com/zh_cn/step-functions/latest/dg/images/use-wfs-in-app-composer.gif)

   为编辑在 Infrastructure Composer 中创建的状态机资源而与 Workflow Studio 的集成仅适用于 [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) 资源。此集成不适用于使用 [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) 资源的模板。

## 在 Workflow Studio 中使用 CloudFormation 定义替换项动态引用资源
<a name="use-cfn-sub-edit-state-machine-resource"></a>

在 Workflow Studio 中，您可以在工作流定义中使用 CloudFormation 定义替换项来动态引用您在 IaC 模板中定义的资源。您可以使用 `${dollar_sign_brace}` 表示法向工作流定义中添加占位符替换项，在 CloudFormation 堆栈创建过程中，它们会替换为实际值。有关定义替换项的更多信息，请参阅 [DefinitionSubstitutions 在AWS SAM模板中](concepts-sam-sfn.md#sam-definition-substitution-eg)。

以下动画显示了如何在状态机定义中为资源添加占位符替换项。

![\[动画演示了如何为状态机中的资源添加占位符替换项。\]](http://docs.aws.amazon.com/zh_cn/step-functions/latest/dg/images/use-def-sub-wfs-app-composer.gif)


## 将服务集成任务连接到增强型组件卡
<a name="connect-service-integrations-enhanced-cards"></a>

您可以在 Infrastructure Composer 画布中将调用[优化的服务集成](integrate-optimized.md)的任务连接到[增强型组件卡](https://docs.aws.amazon.com/application-composer/latest/dg/reference-cards.html#reference-cards-enhanced-components)。这样做会自动映射工作流定义中通过 `${dollar_sign_brace}` 表示法指定的任何占位符替换项和 `StateMachine` 资源的 `DefinitionSubstitution` 属性。它还会为状态机添加适当的 AWS SAM 策略。

如果您映射优化的服务集成任务与[标准组件卡](https://docs.aws.amazon.com/application-composer/latest/dg/using-composer-cards.html#using-composer-cards-component-intro)，则 Infrastructure Composer 画布上不会显示连接线。

以下动画显示了如何将优化的任务连接到增强型组件卡，并在[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)中查看更改。

![\[动画演示了如何连接任务和经优化的服务集成。\]](http://docs.aws.amazon.com/zh_cn/step-functions/latest/dg/images/make-connections-wfs-app-composer.gif)


您无法将处于 Task 状态的 [AWS SDK 集成](supported-services-awssdk.md)与增强型组件卡连接，也无法将优化的服务集成与标准组件卡连接。对于这类任务，您可以在 Infrastructure Composer 画布的**资源属性**面板中映射替换项，并在 AWS SAM 模板中添加策略。

**提示**  
或者，您也可以在**资源属性**面板的**定义替换项**下为状态机映射占位符替换项。执行此操作时，必须为状态机执行角色 AWS 服务 中的任务状态调用添加所需的权限。有关执行角色可能需要的权限的信息，请参阅 [在 Step Functions 中使用工作流程工作室设置执行角色](manage-state-machine-permissions.md)。

以下动画显示了如何在**资源属性**面板中手动更新占位符替换项映射。

![\[动画演示了如何在资源属性面板中更新占位符替换映射。\]](http://docs.aws.amazon.com/zh_cn/step-functions/latest/dg/images/manual-update-placeholder-mapping.gif)


## 导入现有项目并在本地同步它们
<a name="import-projects-local-sync"></a>

您可以在 Infrastructure Composer 中打开现有 CloudFormation 和 AWS SAM 项目，直观查看，以便更好地了解，而且可以修改其设计。使用 Infrastructure Composer 的[本地同步](https://docs.aws.amazon.com/application-composer/latest/dg/reference-features-local-sync.html)功能，您可以自动同步模板和代码文件，并将其保存到本地构建机器上。使用本地同步模式可以对您现有的开发流形成补充。请确保您的浏览器支持 [File System Access API](https://docs.aws.amazon.com/application-composer/latest/dg/reference-fsa.html)，它允许 Web 应用程序在本地文件系统中读取、写入和保存文件。我们建议使用 Google Chrome 或 Microsoft Edge。

## 将 Step Functions 工作流直接导出到 AWS 基础架构编辑器
<a name="export-wsf-projects-into-app-composer"></a>

 AWS Step Functions 控制台允许将保存的状态机工作流程导出为模板，该模板被识别为高级 IaC 资源。Infrastructure Composer此功能将 IaC 模板创建为 AWS SAM 架构，并引导您前往。Infrastructure Composer有关更多信息，请参阅 [将工作流导出到 IaC 模板](exporting-iac-templates.md)。

## AWS 基础架构编辑器 中不可用的 Workflow Studio 功能
<a name="wfs-features-unavailable-app-composer"></a>

当您在 Infrastructure Composer 中使用 Workflow Studio 时，某些 Workflow Studio 功能不可用。此外，[检查器面板](workflow-studio.md#workflow-studio-components-formdefinition) 面板中的 **API 参数**部分支持 CloudFormation 定义替换项。您可以在[代码模式](workflow-studio.md#wfs-interface-code-mode)中使用 `${dollar_sign_brace}` 表示法添加替换项。有关此表示法的更多信息，请参阅 [DefinitionSubstitutions 在AWS SAM模板中](concepts-sam-sfn.md#sam-definition-substitution-eg)。

以下列表说明了在 Infrastructure Composer 中使用 Workflow Studio 时不可用的 Workflow Studio 功能：
+ [入门模板](starter-templates.md)-起始模板是自动创建工作流程原型和定义的 ready-to-run示例项目。这些模板会将您的项目所需的所有相关 AWS 资源部署到您的 AWS 账户。
+ [配置模式](workflow-studio.md#wfs-interface-config-mode)：此模式可让您管理状态机的配置。您可以在 IaC 模板中更新状态机配置，也可以使用 Infrastructure Composer 画布中的**资源属性**面板。有关在**资源属性**面板中更新配置的信息，请参阅 [将服务集成任务连接到增强型组件卡](#connect-service-integrations-enhanced-cards)。
+ [TestState](test-state-isolation.md) API
+ 在 Workflow Studio 中，通过**操作**下拉按钮导入或导出工作流定义的选项。不过，可以在 Infrastructure Composer** 菜单**中，依次选择**打开** > **项目文件夹**。请确保您已启用[本地同步](https://docs.aws.amazon.com/application-composer/latest/dg/reference-features-local-sync.html)模式，以自动将 Infrastructure Composer 画布中的更改直接保存到本地机器。
+ **执行**按钮。当您在 Infrastructure Composer 中使用 Workflow Studio 时，Infrastructure Composer 会为工作流生成 IaC 代码。因此，您必须先部署模板。然后，在控制台中或通过 AWS Command Line Interface(AWS CLI) 运行工作流。

# AWS SAM 用于构建 Step Functions 工作流程
<a name="concepts-sam-sfn"></a>

您可以 AWS Serverless Application Model 与 Step Functions 一起使用来构建工作流程和部署所需的基础架构，包括 Lambda 函数 APIs 和事件，以创建无服务器应用程序。

 AWS Toolkit for Visual Studio Code 作为集成体验的一部分，您还可以将 AWS Serverless Application Model CLI 与结合使用，来构建和部署 AWS Step Functions 状态机。您可以使用 AWS SAM构建无服务器应用程序，然后在 VS Code IDE 中构建状态机。然后，您可以验证、打包和部署您的资源。

**提示**  
要部署使用启动 Step Functions 工作流程的示例无服务器应用程序 AWS SAM，请参阅在* AWS Step Functions 研讨会 AWS SAM*中[使用部署](https://catalog.workshops.aws/stepfunctions/iac/deploy-with-sam)。

## 为什么要将 Step Functions 配合使用 AWS SAM？
<a name="concepts-sam-sfn-integration"></a>

当你将 Step Functions 与配合使用时， AWS SAM 你可以：
+ 开始使用 AWS SAM 示例模板。
+ 将状态机构建到无服务器应用程序中。
+ 在部署时，使用变量替换来替换 ARNs 到状态机中。

   AWS CloudFormation 支持 [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)，它们可让您将工作流定义中的动态引用添加到您在 CloudFormation 模板中提供的值。您可以使用 `${dollar_sign_brace}` 表示法将替换项添加到工作流定义中，从而添加动态引用。您还需要在CloudFormation模板中 StateMachine 资源的`DefinitionSubstitutions`属性中定义这些动态引用。在 CloudFormation 堆栈创建流程中，替换项将替换为实际值。有关更多信息，请参阅 [DefinitionSubstitutions 在AWS SAM模板中](#sam-definition-substitution-eg)。
+ 使用 AWS SAM 策略模板指定状态机的角色。
+ 使用 API Gateway、 EventBridge 事件或按 AWS SAM 模板中的计划启动状态机执行。

## Step Functions 与 AWS SAM 规范集成
<a name="concepts-sam-sfn-ots2"></a>

您可以使用 [AWS SAM 策略模板](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-policy-templates.html)向状态机添加权限。借助这些权限，您可以编排 Lambda 函数 AWS 和其他资源，形成复杂而强大的工作流程。

## Step Functions 与 SAM CLI 集成
<a name="concepts-sam-sfn-ots3"></a>

Step Functions 已与 AWS SAM CLI 集成。这样，就可以快速将状态机开发到无服务器应用程序中。

试试[使用创建 Step Functions 状态机 AWS SAM](tutorial-state-machine-using-sam.md)教程，学习 AWS SAM 如何使用创建状态机。

支持的 AWS SAM CLI 功能包括：


| CLI 命令 | 说明 | 
| --- | --- | 
| sam init |  使用模板初始化无服务器应用程序。 AWS SAM 可以与 SAM 模板一起使用以实现 Step Functions。  | 
| sam validate | 验证 AWS SAM 模板。 | 
| sam package |  打包 AWS SAM 应用程序。它创建一个包含您的代码和依赖项的 ZIP 文件，然后将其上传到 Amazon S3。然后，它返回 AWS SAM 模板的副本，并将对本地构件的引用替换为此命令已将构件上传到的 Amazon S3 位置。  | 
| sam deploy | 部署 AWS SAM 应用程序。 | 
| sam publish |  将 AWS SAM 应用程序发布到 AWS Serverless Application Repository。此命令采用打包的 AWS SAM 模板并将应用程序发布到指定区域。  | 

**注意**  
使用 AWS SAM 本地模式时，您可以在本地模拟 Lambda 和 API Gateway。但是，你不能使用 AWS SAM在本地模拟 Step Functions。

## DefinitionSubstitutions 在AWS SAM模板中
<a name="sam-definition-substitution-eg"></a>

您可以结合使用 CloudFormation 模板和 AWS SAM 来定义状态机。使用 AWS SAM，您可以在模板或单独的文件中定义内联状态机。以下 AWS SAM 模板包含模拟股票交易工作流的状态机。该状态机调用三个 Lambda 函数来查看股票的价格并确定是买入还是卖出股票。然后，相应交易会记录在 Amazon DynamoDB 表中。以下模板中的Lambda函数和DynamoDB表使用指定[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)。 ARNs 

```
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
```

以下代码是[使用创建 Step Functions 状态机 AWS SAM](tutorial-state-machine-using-sam.md)教程中使用的文件 `stock_trader.asl.json` 内的状态机定义。此状态机定义包含几个用 `${dollar_sign_brace}` 表示法表示的 `DefinitionSubstitutions`。例如，使用替换项 `${StockCheckerFunctionArn}`，而不是为 `Check Stock Value` 任务指定静态 Lambda 函数 ARN。此替换项在模板的 [DefinitionSubstitutions](#sam-template-def-substitution) 属性中定义。`DefinitionSubstitutions` 是状态机资源的键值对的映射。在中`DefinitionSubstitutions`，\$1 \$1StockCheckerFunctionArn\$1 使用CloudFormation内部函数映射到`StockCheckerFunction`资源的 ARN。[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)部署 AWS SAM 模板时，模板中的 `DefinitionSubstitutions` 将替换为实际值。

```
{
    "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
        }
    }
}
```

## 后续步骤
<a name="concepts-sam-sfn-next-steps"></a>

您可以通过以下资源了解有关使用 Step Funct AWS SAM ions 的更多信息：
+ 完成教[使用创建 Step Functions 状态机 AWS SAM](tutorial-state-machine-using-sam.md)程以使用创建状态机 AWS SAM。
+ 指定[AWS::Serverless::StateMachine](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-statemachine.html)资源。
+ 查找要使用的 [AWS SAM 策略模板](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-policy-templates.html)。
+ 将 [AWS Toolkit for Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/stepfunctions.html) 与 Step Functions 搭配使用。
+ 查看 [AWS SAM CLI 参考](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-command-reference.html)，详细了解中 AWS SAM提供的特征。

您还可以使用 Infrastructure Composer 中的 Workflow Studio 等可视化构建器在基础设施即代码 (IaC) 中设计和构建工作流。有关更多信息，请参阅 [使用Infrastructure Composer中的工作流程工作室构建 Step Functions 工作流程](use-wfs-in-app-composer.md)。

# 用于在 St CloudFormation ep Functions 中创建工作流程
<a name="tutorial-lambda-state-machine-cloudformation"></a>

在本教程中，您将使用创建 AWS Lambda 函数 AWS CloudFormation。您将使用 CloudFormation 控制台和 YAML 模板来创建*堆栈*（IAM 角色、Lambda 函数和状态机）。然后，您将使用 Step Functions 控制台来启动状态机执行。

有关更多信息，请参阅《*AWS CloudFormation 用户指南》中的使用 CloudFormation *[模板](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-guide.html)和`[AWS::StepFunctions::StateMachine](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html)`资源。

## 第 1 步：设置您的 CloudFormation 模板
<a name="lambda-state-machine-cfn-step-1"></a>

在使用[示例模板](#lambda-state-machine-cfn-step-2)之前，您应该了解如何声明 CloudFormation 模板的不同部分。

### 为 Lambda 创建 IAM 角色
<a name="lambda-state-machine-cfn-procedure-create-iam-role"></a>

定义与 Lambda 函数的 IAM 角色关联的信任策略。以下示例使用 YAML 或 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"
                          }
                      ]
                  }
              }
```

------

### 创建 Lambda 函数
<a name="lambda-state-machine-cfn-create-function"></a>

为将打印 `Hello World` 消息的 Lambda 函数定义以下属性。

**重要**  
确保您的 Lambda 函数与 AWS 区域 状态机位于同一个 AWS 账户下。

------
#### [ 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"
              }
          },
```

------

### 创建用于状态机执行的 IAM 角色
<a name="lambda-state-machine-cfn-create-role"></a>

定义与状态机执行的 IAM 角色关联的信任策略。

------
#### [ 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": "*"
                                  }
                              ]
                          }
                      }
                  ]
              }
          },
```

------

### 创建 Lambda 状态机
<a name="lambda-state-machine-cfn-create"></a>

定义 Lambda 状态机。

------
#### [ 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"
                      ]
                  }
              }
          }
```

------

## 步骤 2：使用 CloudFormation 模板创建 Lambda 状态机
<a name="lambda-state-machine-cfn-step-2"></a>

了解 CloudFormation 模板的组件后，就可以将它们组合在一起并使用模板创建 CloudFormation 堆栈。

### 创建 Lambda 状态机
<a name="to-create-the-lam-state-machine"></a>

1. 将以下示例数据复制到名为 `MyStateMachine.yaml`（适用于 YAML 示例）或 `MyStateMachine.json`（适用于 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. 打开 [CloudFormation](https://console.aws.amazon.com/cloudformation/home) 控制台并选择**创建堆栈**。

1. 在**选择模板**页面上，选择**将模板上传到 Amazon S3**。选择您的 `MyStateMachine` 文件，然后选择**下一步**。

1. 在**指定详细信息**页面上，为**堆栈名称**输入 `MyStateMachine`，然后选择**下一步**。

1. 在**选项**页面上，选择**下一步**。

1. 在**审核**页面上，选择**我确认， CloudFormation 可能创建 IAM 资源。**，然后选择**创建**。

   CloudFormation 开始创建`MyStateMachine`堆栈并显示 **CREATE\$1IN\$1** PROGRESS 状态。在此过程完成后， CloudFormation 将显示 **CREATE\$1COMPLETE** 状态。

1. （可选）要显示您的堆栈中的资源，请选择堆栈，然后选择**资源**选项卡。

## 第 3 步：启动状态机执行
<a name="lambda-state-machine-cfn-step-3"></a>

在创建您的 Lambda 状态机后，可以开始执行。

### 启动状态机执行
<a name="to-start-the-state-machine-execution"></a>

1. 打开 [Step Functions 控制台](https://console.aws.amazon.com/states/home)，然后选择你使用创建的状态机的名称 CloudFormation。

1. 在***MyStateMachine-ABCDEFGHIJ1K***页面上，选择 “**新建执行**”。

   此时将显示**新执行**页面。

1. （可选）输入自定义执行名称，以便覆盖生成的默认执行名称。
**非 ASCII 名称和日志记录**  
Step Functions 对于状态机、执行、活动和标签接受包含非 ASCII 字符的名称。由于此类字符会 CloudWatch 阻止亚马逊记录数据，因此我们建议您仅使用 ASCII 字符，这样您就可以跟踪 Step Functions 的指标。

1. 选择**开始执行**。

   此时将启动新的状态机执行，并显示一个说明正在运行的执行的新页面。

1. （可选）在**执行详细信息**中，查看**执行状态**以及**已开始**和**已关闭**时间戳。

1. 要查看执行结果，请选择**输出**。

# 用于在 St AWS CDK ep Functions 中创建标准工作流程
<a name="tutorial-lambda-state-machine-cdk"></a>

可以使用 AWS Cloud Development Kit (AWS CDK)基础设施即代码（IAC）框架，来创建包含 AWS Lambda 函数的 AWS Step Functions 状态机。

您将使用支持的语言之一来定义 AWS 基础架构。CDK定义基础架构后，您需要将应用程序合成到CloudFormation模板中，然后将其部署到您的 AWS 账户。

 您将使用此方法来定义包含 Lambda 函数的 Step Functions 状态机，然后通过使用 Step Functions AWS 管理控制台来运行状态机。

在开始本教程之前，您必须按照**《AWS Cloud Development Kit (AWS CDK) 开发人员指南》中[开始使用 AWS CDK - 先决条件](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_prerequisites)所述，设置您的 AWS CDK 开发环境。然后，在 AWS CLI 中使用以下命令安装 AWS CDK：

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

本教程产生的结果与[用于在 St CloudFormation ep Functions 中创建工作流程](tutorial-lambda-state-machine-cloudformation.md)相同。但是，在本教程中，AWS CDK 不需要您创建任何 IAM 角色，AWS CDK 会为您创建。AWS CDK 版本还包括一个 [Succeed 工作流程状态](state-succeed.md) 步骤，用于说明如何向状态机添加其他步骤。

**提示**  
*要部署使用和启动Step Functions工作流程的示例无服务器应用程序，请参阅在 The Worksh [op AWS CDK 中使用AWS CDK部署](https://catalog.workshops.aws/stepfunctions/iac/deploy-with-cdk)。 TypeScript AWS Step Functions *

## 第 1 步：设置您的 AWS CDK 项目
<a name="lambda-state-machine-cdk-step-1"></a>

1. 在您的主目录或其他目录中，运行以下命令为您的新 AWS CDK 应用程序创建一个目录。
**重要**  
请确保将目录命名为 `step`。AWS CDK 应用程序模板使用目录的名称来生成源文件和类的名称。如果您使用其他名称，则您的应用将与本教程不匹配。

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

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

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

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

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

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

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

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

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

   确保您已安装.NET 版本 6.0 或更高版本。有关信息，请参阅[受支持的版本](https://dotnet.microsoft.com/en-us/download/dotnet)。

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

------

1. 使用 **cdk init** 命令初始化应用程序。指定所需的模板（“应用程序”）和编程语言，如以下示例所示。

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

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

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

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

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

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

   初始化项目后，激活项目的虚拟环境并安装 AWS CDK 的基线依赖关系。

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

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

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

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

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

------

## 第 2 步：使用 AWS CDK 创建状态机
<a name="lambda-state-machine-cdk-step-2"></a>

首先，我们将展示定义 Lambda 函数和 Step Functions 状态机的单独代码片段。然后，我们将解释如何在您的 AWS CDK 应用程序中将它们组合在一起。最后，您将了解如何合成和部署这些资源。

### 创建 Lambda 函数
<a name="lambda-state-machine-cdk-create-function"></a>

以下 AWS CDK 代码定义了 Lambda 函数，并提供了其内联源代码。

------
#### [ 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)
});
```

------

您可以在这个简短的示例代码中看到：
+ 函数的逻辑名称 `MyLambdaFunction`。
+ 函数的源代码，以字符串形式嵌入到 AWS CDK 应用程序的源代码中。
+ 其他函数属性，例如要使用的运行时间（节点 18.x）、函数的入口点和超时。

### 创建状态机
<a name="lambda-state-machine-cdk-create"></a>

我们的状态机有两种状态：Lambda 函数任务和 [Succeed 工作流程状态](state-succeed.md) 状态。该函数要求我们创建一个 Step Functions [Task 工作流程状态](state-task.md) 来调用我们的函数。此 Task 状态用作状态机的第一个步骤。使用 Task 状态的`next()`方法将 success 状态添加到状态机中。以下代码首先调用名为 `MyLambdaTask` 的函数，然后使用 `next()` 方法定义名为 `GreetedWorld` 的 success 状态。

------
#### [ 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")))
});
```

------

### 构建并部署 AWS CDK 应用程序
<a name="lambda-state-machine-cdk-app"></a>

在新创建的 AWS CDK 项目中，编辑包含堆栈定义的文件，使其与下面的示例代码类似。您将从前面的部分中了解 Lambda 函数和 Step Functions 状态机的定义。

1. 如下例所示更新堆栈。

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

   使用以下代码更新 `lib/step-stack.ts`。

   ```
   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 ]

   使用以下代码更新 `lib/step-stack.js`。

   ```
   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 ]

   使用以下代码更新 `step/step_stack.py`。

   ```
   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 ]

   使用以下代码更新 `src/main/java/com.myorg/StepStack.java`。

   ```
   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 ]

   使用以下代码更新 `src/Step/StepStack.cs`。

   ```
   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. 保存源文件，然后在应用程序的主目录中运行 `cdk synth` 命令。

   AWS CDK 运行应用程序并合成 CloudFormation 模板。然后，AWS CDK 会显示该模板。
**注意**  
如果您曾经 TypeScript 创建过AWS CDK项目，则运行该`cdk synth`命令可能会返回以下错误。  

   ```
   TSError: ⨯ Unable to compile TypeScript:
   bin/step.ts:7:33 - error TS2554: Expected 2 arguments, but got 3.
   ```
修改 `bin/step.ts` 文件，如以下示例所示，可解决此错误。  

   ```
   #!/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. 要将 Lambda 函数和 Step Functions 状态机部署到您的 AWS 账户，请发出 `cdk deploy`。系统将要求您批准 AWS CDK 已生成的 IAM 策略。

## 第 3 步：启动状态机执行
<a name="lambda-state-machine-cdk-step-3"></a>

在创建您的状态机后，可以开始执行。

### 启动状态机执行
<a name="to-start-the-state-machine-execution"></a>

1. 打开 [Step Functions 控制台](https://console.aws.amazon.com/states/home)，然后选择您使用 AWS CDK 创建的状态机的名称。

1. 在状态机页面，选择**启动执行**。

   随即显示**启动执行**对话框。

1. （可选）输入自定义执行名称，以便覆盖生成的默认执行名称。
**非 ASCII 名称和日志记录**  
Step Functions 对于状态机、执行、活动和标签接受包含非 ASCII 字符的名称。由于此类字符会 CloudWatch 阻止亚马逊记录数据，因此我们建议您仅使用 ASCII 字符，这样您就可以跟踪 Step Functions 的指标。

1. 选择**开始执行**。

   状态机的执行将启动，并显示一个说明正在运行的执行的新页面。

1. Step Functions 控制台会将您引导到一个以您的执行 ID 为标题的页面。该页面被称为*执行详细信息*页面。在此页面上，您可以随着执行的进展或者在执行完成后查看执行结果。

   要查看执行结果，请在**图表视图**上选择各个状态，然后在[步骤详细信息](concepts-view-execution-details.md#exec-details-intf-step-details)窗格中选择各个选项卡，分别查看每个状态的详细信息，包括输入、输出和定义。有关可在*执行详细信息*页面上查看的执行信息的详细信息，请参阅[执行详细信息概览](concepts-view-execution-details.md#exec-details-interface-overview)。

## 第 4 步：清除
<a name="lambda-state-machine-cdk-step-4"></a>

测试状态机完成后，我们建议您删除状态机和相关的 Lambda 函数，以释放 AWS 账户中的资源。在您的应用程序的主目录中运行 `cdk destroy` 命令，以删除状态机。

## 后续步骤
<a name="lambda-state-machine-cdk-next-steps"></a>

要详细了解如何使用开发 AWS 基础架构AWS CDK，请参阅《[AWS CDK开发人员指南》](https://docs.aws.amazon.com/cdk/v2/guide/home.html)。

有关使用所选语言编写 AWS CDK 应用程序的信息，请参阅：

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

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

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

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

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

 [在 Python 中使用 AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-python.html) 

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

 [在 Java 中使用 AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-java.html) 

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

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

------

有关本教程中使用的 AWS 构造库模块的更多信息，请参阅以下 AWS CDK API 参考概述：
+  [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) 

# AWS CDK 用于在 Step Functions 中创建 Express 工作流程
<a name="tutorial-step-functions-rest-api-integration-cdk"></a>

在本教程中，您将学习如何使用 AWS Cloud Development Kit (AWS CDK) 基础设施即代码 (IAC) 框架创建 API Gateway REST API，将同步快速状态机作为后端集成。

您将使用 `StepFunctionsRestApi` 构造来将状态机连接到 API Gateway。该`StepFunctionsRestApi`构造将设置默认 input/output 映射和 API Gateway REST API，其中包含所需的权限和 HTTP “ANY” 方法。

 有了基础设施 AWS CDK 即代码 (IAC) 框架，您可以使用编程语言定义 AWS 基础架构。您可以使用 CDK 支持的语言之一定义应用程序，将代码合成到 CloudFormation 模板中，然后将基础架构部署到您的 AWS 账户。

 您将使用 CloudFormation 定义一个 API Gateway REST API，该API与同步快速状态机集成为后端，然后使用启动执行。 AWS 管理控制台 

在开始本教程之前，请[按照入门必备条件](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html#getting_started_prerequisites)中所述设置 AWS CDK 开发环境，然后 AWS CDK 通过发布以下命令进行安装： AWS CDK 

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

## 第 1 步：设置您的 AWS CDK 项目
<a name="step-functions-rest-api-integration-cdk-step-1"></a>

首先，为您的新 AWS CDK 应用程序创建一个目录并初始化项目。

------
#### [ 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
```

项目初始化后，激活项目的虚拟环境并安装其 AWS CDK基准依赖关系。

```
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
```

------

**注意**  
请确保将目录命名为 `stepfunctions-rest-api`。 AWS CDK 应用程序模板使用目录的名称来生成源文件和类的名称。如果您使用其他名称，则您的应用将与本教程不匹配。

现在为 AWS Step Functions 和 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 ]

编辑项目的 `pom.xml` 将以下依赖项添加到现有 `<dependencies>` 容器。

```
        <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 会在下次构建应用程序时自动安装这些依赖关系。要构建，请发出 `mvn compile` 或使用 Java IDE 的**构建**命令。

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

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

您也可以使用 Visual Studio NuGet GUI 安装指定的软件包，该用户界面可通过 “**工具**” > “**NuGet 包管理器**” > **“管理解决方案 NuGet 包**” 获得。

------

安装模块后，您可以通过导入以下软件包在 AWS CDK 应用程序中使用它们。

------
#### [ 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 ]

将以下内容添加到 `stepfunctions-rest-api.go` 内的 `import` 中

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

------

## 第 2 步：使用创建具有同步 Express 状态机后端集成的 API Gateway REST API AWS CDK
<a name="step-functions-rest-api-integration-cdk-step-2"></a>

首先，我们将展示定义同步快速状态机和 API Gateway REST API 的单独代码片段，然后解释如何将它们整合到您的 AWS CDK 应用程序中。然后，您将了解如何合成和部署这些资源。

**注意**  
我们将在此处展示的状态机将是一个带有 `Pass` 状态的简单状态机。

### 创建快速状态机
<a name="step-functions-rest-api-integration-cdk-create-state-machine"></a>

这是定义带有状态的简单`Pass`状态机的 AWS CDK 代码。

------
#### [ 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,
})
```

------

您可以在这个简短的片段中看到：
+ 名为 `PassState` 的计算机定义，它是一个 `Pass` 状态。
+ 状态机的逻辑名称，`MyStateMachine`。
+ 机器定义被用作状态机定义。
+ 状态机类型设置为 `EXPRESS`，因为 `StepFunctionsRestApi` 只支持同步快速状态机。

### 使用 `StepFunctionsRestApi` 构造创建 API Gateway REST API
<a name="step-functions-rest-api-integration-cdk-create-rest-api"></a>

我们将使用`StepFunctionsRestApi`构造来创建具有所需权限和默认 input/output 映射的 API Gateway REST API。

------
#### [ 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,
})
```

------

### 构建和部署 AWS CDK 应用程序
<a name="step-functions-rest-api-integration-cdk-app"></a>

在您创建的 AWS CDK 项目中，编辑包含堆栈定义的文件，使其看起来像下面的代码。您将从上面的部分中了解 Step Functions 状态机和 API Gateway 的定义。

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

更新 ` lib/stepfunctions-rest-api-stack.ts` 读取如下信息。

```
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 ]

更新 `lib/stepfunctions-rest-api-stack.js` 读取如下信息。

```
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 ]

更新 `stepfunctions_rest_api/stepfunctions_rest_api_stack.py` 读取如下信息。

```
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 ]

更新 `src/main/java/com.myorg/StepfunctionsRestApiStack.java` 读取如下信息。

```
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 ]

更新 `src/StepfunctionsRestApi/StepfunctionsRestApiStack.cs` 读取如下信息。

```
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 ]

更新 `stepfunctions-rest-api.go` 读取如下信息。

```
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")),
    // }
}
```

------

保存源文件，然后在应用程序的主目录中发出 `cdk synth`。 AWS CDK 运行应用程序并从中合成一个 CloudFormation 模板，然后显示该模板。

要将 Amazon API Gateway 和 AWS Step Functions 状态机实际部署到您的 AWS 账户，请执行以下操作`cdk deploy`。系统将要求您批准 AWS CDK 已生成的 IAM 策略。

## 第 3 步：测试 API Gateway Gateway
<a name="step-functions-rest-api-integration-cdk-step-3"></a>

使用同步快速状态机创建 API Gateway REST API 作为后端集成后，您可以测试 API Gateway。

### 使用 API Gateway 控制台测试已部署的 API Gateway
<a name="to-test-the-deployed-api-gateway-using-console"></a>

1. 打开 [Amazon API Gateway 控制台](https://console.aws.amazon.com/apigateway/)并登录。

1. 选择名为 `StepFunctionsRestApi` 的 REST API。

1. 在**资源**窗格中，选择 `ANY` 方法。

1. 选择**测试**选项卡。您可能需要选择右箭头按钮，以显示该选项卡。

1. 对于**方法**，选择 **POST**。

1. 在**请求正文**中，复制以下请求参数。

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

1. 选择**测试**。此时将显示以下信息：
   + **请求**是为方法调用的资源路径。
   + **状态**是响应的 HTTP 状态代码。
   + **延迟**是收到调用方请求和返回响应之间的时间。
   + **响应正文**是 HTTP 响应正文。
   + **响应标头**是 HTTP 响应标头。
   + **日志**显示了在 API Gateway 控制台之外调用此方法时本应写入的模拟 Amazon Lo CloudWatch gs 条目。
**注意**  
尽管 CloudWatch 日志条目是模拟的，但方法调用的结果是真实的。

**响应正文**输出应如下所示：

```
"Hello"
```

**提示**  
使用不同的方法和无效的输入来尝试 API Gateway，查看错误输出。您可能希望更改状态机来查找特定的键，并在测试期间提供错误的键，以使状态机执行失败，并在**响应正文**输出中生成错误消息。

### 使用 cURL 测试已部署的 API
<a name="to-test-the-deployed-api-gateway-using-curl"></a>

1. 打开终端窗口。

1. 复制以下 cURL 命令将其粘贴到终端窗口中，同时将 `<api-id>` 替换为您的 API 的 API ID 并将 `<region>` 替换为部署您的 API 的区域。

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

**响应正文**输出应如下所示：

```
"Hello"
```

**提示**  
使用不同的方法和无效的输入来尝试 API Gateway，查看错误输出。您可能希望更改状态机来查找特定的键，并在测试期间提供错误的键，以使状态机执行失败，并在**响应正文**输出中生成错误消息。

## 第 4 步：清除
<a name="step-functions-rest-api-integration-cdk-step-4"></a>

当您完成了 API Gateway 测试后，可以使用 AWS CDK 卸载状态机和 API Gateway。在您的应用程序的主目录中发布 `cdk destroy`。

# 使用 Terraform 在 Step Functions 中部署状态机
<a name="terraform-sfn"></a>

[Terraform](https://www.terraform.io/intro/) by HashiCorp 是一个使用基础设施即代码 (IaC) 构建应用程序的框架。借助 Terraform，您可以创建状态机并使用特征，例如预览基础架构部署和创建可重复使用的模板。Terraform 模板通过将代码分解为多个较小的块来帮助您维护和重用代码。

如果您熟悉 Terraform，则可以按照本主题中描述的开发生命周期作为在 Terraform 中创建和部署状态机的模型。如果您不熟悉 Terraform，我们建议您先完成 [AWS上的 Terraform 入门](https://catalog.workshops.aws/terraform101/en-US)讲习会，以熟悉 Terraform。

**提示**  
*要部署使用 Terraform 构建的状态机的示例，请参阅工作室中的 “使用 T [erraform 部署](https://catalog.workshops.aws/stepfunctions/iac/deploy-with-terraform)”。 AWS Step Functions *

**Topics**
+ [先决条件](#terraform-sfn-prerequisites)
+ [使用 Terraform 的开发生命周期](#terraform-sfn-dev-lifecycle)
+ [状态机的 IAM 角色和策略](#terraform-sfn-iam-policy)

## 先决条件
<a name="terraform-sfn-prerequisites"></a>

在开始之前，您必须满足以下先决条件：
+ 在您的系统上安装 Terraform。有关安装 Terraform 的信息，请参阅[安装 Terraform](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli)。
+ 在系统上安装 Step Functions Local。我们建议您安装 Step Functions Local Docker 映像，用于使用 Step Functions Local。有关更多信息，请参阅 [使用 Step Functions Local 测试状态机（不支持）](sfn-local.md)。
+ 安装 AWS SAM CLI。有关安装信息，请参阅[《*AWS Serverless Application Model 开发人员指南》*中的 “安装 AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html)”。
+ 安装 AWS Toolkit for Visual Studio Code 以查看状态机的工作流程图。有关安装信息，请参阅《AWS Toolkit for Visual Studio Code 用户指南》中的[安装 AWS Toolkit for Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/setup-toolkit.html)。**

## 使用 Terraform 的状态机开发生命周期
<a name="terraform-sfn-dev-lifecycle"></a>

以下过程说明了如何使用在 Step Functions 控制台中使用 [Workflow Studio](workflow-studio.md) 构建的状态机原型作为使用 Terraform 和 [AWS Toolkit for Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/welcome.html) 进行本地开发的起点。

要查看讨论使用 Terraform 开发状态机并详细介绍最佳实操的完整示例，请参阅[编写 Step Functions Terraform 项目的最佳实操](https://aws.amazon.com/blogs/devops/best-practices-for-writing-step-functions-terraform-projects/)。

**使用 Terraform 启动状态机的开发生命周期**

1. 使用以下命令可引导新的 Terraform 项目。

   ```
   terraform init
   ```

1. 打开 [Step Functions 控制台](https://console.aws.amazon.com/states/home?region=us-east-1#/)，为状态机创建原型。

1. 在 Works Studio 中，执行以下操作：

   1. 创建您的工作流原型。

   1. 导出工作流的 [Amazon States Language (ASL)](concepts-amazon-states-language.md) 定义。为此，请选择**导入/导出**下拉列表，然后选择**导出 JSON 定义**。

1. 将导出的 ASL 定义保存在项目目录中。

   您将导出的 ASL 定义作为输入参数传递给使用 [https://developer.hashicorp.com/terraform/language/functions/templatefile](https://developer.hashicorp.com/terraform/language/functions/templatefile) 函数的 [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 资源。此函数在定义字段中使用，该字段传递导出的 ASL 定义和任何变量替换。
**提示**  
由于 ASL 定义文件可能包含较长的文本块，因此我们建议您避免使用内联 EOF 方法。这可让您更轻松地将参数替换到状态机定义中。

1. （可选）更新 IDE 中的 ASL 定义并使用 AWS Toolkit for Visual Studio Code可视化您的更改。  
![\[Visual Studio Code 中工作流的 ASL 定义及其可视化表示的屏幕截图。\]](http://docs.aws.amazon.com/zh_cn/step-functions/latest/dg/images/visualize-sm-terraform-iac.png)

   为避免持续导出定义并将其重构到项目中，我们建议您在 IDE 中进行本地更新，并使用 [Git](https://git-scm.com/) 跟踪这些更新。

1. 使用 [Step Functions Local](sfn-local.md) 测试工作流。
**提示**  
您还可以在状态机中使用 [AWS SAM C](sfn-local-lambda.md) LI Local 在本地测试与 Lambda 函数和 API APIs Gateway 的服务集成。

1. 在部署状态机之前，请预览状态机和其他 AWS 资源。为此，请运行以下命令。

   ```
   terraform plan
   ```

1. 使用以下命令从本地环境或通过 [CI/CD 管道](https://aws.amazon.com/blogs/developer/build-infrastructure-ci-for-terraform-code-leveraging-aws-developer-tools-and-terratest/)部署状态机。

   ```
   terraform apply
   ```

1. （可选）使用以下命令清理资源并删除状态机。

   ```
   terraform destroy
   ```

## 状态机的 IAM 角色和策略
<a name="terraform-sfn-iam-policy"></a>

使用 [Terraform 服务集成策略](https://registry.terraform.io/modules/terraform-aws-modules/step-functions/aws/latest#service-integration-policies)为您的状态机添加必要的 IAM 权限，例如调用 Lambda 函数的权限。您还可以定义明确的角色和策略，并将它们与状态机相关联。

以下 IAM 策略示例授予您的状态机调用名为 `myFunction` 的 Lambda 函数的权限。

****  

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

我们还建议在 Terraform 中为状态机定义 IAM 策略时使用 [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) 数据来源。这可以帮助您检查策略是否格式有误，并用变量替换任何资源。

以下 IAM 策略示例使用 `aws_iam_policy_document` 数据来源，并授予您的状态机调用名为 `myFunction` 的 Lambda 函数的访问权限。

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

    actions = [
      "lambda:InvokeFunction"
    ]

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

**提示**  
要查看使用 Terraform 部署的更高级的 AWS 架构模式，请参阅 Serverless Land Workflows 集合[中的 Terraform 示例](https://serverlessland.com/workflows?framework=Terraform)。

# 将工作流导出到 IaC 模板
<a name="exporting-iac-templates"></a>

借助 AWS Step Functions 控制台，您可以导出保存的工作流并以 AWS CloudFormation 或 AWS SAM（SAM）模板形式下载。对于支持 AWS 基础架构编辑器 的 AWS 区域，还可以将工作流导出到基础设施编辑器并导航到基础设施编辑器控制台，您可以在控制台中继续处理新生成的模板。

## 模板配置选项
<a name="exporting-iac-templates-config-options"></a>

此功能提供以下选项。如果您选择导出并下载 IaC 模板文件，则控制台会显示适用于所保存状态机的选项以供选择。如果您要导出到基础设施编辑器，Step Functions 控制台会自动实施适用于状态机的配置。
+  **包括控制台代表您创建的 IAM 角色** – 此选项可导出执行角色策略。它在模板中构造一个 IAM 角色并将其附加到状态机资源。仅当状态机具有由控制台创建的执行角色时，此选项才适用。
+  **包括 CloudWatch 日志组** – 在模板中构造一个 CloudWatch 日志组并将其附加到状态机资源。仅当状态机附有 CloudWatch 日志组且[日志级别](cw-logs.md#cloudwatch-log-level)*未*设置为 `OFF` 时，此选项才适用。
+  **将资源引用替换为 DefinitionSubstitutions** – 此选项为以下组件生成 [DefinitionSubstitutions](concepts-sam-sfn.md#sam-definition-substitution-eg)：
  + [分布式 Map](state-map-distributed.md) S3 字段。
  + `Activity` 资源。导出内容包括 CloudFormation 模板中适用于任何 `Run Activity` 任务的 `Activity` 资源。导出还提供 `DefinitionSubstitutions`，用于引用所创建的 `Activity` 资源。
  + 所有服务集成的有效载荷字段中的任何 `ARN` 或 `S3URI`。
  + 除 `ARN` 和 `S3URI` 字段外，导出还会为其他常用的服务集成有效载荷字段生成 `DefinitionSubstitutions`。具体的服务集成如下：
    + `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`

## 导出并下载工作流的 IaC 模板
<a name="exporting-iac-templates-files-procedure"></a>

**将工作流导出到 IaC 模板文件**

1. 打开 [Step Functions 控制台](https://console.aws.amazon.com/states/home?region=us-east-1#/)并选择要使用的状态机。继续执行下一步操作之前，请务必先保存对状态机所做的任何更改。

1. 从**操作**菜单中选择**导出到 CloudFormation 或 SAM 模板**。

1. 在出现的对话框中，对于**类型**，选择 **SAM** 或 **CloudFormation**。
   + 如果选择了 **CloudFormation** 模板，则接下来选择 **JSON** 或 **YAML** 文件格式。
   + 如果选择了 **SAM** 模板，则不会显示任何格式选项。SAM 模板默认采用 YAML 文件格式。

1. 展开**其他配置**。默认情况下，所有选项均已选中。查看并更新 IaC 模板的选项选择。上一部分（标题为[模板配置选项](#exporting-iac-templates-config-options)）详细介绍了这些选项。

   如果某个选项不适用于您的特定工作流，则该选项将不会显示在对话框中。

1. 选择**下载**，导出并下载生成的 IaC 模板文件。

## 将工作流直接导出到 AWS 基础架构编辑器
<a name="exporting-iac-templates-infra-composer-procedure"></a>

**将工作流导出到 Infrastructure Composer**

1. 打开 [Step Functions 控制台](https://console.aws.amazon.com/states/home?region=us-east-1#/)并选择要使用的状态机。继续执行下一步操作之前，请务必先保存对状态机所做的任何更改。

1. 从**操作**菜单中选择**导出到基础设施编辑器**。

1. 此时将显示**导出到基础设施编辑器**对话框。可以使用**传输存储桶名称**字段中显示的默认名称，也可以输入新名称。Amazon S3 存储桶的名称必须全局唯一，并遵守[存储桶命名规则](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html)。

1. 选择**确认并创建项目**，将工作流导出到基础设施编辑器。

1. 要在基础设施编辑器中保存项目和工作流定义，请激活[本地同步模式](https://docs.aws.amazon.com/application-composer/latest/dg/reference-features-local-sync.html)。

**注意**  
如果您之前使用过**导出到基础设施编辑器**功能并使用默认名称创建了 Amazon S3 存储桶，Step Functions 可以重复使用该存储桶（如果它仍然存在）。接受对话框中的默认存储桶名称以重复使用现有存储桶。

### Amazon S3 传输存储桶配置
<a name="export-appcomposer-bucket-info"></a>

Step Functions 为传输您的工作流而创建的 Amazon S3 存储桶会使用 AES 256 加密标准自动加密对象。Step Functions 还将存储桶配置为使用[存储桶拥有者条件](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-owner-condition.html)，以确保只有您的 AWS 账户 能向存储桶添加对象。

默认存储桶名称使用前缀 `states-templates`、10 位字母数字字符串以及您创建工作流所在的 AWS 区域：`states-templates-amzn-s3-demo-bucket-us-east-1`。为避免给您的 AWS 账户 增加额外费用，建议在完成将工作流导出到基础设施编辑器后立即删除 Amazon S3 存储桶。

标准 [Amazon S3 定价](https://aws.amazon.com/s3/pricing/)适用。

### 所需的权限
<a name="export-appcomposer-permissions"></a>

要将此 Step Functions 导出功能与基础设施编辑器结合使用，您需要一定的权限才能下载 AWS SAM 模板并将模板配置写入 Amazon S3。

要下载 AWS SAM 模板，您必须拥有使用以下 API 操作的权限：
+ [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)

要让 Step Functions 将您的函数配置写入 Amazon S3，您必须拥有使用以下 API 操作的权限：
+ [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)

如果无法将函数的配置导出到基础设施编辑器，请检查账户是否具有这些操作所需的权限。