Redução de Custos AWS com Lambda e CloudWatch

Tutorial passo a passo para automatizar o start e stop de instâncias EC2 na AWS usando Lambda, Tags e CloudWatch, com economia de até 55% nos custos.

Cloud AWS · Publicado em 04 de maio de 2019 · Por Dan Rezende · 12 min de leitura

Não é de hoje que estas duas expressões agradam os ouvidos e faz brilhar os olhos dos profissionais de T.I, principalmente dos C-Leveis das organizações.

É uma verdade extrema dizer que as palavras de ordem do momento são: automação e redução de custo. Fazer mais com menos, otimizar ao máximo, enxugar recursos, e por aí vai.

Por isso, hoje vou compartilhar com vocês uma dica bem simples, mas que tem auxiliado meus clientes a obterem bons resultados e diminuir os custos com instâncias (servidores) na AWS. Tem ajudado também a otimizar o trabalho e reduzir hora homem executando atividades simples como ligar ou desligar instâncias na AWS.

Sei que podemos encontrar inúmeras ferramentas no mercado que possuem essa mesma funcionalidade, porém, tratando-se de economia, as ferramentas nativas da AWS, além de possuir uma implementação fácil, também são mais acessíveis. Elas dispõem de um período de Free Tier (uso gratuito) generoso, sem elevar os custos.

É possível utilizar estes recursos e economizar bastante. Várias organizações tem seus ambientes de DEV, QA, e as vezes até mesmo alguns ambientes de PRD que podem ser desligados durante a noite e aos finais de semana, isso no fim do mês pode fazer uma diferença enorme em sua fatura da AWS.

Vamos fazer uma conta básica?

Imaginem uma única instância, na região da Virginia, com Linux, do tamanho m5.xlarge, onde o valor estimado é de $140,55 por mês.

Considerando que ela fique ligada 24h por dia, cerca de 732 horas mês.

Essa mesma instância é utilizada apenas no horário comercial, que é o que acontece geralmente com os ambientes de DEV e QA, de segunda a sexta-feira, das 07h:00 ás 19h:00, em média 21 dias úteis por mês, teremos um total de 399 horas.

Sendo bem conservador, ligando o ambiente às 07h:00 e desligando às 19h:00, dependendo do ritmo da empresa é possível encurtar ainda mais essa janela.

Considerando essas 399 horas, pagaríamos no mês por esta mesma instância, o valor de $76,61. Que representa uma economia de -$63,94 ao mês.

Lembre-se, estamos falando apenas de 1 instância. O seu parque de máquinas pode ter várias instâncias nessa mesma situação e com oportunidade de redução.

Comparação de custos entre instância ligada 24h e apenas no horário comercial

Estamos falando de uma redução na casa dos 55%.

A conta fica ainda mais interessante se fizermos os $63,94 x 12 meses = $767,28.

Se convertermos para R$ (Real), temos $767,28 x R$4,00 = R$3.049,12.

Essa é uma simulação de uma conta básica, onde consideramos apenas uma instância pequena. Se pensarmos em um ambiente de ERP SAP, que utiliza instâncias x1, essa conta fica astronômica e a redução vai para a casa de milhares de reais durante o ano, o mesmo pode acontecer em ambientes que utilizaram várias instancias menores (t2, t3, m3, m4, m5, c3, c4, c5) para DEV e QA, a economia pode ser bem interessante.

Bacana Dan, você me convenceu! Ligar e desligar meu ambiente de DEV e QA pode me render uma boa economia, mas como eu implemento isso?

Tenho duas alternativas para te indicar:

É isso que eu vou te mostrar logo mais. Ensino como fazer de forma simples, fácil e rápida. Apenas 20 minutos são suficientes para que você faça essa configuração.

Explicando os serviços utilizados

Lambda - O AWS Lambda faz a execução de códigos sem a necessidade de ter um servidor, ele é um serviço Serverless. Neste exemplo usaremos o Lambda para executar um código em Python que faz a ação de ligar ou desligar instâncias EC2.

