Infracost

Cloud costs firmly under control with Infracost: estimate instead of marvel

Cloud services are flexible - but often expensive. When planning your infrastructure, you need more than just a gut feeling. Even good cost estimates can be inaccurate if important factors are missing. As a result, it often only becomes clear in retrospect how high the monthly costs actually are.

Particularly in the design phase, it can be difficult to make well-founded statements about the expected operating costs.

The CLI tool Infracost starts right here and enables the automated estimation of cloud infrastructure costs based on existing Terraform resources.

Logo infracost, source: https://www.infracost.io

As cloud infrastructure is generally not managed manually, but via Infrastructure as Code (IaC) tools such as Terraform should be defined, created and managed, the Terraform resources also reflect the actual cloud infrastructure very well. In order to estimate the costs involved, Infracost compares all Terraform resources used with the Infracost Cloud Pricing API which is updated once a week with the official prices of the cloud providers AWS, Azure and Google.

The advantage of this is that the cloud infrastructure does not even have to actually exist. The definition alone using Terraform is sufficient to obtain a cost estimate, i.e. even before the cloud infrastructure is created using "terraform apply" is rolled out. This allows cost risks to be identified at an early stage, budgets to be planned realistically and decisions to be made based on data. Infracost is therefore ideal for DevOps teams and cloud architects who want to avoid surprises.

How to use Infracost effectively in practice

Use case 1 - Knowing what your cloud costs before the rollout

This use case outlines the situation described above, where Terraform resources are defined but not yet available using "terraform apply" and the cloud infrastructure therefore does not yet exist at the planned cloud provider. In this case, the command "infracost breakdown --path .", which is to be executed in the file directory of the Terraform resources. Infracost produces the following output, for example, which in this example refers to Azure resources:

INFO Autodetected 1 Terraform project across 1 root module
INFO Found Terraform project main at directory . using Terraform var files terraform.tfvars

Project: main

 Name                                                                                          Monthly Qty  Unit                      Monthly Cost

 module.azurerm_kubernetes.azurerm_kubernetes_cluster.kubernetes_cluster
 └─ default_node_pool
    ├─ Instance usage (Linux, pay as you go, Standard_B2ms)                                            730  hours                           $70.08
    └─ os_disk
       └─ Storage (P10, LRS)                                                                             1  months                          $21.68

 module.azurerm_container_registry.azurerm_container_registry.container_registry
 ├─ Registry usage (Standard)                                                                           30  days                            $20.00
 ├─ Storage (over 100GB)                                                                Monthly cost depends on usage: $0.10 per GB
 └─ Build vCPU                                                                          Monthly cost depends on usage: $0.0001 per seconds

 module.azurerm_postgresql_database.azurerm_postgresql_flexible_server.database_server
 ├─ Compute (B_Standard_B1ms)                                                                          730  hours                           $14.53
 ├─ Storage                                                                                             32  GB                               $4.38
 └─ Additional backup storage                                                           Monthly cost depends on usage: $0.10 per GB

 module.azurerm_kubernetes.azurerm_public_ip.public_ip
 └─ IP address (static, regional)                                                                      730  hours                            $3.65

 module.azurerm_postgresql_database.azurerm_private_dns_zone.dns_zone
 └─ Hosted zone                                                                                          1  months                           $0.50

 module.azurerm_storage.azurerm_storage_account.storage_account
 ├─ Capacity                                                                            Monthly cost depends on usage: $0.0196 per GB
 ├─ Write operations                                                                    Monthly cost depends on usage: $0.054 per 10k operations
 ├─ List and create container operations                                                Monthly cost depends on usage: $0.054 per 10k operations
 ├─ Read operations                                                                     Monthly cost depends on usage: $0.0043 per 10k operations
 ├─ All other operations                                                                Monthly cost depends on usage: $0.0043 per 10k operations
 └─ Blob index                                                                          Monthly cost depends on usage: $0.039 per 10k tags

 OVERALL TOTAL                                                                                                                            $134.82

