Cost as code (also called FinOps as code) means running the objects of cost control the way you run code: budgets and their alerts, the activation of tags, cost categories and exports sit as versioned definitions in a repository and are created through Terraform or the providers' APIs rather than by hand in the console. Alongside them sit the APIs through which scripts and tools read cost. This page covers those two parts. Estimating a change's cost before deployment is covered in cost in the development lifecycle, and enforcing rules in enforcing tagging rules as code.
How it works
Each provider separates reading from managing. Reading runs through a query API or an export, managing through the resources of the Terraform providers.
| Reading cost | What reading costs | As a Terraform resource | |
|---|---|---|---|
| AWS | Cost Explorer API for aggregated queries, Data Exports for line items | USD 0.01 per API request | aws_budgets_budget, aws_budgets_budget_action, aws_ce_cost_allocation_tag, aws_ce_cost_category, aws_bcmdataexports_export |
| Azure | Exports API for recurring exports, Cost Details API for small pulls | no price stated, but rate limited | azurerm_consumption_budget_subscription (and for resource groups and management groups), azurerm_subscription_cost_management_export |
| Google Cloud | SQL on the BigQuery export; the Cloud Billing APIs manage accounts, budgets and prices | BigQuery queries and storage | google_billing_budget |
AWS
The Cost Explorer API returns the same data as the interface (AWS Cost Explorer and AWS Budgets), but every request against the primary billing view costs USD 0.01, and fetching a further page of results with the NextPageToken is another request. In Terraform a budget is a resource with an amount, a period (daily, monthly, quarterly, annually) and notifications that fire on actual or forecasted cost, as a percentage or an absolute value, to email addresses or SNS topics. aws_ce_cost_allocation_tag sets a tag key active or inactive as a cost allocation tag; new keys can take up to 24 hours to appear for activation. The provider's default_tags puts tags on every resource it manages.
Azure
For ingesting cost data Microsoft recommends the Exports API, and the Cost Details API for small datasets only; its size limits are in Azure Cost Management. For a script, the cadence is what counts: Microsoft advises querying at most once a day, because more frequent calls return identical data, and a report covers at most one month. In azurerm_consumption_budget_* thresholds are always percentages between 0 and 1000, on actual or forecasted cost, with email addresses, action groups or roles as recipients.
Google Cloud
Among its billing APIs Google lists the Cloud Billing Budget API, the Cloud Billing Account API, the Cloud Billing Catalog API and the Pricing API (Preview), but no query API for cost; cost data is read with SQL from the export to BigQuery (Google Cloud billing export). google_billing_budget sets thresholds as percentages, can send every update of the spend to a Pub/Sub topic, fixes how credits count (by default, all included) and who may see the budget. The provider's default_labels puts labels on all resources.
Price list APIs (AWS Price List, Azure Retail Prices, Cloud Billing Catalog) are inputs to estimates and belong to the development lifecycle.
What it means for your cost
A budget that exists as code changes only through a pull request. Lowering a threshold or dropping a recipient leaves a diff, a review and a commit that a later decision can point to (traceability of cost decisions). New accounts, subscriptions or projects get their budget, exports and tags in the same module as their resources, so coverage does not depend on someone remembering the console. How budgets and thresholds are designed stays with budgets and budget alerts.
Code has a second effect: it wins over the console. A normal terraform plan reads the current state of the remote objects and proposes to bring them back to the configuration; the -refresh-only mode merely records outside changes in the state. A budget edited in the console reverts at the next apply unless the change makes its way back into the code.
The managed objects themselves cost little: at AWS only action-enabled budgets from the third onwards are charged (budgets, worked through in the example below), and delivered budget reports at USD 0.01 each. Reading becomes expensive when a script polls a billed API more often than the data changes.
Where it goes wrong
- A billed API polled by the minute. A monitoring script calls the Cost Explorer API every few minutes, and the API shows up as a line of its own on the invoice. The cause: every request is charged, and AWS commits only to refreshing Cost Explorer data at least once every 24 hours. On Azure, Microsoft states that more frequent Cost Details calls return identical data, and the API is rate limited.
- Budgets created twice. One account receives two alerts for the same threshold, or a console change disappears after the next deployment. The cause: some budgets were created by hand and some in code, and nobody imported or deleted the old ones.
- State and configuration in public. A repository holding a state file or variables is publicly readable. The cause: Terraform keeps values in its state in plain text, and budget notifications hold recipients' email addresses. AWS says account IDs are not considered secret but should be shared carefully; HashiCorp advises keeping state out of Git and storing it remotely, encrypted and access-controlled.
- Tag set but never activated. Resources carry the tag through
default_tags, yet Cost Explorer still shows the cost as untagged. The cause: activation as a cost allocation tag is an object of its own (aws_ce_cost_allocation_tag) and is missing from the code; why an inactive tag does not count is explained in AWS Cost Explorer and AWS Budgets. - A Google budget failing with 403. Terraform fails to create a budget with user credentials. The cause: the Budget API then requires a
billing_projectanduser_project_overridein the provider.
How open-source tools estimate cost and apply rules is covered in open-source tools.
Example
AWS publishes these prices in US dollars without naming a Region (read on 2026-10-16): USD 0.01 per Cost Explorer API request against the primary billing view, and USD 0.10 a day for each action-enabled budget from the third onwards.
| In a 30-day month | Calculation | Cost |
|---|---|---|
| A script polls every 5 minutes, one page of results | 12 × 24 × 30 = 8,640 requests × USD 0.01 | USD 86.40 |
| The same script once a day | 30 requests × USD 0.01 | USD 0.30 |
| Five action-enabled budgets | (5 − 2) × USD 0.10 × 30 days | USD 9.00 |
Sources
Read on 2026-10-16. AWS Cost Explorer, GetCostAndUsage, Cost Explorer pricing, AWS Budgets pricing and AWS account identifiers; Microsoft Cost Management automation overview and get small cost datasets on demand; Google Cloud Cloud Billing APIs; HashiCorp Terraform providers AWS with aws_budgets_budget, aws_budgets_budget_action, aws_ce_cost_allocation_tag, aws_ce_cost_category and aws_bcmdataexports_export, AzureRM with azurerm_consumption_budget_subscription and azurerm_subscription_cost_management_export, Google with google_billing_budget and the provider reference; HashiCorp manage sensitive data and terraform plan.