

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

# 用于在 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. 要查看执行结果，请选择**输出**。