Skip to content

Instantly share code, notes, and snippets.

@ValterAndrei
Last active October 23, 2025 18:50
Show Gist options
  • Save ValterAndrei/9f3ce4a0ccce2840b7c451302f26127e to your computer and use it in GitHub Desktop.
Save ValterAndrei/9f3ce4a0ccce2840b7c451302f26127e to your computer and use it in GitHub Desktop.
Automating Instance Start/Stop - AWS, Lambda, EC2, RDS and Ruby

🚀 AWS Lambda: Automação de Instâncias EC2 e RDS

📋 Visão Geral

Automatize o gerenciamento de instâncias EC2 e RDS com AWS Lambda, incluindo notificações em tempo real via Slack para monitoramento simplificado do ambiente.

⚙️ Especificações Técnicas

  • Linguagem: Ruby 3.4
  • Serviços AWS:
    • EC2 (Elastic Compute Cloud)
    • RDS (Relational Database Service)
    • Lambda (Serverless Functions)
    • EventBridge (Agendamento)
    • CloudWatch (Logs e Monitoramento)
    • SNS (Simple Notification Service)

📚 Guia de Implementação

1️⃣ Configuração de Permissões IAM

Configure as políticas de acesso necessárias para que as funções Lambda possam gerenciar os recursos EC2 e RDS.

📖 Acessar Documentação Completa


2️⃣ Lambda para Iniciar Instâncias

Implemente a função Lambda responsável por inicializar as instâncias EC2 e RDS nos horários programados.

📖 Acessar Documentação Completa


3️⃣ Lambda para Parar Instâncias

Configure a função Lambda que desliga as instâncias EC2 e RDS automaticamente, otimizando custos operacionais.

📖 Acessar Documentação Completa


💡 Benefícios

  • ✅ Redução de custos com automação de recursos
  • ✅ Monitoramento proativo via Slack
  • ✅ Agendamento flexível com EventBridge
  • ✅ Logs centralizados no CloudWatch
  • ✅ Infraestrutura como código serverless
@ValterAndrei
Copy link
Author

ValterAndrei commented Oct 23, 2025

⏹️ Lambda para Parar Instâncias

📝 Configuração da Função Lambda

1️⃣ Criar Função Lambda

Configure a função Lambda responsável por desligar as instâncias EC2 e RDS automaticamente.

🎯 Passos

  1. Navegue até: Lambda → Create function
  2. Preencha os campos:
    • Function name: stop_instances
    • Runtime: Ruby 3.4
  3. Em Permissions, selecione a role: start-stop-instance-role
  4. Clique em Create function

2️⃣ Estrutura de Arquivos

A função Lambda contém um único arquivo Ruby responsável por toda a lógica de desligamento.

📄 lambda_function.rb - Handler Principal

Arquivo principal que gerencia o fluxo de desligamento das instâncias.

💻 Ver código completo
require 'aws-sdk-ec2'
require 'aws-sdk-rds'

def lambda_handler(event:, context:)
  logger = Logger.new($stdout)
  logger.info(event)

  # Environment variables
  bastion_id      = ENV.fetch('BASTION_ID')
  dev_app_id      = ENV.fetch('DEV_APP_ID')
  rds_instance_id = ENV.fetch('RDS_INSTANCE_ID')
  region          = ENV.fetch('REGION')

  # Create AWS Clients
  ec2_client = Aws::EC2::Client.new(region:)
  rds_client = Aws::RDS::Client.new(region:)

  # Check if EC2 instances are in a state available to stop
  ec2_response = ec2_client.describe_instances(instance_ids: [bastion_id, dev_app_id])
  ec2_instances = ec2_response.reservations.flat_map(&:instances)

  ec2_instances.each do |instance|
    ec2_instance_status = instance.state.name

    if ec2_instance_status != 'running'
      return {
        status: 422,
        message: "A instância EC2 #{instance.instance_id} não está em um estado disponível para ser desligada.",
        state: ec2_instance_status
      }
    end
  end

  # Check if RDS instance is in a state available to stop
  rds_response = rds_client.describe_db_instances(db_instance_identifier: rds_instance_id)
  rds_instance = rds_response.db_instances.first
  rds_instance_status = rds_instance.db_instance_status

  if rds_instance_status != 'available'
    return {
      status: 422,
      message: "A instância RDS #{rds_instance_id} não está em um estado disponível para ser desligada.",
      state: rds_instance_status
    }
  end

  # Stop instances
  ec2_client.stop_instances(instance_ids: [bastion_id, dev_app_id])
  rds_client.stop_db_instance(db_instance_identifier: rds_instance_id)

  # Create Slack message
  send_slack_message_for_success

  # Return success message from Lambda
  {
    status: 200,
    message: 'Instâncias desligadas com sucesso.'
  }
