Automatizando o Gerenciamento de Recursos na AWS para Reduzir Custos: Uma Jornada com Python e Terraform

A Necessidade de Otimizar Custos

Em qualquer ambiente de nuvem, especialmente em contas de desenvolvimento e homologação, os custos podem rapidamente sair do controle. Máquinas virtuais, bancos de dados e serviços ficam ligados 24/7, mesmo q…


This content originally appeared on DEV Community and was authored by Marcos Vilela

A Necessidade de Otimizar Custos

Em qualquer ambiente de nuvem, especialmente em contas de desenvolvimento e homologação, os custos podem rapidamente sair do controle. Máquinas virtuais, bancos de dados e serviços ficam ligados 24/7, mesmo que só sejam usados durante o horário de trabalho. Foi observando esse cenário que uma ideia simples surgiu: por que não automatizar o processo de ligar e desligar esses recursos?

Este artigo conta a jornada de como essa ideia, nascida de um projeto pessoal simples, evoluiu para uma solução robusta e foi adotada no meu ambiente de trabalho, utilizando Python, Terraform e GitHub Actions para orquestrar tudo.

A Solução em Python: Mão na Massa com boto3

A escolha do Python foi natural. Sua sintaxe limpa e o poder da biblioteca boto3 (o SDK da AWS para Python) tornaram o desenvolvimento rápido e intuitivo. O objetivo era criar duas funções Lambda: uma para "acordar" os recursos no início do dia (resources_start.py) e outra para "colocá-los para dormir" no final (resources_stop.py).

A lógica é direta: para cada serviço da AWS, o script busca os recursos em um determinado estado e aplica a ação desejada.

Desligando Recursos (resources_stop.py)

A função de parada itera sobre diferentes serviços, encontra o que está em execução e o desliga.

EC2: Busca por instâncias com o estado running.

# infra/terraform/app/resources_stop.py

# ... (imports e configuração do logger)
def lambda_handler(event, context):
    results = []
    # EC2 - Para todas as instâncias encontradas
    ec2 = boto3.client("ec2")
    instances = ec2.describe_instances(Filters=[{"Name": "instance-state-name", "Values": ["running"]}])
    for reservation in instances["Reservations"]:
        for instance in reservation["Instances"]:
            instance_id = instance["InstanceId"]
            try:
                ec2.stop_instances(InstanceIds=[instance_id])
                # ... (logging e append nos resultados)
            except Exception as e:
                # ... (tratamento de erro)

ECS: Para os serviços ECS, a estratégia é zerar o desiredCount (número de tarefas desejadas), o que efetivamente para as tarefas em execução.

# infra/terraform/app/resources_stop.py

    # ...
    # ECS - Para todos os serviços encontrados
    ecs = boto3.client("ecs")
    clusters = ecs.list_clusters()["clusterArns"]
    for cluster_arn in clusters:
        services = ecs.list_services(cluster=cluster_arn)["serviceArns"]
        for service_arn in services:
            # ...
            try:
                ecs.update_service(cluster=cluster_arn, service=service_arn, desiredCount=0)
                # ... (logging e append nos resultados)
            except Exception as e:
                # ... (tratamento de erro)

RDS e DocumentDB: O processo é semelhante: listar instâncias e clusters e aplicar a ação de stop.

# infra/terraform/app/resources_stop.py

    # ...
    # RDS - Para todas as instâncias encontradas
    rds = boto3.client("rds")
    instances = rds.describe_db_instances()["DBInstances"]
    for instance in instances:
        try:
            rds.stop_db_instance(DBInstanceIdentifier=instance["DBInstanceIdentifier"])
            # ...
        except Exception as e:
            # ...

    # DocumentDB - Para todos os clusters encontrados
    docdb = boto3.client("docdb")
    clusters = docdb.describe_db_clusters()["DBClusters"]
    for cluster in clusters:
        try:
            docdb.stop_db_cluster(DBClusterIdentifier=cluster["DBClusterIdentifier"])
            # ...
        except Exception as e:
            # ...

