DevOps & CI/CD

FinOps e Otimização de Custos em Cloud: Estratégias e Ferramentas na Prática

15 min de leitura

FinOps e Otimização de Custos em Cloud: Estratégias e Ferramentas na Prática

O que é FinOps e por que você deve se importar FinOps é a prática de trazer disciplina financeira para a computação em nuvem. A sigla significa "Financial Operations" e representa um framework cultural e operacional onde times de engenharia, finanças e negócios trabalham juntos para otimizar gastos em cloud. Diferente de simplesmente "cortar custos", FinOps busca maximizar o valor entregue por cada real investido em infraestrutura em nuvem. A realidade é que muitas organizações gastam entre 20% a 30% a mais do que precisam em serviços cloud. Isso acontece porque a maioria dos times não tem visibilidade clara de seus gastos, não entende como as instâncias são precificadas, e não há uma cultura de responsabilidade financeira compartilhada. FinOps muda essa dinâmica estabelecendo processos, ferramentas e incentivos para que todos—desde o desenvolvedor até o CFO—pensem em eficiência de custos como parte do dia a dia. Pilares Estratégicos: Visibilidade, Otimização e Governança Visibilidade: Conhecer seus gastos Você não pode otimizar o

<h2>O que é FinOps e por que você deve se importar</h2>

<p>FinOps é a prática de trazer disciplina financeira para a computação em nuvem. A sigla significa &quot;Financial Operations&quot; e representa um framework cultural e operacional onde times de engenharia, finanças e negócios trabalham juntos para otimizar gastos em cloud. Diferente de simplesmente &quot;cortar custos&quot;, FinOps busca maximizar o valor entregue por cada real investido em infraestrutura em nuvem.</p>

<p>A realidade é que muitas organizações gastam entre 20% a 30% a mais do que precisam em serviços cloud. Isso acontece porque a maioria dos times não tem visibilidade clara de seus gastos, não entende como as instâncias são precificadas, e não há uma cultura de responsabilidade financeira compartilhada. FinOps muda essa dinâmica estabelecendo processos, ferramentas e incentivos para que todos—desde o desenvolvedor até o CFO—pensem em eficiência de custos como parte do dia a dia.</p>

<h2>Pilares Estratégicos: Visibilidade, Otimização e Governança</h2>

<h3>Visibilidade: Conhecer seus gastos</h3>

<p>Você não pode otimizar o que não consegue medir. O primeiro pilar de qualquer estratégia FinOps é estabelecer visibilidade completa dos gastos em nuvem. Isso significa entender não apenas quanto você gasta no total, mas onde exatamente esse dinheiro está sendo gasto: qual serviço, qual projeto, qual time, qual ambiente (dev, staging, produção).</p>

<p>Na prática, as provedoras cloud (AWS, Azure, GCP) fornecem ferramentas nativas para isso. Na AWS, você tem o AWS Cost Explorer e o AWS Billing Dashboard. No GCP, existe o Cloud Billing. Essas ferramentas permitem criar alertas, análises por tag, e até prever gastos futuros. Além delas, existem ferramentas de terceiros como Kubecost (especializada em Kubernetes), CloudHealth, Infracost e Cloudlytics que oferecem análises mais granulares e integrações com seu workflow de desenvolvimento.</p>

<pre><code class="language-python"># Exemplo: Script Python para extrair custos da AWS usando boto3

import boto3

from datetime import datetime, timedelta

