Demo: Desarrollo de funciones AWS Lambda con .NET Core
Switch branches/tags
Nothing to show
Clone or download
Latest commit d862131 Nov 10, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
img api gateway Nov 9, 2018
README.md slack url Nov 10, 2018

README.md

AWS Lambda y .NET Core.

Instrucciones para el workshop "Desarrollo de funciones AWS Lambda con .NET Core", presentado en la .NET Conf CO v2018, entre el 8 y el 10 de noviembre de 2018.

Speakers:

Requisitos:

Introducción

En la primera parte del workshop aprenderá a crear y desplegar una función lambda desarrollada con .NET Core. Y en la segunda aprenderá a crear otra lambda que recibe el resultado de la primera desde una cola o queue y lo envía a un servicio externo.

Configuración

  1. Ingrese al sitio AWS Identity and Access Management (IAM).

  2. Agregue un usuario con tipo de acceso Programmatic access.

    Image

  3. Asigne la política AdministratorAccess o PowerUserAccess. Para este demo, recomendamos la de administrador.

    Image

  4. Descargue el .csv con las credenciales y configure Visual Studio. Puede usar el ayudante que aparece cuando instala el toolkit o desde el menú View, AWS Explorer.

    Image

Primera parte

Lambda que cuenta las palabras de una cadena de texto.

  1. Desde File, New, Project, cree un nuevo proyecto de tipo AWS Lambda Project with Tests (.NET Core). Use la plantilla Empty Function.

    Image

  2. Explore los archivos aws-lambda-tools-defaults.json y Function.cs.

  3. Agregue pruebas unitarias para la función. Es muy importante usar TDD en el desarrollo de lambdas.

    using Xunit;
    using Amazon.Lambda.TestUtilities;
    
    namespace WordCount.Tests
    {
        public class FunctionTest
        {
            [Fact]
            public void TestCountFunction()
            {
                var function = new Function();
                var context = new TestLambdaContext();
    
                var cases = new [] {
                    ("hello world", 2),
                    ("hello .NET Conf CO v2018!", 5),
                    ("We invite you to the\nXamarin Cali Meetup", 8),
                    (null, 0),
                    (" hello   world ", 2),
                    ("   ", 0),
                    ("", 0)
                };
    
                foreach (var (input, expected) in cases)
                {
                    var count = function.FunctionHandler(input, context);
                    Assert.Equal(expected, count);
                }
            }
        }
    }
  4. Escriba una función que reciba como parámetro un string y cuente las palabras. El siguiente código se basa en el ejemplo Word Count de Visual Studio Code.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using System.Text.RegularExpressions;
    
    using Amazon.Lambda.Core;
    
    // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
    [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]
    
    namespace WordCount
    {
        public class Function
        {
    
            /// <summary>
            /// A simple function that takes a string and counts its words
            /// </summary>
            /// <param name="input"></param>
            /// <param name="context"></param>
            /// <returns>Word count</returns>
            public int FunctionHandler(string input, ILambdaContext context)
            {
                if (input == null)
                {
                    return 0;
                }
    
                var content = input;
    
                content = Regex.Replace(content, @"(< ([^>]+)<)", "");
                content = Regex.Replace(content, @"\s+", " ");
                content = Regex.Replace(content, @"^\s\s*", "");
                content = Regex.Replace(content, @"\s\s*$", "");
    
                if (content == "")
                {
                    return 0;
                }
                else
                {
                    return content.Split(" ").Length;
                }
            }
        }
    }
  5. Ejecute los tests desde el menú Test, Run, All Tests.

  6. Despliegue la función usando la opción Publish to AWS Lambda que aparece el menú contextual del proyecto (click derecho); use el rol AWSLambdaFullAccess. Si no encuentra el rol, es probable que deba agregar la política AdministratorAccess, como recomendamos en el punto 3 de la sección de configuración.

    Image

  7. Después de desplegar la función, es probable que haya cambiado el archivo aws-lambda-tools-defaults.json. Explore los cambios.

  8. Use el AWS Explorer (menú View, AWS Explorer) para probar la función.

    Image

Segunda parte

