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
1. Crear un proyecto de .NET sin servidor
dotnet new serverless.AspNetCoreWebApp -n AspNetCoreWebApp
Paso 2: Hacer algunos cambios en el 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
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>
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
Abra el archivo serverless.template.
Busque la clave “Handler” y, en la siguiente línea, agregue:
"Architectures": ["arm64"],
"AspNetCoreFunction": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Handler": "AspNetCoreWebApp::AspNetCoreWebApp.LambdaEntryPoint::FunctionHandlerAsync",
"Architectures": ["arm64"],
Paso 4: Implementar la función
dotnet lambda deploy-serverless --stack-name AspNetCoreWebApp --s3-bucket your-unique-bucket-name1234
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/
Paso 5: Eliminar los recursos
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
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.