

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

# 用于在 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) 