Implementación de funciones de Lambda con el AWS CDK - AWS Lambda

Implementación de funciones de Lambda con el AWS CDK

AWS Cloud Development Kit (AWS CDK) es un marco de infraestructura como código (IAC) que puede usar para definir la infraestructura en la nube de AWS mediante un lenguaje de programación de su elección. Para definir su propia infraestructura de nube, primero escriba una aplicación (en uno de los lenguajes compatibles con CDK) que contenga una o más pilas. Luego, sintetícela en una plantilla de AWS CloudFormation e implemente sus recursos en suCuenta de AWS. Siga los pasos de este tema para implementar una función de Lambda que devuelva un evento desde un punto de conexión de Amazon API Gateway.

La biblioteca de construcción de AWS, incluida con el CDK, ofrece módulos que puede usar para modelar los recursos proporcionados por Servicios de AWS. Para los servicios más populares, la biblioteca proporciona construcciones seleccionadas con valores predeterminados inteligentes y prácticas recomendadas. Puede usar el módulo aws_lambda para definir su función y los recursos de soporte con solo unas pocas líneas de código.

Requisitos previos

Antes de empezar este tutorial, instale el AWS CDK; para ello, ejecute el siguiente comando.

npm install -g aws-cdk

Paso 1: Configurar el proyecto de AWS CDK

Cree un directorio para la nueva aplicación AWS CDK e inicialice el proyecto.

JavaScript
mkdir hello-lambda cd hello-lambda cdk init --language javascript
TypeScript
mkdir hello-lambda cd hello-lambda cdk init --language typescript
Python
mkdir hello-lambda cd hello-lambda 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 hello-lambda cd hello-lambda cdk init --language java

Importe este proyecto de Maven a su entorno de desarrollo integrado (IDE) de Java. Por ejemplo, en Eclipse, elija Archivo, Importar, Maven, Proyectos de Maven existentes.

C#
mkdir hello-lambda cd hello-lambda cdk init --language csharp
nota

La plantilla de la aplicación AWS CDK utiliza el nombre del directorio del proyecto para generar nombres para los archivos y las clases fuente. En este ejemplo, el directorio se llama hello-lambda. Si usa otro nombre de directorio de proyecto, la aplicación no coincidirá con estas instrucciones.

AWS CDK v2 incluye construcciones estables para todos los Servicios de AWS en un solo paquete denominado aws-cdk-lib. Este paquete se instala como dependencia cuando inicializa el proyecto. Al trabajar con ciertos lenguajes de programación, el paquete se instala al crear el proyecto por primera vez.

Paso 2: definición de la pila de AWS CDK

Una pila de CDK es una colección de una o más construcciones que definen los recursos de AWS. Cada pila de CDK representa una pila de AWS CloudFormation en la aplicación del CDK.

Para definir su CDK, siga las instrucciones de su lenguaje de programación preferido. En esta pila se define lo siguiente:

  • Nombre lógico de la función: MyFunction

  • La ubicación del código de la función, especificada en la propiedad code. Para obtener más información, consulte Código del controlador en la Referencia de la API de AWS Cloud Development Kit (AWS CDK).

  • Nombre lógico de la API de REST: HelloApi

  • Nombre lógico del punto de conexión de API Gateway: ApiGwEndpoint

Tenga en cuenta que todas las pilas de CDK de este tutorial utilizan el tiempo de ejecución de Node.js para la función de Lambda. Puede usar diferentes lenguajes de programación para la pila de CDK y la función de Lambda para aprovechar las ventajas de cada lenguaje. Por ejemplo, puede usar TypeScript para la pila de CDK para aprovechar las ventajas de la escritura estática en el código de su infraestructura. Puede utilizar JavaScript para la función de Lambda para aprovechar la flexibilidad y el rápido desarrollo de un lenguaje de tipificación dinámica.

JavaScript