TAG de Instancia EC2 - O próprio nome já diz, são TAGs que usamos para marcar ou identificar nossas instâncias. O EC2 por sua vez é o serviço de capacidade computacional da AWS, é equivalente as VMs antigas, na AWS chamamos de instancias. Neste exemplo usaremos as TAGs para identificar as instâncias que precisam ser ligadas e ou desligadas.

AWS CloudWatch - É a ferramenta da AWS responsável por apoiar no monitoramento e gerenciamento dos recursos e serviços utilizados, neste exemplo ele será utilizado para realizar ações baseados em eventos pré-determinados.

Como essa solução funciona?

Usaremos o Lambda para rodar um código em Python que lista as instâncias EC2 rodando em nossa conta, (na região em que a Lambda foi implementada). Nessa lista de instâncias o código verifica as Tags das instâncias e compara com os valores de Tags que precisamos inserir no código.

De forma simplificada podemos dizer que TAG = LIGAR e VALOR = 7 HORAS.

Se a instância atender os requisitos de TAG e VALOR, ou seja, se as tags forem iguais ao que foi informado no código, a função em Python do Lambda executa uma determinada ação, que pode ser um Start ou Stop de uma ou mais instâncias.

Até o momento usamos as Tags da EC2 onde pretendemos automatizar a tarefa de ligar ou desligar a instância, e o Lambda para executar o código que faz o papel de liga e desliga.

Agora precisamos automatizar, para que esse código seja executado em horários pré-estabelecidos. Neste exemplo vamos trabalhar com o horário de ligar às 07h:00 e o de desligar será às 19h:00. Vamos usar o AWS CloudWatch para criar essa Regra de agendamento, e nos horários determinados ele vai executar o Lambda.

Agora que expliquei a teoria, vamos à prática?

1- Acesse a console da sua conta AWS;

Lembre-se de selecionar a região onde estão as suas instâncias EC2.

2- Acesse o serviço de IAM;

Vamos criar a autorização necessária para que a nossa função Lambda possa ligar e desligar suas instancias EC2.

Console AWS — acessando o serviço IAM

3- Do lado esquerdo, clique em "Funções", em seguida em "Criar Função";

IAM — menu Funções e botão Criar Função

4- Na tela de criar função, escolha o serviço de Lambda, em seguida clique em "Próximo: Permissões";

Criação de função IAM — selecionando serviço Lambda

5- Clique em "Criar política";

Tela de permissões — botão Criar política

6- Na tela de Criar política, clique na guia "JSON";

Criar política — guia JSON selecionada

7- Apague o conteúdo existente, e cole este código que vou disponibilizar no GitHub;

Para facilitar a visualização dos códigos JSON e Python necessários durante este tutorial, acesse o projeto no GitHub pelo link: https://github.com/drezende/aws-lambda-start-stop

Este código contem as permissões necessárias para que nossa função Lambda execute.

Política JSON com permissões para EC2 e CloudWatch Logs

8- Revise a política, insira um nome e a descrição para sua política, sugiro usar o nome: start-stop-instancias-ec2 para facilitar o acompanhamento do tutorial, em seguida clique em "Criar política";

Revisão da política — nome e descrição preenchidos

9- Veja que ao criar a política, você recebe uma notificação na tela:

Notificação de política criada com sucesso

Neste momento, você deve fechar a guia que foi aberta em seu navegador para criar a política, e continuar na guia que ficou aberta para criar a função.

10- Na tela de criação da função, faça o refresh da tela;

Em seguida pesquise o nome da política que você acabou de criar;

Selecione a política e clique em "Próximo: Tags";

Selecionando a política start-stop-instancias-ec2 na criação da função

11- Na tela de TAGs da função, você pode ignorar e clicar em "Próximo: Revisar".

Mesmo sabendo que iremos utilizar as TAGs para identificar as instâncias a serem ligadas e desligas, este ainda não é o momento de utilizá-las.

