Cloud

Envio de SMS na AWS Usando Lambda & SNS

Olá, desenvolvedores, DevOps e SREs! Neste artigo, vou explicar de forma didática e clara como enviar um SMS utilizando o serviço SNS da AWS e uma função Lambda. Essa estratégia é útil para notificar equipes sobre eventos ou situações diversas que possam ocorrer em suas contas AWS, como um login inesperado ou um container offline.

Ao enviar um SMS, é mais provável que alguém da equipe tome conhecimento do incidente, especialmente quando comparado ao e-mail, que nem sempre é verificado com frequência. Além disso, essa abordagem pode ser adaptada para outros serviços e situações, expandindo as possibilidades de uso.

Em resumo, vamos aprender como:

  1. Utilizar o serviço SNS da AWS para enviar SMS;
  2. Integrar uma função Lambda para disparar a notificação;
  3. Aplicar essa estratégia em diferentes cenários e serviços.

Lembre-se: as possibilidades são amplas, e o céu é o limite para o uso dessa abordagem!

Neste artigo, vamos criar uma função Lambda utilizando a linguagem de programação Go, também conhecida como Golang, e integrá-la aos serviços de SMS e SNS da AWS para disparar mensagens. Ao longo deste texto, não entraremos em detalhes sobre o funcionamento do SNS ou do serviço de SMS da AWS, pois os utilizaremos de forma abstrata.

Em vez disso, focaremos no uso do SDK da AWS, que permitirá a comunicação com esses serviços por meio de nosso código. Assim, abordaremos os seguintes passos:

  1. Criar uma função Lambda em Go (Golang);
  2. Integrar a função com os serviços de SMS e SNS da AWS;
  3. Utilizar o SDK da AWS para estabelecer a comunicação entre o código e os serviços mencionados.

Dessa forma, você aprenderá como implementar esta solução de forma didática e eficiente.

O repositorio do código, com os arquivos como:

main.go / go.mod / go.sum

https://github.com/diillson/lambdaGo-AWS-SMSToSNS

   O código Lambda é o seguinte:  

Explanando um pouco do código:

Neste artigo, você aprenderá sobre a implementação de um código que utiliza uma biblioteca específica para gerar logs no formato JSON. A escolha desse formato permite exportar os logs do CloudWatch e integrá-los com diversas ferramentas, como Splunk, Elasticsearch com Kibana e Graylog, Datadog e outros.

O código é desenvolvido de forma enxuta e inclui o AwsRequestID, permitindo rastrear chamadas com o Xray na AWS, caso este recurso seja habilitado na sua função Lambda. Além disso, incluímos informações como nome da aplicação, arquivo executado, função/método e linha de execução para facilitar a rastreabilidade em caso de problemas. Com isso, os logs se tornam claros e fáceis de serem analisados durante um processo de solução de problemas.

Para controlar o StatusCode de saída e o conteúdo apresentado ao usuário, seja em casos de erro ou sucesso, criamos uma estrutura específica.

Ao iniciar a sessão com o serviço SNS, optamos por utilizar o parâmetro "session.NewSession()" em vez de "must". Isso evita um possível Panic na aplicação e permite um tratamento de erros mais adequado.

O código recebe como entrada o número de telefone e a mensagem a ser enviada, ambos fornecidos pelo usuário ou serviço. Esses parâmetros são totalmente personalizáveis.

Caso algum dos campos esteja em branco, o código gera uma exceção e retorna o erro para quem fez a chamada. Dessa forma, garantimos a integridade das informações fornecidas e a eficácia na comunicação.

Sobre o Input:  

   recebe como entrada um evento json como o seguinte:

{
 "queryStringParameters": {
   "phone_number": "+5511999999999",
   "message": "Teste de envio de SMS via AWS LambdaGOLANG e SNS!"
 }
}

Role/Policy no IAM  

   por fim, precisamos adicionar uma política IAM para permitir que a função Lambda crie seu loggroup e tenha permissão de se comunicar com o serviço de SMS e o SNS na aws.

Criamos uma Role com a seguinte relação de confiança:

{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Principal": {
               "Service": "lambda.amazonaws.com"
           },
           "Action": "sts:AssumeRole"
       }
   ]
}

E nela assoaciamos duas policys :

AWSLambdaBasicExecutionRole

AmazonSNSFullAccess

Para que não fosse necessário criar uma role personalizada para o SNS usamos a FullAccess, recomendo limitar e não usá-la em produção rs, sempre siga as boas praticas de menor privilégio.

Com tudo ajustado, o codigo em mãos, a role criada com as devidas policys, voce já consegue subir sua lambda na aws e testa-lá.

Subindo a Lambda na AWS:

após o clone do repo e com o código em seu pc, acessamos path, e rodamos os seguintes comandos.

OBS: Comandos mostrados aqui serão em sistema Linux/Unix/Darwin.

Para baixar todas as dependências:

$ go mod tidy

Depois que tudo ocorrer com sucesso vamos agora buildar a aplicação:

$ GOOS=linux go build -o main main.go

Logo deve gerar o executável "main" , precisamos zipa-lo para poder subir o mesmo no serviço de Lambda na AWS:
$ zip function.zip main

Com o pacote zipado, basta acessar o serviço de Lambda na AWS e criar uma lambda do zero/scratch com as seguintes Opções conforme a imagem abaixo.

Depois clique em Permissões e marque:

* Usar uma função existente - (aqui o que ele chama de função é a famosa role)

clique na box e escolha a role que criou anteriormente para uso na lambda com as policys associadas.

após isso basta clicar em "criar função"

vamos até o serviço de lambda e encontramos nossa função lambda.

selecione sua lambda, e agora iremos antes de subir o código, modificar o manipulador/handler, provavelmente estará como, "hello"

iremos modifica-lo para "main" basta clica na aba "Código" depois mais abaixo em "Configurações de tempo de execução" vamos clicar em editar e escrever main no logar de hello.

Após este passo já podemos subir o código que acabamos de criar o zip.

basta ir em "Origem do código" e clicar ao lado direto em "Fazer Upload", selecione o zip em sua computador.

deve ser entorno de 6.6MB o tamanho do zip, subirá bem rápido, logo após isso sua lambda estará pronta para funcionar.

Vamos testa-la?

Acesse a aba "Testar", clique em "Criar novo evento" marque ele como privado para que somente você tenha acesso.

em "JSON do Evento" coloque o seguinte JSON substituindo o numero pelo seu numero de telefone no mesmo padrão esperado pela lambda e adicione qualquer mensagem, após isso basta clicar no botão TESTAR em laranja para que ele dispare o SMS:

{
 "queryStringParameters": {
   "phone_number": "+5511999999999",
   "message": "Teste de envio de SMS via AWS LambdaGOLANG e SNS!"
 }
}

Vamos olhar o log como ficou ? 

Após fazer a chamada, se caso teve sucesso ficará em verde logo a cima, caso deu algum erro estará em vermelho.

Para ter maior assertividade podemos olhar o log do evento, acessando pelo cloudwatch.

Logo mais a cima após fazer a chamada verá algo parecido como na imagem.

você consegue acessar o log direto no cloudwatch clicando em "logs" logo a cima ao lado de "Resultado de exceção"

ou ver o log ai mesmo pouco mais abaixo em "Resultado de Saída do log", para que tenhamos uma melhor visão, vamos ao cloudwatch, teremos um log parecido com este da imagem abaixo acessando o loggroup que foi criado por sua lambda:

percebe que o log está totalmente em json com tudo que definimos anteriormente.

é isso galera, algo simples, porém de extrema importância no assunto de monitoramento e tomada de ação, seja para comunicar alguém do time, seja um grupo de pessoas, seja envio de algo que ocorreu em sua conta baseado em um evento, como mencionei no inicio do artigo, da para ser usado em vários casos.

espero que ajude no seu dia a dia.