

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 在 Step Functions 中 CloudFormation 建立工作流程
<a name="tutorial-lambda-state-machine-cloudformation"></a>

在本教學課程中，您將使用 建立 AWS Lambda 函數 AWS CloudFormation。您將使用 CloudFormation 主控台和 YAML 範本來建立*堆疊* (IAM 角色、Lambda 函數和狀態機器）。然後，您將使用 Step Functions 主控台來啟動狀態機器執行。

如需詳細資訊，請參閱*AWS CloudFormation 《 使用者指南*`[AWS::StepFunctions::StateMachine](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-statemachine.html)`》中的[使用 CloudFormation 範本](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-guide.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>

為將列印訊息的 Lambda 函數定義下列屬性`Hello World`。

**重要**  
確保您的 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)，然後選擇 **Create Stack (建立堆疊)**。

1. 在 **Select Template (選取範本)** 頁面上，選擇 **Upload a template to Amazon S3 (將範本上傳到 Amazon S3)**。選擇您的 `MyStateMachine` 檔案，然後選擇 **Next (下一步)**。

1. 在 **Specify Details (指定詳細資訊)** 頁面上，為 **Stack Name (堆疊名稱)** 輸入 `MyStateMachine`，然後選擇 **Next (下一步)**。

1. 在**選項**頁面上，選擇**下一步**。

1. 在**檢閱**頁面上，選擇**我確認 CloudFormation 可能會建立 IAM 資源，**然後選擇**建立**。

   CloudFormation 開始建立`MyStateMachine`堆疊，並顯示 **CREATE\$1IN\$1PROGRESS** 狀態。程序完成後， CloudFormation 會顯示 **CREATE\$1COMPLETE** 狀態。

1. (選用) 若要顯示堆疊中的資源，請選取堆疊，然後選擇 **Resources (資源)** 標籤。

## 步驟 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*** 頁面上，選擇 **New execution (新執行)**。

   系統會隨即顯示 **New execution (新執行)** 頁面。

1. （選用） 輸入自訂執行名稱以覆寫產生的預設值。
**非 ASCII 名稱和記錄**  
Step Functions 接受包含非 ASCII 字元的狀態機器、執行、活動和標籤名稱。由於這類字元會阻止 Amazon CloudWatch 記錄資料，因此我們建議您僅使用 ASCII 字元，以便您可以追蹤 Step Functions 指標。

1. 選擇 **Start Execution (開始執行)**。

   狀態機器會開始新執行，且隨即會出現新頁面顯示您正在執行的執行。

1. (選用) 在 **Execution Details (執行詳細資訊)** 中，檢閱 **Execution Status (執行狀態)**、**Started (已開始)** 和 **Closed (已結束)** 時間戳記。

1. 若要檢視執行結果，請選擇 **Output (輸出)**。