end

def send_slack_message_for_success
  message = {
    blocks: [
      {
        type: 'header',
        text: {
          type: 'plain_text',
          text: ':black_circle: Instâncias desligadas'
        }
      },
      {
        type: 'section',
        text: {
          type: 'mrkdwn',
          text: '_Clique no botão para *ligar* as instâncias._'
        },
        accessory: {
          type: 'button',
          text: {
            type: 'plain_text',
            text: 'Ligar instâncias'
          },
          url: ENV.fetch('START_FUNCTION_URL')
        }
      }
    ]
  }

  uri = URI(ENV.fetch('SLACK_WEBHOOK_URL'))
  Net::HTTP.post(uri, message.to_json, 'Content-Type' => 'application/json')
end

🔍 Funcionalidades:

  • Valida estado das instâncias EC2 e RDS antes de desligar
  • Garante que apenas instâncias em execução sejam desligadas
  • Envia notificações para o Slack com status da operação
  • Inclui botão interativo para ligar novamente as instâncias

3️⃣ Variáveis de Ambiente

Configure as variáveis de ambiente necessárias para o funcionamento da Lambda.

🎯 Passos

  1. Na página da função Lambda, acesse: Configuration → Environment variables
  2. Clique em Edit e adicione as seguintes variáveis:
🔑 Lista de Variáveis
Variável Exemplo Descrição
BASTION_ID i-0a1b2c3d4e5f6g7h8 ID da instância EC2 Bastion
DEV_APP_ID i-9j8h7g6f5e4d3c2b1 ID da instância EC2 de Aplicação
RDS_INSTANCE_ID dev-db Identificador da instância RDS
REGION us-east-1 Região AWS das instâncias
SLACK_WEBHOOK_URL https://hooks.slack.com/services/... Webhook do Slack para notificações
START_FUNCTION_URL https://...lambda-url... URL pública da função de iniciar

4️⃣ Configurar Trigger com EventBridge

Agende a execução automática da função Lambda usando EventBridge.

🎯 Passos

  1. Na página da função Lambda, clique em Add trigger
  2. Selecione EventBridge (CloudWatch Events)
  3. Escolha Create a new rule
  4. Configure:
    • Rule name: stop_instances_event
    • Rule type: Schedule expression
    • Schedule expression: cron(00 22 ? * MON-FRI *)
  5. Clique em Add

⏰ Expressão Cron

cron(00 22 ? * MON-FRI *)

📅 Agendamento:

  • Executa às 19:00h (GMT-3) / 22:00h (UTC)
  • Apenas em dias úteis (segunda a sexta-feira)
  • Desliga automaticamente ao final do expediente

✅ Resultado

Após a configuração completa, a função Lambda irá:

  • ✅ Desligar instâncias EC2 e RDS automaticamente ao final do expediente
  • ✅ Validar o estado das instâncias antes de desligar
  • ✅ Enviar notificações para o Slack com status da operação
  • ✅ Fornecer botão interativo para ligar novamente as instâncias via Slack
  • ✅ Otimizar custos ao desligar recursos fora do horário de trabalho

🎯 Automação Completa

Com as duas funções Lambda configuradas (start_instances e stop_instances), você agora possui um sistema completo de automação que:

  • 🌅 Liga as instâncias automaticamente pela manhã (07:00h)
  • 🌙 Desliga as instâncias automaticamente à noite (19:00h)
  • 🎉 Respeita feriados brasileiros (apenas na função de iniciar)
  • 💬 Notifica o time via Slack com controles interativos
  • 💰 Reduz custos operacionais significativamente

📊 Monitoramento

Para acompanhar a execução das funções Lambda:

  1. Acesse CloudWatch → Log groups
  2. Localize os grupos: /aws/lambda/start_instances e /aws/lambda/stop_instances
  3. Visualize logs de execução, erros e métricas de performance

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment