Criando função AWS Lambda utilizando .Net Core
Processe um console window sem a necessidade de provisionar uma instância EC2
Afinal de contas, o que é o AWS Lambda?
Em poucas palavras, é um console window que processa um volume de informações, dentro de um servidor qualquer. E só.
Dá pra fazer bastante coisa num console window: processamento batch, bulk insert no sql, disparo de e-mails em massa, etc.
Por ser "apenas" um console window, a parte de servidor é abstraída. Isso significa que você não precisa se preocupar em configurar o Sistema Operacional, atualizações de segurança, patches, etc. Basta realizar o upload do executável.
Tudo isso denominado serverless
Essa facilidade serverless pode trazer outros problemas: é 15% mais lento e até 8x mais caro que uma instância EC2.
Entretanto, a vantagem é que não se paga por 720h mensais, mas sim pelo tempo de cada execução.
Se a sua necessidade é construir uma ferramenta de disparo de e-mails 5x no mês e cada execução demora 5 minutos, não pense 2x em utilizá-lo! Sai bem mais barato que reservar uma instância EC2 para um processo tão simples.
Histórias a parte, vamos ao que interessa! Iremos construir uma função ASW Lambda em .Net Core :-)
1. Criando a função na AWS
Acesse o console AWS https://console.aws.amazon.com/ , Lambda, Funções.
Clique no botão Criar Função.

Selecione a opção Criar do Zero...

Nome da função: minhaFuncao
Tempo de execução: .NET Core 3.1

Em Permissões, marque a opção Criar uma função com permissões básicas do Lambda. Clique no botão Criar função.

Por fim a função é criada.

No Visual Studio, crie um Projeto vazio do tipo Console Window, na linguagem .Net Core 3.1.
Program.cs:
using Amazon.Lambda.Core;
using System;
using System.Collections;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using System.IO;
using System.Net;
namespace ConsoleLambda
{
public class Program
{
public static IConfigurationRoot Configuration;
public static IConfiguration configuration { get; private set; }
/// <summary>
/// Este método só será executado durante o Debug.
/// Não será invocado via execução AWS Lambda
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Console.WriteLine("Main!");
Program instancia = new Program();
LambdaContext lambda = new LambdaContext();
instancia.Handler(lambda);
}
private void ConfigureSettings()
{
Configuration = new ConfigurationBuilder()
.SetBasePath(System.IO.Directory
.GetParent(AppContext.BaseDirectory).FullName)
.AddJsonFile("appsettings.json", optional: true)
.Build();
// Não esqueça de habilitar a opção
// "Copiar diretório de saída" para o arquivo appsettings.json,
// caso contrário, Configuration sempre será NULL
}
public async Task Handler(ILambdaContext context)
{
this.ConfigureSettings();
StringBuilder sb = new StringBuilder();
sb.AppendLine("Hello World! My name is Lambda ;-)");
sb.AppendLine("");
sb.AppendLine("Variaveis de ambiente:");
foreach (DictionaryEntry de in Environment.
GetEnvironmentVariables())
sb.AppendLine(de.Key + " = " + de.Value);
sb.AppendLine("========================");
sb.AppendLine("ILambdaContext:");
sb.AppendLine("FunctionName: " + context.FunctionName);
sb.AppendLine("RemainingTime: " + context.RemainingTime);
sb.AppendLine("AwsRequestId: " + context.AwsRequestId);
sb.AppendLine("FunctionVersion: " + context.FunctionVersion);
sb.AppendLine("InvokedFunctionArn: " + context.InvokedFunctionArn);
sb.AppendLine("LogGroupName: " + context.LogGroupName);
sb.AppendLine("LogStreamName: " + context.LogStreamName);
sb.AppendLine("MemoryLimitInMB: " + context.MemoryLimitInMB);
sb.AppendLine("null: " + null);
sb.AppendLine("========================");
sb.AppendLine("appsettings:");
sb.AppendLine("Versao: " + Configuration["versao"].ToString());
sb.AppendLine("Autor: " + Configuration["autor"].ToString());
Console.WriteLine(sb.ToString());
// Testando requisições internet (teste de firewall)
var requisicaoWeb = WebRequest.CreateHttp("https://www.leobreda.net/");
requisicaoWeb.Method = "GET";
using (var resposta = requisicaoWeb.GetResponse())
{
var streamDados = resposta.GetResponseStream();
StreamReader reader = new StreamReader(streamDados);
object objResponse = reader.ReadToEnd();
Console.WriteLine(objResponse.ToString());
Console.ReadLine();
streamDados.Close();
resposta.Close();
}
}
}
}
LambdaContext.cs (necessário para executar localmente o console window):
using Amazon.Lambda.Core;
using System;
namespace ConsoleLambda
{
public class LambdaContext : ILambdaContext
{
public string AwsRequestId => null;
public IClientContext ClientContext => null;
public string FunctionName => null;
public string FunctionVersion => null;
public ICognitoIdentity Identity => null;
public string InvokedFunctionArn => null;
public ILambdaLogger Logger => null;
public string LogGroupName => null;
public string LogStreamName => null;
public int MemoryLimitInMB => 0;
public TimeSpan RemainingTime => new DateTime().TimeOfDay;
}
}
appsettings.json (arquivo de configuração do console window):
{
"versao": "2020.10.20.a",
"autor": "Leonardo Breda"
}
NuGet:
Amazon.Lambda.Core Microsoft.Extensions.Configuration Microsoft.Extensions.Configuration.FileExtensions Microsoft.Extensions.Configuration.Json
Execute o console em debug para verificar se rodou com sucesso.

Faça a publicação do projeto...

Configuração: Release
Estrutura de destino: netcoreapp3.1
Tempo de execução de destino: linux-x64
Clique em publicar.

Vá até o diretório de destino e compacte todos os arquivos num único ZIP.

Volte até a função Lambda no console AWS. Em código da função, faça o upload do arquivo ZIP.

Na aba Permissões, Papel de execução, clique em Editar.

No campo manipulador, adote a seguinte nomenclatura:
Assembly::Namespace.Classe::Metodo
Clique em salvar.

Clique no botão Testar. Caso não tenha um teste associado, crie conforme a figura abaixo.

Clique novamente no botão Testar, onde deverá processar a função com sucesso .

No quadro resumo, é possível identificar o tempo de execução e memória RAM consumida.

No CloudWatch, é possível ver toda a saída produzida pelo console window.

E assim concluímos um aprendizado básico do AWS Lambda.