ce_client = boto3.client(&#039;ce&#039;, region_name=&#039;us-east-1&#039;)

def get_daily_costs_by_service(days_back=30):

&quot;&quot;&quot;

Retorna custos diários agrupados por serviço nos últimos N dias

&quot;&quot;&quot;

end_date = datetime.now().date()

start_date = end_date - timedelta(days=days_back)

response = ce_client.get_cost_and_usage(

TimePeriod={

&#039;Start&#039;: start_date.isoformat(),

&#039;End&#039;: end_date.isoformat()

},

Granularity=&#039;DAILY&#039;,

Metrics=[&#039;UnblendedCost&#039;],

GroupBy=[

{&#039;Type&#039;: &#039;DIMENSION&#039;, &#039;Key&#039;: &#039;SERVICE&#039;}

]

)

costs_by_service = {}

for result in response[&#039;ResultsByTime&#039;]:

date = result[&#039;TimePeriod&#039;][&#039;Start&#039;]

for group in result[&#039;Groups&#039;]:

service = group[&#039;Keys&#039;][0]

cost = float(group[&#039;Metrics&#039;][&#039;UnblendedCost&#039;][&#039;Amount&#039;])

if service not in costs_by_service:

costs_by_service[service] = {}

costs_by_service[service][date] = cost

return costs_by_service

Uso

costs = get_daily_costs_by_service(days_back=7)

for service, dates in costs.items():

total = sum(dates.values())

print(f&quot;{service}: ${total:.2f}&quot;)</code></pre>

<h3>Otimização: Reduzindo desperdícios</h3>

<p>Com visibilidade em mano, você identifica oportunidades de otimização. As mais comuns são: eliminar recursos ociosos, usar instâncias reservadas ou savings plans, rightsizing (usar o tamanho correto de máquina), e otimizar transferências de dados. Uma instância EC2 rodando em produção mas que está 5% utilizada é um desperdício óbvio.</p>

<p>A otimização não é um evento único, é um processo contínuo. Recomenda-se revisar custos semanalmente, identificar padrões, e automatizar as otimizações sempre que possível. Ferramentas como o AWS Trusted Advisor, Compute Optimizer, e Right Sizing Recommendations dão insights automáticos sobre o que pode ser otimizado.</p>

<pre><code class="language-python"># Exemplo: Identificar instâncias EC2 subutilizadas usando CloudWatch

import boto3

from datetime import datetime, timedelta

ec2_client = boto3.client(&#039;ec2&#039;, region_name=&#039;us-east-1&#039;)

cloudwatch_client = boto3.client(&#039;cloudwatch&#039;, region_name=&#039;us-east-1&#039;)

def find_underutilized_instances(cpu_threshold=10, days=7):

&quot;&quot;&quot;

Encontra instâncias EC2 com CPU média abaixo de um threshold nos últimos dias

&quot;&quot;&quot;

Listar todas as instâncias rodando

response = ec2_client.describe_instances(

Filters=[{&#039;Name&#039;: &#039;instance-state-name&#039;, &#039;Values&#039;: [&#039;running&#039;]}]

)

underutilized = []

end_time = datetime.utcnow()

start_time = end_time - timedelta(days=days)

for reservation in response[&#039;Reservations&#039;]:

for instance in reservation[&#039;Instances&#039;]:

instance_id = instance[&#039;InstanceId&#039;]

instance_type = instance[&#039;InstanceType&#039;]

Obter métrica de CPU média

metrics = cloudwatch_client.get_metric_statistics(

Namespace=&#039;AWS/EC2&#039;,

MetricName=&#039;CPUUtilization&#039;,

Dimensions=[{&#039;Name&#039;: &#039;InstanceId&#039;, &#039;Value&#039;: instance_id}],

StartTime=start_time,

EndTime=end_time,

Period=3600, # 1 hora

Statistics=[&#039;Average&#039;]

)

if metrics[&#039;Datapoints&#039;]:

avg_cpu = sum(dp[&#039;Average&#039;] for dp in metrics[&#039;Datapoints&#039;]) / len(metrics[&#039;Datapoints&#039;])

if avg_cpu &lt; cpu_threshold:

underutilized.append({

&#039;instance_id&#039;: instance_id,

&#039;instance_type&#039;: instance_type,

&#039;avg_cpu&#039;: avg_cpu

})

return underutilized

Uso

underutilized = find_underutilized_instances(cpu_threshold=10, days=7)

for instance in underutilized:

print(f&quot;ID: {instance[&#039;instance_id&#039;]}, Tipo: {instance[&#039;instance_type&#039;]}, CPU Média: {instance[&#039;avg_cpu&#039;]:.2f}%&quot;)</code></pre>

<h3>Governança: Estabelecendo controle</h3>

<p>Governança em FinOps significa definir políticas, responsabilidades e processos que garantam que os custos sejam gerenciados adequadamente. Isso inclui: aprovações para provisionamento de recursos, limite de gastos por projeto/time, políticas de naming convention para rastrear recursos, e automated cleanup de recursos não utilizados.</p>

<p>A governança deve equilibrar liberdade de inovação com controle financeiro. Um time de desenvolvimento não pode estar preso a burocracias que o impeçam de escalar rapidamente, mas também não pode provisionar infraestrutura de forma caótica. Ferramentas como AWS Organizations, IAM Policies com Cost Tags, e serviços como Terraform com políticas Sentinel permitem estabelecer guardrails efetivas.</p>

<pre><code class="language-hcl"># Exemplo: Terraform com políticas de governança

Este arquivo define tagging obrigatório e limites em tipos de instância

terraform {

required_providers {

aws = {

source = &quot;hashicorp/aws&quot;

version = &quot;~&gt; 5.0&quot;

}

}

}

variable &quot;required_tags&quot; {

description = &quot;Tags obrigatórias em todos os recursos&quot;

type = map(string)

default = {

Environment = &quot;&quot;

CostCenter = &quot;&quot;

Owner = &quot;&quot;

Project = &quot;&quot;

}

}

Variável local para instâncias permitidas (economia: evita tipos muito caros)

locals {

allowed_instance_types = [

&quot;t3.micro&quot;,

&quot;t3.small&quot;,

&quot;t3.medium&quot;,

&quot;m5.large&quot;,

&quot;m5.xlarge&quot;

]

}

resource &quot;aws_instance&quot; &quot;example&quot; {

ami = &quot;ami-0c55b159cbfafe1f0&quot;

instance_type = &quot;t3.micro&quot;

Validação: apenas tipos permitidos

lifecycle {

precondition {

condition = contains(local.allowed_instance_types, self.instance_type)

error_message = &quot;Instance type ${self.instance_type} não é permitido por política de governança.&quot;

}

}

Tags obrigatórias

tags = merge(

var.required_tags,

{

Name = &quot;web-server-01&quot;

LaunchDate = timestamp()

ManagedBy = &quot;terraform&quot;

}

)

}

Output mostrando o custo estimado (informativo)

output &quot;instance_details&quot; {

value = {

id = aws_instance.example.id

instance_type = aws_instance.example.instance_type

tags = aws_instance.example.tags

}

}</code></pre>

<h2>Estratégias Práticas de Redução de Custos</h2>

<h3>Instâncias Reservadas e Savings Plans</h3>

<p>Servidores em nuvem são precificados sob demanda por padrão: você paga por hora de uso. Se você sabe que uma aplicação rodará por 12 meses, comprar uma Reserved Instance (RI) ou Savings Plan oferece desconto de até 70% comparado ao preço sob demanda. A desvantagem é o comprometimento antecipado: você paga agora por um período futuro.</p>

<p>Essa é geralmente a primeira otimização que gera ROI imediato. Reserve apenas o que você realmente precisa usar continuamente (bases de dados, servidores web sempre ativos). Deixe flexibilidade para picos de demanda usando instâncias sob demanda. No GCP e Azure existem opções similares (Committed Use Discounts e Reserved Instances, respectivamente).</p>

<pre><code class="language-python"># Exemplo: Calcular economia com Reserved Instances

def calculate_ri_savings(

instance_type=&quot;m5.large&quot;,

hours_per_month=720, # 30 dias * 24 horas

months=12,

on_demand_hourly=0.096, # Preço sob demanda (exemplo AWS)

ri_hourly=0.0345 # Preço RI 1 ano (aproximado)

):

&quot;&quot;&quot;

Calcula economia usando Reserved Instances vs On-Demand

&quot;&quot;&quot;

total_hours = hours_per_month * months

on_demand_cost = total_hours * on_demand_hourly

ri_cost = total_hours * ri_hourly

savings = on_demand_cost - ri_cost

savings_percentage = (savings / on_demand_cost) * 100

print(f&quot;Instância: {instance_type}&quot;)

print(f&quot;Período: {months} meses ({total_hours} horas)&quot;)

print(f&quot;Custo On-Demand: ${on_demand_cost:.2f}&quot;)

print(f&quot;Custo com RI: ${ri_cost:.2f}&quot;)

print(f&quot;Economia: ${savings:.2f} ({savings_percentage:.1f}%)&quot;)

return {

&#039;on_demand&#039;: on_demand_cost,

&#039;ri&#039;: ri_cost,

&#039;savings&#039;: savings,

&#039;savings_percentage&#039;: savings_percentage

}

Uso

calculate_ri_savings()</code></pre>

<h3>Otimização em Kubernetes e Containers</h3>

<p>Kubernetes é excelente para otimizar custos porque permite compartilhar recursos eficientemente entre múltiplos containers. Porém, muitos times deixam recursos sobre-provisionados ou executam workloads sem otimização. Usar Horizontal Pod Autoscaler (HPA), Vertical Pod Autoscaler (VPA), e Node Autoscaling reduz significativamente os custos.</p>

<p>Além disso, usar Spot Instances (EC2 Spot, GKE Preemptible) pode reduzir custos em até 90%, ideal para workloads tolerantes a interrupção como batch jobs e processamento de dados. A chave é categorizar seus workloads: produção crítica usa On-Demand/Reserved, batch e dev usa Spot.</p>

<pre><code class="language-yaml"># Exemplo: Kubernetes com autoscaling e resource requests/limits

apiVersion: apps/v1

kind: Deployment

metadata:

name: api-server

namespace: production

spec:

replicas: 2 # Será ajustado pelo HPA

selector:

matchLabels:

app: api-server

template:

metadata:

labels:

app: api-server

cost-center: &quot;platform&quot; # Para rastreamento de custos

spec:

containers:

  • name: api

image: myregistry.azurecr.io/api-server:v1.2.0

ports:

  • containerPort: 8080

Limites e requests são CRÍTICOS para otimizar custos

resources:

requests:

memory: &quot;256Mi&quot; # Mínimo que a app precisa

cpu: &quot;100m&quot; # 0.1 CPUs

limits:

memory: &quot;512Mi&quot; # Máximo antes de kill

cpu: &quot;500m&quot; # 0.5 CPUs

Readiness e liveness probes ajudam autoscaler a tomar decisões corretas

readinessProbe:

httpGet:

path: /health

port: 8080

initialDelaySeconds: 10

periodSeconds: 5

livenessProbe:

httpGet:

path: /health

port: 8080

initialDelaySeconds: 15

periodSeconds: 20

---

Horizontal Pod Autoscaler: escala automaticamente pods baseado em CPU

apiVersion: autoscaling/v2

kind: HorizontalPodAutoscaler

metadata:

name: api-server-hpa

namespace: production

spec:

scaleTargetRef:

apiVersion: apps/v1

kind: Deployment

name: api-server

minReplicas: 2 # Nunca menos de 2

maxReplicas: 10 # Nunca mais de 10

metrics:

  • type: Resource

resource:

name: cpu

target:

type: Utilization

averageUtilization: 70 # Escala quando CPU &gt; 70%

  • type: Resource

resource:

name: memory

target:

type: Utilization

averageUtilization: 80 # Escala quando memória &gt; 80%

---

Node Pool com Spot Instances (GKE) para workloads não-críticos

apiVersion: container.cnrm.cloud.google.com/v1beta1

kind: ContainerNodePool

metadata:

name: batch-processing-pool

spec:

cluster:

name: production-cluster

nodeCount: 0 # Autoscaling ativo

autoscaling:

minNodeCount: 0

maxNodeCount: 20

nodeConfig:

machineType: n2-standard-4

spot: true # 70% mais barato que On-Demand!

diskSizeGb: 50

labels:

workload-type: batch</code></pre>

<h3>Análise e Otimização de Transferência de Dados</h3>

<p>Transferência de dados entre regiões e para a internet é frequentemente uma surpresa cara. Uma aplicação que move 100GB entre regiões pode custar centenas de reais por mês. Estratégias incluem: manter dados perto da computação (usar regiões específicas), usar CDN (CloudFront, Cloud CDN), comprimir dados, e implementar cache agressivo.</p>

<p>Analisar padrões de tráfego e estabelecer políticas é essencial. Às vezes, duplicar dados em outra região é mais barato que pagar pela transferência repetida. Ferramentas como VPC Flow Logs e observabilidade de rede ajudam identificar onde o tráfego está indo.</p>

<h2>Ferramentas e Integração com Workflow de Desenvolvimento</h2>

<h3>Ferramentas de Monitoramento e Alerting</h3>

<p>Usar ferramentas especializadas acelera a detecção de problemas. Kubecost é excelente para Kubernetes porque quebra custos por namespace, label, e até pod. Infracost integra-se ao seu pipeline Terraform/CloudFormation e mostra o custo estimado de uma mudança <em>antes</em> de fazer deploy. CloudHealth oferece análises multi-cloud e recomendações automatizadas.</p>

<pre><code class="language-bash"># Exemplo: Usando Infracost para estimar custo de mudanças Terraform

Instalar: brew install infracost

Verificar custo atual

infracost breakdown --path ./terraform

Verificar custo de mudanças antes de aplicar

infracost diff --path ./terraform --compare-to main

Output mostra incremento/decremento de custo

exemplo:

✓ Detected 3 resource types

#

Monthly costs will increase by $150 (5%)

#

+ aws_instance.web_server: $100 → $150 (+$50, +50%)

+ aws_rds_instance.db: $75 → $80 (+$5, +6.7%)</code></pre>

<h3>Integração com CI/CD</h3>

<p>A melhor forma de garantir que FinOps seja praticado é integrar verificações de custo no pipeline de CI/CD. Você pode rejeitar pull requests que aumentem custos acima de um limite, ou exigir aprovação explícita. Isso traz a conversa sobre custos para o momento da decisão (durante code review) e não para depois (quando a fatura chega).</p>

<pre><code class="language-yaml"># Exemplo: GitHub Actions com Infracost

name: Cost Analysis

on:

pull_request:

paths:

  • &#039;terraform/**&#039;

jobs:

infracost:

runs-on: ubuntu-latest

steps:

  • uses: actions/checkout@v3

with:

fetch-depth: 0

  • name: Setup Infracost

uses: infracost/actions/setup@v2

with:

api-key: ${{ secrets.INFRACOST_API_KEY }}

  • name: Generate Infracost JSON

run: |

infracost breakdown --path terraform --format json --out-file /tmp/infracost-base.json

  • name: Post cost estimate to PR

uses: infracost/actions/comment@v2

with:

path: /tmp/infracost-base.json

behavior: update</code></pre>

<h2>Conclusão</h2>

<p>Aprendemos que FinOps é um framework prático e acessível para qualquer organização que use cloud. Os três pilares—<strong>visibilidade, otimização contínua, e governança compartilhada</strong>—devem ser implementados juntos para gerar valor real. Visibilidade sem ação é apenas um relatório bonito; otimização sem governança volta a gastar descontrolado; e governança sem visibilidade é somente burocracia.</p>

<p>A prática de FinOps também mudou meu entendimento sobre como construir arquiteturas em cloud: não é mais &quot;quanto posso escalar&quot;, mas &quot;quanto preciso escalar para entregar valor&quot;. Isso naturalmente leva a decisões mais bem pensadas sobre tamanho de instância, regiões, e padrões de arquitetura. Por fim, implemente FinOps como um processo iterativo, não um projeto único. Comece por visibilidade (20% do esforço, 80% do valor), depois otimize (recursos ociosos, RIs), e por último, formalize governança conforme a prática amadurece.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://aws.amazon.com/aws-cost-management/aws-cost-optimization-hub/" target="_blank" rel="noopener noreferrer">AWS Cost Optimization Hub</a></li>

<li><a href="https://www.infracost.io/" target="_blank" rel="noopener noreferrer">Infracost - Cost estimation for infrastructure</a></li>

<li><a href="https://www.kubecost.com/" target="_blank" rel="noopener noreferrer">Kubecost - Kubernetes Cost Monitoring</a></li>

<li><a href="https://www.finops.org/" target="_blank" rel="noopener noreferrer">The FinOps Framework - Linux Foundation</a></li>

<li><a href="https://cloud.google.com/architecture/best-practices-for-running-cost-effective-workloads-on-gcp" target="_blank" rel="noopener noreferrer">Google Cloud Cost Optimization Best Practices</a></li>

</ul>

<p>&lt;!-- FIM --&gt;</p>

Comentários

Mais em DevOps & CI/CD

Como Usar Gerenciamento de Secrets em Produção: Vault, AWS Secrets Manager e SOPS em Produção
Como Usar Gerenciamento de Secrets em Produção: Vault, AWS Secrets Manager e SOPS em Produção

O Problema Real: Por Que Gerenciar Secrets? Quando você trabalha em produção,...

Incident Management: Runbooks, Post-mortems e Cultura de Confiabilidade na Prática
Incident Management: Runbooks, Post-mortems e Cultura de Confiabilidade na Prática

Incident Management: Fundamentos e Importância Incident Management é a discip...

O que Todo Dev Deve Saber sobre Prometheus: Coleta de Métricas, PromQL e Alertmanager
O que Todo Dev Deve Saber sobre Prometheus: Coleta de Métricas, PromQL e Alertmanager

Introdução ao Prometheus: Por que Monitorar? Quando você trabalha com sistema...