1. Introdução
Em muitos ambientes corporativos, é comum manter instâncias ligadas mesmo durante períodos em que não estão sendo utilizadas. Em ambientes de desenvolvimento, homologação e testes, por exemplo, muitas instâncias EC2 permanecem em execução fora do horário comercial, gerando custos mesmo sem demanda. Uma alternativa simples para reduzir esse desperdício é automatizar o start/stop das máquinas, definindo horários para ligar e desligar de acordo com a necessidade do ambiente.
Neste artigo, será apresentada uma arquitetura na AWS, utilizando os serviços EC2, EventBridge, Lambda (o código será em Python), IAM e CloudWatch Logs para automatizar esse processo. A solução também utiliza tags para identificar quais recursos devem participar da automação. Além de reduzir custos, a automação ajuda a evitar processos manuais e cria um padrão para o gerenciamento de ambientes que não precisam permanecer ativos 24h por dia.
Abaixo, arquitetura da solução:
2. Serviços utilizados na arquitetura
2.1 Amazon EC2
O Amazon EC2 oferece as máquinas virtuais (instâncias) que a automação vai ligar e desligar. Para dizer à automação quais instâncias devem participar, será utilizada uma tag, que é uma etiqueta formada por uma chave e um valor.
Por exemplo:
tag_key = "lambda-start-stop" tag_value = "true" Assim, a função Lambda pode buscar somente as instâncias que possuem essa tag.
Documentação: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html
Documentação: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Instances.html
--
2.2 Amazon EventBridge
Responsável por definir quando a automação será executada. O EventBridge Scheduler chama a função Lambda no horário configurado.
Exemplo comum nas empresas:
- 08h00 - ligar as instâncias
- 18h00 - desligar as instâncias
Documentação: https://docs.aws.amazon.com/scheduler/latest/UserGuide/what-is-scheduler.html
--
2.3 AWS Lambda
É responsável por executar o código da automação, sem a necessidade de gerenciar servidores. Neste caso, a função roda um código em Python que usa o boto3 (o SDK da AWS para Python) para:
- Procurar as instâncias com a tag lambda-start-stop = true
- Executar a ação de start ou stop, conforme o horário que disparou a função.
Documentação: https://docs.aws.amazon.com/lambda/latest/dg/welcome.html
--
2.4 IAM Role
Define quais permissões a Lambda possui. Por exemplo, a função pode receber permissão para:
- Iniciar instâncias EC2
- Parar instâncias EC2
- Consultar informações das instâncias
- Enviar logs para o CloudWatch
Documentação: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html
--
2.5 Amazon CloudWatch
O CloudWatch guarda os logs de cada execução da Lambda. A Lambda envia esses logs automaticamente, desde que a role tenha as permissões adequadas. Os logs podem mostrar:
- Quando a função foi executada
- Status das instâncias encontradas
- Quais ações foram realizadas
- Possíveis erros durante a execução
Documentação: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html
3. Implementação
3.1 Criação da IAM policy
Para que a Lambda consiga ligar e desligar as instâncias, é necessário criar no IAM uma policy com as permissões necessárias e uma role (função de execução) que será associada à Lambda. A policy deve permitir que a Lambda chame as ações da API do EC2 para consultar, iniciar e parar instâncias, além de enviar os logs para o CloudWatch.
1.Na barra de pesquisa, procurar por “IAM” e acessar o serviço:
2.Após acessar o IAM, clicar em “Policies” e “Create policy” para criar uma nova política:
3.Ao abrir a tela de criação, clicar em “JSON”, inserir o código abaixo e clicar em “Next” para dar continuidade:
Essa política define o que a função Lambda está autorizada a fazer. Neste caso, ela permite que a Lambda registre logs no CloudWatch e consulte, inicie e pare instâncias EC2.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:*" }, { "Effect": "Allow", "Action": [ "ec2:Start*", "ec2:Stop*", "ec2:Describe*" ], "Resource": "*" } ] } 4.Em seguida, revisar e clicar em “Create policy”:
5.A política foi criada com sucesso:
--
3.2 Criação da IAM role
1.Acessar a aba “Roles” e clicar em “Create role”:
2.Em seguida, selecionar o serviço “Lambda”, caso de uso e clicar em “Next”:
3.Na próxima tela, pesquisar e selecionar a política “ec2-start-stop-policy” criada anteriormente e clicar em “Next”:
4.Em seguida, definir um nome para a role, revisar e clicar em “Create role”, para criar a “ec2-start-stop-role”:
5.A role foi criada com sucesso:

--
3.3 Criação da função Lambda
1.Na barra de pesquisa, procurar por “Lambda” e acessar o serviço:
2.Em seguida, clicar em “Create a function”:
3.Na próxima tela, definir um nome para as duas funções (ec2-start e ec2-stop), selecionar “Python”, que será a linguagem de programação utilizada na automação e clicar em “Create funcion”:
4.O Timeout define o tempo máximo que a função Lambda pode permanecer em execução. O valor padrão é de 3 segundos, mas pode ser alterado conforme a necessidade da aplicação. Para essa automação, será utilizado um timeout de 30 segundos, proporcionando tempo suficiente para consultar e executar as operações nas instâncias EC2.
- Além do timeout, também será necessário selecionar a role que foi criada “ec2-start-stop-role”. Esses procedimentos deverão ser realizados tanto na Lambda “ec2-start” quanto na “ec2-stop”:
5.Agora, podemos inserir o código na função criada “ec2-start” e clicar em “Deploy”:
Código Python “ec2-start”:
import json import boto3 import logging logger = logging.getLogger() logger.setLevel(logging.INFO) def lambda_handler(event, context): region = 'us-east-1' client = boto3.client('ec2', region_name=region) tag_key = "lambda-start-stop" tag_value = "true" try: response = client.describe_instances( Filters=[ { 'Name': f'tag:{tag_key}', 'Values': [tag_value] }, ] ) for reservation in response['Reservations']: for instance in reservation['Instances']: instanceId = instance['InstanceId'] state = instance['State']['Name'] logger.info(f"Instance ID: {instanceId} - State: {state}") if state == 'stopped': logger.info(f"Starting instance {instanceId}") client.start_instances(InstanceIds=[instanceId]) else: logger.info(f"Instance {instanceId} is not in 'stopped' state, current state: {state}") except Exception as e: logger.error(f"Error managing EC2 instances: {str(e)}") raise return { 'statusCode': 200, 'body': 'Start script executed successfully' } 6.Em seguida, podemos fazer o mesmo com a função Lambda “ec2-stop”:
Código Python “ec2-stop”:
import json import boto3 import logging logger = logging.getLogger() logger.setLevel(logging.INFO) def lambda_handler(event, context): region = 'us-east-1' client = boto3.client('ec2', region_name=region) tag_key = "lambda-start-stop" tag_value = "true" try: response = client.describe_instances( Filters=[ { 'Name': f'tag:{tag_key}', 'Values': [tag_value] }, ] ) for reservation in response['Reservations']: for instance in reservation['Instances']: instanceId = instance['InstanceId'] state = instance['State']['Name'] logger.info(f"Instance ID: {instanceId} - State: {state}") if state == 'running': logger.info(f"Stopping instance {instanceId}") client.stop_instances(InstanceIds=[instanceId]) else: logger.info(f"Instance {instanceId} is not in 'running' state, current state: {state}") except Exception as e: logger.error(f"Error managing EC2 instances: {str(e)}") raise return { 'statusCode': 200, 'body': 'Stop script executed successfully' } --
3.4 Configuração do CloudWatch para visualizar os logs
1.Na barra de pesquisa, procurar por “CloudWatch” e acessar o serviço:
2.Na aba “Logs”, clicar em “Log Management” e em “Create log group”:
3.Na próxima tela, definir o nome dos grupos de logs (ec2-start-logs e ec2-stop-logs), retenção (5 dias, por exemplo), classe, habilitar a proteção contra deleção e clicar em “Create”:
4.Os grupos de logs foram criados com sucesso:
5.Agora será necessário acessar a função Lambda “ec2-start” e editar o destino dos logs que vem por padrão, apontando para o grupo de logs criado acima “ec2-start-logs”:
Destino alterado com sucesso:
6.Em seguida, repetir o mesmo com a função Lambda “ec2-stop” removendo o destino padrão e apontando para o grupo de logs “ec2-stop-logs”:
Destino alterado com sucesso:
--
3.5 Criação das instâncias EC2 para testar a Lambda
1.Para testar se as funções Lambda estão funcionando corretamente, será necessário criar uma instância para teste.
- Na aba de pesquisa, procurar por “EC2”, acessar e clicar em “Launch instance”:
2.Definir um nome para a instância (por exemplo: srv-test-01) e clicar em “Add additional tags” para inserir a chave “lambda-start-stop” e valor “true”, conforme está no código:
3.A máquina foi criada com sucesso e está ligada:
4.Para testar se a função “ec2-stop” vai desligar a instância, podemos clicar em “Test” e na barra que irá abrir, escrever algo como “Test” também, seguido e um Enter:
5.Na próxima tela, será necessário definir um nome (por exemplo: test-01) e clicar em “Save”:
6.Em seguida, podemos clicar em “Test” para iniciar a execução:
7.A execução do código está em andamento:
O desligamento da máquina “srv-test-01” foi executado com sucesso:
No CloudWatch, é possível visualizar os logs no grupo “ec2-stop-logs”, onde aparece o estado da instância antes da execução da função Lambda (running) e depois da execução (stopped).
8.Em seguida, podemos repetir o mesmo procedimento com a função “ec2-start”, para ligar a máquina “srv-test-01”. Para isso, outro caminho é clicar em “Create new test event”, na aba “TEST EVENTS”, definir um nome (por exemplo: test-02) e clicar em “Save”:
Em seguida, clicar em “Test” para executar. A função foi executada com sucesso:
A instância foi ligada com sucesso:













