Reemplace el contenido del archivo lib/hello-lambda-stack.js por lo siguiente.

const { Stack } = require('aws-cdk-lib'); const lambda = require('aws-cdk-lib/aws-lambda'); const apigw = require('aws-cdk-lib/aws-apigateway'); class HelloLambdaStack extends Stack { /** * * @param {Construct} scope * @param {string} id * @param {StackProps=} props */ constructor(scope, id, props) { super(scope, id, props); const fn = new lambda.Function(this, 'MyFunction', { code: lambda.Code.asset('lib/lambda-handler'), runtime: lambda.Runtime.NODEJS_LATEST, handler: 'index.handler' }); const endpoint = new apigw.LambdaRestApi(this, 'MyEndpoint', { handler: fn, restApiName: "HelloApi" }); } } module.exports = { HelloLambdaStack }
TypeScript

Reemplace el contenido del archivo lib/hello-lambda-stack.ts por lo siguiente.

import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; import * as apigw from "aws-cdk-lib/aws-apigateway"; import * as lambda from "aws-cdk-lib/aws-lambda"; import * as path from 'node:path'; export class HelloLambdaStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps){ super(scope, id, props) const fn = new lambda.Function(this, 'MyFunction', { runtime: lambda.Runtime.NODEJS_LATEST, handler: 'index.handler', code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), }); const endpoint = new apigw.LambdaRestApi(this, `ApiGwEndpoint`, { handler: fn, restApiName: `HelloApi`, }); } }
Python

Reemplace el contenido del archivo /hello-lambda/hello_lambda/hello_lambda_stack.py por lo siguiente.

from aws_cdk import ( Stack, aws_apigateway as apigw, aws_lambda as _lambda ) from constructs import Construct class HelloLambdaStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) fn = _lambda.Function( self, "MyFunction", runtime=_lambda.Runtime.NODEJS_LATEST, handler="index.handler", code=_lambda.Code.from_asset("lib/lambda-handler") ) endpoint = apigw.LambdaRestApi( self, "ApiGwEndpoint", handler=fn, rest_api_name="HelloApi" )
Java

Reemplace el contenido del archivo /hello-lambda/src/main/java/com/myorg/HelloLambdaStack.java por lo siguiente.

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; import software.amazon.awscdk.services.apigateway.LambdaRestApi; import software.amazon.awscdk.services.lambda.Function; public class HelloLambdaStack extends Stack { public HelloLambdaStack(final Construct scope, final String id) { this(scope, id, null); } public HelloLambdaStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); Function hello = Function.Builder.create(this, "MyFunction") .runtime(software.amazon.awscdk.services.lambda.Runtime.NODEJS_LATEST) .code(software.amazon.awscdk.services.lambda.Code.fromAsset("lib/lambda-handler")) .handler("index.handler") .build(); LambdaRestApi api = LambdaRestApi.Builder.create(this, "ApiGwEndpoint") .restApiName("HelloApi") .handler(hello) .build(); } }
C#

Reemplace el contenido del archivo src/HelloLambda/HelloLambdaStack.cs por lo siguiente.

using Amazon.CDK; using Amazon.CDK.AWS.APIGateway; using Amazon.CDK.AWS.Lambda; using Constructs; namespace HelloLambda { public class HelloLambdaStack : Stack { internal HelloLambdaStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { var fn = new Function(this, "MyFunction", new FunctionProps { Runtime = Runtime.NODEJS_LATEST, Code = Code.FromAsset("lib/lambda-handler"), Handler = "index.handler" }); var api = new LambdaRestApi(this, "ApiGwEndpoint", new LambdaRestApiProps { Handler = fn }); } } }

Paso 3: creación del código de la función de Lambda

  1. Desde la raíz del proyecto (hello-lambda), cree el directorio /lib/lambda-handler para el código de la función de Lambda. Este directorio se especifica en la propiedad code de la pila de AWS CDK.

  2. Cree un archivo con el nombre index.js en el directorio /lib/lambda-handler. Pegue el código siguiente en el archivo. La función extrae propiedades específicas de la solicitud de API y las devuelve como una respuesta JSON.

    exports.handler = async (event) => { // Extract specific properties from the event object const { resource, path, httpMethod, headers, queryStringParameters, body } = event; const response = { resource, path, httpMethod, headers, queryStringParameters, body, }; return { body: JSON.stringify(response, null, 2), statusCode: 200, }; };

Paso 4: implementación de la pila de AWS CDK

  1. Desde la raíz del proyecto, ejecute el comando cdk synth:

    cdk synth

    Este comando sintetiza una plantilla AWS CloudFormation de la pila de CDK. La plantilla es un archivo YAML de aproximadamente 400 líneas, similar al siguiente.

    nota

    Si aparece el siguiente error, asegúrese de que está en la raíz del directorio del proyecto.

    --app is required either in command-line, in cdk.json or in ~/.cdk.json
    ejemplo Plantilla de AWS CloudFormation
    Resources: MyFunctionServiceRole3C357FF2: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: lambda.amazonaws.com Version: "2012-10-17" ManagedPolicyArns: - Fn::Join: - "" - - "arn:" - Ref: AWS::Partition - :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Metadata: aws:cdk:path: HelloLambdaStack/MyFunction/ServiceRole/Resource MyFunction1BAA52E7: Type: AWS::Lambda::Function Properties: Code: S3Bucket: Fn::Sub: cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region} S3Key: ab1111111cd32708dc4b83e81a21c296d607ff2cdef00f1d7f48338782f92l3901.zip Handler: index.handler Role: Fn::GetAtt: - MyFunctionServiceRole3C357FF2 - Arn Runtime: nodejs20.x ...
  2. Ejecute el comando cdk deploy:

    cdk deploy

    Espere a que se creen sus recursos. El resultado final incluye la URL de su punto de conexión de API Gateway. Ejemplo:

    Outputs: HelloLambdaStack.ApiGwEndpoint77F417B1 = https://abcd1234.execute-api.us-east-1.amazonaws.com/prod/

Paso 5: prueba de la función

Para invocar la función de Lambda, copie el punto de conexión de API Gateway y péguelo en un navegador web o ejecute un comando curl:

curl -s https://abcd1234.execute-api.us-east-1.amazonaws.com/prod/

La respuesta es una representación en JSON de las propiedades seleccionadas del objeto de evento original, que contiene información sobre la solicitud hecha al punto de conexión de API Gateway. Ejemplo:

{ "resource": "/", "path": "/", "httpMethod": "GET", "headers": { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Accept-Encoding": "gzip, deflate, br, zstd", "Accept-Language": "en-US,en;q=0.9", "CloudFront-Forwarded-Proto": "https", "CloudFront-Is-Desktop-Viewer": "true", "CloudFront-Is-Mobile-Viewer": "false", "CloudFront-Is-SmartTV-Viewer": "false", "CloudFront-Is-Tablet-Viewer": "false", "CloudFront-Viewer-ASN": "16509", "CloudFront-Viewer-Country": "US", "Host": "abcd1234.execute-api.us-east-1.amazonaws.com", ...

Paso 6: Eliminar los recursos

El punto de conexión de API Gateway es de acceso público. Para evitar cargos inesperados, ejecute el comando cdk destroy para eliminar la pila y todos los recursos asociados.

cdk destroy

Siguientes pasos

Para obtener información sobre cómo escribir aplicaciones de AWS CDK en el lenguaje de su elección, consulte:

TypeScript

Utilización del AWS CDK en TypeScript

JavaScript

Utilización del AWS CDK en JavaScript

Python

Utilización del AWS CDK en Python

Java

Utilización del AWS CDK en Java

C#

Utilización del AWS CDK en C#

Go

Uso del AWS CDK en Go