*Usage costs can be estimated by updating Infracost Cloud settings, see docs for other options.

──────────────────────────────────
13 cloud resources were detected:
∙ 6 were estimated
∙ 7 were free

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Project                                            ┃ Baseline cost ┃ Usage cost* ┃ Total cost ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━┫
┃ main                                               ┃          $135 ┃           - ┃       $135 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━┻━━━━━━━━━━━━┛

In this example, Infracost estimates the initial total costs of the planned cloud infrastructure per calendar month at $135. By default, however, only the baseline costs are taken into account, i.e. the fixed costs that are incurred regardless of the actual duration or frequency of use of the cloud infrastructure. If you do not specify any concrete quantities, the usage costs are not included in the estimate. This can lead to very inaccurate cost estimates, especially for data-driven projects, as the costs scale greatly with the amount of data: The more data is received, processed and stored via the cloud infrastructure at runtime, the higher its costs. Therefore, if a quantity structure that is as concrete as possible is already known, this should be used via the infracost-usage.yml can be specified (see Usage costs).

If you want to redirect each cost estimate to a JSON file and version it via Git, for example, you can use the "infracost breakdown --path . --format json --out-file <costs-file>" can be used, which is particularly interesting in Use Case 3.

Use Case 2 - How expensive is my current cloud infrastructure

This use case outlines the case where Terraform resources have already been applied, but no changes have been made to them. Here too, the command "infracost breakdown --path .", which should lead to the same output as in Use Case 1, provided the Terraform resources have not been changed in the meantime.

Important: As soon as actual costs are incurred by the cloud provider, these costs should be regularly compared with the costs estimated by Infracost in order to validate them. If the actual costs are higher than the estimated costs, either cloud services are being used that have not been defined using Terraform and are therefore unknown to Infracost, or the usage costs have not been taken into account at all or only in part. In general, it should be noted that in all cases it is only a cost estimate, which in the best case differs only minimally from the actual costs.

Use Case 3 - Changing costs: How do changes affect my costs?

This use case outlines the case where changes are made to Terraform resources that have already been applied, which affect the costs of the cloud infrastructure. In the following example, a Kubernetes cluster node size was increased from "Standard_B2ms" on "Standard_B4ms". The command "infracost breakdown --path ." for use:

INFO Autodetected 1 Terraform project across 1 root module
INFO Found Terraform project main at directory . using Terraform var files terraform.tfvars

Project: main

 Name                                                                                          Monthly Qty  Unit                      Monthly Cost

 module.azurerm_kubernetes.azurerm_kubernetes_cluster.kubernetes_cluster
 └─ default_node_pool
    ├─ Instance usage (Linux, pay as you go, Standard_B4ms)                                            730  hours                          $140.16
    └─ os_disk
       └─ Storage (P10, LRS)                                                                             1  months                          $21.68

 module.azurerm_container_registry.azurerm_container_registry.container_registry
 ├─ Registry usage (Standard)                                                                           30  days                            $20.00
 ├─ Storage (over 100GB)                                                                Monthly cost depends on usage: $0.10 per GB
 └─ Build vCPU                                                                          Monthly cost depends on usage: $0.0001 per seconds

 module.azurerm_postgresql_database.azurerm_postgresql_flexible_server.database_server
 ├─ Compute (B_Standard_B1ms)                                                                          730  hours                           $14.53
 ├─ Storage                                                                                             32  GB                               $4.38
 └─ Additional backup storage                                                           Monthly cost depends on usage: $0.10 per GB

 module.azurerm_kubernetes.azurerm_public_ip.public_ip
 └─ IP address (static, regional)                                                                      730  hours                            $3.65

 module.azurerm_postgresql_database.azurerm_private_dns_zone.dns_zone
 └─ Hosted zone                                                                                          1  months                           $0.50

 module.azurerm_storage.azurerm_storage_account.storage_account
 ├─ Capacity                                                                            Monthly cost depends on usage: $0.0196 per GB
 ├─ Write operations                                                                    Monthly cost depends on usage: $0.054 per 10k operations
 ├─ List and create container operations                                                Monthly cost depends on usage: $0.054 per 10k operations
 ├─ Read operations                                                                     Monthly cost depends on usage: $0.0043 per 10k operations
 ├─ All other operations                                                                Monthly cost depends on usage: $0.0043 per 10k operations
 └─ Blob index                                                                          Monthly cost depends on usage: $0.039 per 10k tags

 OVERALL TOTAL                                                                                                                            $204.90