Tela de TAGs da função IAM — pular para revisão

12- Nesta última etapa, defina um nome para sua função;

Você pode usar o mesmo nome da política, sugiro usar por exemplo: start-stop-instances-ec2

Definindo nome da função IAM — start-stop-instances-ec2

Pronto, a parte do IAM, para criar as autorizações foi concluída.

13- Acesse o serviço Lambda:

Console AWS — acessando o serviço Lambda

14- Clique em "Create Function";

Essa tela pode mudar caso você já tenha alguma Lambda criada, procure pelo botão "Create Function" ou "Criar função".

Lambda — botão Create Function
Lambda — tela de criação de função

15- Preencha as informações para criar sua função Lambda;

Selecione criar do zero; dê um nome para a função; selecione o Runtime como Python 3.6. Em seguida clique em "Escolher ou criar uma função de execução" para inserir a política criada anteriormente.

Preenchendo informações da função Lambda — nome e runtime Python 3.6

16- Termine de preencher escolhendo "utilizar função existente", e marcando a função que criou anteriormente no IAM, como na imagem abaixo:

Selecionando função de execução existente do IAM

17- Essa é a tela que será exibida após criação:

Tela da função Lambda após criação

18- Role a tela para baixo, até o código da função;

Certifique-se de que sua tela esteja configurada como no exemplo abaixo:

Editor de código da função Lambda

19- Cole o código abaixo, substituindo o código de exemplo;

Copie o código do GitHub: lambda-start-instances.py

20- Após colar o código, role para cima e clique em SALVAR.

Sempre SALVE suas alterações!

Botão Salvar após colar o código Python na Lambda

21- Explicando o código da função Lambda:

Este é um pequeno código em Python, ele procura por instâncias que estão no estado (modo) desligado (stopped), que tenham a TAG: LIGAR com VALOR: 07HORAS.

Se ele encontrar instâncias que preencham estes requisitos, a função dá um start na instância.

Veja onde estão configurado esses valores:

Código Python destacando TAG LIGAR e VALOR 07HORAS

22- Role para baixo e termine de configurar sua Lambda.

Não precisamos configurar variáveis de ambiente e Tags neste momento, a função de execução já estará configurada com a função de start-stop.

Do lado direito em "Configurações básicas" aumente o tempo limite para 5 minutos.

Configurações básicas da Lambda — timeout de 5 minutos

23- Vamos testar nosso código?

Role a tela para o início da página;

Clique ao lado do botão de teste na seta, em seguida selecione "Configurar eventos de teste";

Menu para configurar eventos de teste na Lambda

24- Apenas dê um nome para o teste. Exemplo: teste1

Não é necessário alterar nada mais, e podemos clicar em "Criar".

Configurando evento de teste — nome teste1

25- Antes de testar, vamos preparar a instancia EC2 com as TAGs para validar a execução da Lambda, acesse o serviço EC2;

Console AWS — acessando o serviço EC2

26- Clique em "Instancias";

EC2 — menu Instâncias

27- Filtre a instância que deseja fazer o teste;

Neste exemplo filtrei a instância: teste-automação-lambda.

Filtrando instância EC2 para teste de automação

28- Com a instância selecionada na console, clique na Guia de Tags;

Insira a TAG conforme na imagem; TAG: LIGAR / VALOR: 07HORAS

Salve

Adicionando TAG LIGAR com valor 07HORAS na instância EC2

29- Volte ao serviço do Lambda, acesse a função que criamos, e vamos rodar o teste.

Voltando à função Lambda para executar o teste

30- Rode o teste e veja o resultado:

Resultado do teste da Lambda — execução com sucesso

O log indica que o seu código foi executado com sucesso.

31- Volte a sua EC2, e veja se ela está iniciando:

Instância EC2 iniciando após execução da Lambda

Sucesso, Instância iniciada!

32- Para o processo de desligar a instância, o Stop é feito da mesma forma, repetimos o processo:

Criamos um Lambda; configuramos a permissão; aumentamos o time-out e definimos as TAGs.

