.NET Workloads on AWS Lambda

MÓDULO 6

Módulo 6: Laboratorio práctico: creación e implementación de funciones de Lambda

 LABORATORIO PRÁCTICO

Objetivos del laboratorio

En estos laboratorios pondrá en práctica lo aprendido en este curso

Creará diversas funciones de Lambda para .NET 6/7, las implementará y las invocará.

Hay 3 laboratorios en este módulo:

Laboratorio 1: Una aplicación web .NET 6 que se ejecute en Arm64
Laboratorio 2: Invocación de una función de Lambda desde un programa de C# en su computadora
Laboratorio 3: Invocación de una función de Lambda desde otra

Requisitos previos

Tiene una cuenta de AWS.

Tiene un usuario de AWS con la política AdministratorAccess adjunta; consulte la sección Nota sobre los permisos del módulo 3 para obtener más información./p>

Instaló el SDK para .NET 6.

Instaló las Extensiones de AWS para la CLI de .NET (dotnet lambda...).

Instaló las plantillas de AWS Lambda para .NET Core.

Instaló PowerShell. Si necesita instalarlo para Windows/Mac/Linux, consulte https://github.com/PowerShell/PowerShell.

Puede encontrar más información sobre las herramientas anteriores en el módulo 2.

Tiene un bucket de S3 para las pilas de CloudFormation. En caso contrario, siga las instrucciones que se indican a continuación.

 Tiempo de realización

45 minutos

Laboratorio 1: Una aplicación web .NET 6 que se ejecute en Arm64

Paso 1: Crear el proyecto

En este proceso, creará un proyecto de .NET sin servidor.

1. Crear un proyecto de .NET sin servidor

dotnet new serverless.AspNetCoreWebApp -n AspNetCoreWebApp
Esto creará el proyecto dentro del directorio AspNetCoreWebApp\src\AspNetCoreWebApp.
2. Abrir el proyecto
Abra este proyecto en su IDE preferido.

Paso 2: Hacer algunos cambios en el código

En este paso, modificará el código de proyecto generado.
1. Actualizar Index.cshtml.cs
Una vez que tenga el proyecto abierto en el IDE, abra Pages/Index.cshtml.cs en el editor de código.

Puede dejar la instrucción using y el espacio de nombres tal como están, pero reemplace la clase IndexModel por lo siguiente:
public class IndexModel : PageModel
{
    public string? Architecture { get; set; }
    public string? DotnetVersion { get; set; }
    
    public void OnGet()
    {
        Architecture = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture.ToString();
        DotnetVersion = Environment.Version.ToString();
    }
}

2. Actualizar Index.cshtml

Abra el archivo Pages/Index.cshtml.

Sustituya el contenido del archivo hasta el elemento </h2> por:
@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="text-center">
  <h1 class="display-4">Welcome to .NET Lambda functions on AWS!</h1>
  <h2>Your application is using .NET <code>@Model.DotnetVersion</code>, <code>@Model.Architecture</code>.</h2>
</div>
Deje el elemento <svg> en su lugar.

Estos cambios le permitirán ver qué versión de .NET está ejecutando y el tipo de procesador que está utilizando

Paso 3: Configurar la arquitectura del procesador

En este paso, configurará la arquitectura del procesador en Arm64.
1. Cambiar la arquitectura del procesador a Arm64
Un cambio más.

Abra el archivo serverless.template.

Busque la clave “Handler” y, en la siguiente línea, agregue:
"Architectures": ["arm64"],
Su bloque de código debería tener ahora el siguiente aspecto:
"AspNetCoreFunction": {
  "Type": "AWS::Serverless::Function",
  "Properties": {
    "Handler": "AspNetCoreWebApp::AspNetCoreWebApp.LambdaEntryPoint::FunctionHandlerAsync",
    "Architectures": ["arm64"],
2. Guardar y crear
Guarde todos los cambios y compile la aplicación para asegurarse de no recibir ningún error de compilación.

Paso 4: Implementar la función

En este paso, implementará y probará la función de Lambda.
1. Implementar la función en AWS
Desde la línea de comandos, ejecute:
dotnet lambda deploy-serverless --stack-name AspNetCoreWebApp --s3-bucket your-unique-bucket-name1234
Espere mientras AWS implementa la función de Lambda.

Verá el resultado de cada paso de la implementación a medida que se vaya trabajando en ella y finalice.
8/9/2022 1:45 PM     AspNetCoreFunctionProxyResourcePermissionProd CREATE_COMPLETE
8/9/2022 1:45 PM     AspNetCoreWebApp                         CREATE_COMPLETE
Stack finished updating with status: CREATE_COMPLETE

Output Name                    Value
------------------------------ --------------------------------------------------
ApiURL                         https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/Prod/
2. Crear un proyecto de API web en .NET
Al final de la salida, habrá una URL de API. Ábrala en su navegador.

Paso 5: Eliminar los recursos

En este paso, eliminará el proyecto sin servidor de AWS.
1. Eliminar el proyecto sin servidor
Para eliminar todos los recursos creados durante la ejecución:
dotnet lambda delete-serverless --stack-name AspNetCoreWebApp

Laboratorio 2: Invocación de una función de Lambda desde un programa de C# en su computadora

Paso 1: Crear la función de Lambda

En este paso, creará un proyecto de Lambda vacío.

1. Crear el proyecto

Si todavía se encuentra en el directorio que creó para el laboratorio anterior, muévalo de allí a un directorio limpio. Cree una nueva función de Lambda desde la línea de comandos:

dotnet new lambda.EmptyFunction -n GetS3Buckets
Esto creará el proyecto dentro del directorio AspNetCoreWebApp\src\AspNetCoreWebApp.

Paso 2: Cambios de código

En este paso, modificará el código de proyecto generado.

1. Agregar paquete

Cambie a la carpeta GetS3Buckets\src\GetS3Buckets y agregue el paquete AWS SDK S3 al proyecto:

cd GetS3Buckets\src\ GetS3Buckets
dotnet add package AWSSDK.S3

2. Actualizar Function.cs

Abra Function.cs en su IDE y sustituya el código por:

using Amazon.Lambda.Core;
using Amazon.S3;
using Amazon.S3.Model;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace GetS3Buckets;

public class Function
{
   public async Task<IEnumerable<string>> FunctionHandler(ILambdaContext context)
    {
        var s3Client = new AmazonS3Client();

        ListBucketsRequest listBucketsRequest = new ListBucketsRequest();
        ListBucketsResponse listBucketsResponse = await s3Client.ListBucketsAsync(listBucketsRequest);

        var bucketNames = listBucketsResponse.Buckets.Select(b => b.BucketName);

        return bucketNames;
    }
}

Paso 3: Implementar la función

En este paso, implementará y probará la función de Lambda.

1. Implementar la función en AWS

Implemente la función en AWS mediante:

dotnet lambda deploy-function GetS3Buckets

Cuando se le pida que seleccione un rol, elija la opción de crear uno nuevo. Use el nombre GetS3BucketsRole para el nombre del rol.

Cuando se le pida que adjunte una política, elija la opción de AWSLambdaBasicExecutionRole, que es la número 6 de mi lista.

Paso 4: Agregar permiso a ListAllMyBuckets

En este paso, agregará permisos para listar sus buckets de S3.

1. Crear una política de IAM

La política que asignó al rol no tiene los permisos necesarios para listar sus buckets de S3.

Cree un nuevo archivo llamado S3ListAllMyBucketsPolicy.json.

Pegue lo siguiente en el archivo:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "*"
        }
    ]
}

2. Agregar política al rol

Agregue la política a GetS3BucketsRole:.

aws iam put-role-policy --role-name GetS3BucketsRole --policy-name ListAllMyBuckets --policy-document file://S3ListAllMyBucketsPolicy.json

Espere unos instantes a que se apliquen los permisos.

Paso 5: Invocar la función de Lambda desde la línea de comandos

En este paso, implementará y probará la función de Lambda.

1. Invocar la función desde la línea de comandos

Antes de crear un programa en C# para invocar la función, intente invocarlo desde la línea de comandos:

dotnet lambda invoke-function --function-name GetS3Buckets

Debería ver un resultado que muestre todos los buckets.

Esto verifica que la función de Lambda funcione según lo esperado.

