Você versiona sua infraestrutura e revisa pull requests do código da aplicação. Mas e a sua configuração de FinOps — budgets, alocações de custo, alertas e relatórios analíticos?
Na maioria dos times, essas configurações ficam em uma UI. Alguém passa por um wizard, define um threshold, escolhe um filtro e torce para que a próxima pessoa que precisar mexer ali consiga entender o que foi feito. Não há histórico, nem peer review, nem como replicar o setup entre ambientes. Quando suas práticas de FinOps são tão críticas quanto sua infraestrutura, elas merecem o mesmo rigor.
Foi por isso que criamos o provider Terraform da DoiT. Ele leva sua configuração do DoiT Cloud Intelligence para o mesmo fluxo de Infrastructure as Code que você já usa para recursos de nuvem — com 17 recursos gerenciados e 61 data sources que cobrem desde budgets e relatórios até consultas ao assistente de IA e diagramas de infraestrutura em nuvem.
Primeiros passos
Para começar, basta um bloco de provider e uma API key:
terraform { required_providers { doit = { source = "doitintl/doit" version = "~> 1.0" } }}
provider "doit" {}Defina DOIT_API_TOKEN no seu ambiente (dá para criar API keys no DoiT Console) e pronto. É só isso — nenhuma configuração adicional.
O fluxo central de FinOps
Vamos passar pelos recursos que a maioria dos times adota primeiro: alocações, budgets, alertas e relatórios. Juntos, eles formam um pipeline completo de FinOps — e gerenciá-los como código permite versionar, revisar e replicar todo o setup.
Alocações de custo
As alocações são a forma de fatiar o gasto em nuvem em categorias que fazem sentido. O provider conta com um motor de fórmulas booleanas para combinar critérios de filtro, alocações em grupo que dividem custos em buckets nomeados e até alocações aninhadas que referenciam outras alocações por ID.
Veja uma alocação em grupo que divide os custos por região, com um catch-all para o que não se encaixar:
resource "doit_allocation" "by_region" { name = "By Region" description = "Group costs by geographic region" unallocated_costs = "Other Regions" rules = [ { action = "create" name = "US" formula = "A" components = [{ key = "country", mode = "is", type = "fixed", values = ["US"] }] }, { action = "create" name = "Europe" formula = "A" components = [{ key = "country", mode = "is", type = "fixed", values = ["DE", "FR", "GB", "NL"] }] } ]}Precisa de mais granularidade? Use type = "allocation_rule" em um componente para referenciar uma alocação existente — compondo alocações a partir de outras, em até 3 níveis de profundidade. E em vez de cravar valores de dimensão como "US" ou "DE" no código, dá para usar o data source doit_dimension para descobrir os valores válidos dinamicamente via API.
Budgets
Budgets são as guardrails. O provider permite definir alertas com múltiplos thresholds, restringir o escopo de budgets a alocações ou dimensões específicas e — aqui vai um padrão útil — filtrar colaboradores por função em vez de adicionar todo mundo da organização:
data "doit_users" "all" {}
locals { engineers = [ for u in data.doit_users.all.users : u if u.job_title == "Software / Ops Engineer" ]}
resource "doit_budget" "eng_budget" { name = "Engineering Budget" currency = "USD" type = "recurring" amount = 10000 time_interval = "month" start_period = provider::time::rfc3339_parse("2026-01-01T00:00:00Z") * 1000
alerts = [ { percentage = 50 }, { percentage = 80 }, { percentage = 100 } ]
collaborators = concat( [{ email = data.doit_current_user.me.email, role = "owner" }], [for u in local.engineers : { email = u.email, role = "viewer" }] )
recipients = [for u in local.engineers : u.email]
scopes = [{ type = "allocation_rule" id = "allocation_rule" mode = "is" values = [doit_allocation.by_region.id] }]}Esse budget tem escopo na alocação por região que acabamos de criar e só notifica usuários com o cargo "Software / Ops Engineer". Os budgets também suportam seasonal_amounts para meses em que suas metas de gasto variam, e campos computados como current_utilization e forecasted_utilization ficam disponíveis como saídas somente leitura.
Alertas
Alertas disparam notificações quando o custo ou o uso ultrapassa um threshold. A grande sacada aqui é o escopo — você pode restringir um alerta a um provedor de nuvem, serviço, região ou qualquer dimensão. Este exemplo usa o data source doit_products para buscar dinamicamente o ID do serviço Compute Engine, em vez de deixá-lo cravado no código:
data "doit_products" "gcp" { platform = "google_cloud_platform"}
resource "doit_alert" "compute_cost" { name = "GCP Compute Cost Alert" config = { metric = { type = "basic", value = "cost" } time_interval = "day" value = 500 currency = "USD" condition = "value" operator = "gt" scopes = [{ type = "fixed" id = "service_description" mode = "is" values = [ for p in data.doit_products.gcp.products : p.id if p.display_name == "Compute Engine" ] }] } recipients = [data.doit_current_user.me.email]}Relatórios
Os relatórios do Cloud Analytics são o recurso mais completo do provider. Dá para configurar até 4 métricas, adicionar comparações ano a ano com secondary_time_range, aplicar filtros e dimensões de group-by e organizar relatórios em pastas.
resource "doit_report" "monthly_costs" { name = "Monthly Cost Report" description = "Tracks monthly costs across cloud providers with YoY comparison" config = { metrics = [ { type = "basic", value = "cost" }, { type = "basic", value = "usage" } ] aggregation = "total" time_interval = "month" data_source = "billing" time_range = { mode = "last" amount = 3 include_current = true unit = "month" } secondary_time_range = { amount = 1, unit = "year", include_current = false } filters = [{ id = "cloud_provider", type = "fixed", mode = "is" values = ["amazon-web-services", "google-cloud"] }] group = [{ id = "cloud_provider", type = "fixed" }] layout = "table" display_values = "actuals_only" currency = "USD" }}Se precisar descobrir IDs e tipos de dimensão válidos para filtros e agrupamentos, o data source doit_dimensions entrega um catálogo completo — chega de chutar.
Além do FinOps
Os recursos centrais de FinOps são por onde a maioria dos times começa, mas o provider cobre bem mais coisa da plataforma DoiT. Algumas dessas funcionalidades você pode nem saber que existem no console — e gerenciá-las como código é uma ótima forma de descobri-las.
Pergunte para a Ava direto do Terraform
Sim, dá para consultar a Ava — a assistente de IA da DoiT — diretamente da sua configuração Terraform. O que torna isso especialmente útil é poder referenciar IDs de relatórios de outros recursos Terraform no seu prompt:
data "doit_ava" "report_summary" { question = "Can you summarize report ${doit_report.monthly_costs.id} for me?"}
output "report_summary" { value = data.doit_ava.report_summary.answer}Crie um relatório e, logo em seguida, peça à Ava para explicá-lo — tudo no mesmo terraform apply. Também dá para usar isso em consultas rápidas como "Quais são meus 3 principais serviços de nuvem por custo neste mês?" e direcionar a resposta para outputs do Terraform.
Consultas analíticas ad-hoc
Às vezes você não precisa de um relatório persistido — só quer responder a uma pergunta. O data source doit_report_query roda consultas do Cloud Analytics na hora e retorna JSON estruturado, que você pode parsear, transformar ou exportar:
data "doit_report_query" "cost_by_provider" { config = { metrics = [{ type = "basic", value = "cost" }] aggregation = "total" time_interval = "month" currency = "USD" time_range = { mode = "last", amount = 3, include_current = true, unit = "month" } group = [{ id = "cloud_provider", type = "fixed" }] }}
locals { result = jsondecode(data.doit_report_query.cost_by_provider.result_json) columns = [for s in local.result.schema : s.name]}
resource "local_file" "query_csv" { filename = "cost_by_provider.csv" content = join("\n", concat( [join(",", local.columns)], [for row in local.result.rows : join(",", [for cell in row : cell == null ? "" : tostring(cell)])] ))}Isso é especialmente útil para cost gates em CI/CD — rode uma consulta no pipeline, verifique se o gasto ultrapassa um threshold e quebre o build se for o caso. Você também pode usar doit_report_result para buscar resultados de relatórios já salvos.
Diagramas de nuvem como fluxogramas Mermaid
O provider inclui 12 data sources para a funcionalidade Cloud Diagrams, cobrindo busca, exportação, relacionamentos, snapshots e estatísticas. Um caso de uso criativo: gerar fluxogramas Mermaid a partir da topologia da sua infraestrutura em nuvem, que dá para embutir diretamente em READMEs, páginas do Confluence ou relatórios de incidente.
data "doit_cloud_diagrams_search" "project" { query = "my-gcp-project"}
data "doit_cloud_diagrams_schemes" "diagram" { layer_ids = [data.doit_cloud_diagrams_search.project.scheme[0].ss_id] components = true link = true}
locals { ss = data.doit_cloud_diagrams_schemes.diagram.statussheet[ data.doit_cloud_diagrams_search.project.scheme[0].ss_id ]
node_lines = [ for id, n in local.ss.node : " ${id}[\"${replace(coalesce(n.name, id), "\"", "#quot;")}\"]" ]
edge_lines = [ for id, l in local.ss.link : l.connection_type != null ? " ${l.origin._id} -->|${l.connection_type}| ${l.destination._id}" : " ${l.origin._id} --> ${l.destination._id}" ]
mermaid = join("\n", concat(["flowchart LR"], local.node_lines, local.edge_lines))}
output "mermaid" { value = local.mermaid}Cole a saída no mermaid.live ou em qualquer renderizador de Markdown e você terá uma representação visual dos relacionamentos da sua infraestrutura — diffs de topologia ao longo do tempo, snapshots de compliance ou só uma visão rápida do que está conectado a quê.
Compartilhamento e controle de acesso
Gerenciar quem pode ver seus recursos de FinOps costuma ficar para depois — até o dia em que não dá mais. O recurso doit_sharing permite definir permissões para relatórios, budgets, alertas e alocações:
locals { permissions = [ { user = data.doit_current_user.me.email, role = "owner" }, ]}
resource "doit_sharing" "report" { resource_type = "reports" resource_id = doit_report.monthly_costs.id permissions = local.permissions public = "viewer" # Grant org-wide read access}Defina seus conjuntos de permissões uma vez em locals e aplique-os de forma consistente em todos os recursos compartilhados. Combine isso com doit_user para o onboarding de novos integrantes do time e doit_roles para descobrir as roles disponíveis — tudo direto da sua configuração Terraform.
Anotações e labels
Já olhou para um pico de custo de seis meses atrás e ficou se perguntando o que tinha acontecido? As anotações permitem documentar eventos de custo — deploys, migrações, incidentes — diretamente sobre seus dados de custo:
resource "doit_label" "infrastructure" { name = "infrastructure" color = "blue"}
resource "doit_annotation" "black_friday" { content = "AWS cost spike due to Black Friday traffic" timestamp = "2024-11-29T00:00:00Z" reports = [doit_report.monthly_costs.id] labels = [doit_label.infrastructure.id]}Labels e suas atribuições oferecem tagging cross-resource — categorize relatórios, alertas e anotações por time, projeto ou qualquer taxonomia que faça sentido para a sua organização.
Organização em escala com pastas
À medida que sua configuração de FinOps gerenciada por Terraform cresce, as pastas mantêm tudo no lugar. Elas suportam aninhamento e funcionam tanto para relatórios quanto para alocações:
resource "doit_folder" "analytics" { name = "Analytics" description = "Cloud Analytics reports and dashboards"}
resource "doit_folder" "cost_reports" { name = "Cost Reports" description = "Monthly and quarterly cost breakdowns" parent_folder_id = doit_folder.analytics.id}
resource "doit_report" "monthly_costs" { name = "Monthly Cost Overview" folder_id = doit_folder.cost_reports.id # ... report config ...}Também dá para personalizar a identidade visual dos seus analytics com temas customizados — defina paletas de cores para os modos claro e escuro que se aplicam aos gráficos dos relatórios do Cloud Analytics, deixando seus dashboards com um visual caprichado e alinhado à marca.
Onboarding do AWS CloudConnect
Conectar contas AWS ao DoiT costuma ser um processo de várias etapas: criar uma IAM role, configurar um bucket S3, registrar a conta. Publicamos um módulo Terraform dedicado que cuida da stack inteira em um único terraform apply:
module "doit_cloudconnect" { source = "doitintl/doit-cloudconnect/aws" version = "~> 1.0"}O módulo cria a IAM role, o bucket S3 e o registro no CloudConnect de uma vez só. Para empresas fazendo o onboarding de dezenas de contas, use-o com for_each sobre uma lista de contas. Se precisar de mais controle, o recurso subjacente doit_cloudconnect_aws_account está disponível para uso direto.
Insights customizados
Se você roda suas próprias verificações de otimização — varrendo recursos ociosos, identificando oportunidades de right-sizing, sinalizando problemas de segurança — pode publicar os achados direto no console da DoiT:
resource "doit_insight" "unused_instances" { key = "unused-ec2-instances" title = "Unused EC2 Instances" short_description = "EC2 instances with consistently low CPU utilization" cloud_provider = "aws" categories = ["FinOps"]}Combine isso com doit_insight_resource_results para anexar achados por recurso, e seu motor de otimização customizado passa a mostrar os resultados ao lado dos insights nativos da DoiT.
O padrão de composabilidade
Em todos esses exemplos, dá para perceber um tema recorrente: os data sources são a cola. Em vez de deixar IDs de dimensão, nomes de serviço ou e-mails de usuário cravados no código, você descobre tudo em tempo de plan:
data "doit_dimensions" "all" {}
locals { dimension_types = { for id, types in { for d in data.doit_dimensions.all.dimensions : d.id => d.type... } : id => types[0] }}Esse mapa de lookup de dimensões é reutilizável em relatórios, budgets, alertas e alocações — escreva uma vez e referencie local.dimension_types["region"] em todo lugar. Da mesma forma, doit_current_user elimina e-mails cravados no código, doit_products descobre valores válidos para filtros de serviço e doit_platforms lista os provedores de nuvem disponíveis para a sua organização.
Em desenvolvimento ativo e open source
O provider teve 5 releases menores nos quatro meses desde o lançamento da v1.0, em fevereiro de 2026, e cada uma trouxe novos recursos e data sources. Entre os destaques recentes estão suporte a Cloud Diagrams, temas customizados de console, gestão de pastas, compartilhamento e controle de acesso, onboarding do AWS CloudConnect e o data source da Ava AI.
Se você ainda está em uma release v0.x, este é um ótimo momento para atualizar. As versões v0.x eram um technical preview — a linha v1.x é a estável e pronta para produção, com migração automática de estado para tornar a transição tranquila. Confira o Guia de Upgrade da v1.0.0 para as instruções de migração.
O provider é open source em github.com/doitintl/terraform-provider-doit. Aceitamos issues, feature requests e contribuições. Todo recurso conta com testes de aceitação que rodam contra a API real da DoiT, e o módulo CloudConnect AWS é o primeiro de uma série de módulos de mais alto nível que combinam recursos do provider em padrões prontos para uso.
Comece agora
- Instale a partir do Terraform Registry
- Crie uma API key
- Explore a documentação completa para detalhes de schema e mais exemplos
- Dê uma estrela no repositório do GitHub e conte para a gente o que gostaria de ver a seguir
Suas práticas de FinOps merecem o mesmo controle de versão, peer review e reprodutibilidade que sua infraestrutura. Experimente o provider e coloque seu cloud intelligence sob código.