*Usage costs can be estimated by updating Infracost Cloud settings, see docs for other options.

──────────────────────────────────
13 cloud resources were detected:
∙ 6 were estimated
∙ 7 were free

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Project                                            ┃ Baseline cost ┃ Usage cost* ┃ Total cost ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━┫
┃ main                                               ┃          $205 ┃           - ┃       $205 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━┻━━━━━━━━━━━━┛

Infracost now estimates the costs of the changed cloud infrastructure per calendar month at $205, which represents an increase of $70 compared to Use Case 2.

To avoid having to calculate the cost difference yourself, you can alternatively use "infracost diff --path <new-costs-file> --compare-to <old-costs-file>" which leads to the following output:

Key: * usage cost, ~ changed, + added, - removed

──────────────────────────────────
Project: main

~ module.azurerm_kubernetes.azurerm_kubernetes_cluster.kubernetes_cluster
  +$70 ($92 → $162)

    ~ default_node_pool

        ~ Instance usage (Linux, pay as you go, Standard_B2ms → Standard_B4ms)
          +$70 ($70 → $140)

Monthly cost change for Kunde_doubleSlash/update-manager/additional/dsum-infrastructure/terraform/environments/dev
Amount:  +$70 ($135 → $205)
Percent: +52%

──────────────────────────────────
Key: * usage cost, ~ changed, + added, - removed

*Usage costs can be estimated by updating Infracost Cloud settings, see docs for other options.

13 cloud resources were detected:
∙ 6 were estimated
∙ 7 were free

Infracost estimate: Monthly estimate increased by $70 ↑
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Changed project                                                  ┃ Baseline cost ┃ Usage cost* ┃ Total change ┃
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━╋━━━━━━━━━━━━━╋━━━━━━━━━━━━━━┫
┃ Kunde_doubleSlash/update-manage...ure/terraform/environments/dev ┃          +$70 ┃           - ┃  +$70 (+52%) ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━┻━━━━━━━━━━━━━━┛

This approach is particularly useful for the use of Infracost in an automated CI/CD pipeline, whereby the older of the two JSON files can be versioned using Git, for example, and compared with a newly created JSON file. For the next execution of the pipeline, the versioned JSON file must then be overwritten with the newly created JSON file so that it contains the cost estimate of the Terraform resources actually used.

Not everyone can know everything

Infracost currently supports around 1,100 Terraform resources. If you use services that are not (yet) supported, the estimate may be incomplete.

Avoid unpleasant surprises with Infracost

Infracost offers enormous added value when it comes to proactively planning cloud infrastructure costs in conjunction with Terraform. Who Infrastructure as Code (IaC) should also think "Costs as Code". This is exactly what Infracost makes possible.

For two reasons, however, the following should always apply: Trust is good, control is better!

Reason 1: A cost estimate is just a cost estimate and does not necessarily have to correspond to the actual costs.

Reason 2: A cost estimate is only as good as the information that has been taken into account. A missing or inadequate quantity structure can greatly distort the cost estimate due to incorrect usage costs.

Marcel Sommer

About ME

Marcel Sommer has a Bachelor of Science in Applied Computer Science and has been working as a software developer at doubleSlash since 2016. He primarily deals with complex IT systems in the cloud environment. He uses his expertise in projects for well-known customers such as BMW AG and ZF, but also enjoys working with current technologies as part of internal research projects.

All contributions from Marcel Sommer

Learn more

Further information on our website and in our newsletter

Arrow up