

# Implementación de funciones de Lambda con AWS CDK
<a name="lambda-cdk-tutorial"></a>

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 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\$1lambda](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html) para definir su función y los recursos de soporte con solo unas pocas líneas de código. 

## Requisitos previos
<a name="lambda-cdk-prerequisites"></a>

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
<a name="lambda-cdk-step-1"></a>

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\$1 ]

```
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
<a name="lambda-cdk-step-2"></a>

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 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](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html#handler-code) 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](lambda-runtimes.md) 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.fromAsset('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\$1 ]

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
<a name="lambda-cdk-step-3"></a>

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.

1. En el directorio `index.js`, cree un archivo con el nombre `/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
<a name="lambda-cdk-step-4"></a>

1. Desde la raíz del proyecto, ejecute el comando [cdk synth](https://docs.aws.amazon.com/cdk/v2/guide/ref-cli-cmd-synth.html):

   ```
   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
   ```  
**Example CloudFormationPlantilla de**  

   ```
   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: nodejs24.x
         ...
   ```

1. Ejecute el comando [cdk deploy](https://docs.aws.amazon.com/cdk/v2/guide/ref-cli-cmd-deploy.html):

   ```
   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
<a name="lambda-cdk-step-5"></a>

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
<a name="lambda-cdk-step-6"></a>

El punto de conexión de API Gateway es de acceso público. Para evitar cargos inesperados, ejecute el comando [cdk destroy](https://docs.aws.amazon.com/cdk/v2/guide/ref-cli-cmd-destroy.html) para eliminar la pila y todos los recursos asociados.

```
cdk destroy
```

## Siguientes pasos
<a name="lambda-cdk-next-steps"></a>

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](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-typescript.html)

------
#### [ JavaScript ]

[Utilización del AWS CDK en JavaScript](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-javascript.html)

------
#### [ Python ]

[Utilización del AWS CDK en Python](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-python.html)

------
#### [ Java ]

[Utilización del AWS CDK en Java](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-java.html)

------
#### [ C\$1 ]

[Utilización del AWS CDK en C\$1](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-csharp.html)

------
#### [ Go ]

[Uso del AWS CDK en Go](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-go.html)

------