Enviar el resultado a una cola de Amazon SQS.

  1. Modifique la función y el test para que la lógica de negocios quede aislada del handler. En este ejercicio no vamos a crear clases adicionales, pero eso es lo ideal.

    public int FunctionHandler(string input, ILambdaContext context)
    {
        var result = CountWords(input);
        return result;
    }
    
    public int CountWords(string input)
    {
        if (input == null)
        {
            return 0;
        }
    
        var content = input;
    
        content = Regex.Replace(content, @"(< ([^>]+)<)", "");
        content = Regex.Replace(content, @"\s+", " ");
        content = Regex.Replace(content, @"^\s\s*", "");
        content = Regex.Replace(content, @"\s\s*$", "");
    
        if (content == "")
        {
            return 0;
        }
        else
        {
            return content.Split(" ").Length;
        }
    }
    [Fact]
    public void TestCountFunction()
    {
        var function = new Function();
    
        var cases = new [] {
            ("Hello World", 2),
            ("Hello .NET Conf CO v2018!", 5),
            ("We invite you to the\nXamarin Cali Meetup", 8),
            (null, 0),
            (" Hello   World ", 2),
            ("   ", 0),
            ("", 0)
        };
    
        foreach (var (input, expected) in cases)
        {
            var count = function.CountWords(input);
            Assert.Equal(expected, count);
        }
    }
  2. Desde el AWS Explorer, cree una SQS.

    Image

  3. Usando Nuget, agregue el paquete AWSSDK.SQS.

  4. Importe las dependencias de SQS y modifique el handler para enviar el resultado a la cola. Note el uso de las variables de entorno SERVICE_URL y RESULT_QUEUE.

    using Amazon.SQS;
    using Amazon.SQS.Model;
    public async Task<int> FunctionHandler(string input, ILambdaContext context)
    {
        var result = CountWords(input);
    
        var serviceUrl = Environment.GetEnvironmentVariable("SERVICE_URL");
        var queueUrl = Environment.GetEnvironmentVariable("RESULT_QUEUE");
    
        var sqsConfig = new AmazonSQSConfig() { ServiceURL = serviceUrl };
        var sqsClient = new AmazonSQSClient(sqsConfig);
    
        var message = result.ToString();
        var request = new SendMessageRequest(queueUrl, message);
        var sendMessageResponse = await sqsClient.SendMessageAsync(request);
    
        return result;
    }
  5. Despliegue la lambda, teniendo en cuenta que debe agregar las variables de entorno con los datos de la SQS. Usar variables de entorno ayuda a desacoplar el ambiente de desarrollo del de producción. Además, facilita los cambios en el flujo de la aplicación.

    Image

  6. Pruebe la lambda y observe el estado de la cola en el AWS Explorer.

    Image

Usar otra lambda para leer el resultado de la cola.

  1. Agregue otro proyecto de tipo AWS Lambda Project with Tests (.NET Core), pero use la plantilla Simple SQS Function. Recomendamos el nombre PushToSlack.

  2. Despliegue la función.

  3. Desde el AWS Explorer, configure las fuentes de eventos (Event Sources) de la función y agregue la SQS. Visual Studio le ayudará a agregar la política de lectura de SQS para la lambda.

    Image

  4. Ejecute la función WordCount y luego revise los logs de PushToSlack. Verá que la salida de la primera función es ahora la entrada de la segunda, a través de la cola.

    Image

Reto

Modifique la segunda función para que publique el número de palabras en un canal de Slack. Use la siguiente Webhook URL.

https://hooks.slack.com/services/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

Este es un ejemplo del mensaje JSON que debe enviar al Webhook.

{
    "text": "Hola desde C#",
    "attachments": [
        {
            "title": "Autor",
            "text": "Manuel Zapata"
        },
        {
            "title": "Número de palabras",
            "text": "5"
        }
    ]
}

Bonus: API Gateway

Desde la consola de AWS, busque el servicio API Gateway, que permitirá abstraer el conjunto de funciones, generar SDKs para clientes, administrar cargas de trabajo, etc.

  1. Cree un nuevo API.

    Image

  2. Explore el menú de acciones.

    Image

  3. Cree un nuevo recurso /wordcount dentro del API.

    Image

  4. Cree un método POST asociado al recurso, que apunte a la primera función; obtenga el ARN desde la consola de AWS.

    Image

  5. Pruebe el API desde la consola de AWS.

    Image

    Image

  6. Despliegue el API y realice pruebas desde distintos clientes.