Terraform Resource Count Calculator

Count the objects a configuration creates, rather than the blocks it contains. Bind any variables above the blocks and the count and for_each expressions are evaluated for real.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Calculate. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

Two blocks, five objects

The count that matters is the instances, not the blocks in the file

zones = ["a", "b", "c"]

resource "aws_subnet" "private" {
  for_each = toset(zones)
}

resource "aws_instance" "web" {
  count = 2
}

A variable that came through false

Plans as a destroy of everything that exists, and looks like a deliberate removal

enabled = false

resource "aws_instance" "bastion" {
  count = enabled ? 1 : 0
}

for_each on a string

Terraform needs a map or a set: a list has positions, which is what for_each avoids

resource "aws_subnet" "private" {
  for_each = "a-string"
}

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Raising -parallelism to speed up a large apply

    The bottleneck is usually the provider's API rate limit rather than Terraform. More concurrency produces throttling and retries, which is slower.

    Instead:Check the provider's limits first. If the apply is genuinely too big, split the state instead.

  2. Passing a list to for_each

    A list has positions, not keys, and for_each exists to avoid positions. Terraform refuses rather than converting.

    Instead:Wrap it in toset(), and check the count afterwards because toset drops duplicates.

  3. Letting a variable arrive empty in CI

    An empty collection means zero instances, which plans as a destroy of everything that exists. It looks identical to a deliberate removal.

    Instead:Add a validation block on the variable, and read the destroy count in every plan before approving it.

Apply time and blast radius both follow the instance count

A file with four resource blocks can create four objects or four hundred. The number that matters is never visible in the file.

Terraform applies ten at a time by default

So three hundred instances is thirty rounds, plus whatever the provider's rate limiter does to them. Raising -parallelism is the obvious move and usually the wrong one: the common result is throttling and retries, which is slower than the limit you were trying to beat.

An expansion to zero destroys what exists

count = 0 or an empty for_each is legal and means the resource is not created. If instances already exist, that plan destroys all of them. It is the shape of an accidental teardown when a variable arrives empty from CI, and the plan looks exactly like a deliberate removal.

for_each rejects a list

It needs a map or a set of strings. A list has positions rather than keys, and positions are the thing for_each exists to avoid, so Terraform refuses rather than converting. toset() is the usual fix, and it also collapses duplicates, which silently reduces the count.

count needs a whole number and does not convert a bool

count = var.enabled is an error even though the intent is obvious. The conditional form count = var.enabled ? 1 : 0 is what Terraform wants, and it is the one case where count beats for_each.

An expression that cannot be resolved is what "known after apply" means

If the count depends on something Terraform cannot know until it applies, it cannot tell you the number either. That is why a plan sometimes cannot say what it will do: it does not know how many of a thing there will be.

Nested modules multiply

A module with count = 3 containing a resource with for_each over five items creates fifteen objects. This page counts the blocks you paste, so a module call counts as its own expansion rather than as everything inside it.

More terraform tools

Terraform Validator & Formatter Does it parse, and is it formatted? Terraform dynamic Block Generator It is ingress.value, not each.value Terraform check and precondition Generator A failed check does not stop the apply Terraform variables.tf Generator From the var. references you already wrote Terraform Unused Declaration Linter Dead variables, locals and data sources Terraform Atlantis YAML Generator when_modified misses your modules Terraform Function Tester and HCL Console terraform console, in a tab Terraform for Expression Tester Where do the keys collide? Terraform Interpolation Tester null becomes an empty string Terraform templatefile Tester Render it before you apply it Terraform count to for_each Converter With the moved blocks it needs Terraform moved Block Generator Rename without destroying Terraform state mv Command Builder No plan, no undo Terraform target Flag Builder And why to stop using it Terraform outputs.tf Generator Outputs are not sensitive by default Terraform Remote State Data Source Generator It grants read of the whole state Terraform Provider Block Generator docker is not hashicorp/docker Terraform .gitignore Generator and Checker .terraform* eats the lock file Terraform to OpenTofu Migration Checker The state is the part to watch Terraform tfvars to JSON Converter The JSON file wins Terraform Version Constraint Parser What ~> actually allows Terraform Resource Address Parser Quote it before the shell eats it Terraform cidrsubnet Calculator newbits is added, not the target Terraform Import Block Generator The id is not the name Terraform Lock File Viewer Why CI fails and your laptop does not Terraform Variables Checker A missing value hangs CI Terraform tfvars to Env Vars Converter Lists and maps have to be JSON Terraform Deprecated Syntax Checker What a current Terraform rejects Terraform State File Viewer Read it without uploading it Terraform Plan JSON Viewer It is not redacted Terraform HCL to JSON Converter And what the conversion loses Terraform Module Source Validator version only works for the registry Terraform Backend Config Decoder Is state actually locked? Terraform Naming Convention Validator A hyphen makes a resource unreferenceable

Elsewhere on the site