Ligando Recursos (resources_start.py)

A função de início (resources_start.py) segue a mesma lógica, mas com a ação inversa. Para instâncias EC2, busca as que estão stopped e as inicia. Para serviços ECS, define o desiredCount de volta para 1 (ou o valor que for ideal para seu ambiente). Para RDS e DocumentDB, inicia as instâncias e clusters parados.

O uso do boto3 se mostrou extremamente poderoso, permitindo interagir com toda a gama de serviços da AWS de forma programática e consistente.

Infraestrutura como Código: Orquestrando com Terraform

Com os scripts prontos, o próximo passo era provisionar a infraestrutura de forma automatizada. O Terraform foi a escolha óbvia para gerenciar a criação das Lambdas, permissões e agendamentos.

O arquivo main.tf concentra toda a nossa lógica de provisionamento.

  1. Empacotando as Lambdas: Primeiro, usamos o archive_file para compactar nossos scripts Python em arquivos .zip, prontos para o deploy.

    # infra/terraform/main.tf
    
    data "archive_file" "resources_start_lambda" {
      type        = "zip"
      source_file = "${path.module}/app/resources_start.py"
      output_path = "${path.module}/app/resources_start.zip"
    }
    
    data "archive_file" "resources_stop_lambda" {
      # ... (similar para o stop)
    }
    
  2. Criando as Funções Lambda: Em seguida, definimos as aws_lambda_function, apontando para os arquivos zipados, definindo o runtime (python3.12) e o handler.

    # infra/terraform/main.tf
    
    resource "aws_lambda_function" "resources_start" {
      filename         = data.archive_file.resources_start_lambda.output_path
      function_name    = "${var.namespace}-${var.stage}-${var.name}-resources-start"
      role             = aws_iam_role.scheduler_role.arn
      handler          = "resources_start.lambda_handler"
      source_code_hash = data.archive_file.resources_start_lambda.output_base64sha256
      runtime          = "python3.12"
      # ...
    }
    
    resource "aws_lambda_function" "resources_stop" {
        # ... (similar para o stop)
    }
    
  3. Gerenciando Permissões com IAM: Um dos pontos cruciais é garantir que as Lambdas tenham permissão para agir sobre outros recursos. Criamos uma aws_iam_role_policy que concede explicitamente as ações necessárias (ec2:StartInstances, rds:StopDBInstance, etc.).

    # infra/terraform/main.tf
    
    resource "aws_iam_role_policy" "resource_manager_policy" {
      name = "${var.namespace}-${var.stage}-${var.name}-resource-manager-policy"
      role = aws_iam_role.scheduler_role.id
      policy = jsonencode({
        Version = "2012-10-17",
        Statement = [
          {
            Effect = "Allow",
            Action = [
              "rds:StartDBCluster",
              "rds:StopDBCluster",
              # ... outras permissões
              "ec2:StopInstances"
            ],
            Resource = "*"
          }
        ]
      })
    }
    
  4. Agendando as Execuções com EventBridge Scheduler: Finalmente, para automatizar a execução, usamos o aws_scheduler_schedule. Ele nos permite definir uma expressão cron (schedule_expression) para invocar cada Lambda em um horário específico.

    # infra/terraform/main.tf
    
    resource "aws_scheduler_schedule" "resources_start_schedule" {
      name                = "${var.namespace}-${var.stage}-${var.name}-resources-start-schedule"
      schedule_expression = var.start_schedule_expression # ex: "cron(0 8 * * ? *)"
      # ...
      target {
        arn      = aws_lambda_function.resources_start.arn
        role_arn = aws_iam_role.eventbridge_scheduler_role[0].arn
        # ...
      }
    }
    
    resource "aws_scheduler_schedule" "resources_stop_schedule" {
        # ... (similar para o stop, com outro schedule_expression)
    }
    

Implantação Contínua com GitHub Actions

