{
  "name": "Terraform Cost Estimator",
  "url": "https://tools.finitizer.com/terraform-cost-estimator",
  "purpose": "See what your Terraform changes could cost on AWS, Google Cloud or Azure before you deploy.",
  "lastReviewed": "2026-11-04",
  "accepts": {
    "planJson": "terraform show -json output: before, after and the change.",
    "terraformSource": ".tf and .tf.json files, read without running Terraform: the monthly cost of what they configure.",
    "githubFolder": "A link to a public folder: read by the browser, with its local modules and the public modules it uses.",
    "infracostJson": "infracost breakdown --format json: re-priced where its components say what the price depends on."
  },
  "method": [
    "Each resource is priced from its own arguments at public on-demand list prices in US dollars, over a 730-hour month.",
    "A plan shows before, after and the change: a delete removes cost, an update prices the difference, a replacement counts the old and new resource once each.",
    "Source is expanded as Terraform would: count, for_each, conditionals, for expressions, splats, dynamic blocks, locals, module inputs and outputs, and optional() defaults.",
    "Usage an input cannot state, such as traffic through a NAT gateway, takes a small stated default, or the figure or profile given. The summary reports how much of the total is assumed.",
    "Anything not priced is listed by name with the reason, never counted as zero."
  ],
  "certainty": {
    "complete": "Everything in the input was priced.",
    "floor": "Something was not priced and each missing piece can only add cost, so the figure is a lower bound.",
    "open": "Something was not priced and it could move the figure either way, such as an unpriced delete or an unknown count."
  },
  "forAgents": {
    "api": {
      "url": "https://tools.finitizer.com/terraform-cost-estimator/api",
      "method": "POST",
      "openapi": "https://tools.finitizer.com/terraform-cost-estimator/openapi.json",
      "privacy": "The request is priced in memory and dropped with the response. It is not stored or logged.",
      "example": {
        "files": [
          {
            "name": "main.tf",
            "text": "resource \"aws_ebs_volume\" \"data\" {\n  availability_zone = \"us-east-1a\"\n  size = 100\n  type = \"gp3\"\n}\n"
          }
        ]
      },
      "modules": "The API does not fetch modules. Unread ones are listed in configuration.unreadModules: send plan JSON instead, or use a browser, which reads up to 15 repositories."
    },
    "withABrowser": {
      "linkToAPublicFolder": "https://tools.finitizer.com/terraform-cost-estimator?github=https://github.com/OWNER/REPO/tree/BRANCH/FOLDER",
      "linkToASample": "https://tools.finitizer.com/terraform-cost-estimator?sample=aws-web",
      "input": "#tf-input",
      "estimateButton": "[data-testid=\"estimate-cost\"]",
      "headline": "[data-testid=\"headline\"]",
      "figure": "[data-testid=\"headline-figure\"]",
      "lineItems": "[data-testid=\"breakdown\"]",
      "notPriced": "[data-testid=\"not-priced\"]"
    },
    "noCredentials": "Nothing here needs an account, a key or a cloud login."
  },
  "pricedResourceTypes": {
    "aws": [
      "aws_acmpca_certificate_authority",
      "aws_alb",
      "aws_autoscaling_group",
      "aws_cloudfront_distribution",
      "aws_cloudwatch_log_group",
      "aws_cloudwatch_metric_alarm",
      "aws_db_instance",
      "aws_docdb_cluster",
      "aws_docdb_cluster_instance",
      "aws_dynamodb_table",
      "aws_ebs_snapshot",
      "aws_ebs_volume",
      "aws_ec2_transit_gateway_peering_attachment",
      "aws_ec2_transit_gateway_vpc_attachment",
      "aws_ecs_service",
      "aws_efs_file_system",
      "aws_eip",
      "aws_eks_cluster",
      "aws_eks_node_group",
      "aws_elasticache_cluster",
      "aws_elasticache_replication_group",
      "aws_elasticsearch_domain",
      "aws_elb",
      "aws_instance",
      "aws_kinesis_stream",
      "aws_kms_key",
      "aws_lambda_function",
      "aws_lb",
      "aws_msk_cluster",
      "aws_nat_gateway",
      "aws_networkfirewall_firewall",
      "aws_opensearch_domain",
      "aws_rds_cluster",
      "aws_rds_cluster_instance",
      "aws_redshift_cluster",
      "aws_route53_resolver_endpoint",
      "aws_route53_zone",
      "aws_s3_bucket",
      "aws_sagemaker_endpoint",
      "aws_secretsmanager_secret",
      "aws_vpc_endpoint",
      "aws_vpc_endpoint_subnet_association",
      "aws_wafv2_web_acl"
    ],
    "gcp": [
      "google_alloydb_cluster",
      "google_alloydb_instance",
      "google_bigquery_capacity_commitment",
      "google_bigquery_reservation",
      "google_bigquery_table",
      "google_bigtable_instance",
      "google_cloud_run_service",
      "google_cloud_run_v2_service",
      "google_compute_address",
      "google_compute_disk",
      "google_compute_forwarding_rule",
      "google_compute_global_forwarding_rule",
      "google_compute_instance",
      "google_compute_instance_group_manager",
      "google_compute_region_instance_group_manager",
      "google_compute_router_nat",
      "google_compute_snapshot",
      "google_compute_vpn_tunnel",
      "google_container_cluster",
      "google_container_node_pool",
      "google_dns_managed_zone",
      "google_filestore_instance",
      "google_kms_crypto_key",
      "google_redis_instance",
      "google_spanner_instance",
      "google_sql_database_instance",
      "google_storage_bucket",
      "google_vpc_access_connector"
    ],
    "azure": [
      "azurerm_api_management",
      "azurerm_app_service_plan",
      "azurerm_application_gateway",
      "azurerm_bastion_host",
      "azurerm_cdn_frontdoor_profile",
      "azurerm_container_group",
      "azurerm_container_registry",
      "azurerm_cosmosdb_mongo_collection",
      "azurerm_cosmosdb_mongo_database",
      "azurerm_cosmosdb_sql_container",
      "azurerm_cosmosdb_sql_database",
      "azurerm_eventhub_namespace",
      "azurerm_firewall",
      "azurerm_kubernetes_cluster",
      "azurerm_kubernetes_cluster_node_pool",
      "azurerm_lb",
      "azurerm_linux_virtual_machine",
      "azurerm_linux_virtual_machine_scale_set",
      "azurerm_managed_disk",
      "azurerm_mssql_database",
      "azurerm_mssql_elastic_pool",
      "azurerm_mysql_flexible_server",
      "azurerm_nat_gateway",
      "azurerm_orchestrated_virtual_machine_scale_set",
      "azurerm_postgresql_flexible_server",
      "azurerm_private_endpoint",
      "azurerm_public_ip",
      "azurerm_public_ip_prefix",
      "azurerm_redis_cache",
      "azurerm_service_plan",
      "azurerm_storage_account",
      "azurerm_virtual_machine",
      "azurerm_virtual_network_gateway",
      "azurerm_windows_virtual_machine",
      "azurerm_windows_virtual_machine_scale_set"
    ]
  },
  "workedExamples": [
    {
      "id": "aws-disk",
      "label": "Add a 100 GiB data disk",
      "blurb": "One AWS gp3 volume in us-east-1, as a .tf file. Small enough to check the arithmetic by hand.",
      "link": "https://tools.finitizer.com/terraform-cost-estimator?sample=aws-disk",
      "measure": "cost",
      "certainty": "complete",
      "figure": "$8.00 a month",
      "monthlyUsd": 8,
      "assumedUsd": 0,
      "top": [
        {
          "address": "aws_ebs_volume.example_data",
          "monthlyUsd": 8
        }
      ]
    },
    {
      "id": "aws-web",
      "label": "AWS web app",
      "blurb": "Two web servers behind a load balancer, PostgreSQL and NAT. The load balancer capacity units need a usage figure.",
      "link": "https://tools.finitizer.com/terraform-cost-estimator?sample=aws-web",
      "measure": "change",
      "certainty": "floor",
      "figure": "+$470.13 a month",
      "monthlyUsd": 470.12500000000006,
      "assumedUsd": 9.8,
      "top": [
        {
          "address": "aws_db_instance.orders",
          "monthlyUsd": 255.14000000000001
        },
        {
          "address": "aws_instance.web[0]",
          "monthlyUsd": 72.48
        },
        {
          "address": "aws_instance.web[1]",
          "monthlyUsd": 72.48
        }
      ]
    },
    {
      "id": "aws-kubernetes",
      "label": "AWS Kubernetes",
      "blurb": "An EKS cluster, three worker nodes, a NAT gateway per zone and private ECR endpoints: the costs around the nodes.",
      "link": "https://tools.finitizer.com/terraform-cost-estimator?sample=aws-kubernetes",
      "measure": "change",
      "certainty": "floor",
      "figure": "+$694.18 a month",
      "monthlyUsd": 694.18,
      "assumedUsd": 13.5,
      "top": [
        {
          "address": "aws_eks_node_group.workers",
          "monthlyUsd": 432.48
        },
        {
          "address": "aws_eks_cluster.main",
          "monthlyUsd": 73
        },
        {
          "address": "aws_nat_gateway.az[0]",
          "monthlyUsd": 37.35
        }
      ]
    },
    {
      "id": "gcp-web",
      "label": "Google Cloud web app",
      "blurb": "Two VMs, a regional Cloud SQL database, an SSD and a bucket. Sustained use discounts show on the VM lines.",
      "link": "https://tools.finitizer.com/terraform-cost-estimator?sample=gcp-web",
      "measure": "change",
      "certainty": "complete",
      "figure": "+$504.11 a month",
      "monthlyUsd": 504.113648,
      "assumedUsd": 2,
      "top": [
        {
          "address": "google_sql_database_instance.orders",
          "monthlyUsd": 231.246
        },
        {
          "address": "google_compute_instance.web[0]",
          "monthlyUsd": 118.433824
        },
        {
          "address": "google_compute_instance.web[1]",
          "monthlyUsd": 118.433824
        }
      ]
    },
    {
      "id": "gcp-kubernetes",
      "label": "Google Cloud GKE",
      "blurb": "A regional GKE cluster whose node pool runs in three zones: two nodes per zone is six nodes, not two.",
      "link": "https://tools.finitizer.com/terraform-cost-estimator?sample=gcp-kubernetes",
      "measure": "change",
      "certainty": "complete",
      "figure": "+$1,307.84 a month",
      "monthlyUsd": 1307.8400784,
      "assumedUsd": 0.8,
      "top": [
        {
          "address": "google_container_node_pool.general",
          "monthlyUsd": 1234.0400784
        },
        {
          "address": "google_container_cluster.main",
          "monthlyUsd": 73
        },
        {
          "address": "google_cloud_run_v2_service.api",
          "monthlyUsd": 0.8
        }
      ]
    },
    {
      "id": "azure-web",
      "label": "Azure web app",
      "blurb": "Two VMs in a scale set behind a load balancer, PostgreSQL with a standby, NAT and storage. Disks bill by tier.",
      "link": "https://tools.finitizer.com/terraform-cost-estimator?sample=azure-web",
      "measure": "change",
      "certainty": "floor",
      "figure": "+$653.88 a month",
      "monthlyUsd": 653.884,
      "assumedUsd": 9.08,
      "top": [
        {
          "address": "azurerm_linux_virtual_machine_scale_set.web",
          "monthlyUsd": 300.734
        },
        {
          "address": "azurerm_postgresql_flexible_server.orders",
          "monthlyUsd": 289.32
        },
        {
          "address": "azurerm_nat_gateway.main",
          "monthlyUsd": 37.35
        }
      ]
    },
    {
      "id": "azure-kubernetes",
      "label": "Azure AKS",
      "blurb": "AKS on the Standard tier, a pool that autoscales, a geo-replicated registry and a WAF gateway: the costs around the nodes.",
      "link": "https://tools.finitizer.com/terraform-cost-estimator?sample=azure-kubernetes",
      "measure": "change",
      "certainty": "floor",
      "figure": "+$2,274.66 a month",
      "monthlyUsd": 2274.6648333333333,
      "assumedUsd": 65.03999999999999,
      "top": [
        {
          "address": "azurerm_kubernetes_cluster_node_pool.workers",
          "monthlyUsd": 887.68
        },
        {
          "address": "azurerm_kubernetes_cluster.main",
          "monthlyUsd": 733.72
        },
        {
          "address": "azurerm_application_gateway.ingress",
          "monthlyUsd": 551.88
        }
      ]
    }
  ],
  "limits": [
    "Public list prices only: negotiated discounts, Savings Plans, Reserved Instances, committed use discounts and Azure reservations are not applied.",
    "Steady-state monthly figures: one-time charges and a partial first month are not included.",
    "Source is read without running Terraform, so a value from a data source or live state is unknown. A plan is more exact.",
    "A .tfvars file is never read. Pass variable values directly."
  ],
  "checks": "Each rate source is listed on the page with the date it was read."
}
