Uso de AWS CDK para crear un flujo de trabajo rápido en Step Functions - AWS Step Functions

Uso de AWS CDK para crear un flujo de trabajo rápido en Step Functions

En este tutorial, aprenderá a crear una API de REST de API Gateway con una máquina de estado rápida síncrona como integración de backend, utilizando el marco de infraestructura como código (IaC) de AWS Cloud Development Kit (AWS CDK).

Usará el constructo StepFunctionsRestApi para conectar la máquina de estado a API Gateway. El constructo StepFunctionsRestApi configurará una asignación de entrada/salida predeterminado y la API de REST de API Gateway, con los permisos necesarios y un método HTTP “ANY”.

Con AWS CDK, un marco de trabajo de infraestructura como código (IaC), define la infraestructura de AWS utilizando un lenguaje de programación. Defina una aplicación en uno de los lenguajes compatibles con CDK, sintetícela en una plantilla de CloudFormation e implemente la infraestructura en la cuenta de AWS.

Usará CloudFormation para definir una API de REST de API Gateway, que está integrada con una máquina de estado rápida sincrónica como backend, y luego usaremos la Consola de administración de AWS para iniciar la ejecución.

Antes de iniciar este tutorial, configure su entorno de desarrollo del AWS CDK tal como se describe en Introducción al AWS CDK - requisitos previos y, a continuación, instale el AWS CDK mediante su ejecución:

npm install -g aws-cdk

Paso 1: Configurar el proyecto de AWS CDK

En primer lugar, cree un directorio para la nueva aplicación AWS CDK e inicialice el proyecto.

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

Después de inicializar el proyecto, active el entorno virtual del proyecto e instale las dependencias de referencia del 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#
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
nota

Asegúrese de asignarle al directorio el nombre stepfunctions-rest-api. La plantilla de la aplicación de AWS CDK utiliza el nombre del directorio para generar nombres para los archivos y las clases fuente. Si utiliza otro nombre, la aplicación no coincidirá con este tutorial.

Ahora instale los módulos de la biblioteca de constructo para AWS Step Functions y 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

Edite el archivo pom.xml del proyecto para agregar las siguientes dependencias dentro del contenedor <dependencies> existente.

<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 instala automáticamente estas dependencias la próxima vez que cree su aplicación. Para la creación, ejecute mvn compile o utilice el comando Build (Crear) del IDE de Java.

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

Para instalar los paquetes indicados, también puede utilizar la GUI NuGet de Visual Studio, a la que puede acceder desde Tools > NuGet Package Manager > Manage NuGet Packages for Solution (Herramientas > Administrador de paquetes NuGet > Administrar paquetes NuGet para la solución).

Una vez que haya instalado los módulos, podrá utilizarlos en su aplicación de AWS CDK importando los siguientes paquetes.

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#
Amazon.CDK.AWS.StepFunctions Amazon.CDK.AWS.APIGateway
Go

Añada lo siguiente a import dentro de stepfunctions-rest-api.go.

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

Paso 2: Utilizar la AWS CDK para crear una API de REST de API Gateway con integración de backend de máquina de estado rápida sincrónica

En primer lugar, presentaremos los fragmentos de código individuales que definen la máquina de estado rápida sincrónica y la API de REST de API Gateway y, a continuación, explicaremos cómo unirlos en su aplicación AWS CDK. A continuación, verá cómo sintetizar e implementar estos recursos.

nota

La máquina de estado que mostraremos aquí será una máquina de estado simple con un estado Pass.

Para crear una máquina de estado rápida

Este es el código AWS CDK que define una máquina de estado simple con un estado Pass.

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

En este breve fragmento de código, puede ver lo siguiente:

  • La definición de máquina denominada PassState, que es un estado Pass.

  • El nombre lógico de la máquina de estado, MyStateMachine.

  • La definición de la máquina se utiliza como definición de la Máquina de estado.

  • El tipo de máquina de estado se establece como EXPRESS porque StepFunctionsRestApi solo permitirá una máquina de estado rápida síncrona.

Para crear una API de REST de API Gateway utilizando constructo StepFunctionsRestApi

Usaremos el constructo StepFunctionsRestApi para crear la API de REST de API Gateway con los permisos necesarios y la asignación de entrada/salida predeterminada.

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#
var api = new StepFunctionsRestApi(this, "StepFunctionsRestApi", new StepFunctionsRestApiProps { StateMachine = stateMachine });
Go
awsapigateway.NewStepFunctionsRestApi(stack, jsii.String("StepFunctionsRestApi"), &awsapigateway.StepFunctionsRestApiProps { StateMachine = stateMachine, })