Com o código e a infraestrutura definidos, o ciclo se fecha com a automação do deploy. Um workflow simples no GitHub Actions foi criado para aplicar as mudanças do Terraform a cada push na branch principal, garantindo que qualquer alteração nos scripts ou na infra fosse implantada de forma rápida e segura.

O pipeline basicamente consiste em:

  1. Fazer o checkout do código.
  2. Configurar as credenciais da AWS.
  3. Inicializar o Terraform (terraform init).
  4. Planejar e aplicar as mudanças (terraform apply).

Conclusão: De um "Script Simples" a uma Solução de Valor

O que começou como um exercício para resolver um problema simples se transformou em uma ferramenta valiosa. A automação do gerenciamento de recursos não apenas gerou uma economia de custos mensurável, mas também serviu como uma incrível experiência de aprendizado.

Essa jornada reforçou a importância de:

  • Começar simples: Uma solução não precisa ser complexa para ser eficaz.
  • O poder da automação: Tarefas manuais e repetitivas são candidatas perfeitas para automação.
  • Infraestrutura como Código: Ferramentas como o Terraform são essenciais para criar sistemas gerenciáveis, replicáveis e transparentes.

Espero que esta experiência inspire outros a olharem para seus próprios desafios diários e a enxergarem neles oportunidades para inovar, aprender e agregar valor, mesmo que a solução comece com um simples script.


This content originally appeared on DEV Community and was authored by Marcos Vilela


Print Share Comment Cite Upload Translate Updates
APA

Marcos Vilela | Sciencx (2025-10-14T20:04:40+00:00) Automatizando o Gerenciamento de Recursos na AWS para Reduzir Custos: Uma Jornada com Python e Terraform. Retrieved from https://www.scien.cx/2025/10/14/automatizando-o-gerenciamento-de-recursos-na-aws-para-reduzir-custos-uma-jornada-com-python-e-terraform/

MLA
" » Automatizando o Gerenciamento de Recursos na AWS para Reduzir Custos: Uma Jornada com Python e Terraform." Marcos Vilela | Sciencx - Tuesday October 14, 2025, https://www.scien.cx/2025/10/14/automatizando-o-gerenciamento-de-recursos-na-aws-para-reduzir-custos-uma-jornada-com-python-e-terraform/
HARVARD
Marcos Vilela | Sciencx Tuesday October 14, 2025 » Automatizando o Gerenciamento de Recursos na AWS para Reduzir Custos: Uma Jornada com Python e Terraform., viewed ,<https://www.scien.cx/2025/10/14/automatizando-o-gerenciamento-de-recursos-na-aws-para-reduzir-custos-uma-jornada-com-python-e-terraform/>
VANCOUVER
Marcos Vilela | Sciencx - » Automatizando o Gerenciamento de Recursos na AWS para Reduzir Custos: Uma Jornada com Python e Terraform. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/10/14/automatizando-o-gerenciamento-de-recursos-na-aws-para-reduzir-custos-uma-jornada-com-python-e-terraform/
CHICAGO
" » Automatizando o Gerenciamento de Recursos na AWS para Reduzir Custos: Uma Jornada com Python e Terraform." Marcos Vilela | Sciencx - Accessed . https://www.scien.cx/2025/10/14/automatizando-o-gerenciamento-de-recursos-na-aws-para-reduzir-custos-uma-jornada-com-python-e-terraform/
IEEE
" » Automatizando o Gerenciamento de Recursos na AWS para Reduzir Custos: Uma Jornada com Python e Terraform." Marcos Vilela | Sciencx [Online]. Available: https://www.scien.cx/2025/10/14/automatizando-o-gerenciamento-de-recursos-na-aws-para-reduzir-custos-uma-jornada-com-python-e-terraform/. [Accessed: ]
rf:citation
» Automatizando o Gerenciamento de Recursos na AWS para Reduzir Custos: Uma Jornada com Python e Terraform | Marcos Vilela | Sciencx | https://www.scien.cx/2025/10/14/automatizando-o-gerenciamento-de-recursos-na-aws-para-reduzir-custos-uma-jornada-com-python-e-terraform/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.