Paso 6: Invocar la función de Lambda desde la línea de comandos

En este paso, creará un programa de C# que invoque su función de Lambda.

1. Crear una aplicación de consola

Cree una aplicación de consola de .NET mediante:

dotnet new console -n GetS3BucketsCallFromLocal

2. Agregar el paquete AWSSDK.Lambda

Cambie a la carpeta GetS3BucketsCallFromLocal.

cd GetS3BucketsCallFromLocal

Agregue el paquete AWS SDK Lambda para poder invocar funciones de Lambda:

dotnet add package AWSSDK.Lambda

3. Actualizar Program.cs

Abra el archivo Program.cs y sustitúyalo por:

using System.Text.Json;
using Amazon.Lambda;
using Amazon.Lambda.Model;

AmazonLambdaClient client = new AmazonLambdaClient();

var request = new InvokeRequest
{
    FunctionName = "GetS3Buckets"
};

var result = await client.InvokeAsync(request);

var buckets = JsonSerializer.Deserialize<IEnumerable<string>>(result.Payload);

foreach (var bucket in buckets)
{
    Console.WriteLine(bucket);
}

Paso 7: Hacer una prueba

En este paso, probará el programa de consola e invocará la función de Lambda.

1. Ejecutar la aplicación de consola

Desde la línea de comandos del directorio GetS3BucketsCallFromLocal, ejecute:

dotnet run 

Debería ver una lista de los nombres de los buckets.

Paso 8: Eliminar los recursos

Va a utilizar esta función en el laboratorio siguiente, así que no hay que limpiarla por ahora.

Laboratorio 3: Invocación de una función de Lambda desde otra

Paso 1: Crear la función GetS3Buckets

Complete el laboratorio anterior.

Paso 2: Crear una función de Lambda

En este paso, creará una función de Lambda para llamar a las funciones GetS3Buckets.

1. Crear un proyecto de Lambda vacío

Desde la línea de comandos, ejecute:

dotnet new lambda.EmptyFunction -n GetS3BucketsCallFromLambdaFunction

2. Cambiar de carpeta

Cambie al directorio GetS3BucketsCallFromLambdaFunction\src\GetS3BucketsCallFromLambdaFunction.

Paso 3: Actualizar el código

En este paso, actualizará el código del proyecto.

1. Agregar el paquete AWSSDK.Lambda

Agregar el paquete AWS SDK Lambda al proyecto:

dotnet add package AWSSDK.Lambda

2. Actualizar Function.cs

Abra el archivo Function.cs y sustituya el código por:

using Amazon.Lambda;
using Amazon.Lambda.Core;
using Amazon.Lambda.Model;
using System.Text.Json;
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace GetS3BucketsCallFromLambdaFunction;

public class Function
{
    
    public async Task<IEnumerable<string>> FunctionHandler(ILambdaContext context)
    {
        AmazonLambdaClient client = new AmazonLambdaClient();

        var request = new InvokeRequest
        {
            FunctionName = "GetS3Buckets",
        };

        var result = await client.InvokeAsync(request);

        var bucketNames = JsonSerializer.Deserialize<IEnumerable<string>>(result.Payload);

        return bucketNames;
    }
}

En este ejemplo, la función de Lambda GetS3BucketsCallFromLambdaFunction llama a la función GetS3Buckets y devuelve la respuesta sin modificarla.

Paso 4: Implementar la función GetS3BucketsCallFromLambdaFunction

En este paso, implementará la función de Lambda GetS3BucketsCallFromLambdaFunction en AWS.

1. Implementar la función

Desde la línea de comandos, ejecute:

dotnet lambda deploy-function GetS3BucketsCallFromLambdaFunction

2. Crear un rol

Cree un nuevo rol para la función denominada 

GetS3BucketsCallFromLambdaFunctionRole.

3. Adjuntar la política al rol

Adjunte la política AWSLambdaBasicExecutionRole al rol.

Paso 5: Intentar la invocación de la función GetS3BucketsCallFromLambdaFunction

En este paso, intentará invocar la función.

1. Implementar la función

Intente invocar GetS3BucketsCallFromLambdaFunctionRole:

dotnet lambda invoke-function --function-name GetS3BucketsCallFromLambdaFunction

Recibirá un error como el siguiente:

Payload:
{
  "errorType": "AmazonLambdaException",
  "errorMessage": "User: arn:aws:sts::000000000000:assumed-role/GetS3BucketsCallFromLambdaFunctionRole/GetS3BucketsCallFromLambdaFunction 
is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-east-1:000000000000:function:GetS3Buckets because no 
identity-based policy allows the lambda:InvokeFunction action",

Esto se debe a que GetS3BucketsCallFromLambdaFunction requiere permisos para invocar GetS3Buckets.

En el siguiente paso, agregará una política en línea que otorgue a GetS3BucketsCallFromLambdaFunction el permiso que necesita.

Paso 6: Otorgue permiso a GetS3BucketsCallFromLambdaFunction para invocar GetS3Buckets

En este paso, otorgará a GetS3BucketsCallFromLambdaFunction permisos para invocar GetS3Buckets.

1. Obtener el ARN de GetS3Buckets

Antes de poder conceder derechos de invocación a GetS3BucketsCallFromLambdaFunction, necesita obtener el nombre de recurso de Amazon (ARN) de GetS3Buckets.

Puede hacerlo de un par de maneras. Primero desde la Consola de AWS. Acceda al servicio Lambda y seleccione la función GetS3Buckets

Puede hacer clic en Copiar ARN desde las dos áreas resaltadas.

Para obtener el ARN de GetS3Buckets desde la línea de comandos, ejecute:

dotnet lambda get-function-config GetS3Buckets

Verá una salida similar a la siguiente:

Inicio del proyecto: https://github.com/aws/aws-extensions-for-dotnet-cli,

 https://github.com/aws/aws-lambda-dotnet

Name:                         GetS3Buckets
Arn:                          arn:aws:lambda:us-east-1:000000000000:function:GetS3Buckets
Package Type:                 Zip
Runtime:                      dotnet6
Function Handler:             GetS3Buckets::GetS3Buckets.Function::FunctionHandler
Last Modified:                2022-08-10T13:58:29.211+0000
Memory Size:                  256
Ephemeral Storage Size:       512
Role:                         arn:aws:iam::000000000000:role/GetS3Buckets
Timeout:                      30
Version:                      $LATEST
State:                        Active
Last Update Status:           Successful
KMS Key ARN:                  (default) aws/lambda

Mucha información útil, pero lo que busca está en la segunda línea de la tabla, el ARN.

Cree un archivo llamado InvokeGetS3Buckets.json y agregue lo siguiente:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action":[
                "lambda:InvokeFunction"
            ],
            "Resource": "arn:aws:lambda:us-east-1:000000000000:function:GetS3Buckets"
        }
    ]
}
Repl

Sustituya el “Recurso” por el ARN de la función de Lambda que obtuvo de la línea de comandos o de la interfaz de usuario de la consola.

2. Actualizar permisos

Ejecute lo siguiente:

aws iam put-role-policy --role-name GetS3BucketsCallFromLambdaFunctionRole
 --policy-name InvokeGetS3BucketsFunction 
 --policy-document file://InvokeGetS3Buckets.json

Los permisos pueden tardar unos minutos en actualizarse en AWS.

Paso 7: Invocar la función GetS3BucketsCallFromLambdaFunction nuevamente

En este paso, volverá a invocar la función.

1. Invocar la función con dotnet lambda invoke-function

Esta vez podrá invocar la función:

dotnet lambda invoke-function --function-name GetS3BucketsCallFromLambdaFunction

Conclusión

En estos laboratorios pone en práctica lo que aprendió. Primero creó una aplicación web a la que se puede acceder desde cualquier parte del mundo. A continuación, implementó una función de Lambda que invocó directamente desde un programa de C# en su computadora. Después, creó el segundo laboratorio implementando otra función de Lambda e invocando una función de Lambda desde otra. También tuvo que resolver los problemas de permisos a medida que surgían.

Desde aquí, puede experimentar con el uso de otros servicios de AWS con funciones de Lambda y crear aplicaciones Lambda más complejas.

¿Le resultó útil esta página?

Evaluación de habilidades