Para compilar e implementar la aplicación de AWS CDK

En el proyecto AWS CDK que creó, edite el archivo que contiene la definición de la pila para que se parezca al siguiente código. Reconocerá las definiciones de la máquina de estado de Step Functions y la API Gateway de más arriba.

TypeScript

Actualice lib/stepfunctions-rest-api-stack.ts para que diga lo siguiente.

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

Actualice lib/stepfunctions-rest-api-stack.js para que diga lo siguiente.

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

Actualice stepfunctions_rest_api/stepfunctions_rest_api_stack.py para que diga lo siguiente.

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

Actualice src/main/java/com.myorg/StepfunctionsRestApiStack.java para que diga lo siguiente.

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#

Actualice src/StepfunctionsRestApi/StepfunctionsRestApiStack.cs para que diga lo siguiente.

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

Actualice stepfunctions-rest-api.go para que diga lo siguiente.

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

Guarde el archivo fuente y, a continuación, ejecute cdk synth en el directorio principal de la aplicación. El AWS CDK ejecuta la aplicación y sintetiza una plantilla de CloudFormation y, a continuación, la muestra.

Para implementar realmente la Amazon API Gateway y la máquina de estado AWS Step Functions en su cuenta de AWS, procese cdk deploy. Se le pedirá que apruebe las políticas de IAM que ha generado el AWS CDK.

Paso 3: Comprobar la API Gateway

Después de crear la API de REST de API Gateway con máquina de estado rápida sincrónica como integración de backend, puede probar la API Gateway.

Para probar la API Gateway implementada mediante la consola de API Gateway

  1. Abra la consola de Amazon API Gateway e inicie sesión.

  2. Elija el nombre de su API de REST denominada StepFunctionsRestApi.

  3. En el panel Recursos, elija el método ANY.

  4. Elija la pestaña Prueba. Puede que tenga que elegir el botón de flecha hacia la derecha para mostrar la pestaña.

  5. En Method (Método), elija POST.

  6. En Cuerpo de la solicitud, copie los siguientes parámetros de solicitud.

    { "key": "Hello" }
  7. Seleccione Test (Probar). Se mostrará la siguiente información:

    • Request (Solicitud) es la ruta del recurso llamada para el método.

    • Status (Estado) es el código de estado HTTP de la respuesta.

    • Latency (Latencia) es el tiempo entre la recepción de la solicitud del intermediario y la respuesta devuelta.

    • Cuerpo de respuesta es el cuerpo de la respuesta HTTP.

    • Encabezados de respuesta son los encabezados de respuesta HTTP.

    • El registro muestra las entradas simuladas de los registros de Amazon CloudWatch que se habrían escrito si se hubiera llamado a este método fuera de la consola de API Gateway.

      nota

      Aunque las entradas de CloudWatch Logs son simuladas, los resultados de la llamada al método son reales.

La salida de Cuerpo de respuesta debe tener un aspecto similar al siguiente:

"Hello"
sugerencia

Pruebe la API Gateway con métodos diferentes y una entrada no válida para ver el resultado del error. Es posible que desee cambiar la máquina de estado para buscar una clave en particular y, durante las pruebas, proporcionar la clave incorrecta para que no se ejecute correctamente la máquina de estado y generar un mensaje de error en la salida de Cuerpo de respuesta.

Para probar la API implementada mediante cURL

  1. Abra una ventana de terminal.

  2. Copie el siguiente comando cURL y péguelo en la ventana de terminal, sustituyendo <api-id> por el ID de la API de la API y <region> por la región en la que se implementa la API.

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

El resultado del cuerpo de la respuesta debe tener un aspecto similar al siguiente:

"Hello"
sugerencia

Pruebe la API Gateway con métodos diferentes y una entrada no válida para ver el resultado del error. Es posible que desee cambiar la máquina de estado para buscar una clave en particular y, durante las pruebas, proporcionar la clave incorrecta para que no se ejecute correctamente la máquina de estado y generar un mensaje de error en el resultado del cuerpo de la respuesta.

Paso 4: Eliminación

Cuando termine de probar su API Gateway, podrá desmantelar tanto la máquina de estado como la API Gateway con el AWS CDK. Ejecute cdk destroy en el directorio principal de la aplicación.