L'infrastruttura è sotto version control. Il codice applicativo passa dalle pull request. E la configurazione FinOps — budget, allocazioni di costo, alert e report di analytics?
Nella maggior parte dei team vive in una UI. Qualcuno clicca attraverso una procedura guidata, imposta una soglia, sceglie un filtro e spera che la prossima persona che dovrà modificarla riesca a capire l'intento iniziale. Niente cronologia, niente peer review, nessun modo per replicare la configurazione tra ambienti. Quando le pratiche FinOps sono critiche quanto l'infrastruttura, meritano lo stesso rigore.
È per questo che abbiamo realizzato il provider Terraform di DoiT. Porta la configurazione di DoiT Cloud Intelligence nello stesso workflow Infrastructure as Code che utilizza già per le risorse cloud — con 17 risorse gestite e 61 data source che coprono tutto: dai budget ai report, fino alle query all'assistente AI e ai diagrammi dell'infrastruttura cloud.
Come iniziare
Per partire bastano un blocco provider e una chiave API:
terraform { required_providers { doit = { source = "doitintl/doit" version = "~> 1.0" } }}
provider "doit" {}Imposti DOIT_API_TOKEN nel suo ambiente (le chiavi API si creano dalla DoiT Console) e il gioco è fatto. Tutto qui — nessuna configurazione aggiuntiva.
Il workflow FinOps essenziale
Vediamo le risorse a cui la maggior parte dei team ricorre per prime: allocazioni, budget, alert e report. Insieme formano una pipeline FinOps completa — e gestirle come codice significa poter versionare, revisionare e replicare l'intera configurazione.
Allocazioni di costo
Le allocazioni sono il modo in cui suddivide la spesa cloud in categorie significative. Il provider offre un motore di formule booleane per combinare criteri di filtro, group allocation che dividono i costi in bucket nominati e perfino allocazioni annidate che fanno riferimento ad altre allocazioni tramite ID.
Ecco una group allocation che suddivide i costi per regione, con un catch-all per tutto ciò che non rientra nei criteri:
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"] }] } ]}Le serve una granularità più fine? Usi type = "allocation_rule" in un component per fare riferimento a un'allocazione esistente — componendo allocazioni a partire da altre allocazioni, fino a 3 livelli di profondità. E invece di scrivere a mano valori di dimensione come "US" o "DE", può usare il data source doit_dimension per recuperare dinamicamente i valori validi dall'API.
Budget
I budget sono i guardrail. Il provider le consente di definire alert a più soglie, vincolare i budget ad allocazioni o dimensioni specifiche e — ecco un pattern utile — filtrare i collaboratori per ruolo aziendale invece di aggiungere tutti gli utenti dell'organizzazione:
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] }]}Questo budget si applica all'allocazione per regione appena creata e notifica solo gli utenti con la qualifica "Software / Ops Engineer". I budget supportano anche seasonal_amounts per i mesi in cui i target di spesa variano, mentre i campi calcolati come current_utilization e forecasted_utilization sono disponibili come output di sola lettura.
Alert
Gli alert generano notifiche quando i costi o l'utilizzo superano una soglia. La vera forza qui è lo scoping — può restringere un alert a uno specifico cloud provider, servizio, regione o a qualsiasi altra dimensione. Questo esempio usa il data source doit_products per recuperare dinamicamente l'ID del servizio Compute Engine, evitando di scriverlo a mano:
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]}Report
I report di Cloud Analytics sono la risorsa più ricca del provider. Può configurare fino a 4 metriche, aggiungere confronti year-over-year con secondary_time_range, applicare filtri e dimensioni di raggruppamento e organizzare i report in cartelle.
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 le servono ID e tipi di dimensione validi per filtri e raggruppamenti, il data source doit_dimensions offre un catalogo completo — basta con i tentativi al buio.
Oltre il FinOps
Le risorse FinOps di base sono il punto di partenza della maggior parte dei team, ma il provider copre una porzione molto più ampia della piattaforma DoiT. Alcune funzionalità forse non sa nemmeno che esistono nella console — e gestirle come codice è un ottimo modo per scoprirle.
Interrogare Ava da Terraform
Sì, può interrogare Ava — l'assistente AI di DoiT — direttamente dalla sua configurazione Terraform. La cosa particolarmente utile è che nel prompt può riferirsi agli ID dei report di altre risorse Terraform:
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}Crei un report e poi chieda subito ad Ava di spiegarglielo — il tutto nello stesso terraform apply. Può anche usarlo per ricerche rapide come "Quali sono i miei 3 servizi cloud più costosi questo mese?", indirizzando la risposta verso gli output di Terraform.
Query analitiche ad-hoc
A volte non le serve un report persistente: vuole solo una risposta a una domanda. Il data source doit_report_query esegue query di Cloud Analytics al volo e restituisce JSON strutturato pronto da analizzare, trasformare o esportare:
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)])] ))}È particolarmente utile per i cost gate in CI/CD: esegue una query durante la pipeline, verifica se la spesa supera una soglia e fa fallire la build in caso affermativo. Può anche usare doit_report_result per recuperare i risultati di report salvati esistenti.
Cloud Diagrams come flowchart Mermaid
Il provider include 12 data source per la funzionalità Cloud Diagrams, che coprono ricerca, esportazione, relazioni, snapshot e statistiche. Un caso d'uso creativo: generare flowchart Mermaid dalla topologia della sua infrastruttura cloud, da incorporare direttamente nei README, nelle pagine Confluence o nei report di incidenti.
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}Incolli l'output in mermaid.live o in qualunque renderer Markdown e otterrà una rappresentazione visiva delle relazioni della sua infrastruttura — diff topologici nel tempo, snapshot di conformità o semplicemente una panoramica rapida di cosa è collegato a cosa.
Condivisione e controllo degli accessi
Gestire chi può vedere le sue risorse FinOps è spesso un dettaglio rimandato — finché non diventa urgente. La risorsa doit_sharing le permette di definire i permessi per report, budget, alert e allocazioni:
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}Definisca i set di permessi una volta sola in locals e li applichi in modo coerente a ogni risorsa condivisa. Lo abbini a doit_user per l'onboarding dei nuovi membri del team e a doit_roles per scoprire i ruoli disponibili — tutto dalla sua configurazione Terraform.
Annotazioni ed etichette
Le è mai capitato di osservare un picco di costi di sei mesi fa e chiedersi cosa fosse successo? Le annotazioni le permettono di documentare gli eventi di costo — deployment, migrazioni, incidenti — direttamente sui dati di costo:
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]}Etichette e relative assegnazioni offrono un tagging trasversale alle risorse: può categorizzare report, alert e annotazioni per team, progetto o qualsiasi tassonomia abbia senso nella sua organizzazione.
Organizzare su larga scala con le cartelle
Man mano che la sua configurazione FinOps gestita con Terraform cresce, le cartelle mantengono l'ordine. Supportano l'annidamento e funzionano sia con i report sia con le allocazioni:
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 ...}Può anche dare un tocco di branding alle sue analytics con temi personalizzati — definisca palette di colori per modalità chiara e scura da applicare ai grafici dei report di Cloud Analytics, per dashboard dall'aspetto curato e in linea con il brand.
Onboarding di AWS CloudConnect
Collegare account AWS a DoiT è di norma un processo in più fasi: creare un ruolo IAM, configurare un bucket S3, registrare l'account. Abbiamo pubblicato un modulo Terraform dedicato che gestisce l'intero stack in un singolo terraform apply:
module "doit_cloudconnect" { source = "doitintl/doit-cloudconnect/aws" version = "~> 1.0"}Il modulo crea ruolo IAM, bucket S3 e registrazione CloudConnect in un colpo solo. Per le aziende che devono onboardare decine di account, lo combini con for_each su un elenco di account. Se le serve un controllo più granulare, la risorsa sottostante doit_cloudconnect_aws_account è disponibile per l'uso diretto.
Insight personalizzati
Se esegue controlli di ottimizzazione propri — scansione di risorse inutilizzate, opportunità di right-sizing, segnalazione di problemi di sicurezza — può pubblicare i risultati direttamente nella console 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"]}Lo abbini a doit_insight_resource_results per allegare i risultati a livello di singola risorsa: così il suo motore di ottimizzazione personalizzato farà emergere i risultati accanto agli insight nativi di DoiT.
Il pattern della componibilità
In tutti questi esempi noterà un filo conduttore: i data source sono il collante. Invece di scrivere a mano ID di dimensione, nomi di servizio o email degli utenti, li recupera al momento del 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] }}Questa mappa di lookup delle dimensioni è riutilizzabile in report, budget, alert e allocazioni: la scriva una volta e usi local.dimension_types["region"] dovunque. Allo stesso modo, doit_current_user elimina le email scritte a mano, doit_products scopre i valori validi per i filtri di servizio e doit_platforms elenca i cloud provider disponibili alla sua organizzazione.
In sviluppo attivo e open source
Il provider ha avuto 5 release minori nei quattro mesi dal lancio della v1.0 a febbraio 2026, ognuna con nuove risorse e data source. Tra le novità recenti: supporto per Cloud Diagrams, temi personalizzati per la console, gestione delle cartelle, condivisione e controllo degli accessi, onboarding di AWS CloudConnect e il data source AI di Ava.
Se è ancora su una release v0.x, è il momento giusto per aggiornare. Le versioni v0.x erano una technical preview — la v1.x è la linea stabile e pronta per la produzione, con migrazione automatica dello stato per una transizione fluida. Consulti la Guida all'upgrade alla v1.0.0 per le istruzioni di migrazione.
Il provider è open source su github.com/doitintl/terraform-provider-doit. Accogliamo volentieri issue, richieste di funzionalità e contributi. Ogni risorsa ha test di accettazione che girano sull'API reale di DoiT, e il modulo CloudConnect AWS è il primo di una serie di moduli di livello superiore che combinano le risorse del provider in pattern pronti all'uso.
Inizi subito
- Installi il provider dal Terraform Registry
- Crei una chiave API
- Consulti la documentazione completa per i dettagli sugli schemi e altri esempi
- Metta una stella al repo GitHub e ci dica cosa vorrebbe vedere come prossima novità
Le sue pratiche FinOps meritano lo stesso version control, peer review e riproducibilità della sua infrastruttura. Provi il provider e porti la sua cloud intelligence sotto codice.