Geralmente eu gosto de utilizar: TAG: DESLIGAR VALOR: 19HORAS

33- Este é o código de exemplo para criar a Lambda de Stop:

Copie o código do GitHub: lambda-stop-instances.py

34- Acesse a Home do serviço Lambda e você verá as duas funções criadas:

Home do Lambda com duas funções — start e stop

35- Agora que temos uma Lambda que liga as instâncias, e uma Lambda que desliga as instâncias, precisamos acessar o CloudWatch para configurar a periodicidade com que será executado.

Tenha em mente que a mesma função pode ligar ou desligar várias instâncias de uma só vez, basta que você insira as TAGs nas instâncias.

Esse trabalho inicial pode parecer longo e complicado, mais o interessante é que uma vez configurado, basta manipular as TAGs e inserir ou remover instâncias no processo automático de start-stop.

Outro detalhe é que no CloudWatch é possível configurar uma expressão no formato CRON. Onde vamos dizer que ele deve executar uma função Lambda de segunda a sexta-feira, ás 07h:00 para ligar, e outra às 19h:00 que executa a Lambda que desliga as instâncias.

O CloudWatch usa o padrão de hora UTC-0.

Quer dizer que se você está em São Paulo, por exemplo, o horário é UTC-3, é preciso considerar essas 3 horas de diferença na hora de configurar o CloudWatch.

Exemplo: O evento que liga as instâncias não será configurado para rodar as 07h:00 e sim às 10h:00. Considerando essa diferença do Time-Zone, o mesmo ocorre para o evento de desligar.

36- Acesse o CloudWatch:

Console AWS — acessando o serviço CloudWatch

37- Clique em "Regras", em seguida "Criar regra";

CloudWatch — menu Regras e botão Criar regra

38- Veja a primeira etapa de configuração da Regra do CloudWatch:

Em "Origem do evento", marque "Programação";

Selecione a "Expressão Cron". No exemplo: 01 10 ? * MON-FRI *

Veja como ficou preenchido:

Configuração da regra CloudWatch — expressão CRON para segunda a sexta

39- Ainda nessa etapa, do lado direito, clique em "Adicionar destino";

É aqui que vamos dizer ao CloudWatch que nesses dias e horários definidos na expressão CRON ele deve chamar a execução da Lambda que criamos.

Confira na imagem:

Adicionando destino na regra do CloudWatch — função Lambda

40- Preencha com a Lambda de Start ou Stop.

O exemplo abaixo mostra a configuração selecionando a Lambda de Start no campo da Função;

Selecionando a função Lambda de Start como destino

41- Defina um nome para sua regra do CloudWatch, em seguida faça uma descrição e marque para que ela esteja habilitada. Depois clique em "Criar regra";

Definindo nome e descrição da regra do CloudWatch

42- Repita o processo, para ter uma CRON que chame a função de desligar as instâncias.

A sugestão de usar a cron: 00 22 ? * MON-FRI *

Dessa forma vai rodar a REGRA de desligar as 19h, considerando o time-zone.

43- Clique nas regras do CloudWatch e você deve ver suas 2 regras de start e stop configuradas.

Lembre-se que cada regra deve chamar a lambda específica, que liga ou desliga as instâncias;

CloudWatch — duas regras configuradas para start e stop

Parece um pouco extenso, mas é bem simples e tranquilo de ser implementado. Pode ajudar bastante a automação e redução de custos em seu ambiente.

Espero que tenha contribuído, que isso te faça pensar mais sobre como podemos automatizar e otimizar tarefas do dia a dia.

Fiquem à vontade para fazer sugestões de melhorias para este processo, ficaria feliz em ouvir e discutir mais a respeito.

Caso você tenha interesse sobre o assunto de AWS, te convido a conhecer o meu Curso focado na certificação AWS Certified Solutions Architect Associate.

Tenho turmas presenciais agendada em Goiânia, São Paulo, Brasília e Belo Horizonte.

Abraço!