Terraform Version Constraint Parser

Get the actual range a constraint allows. The one worth checking is ~>, where two components and three components mean different things and both look equally deliberate.

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 Parse. 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.

A minor-freedom constraint

Two components, so the minor may move and the next major cannot arrive

"~> 5.0"

No upper bound

Satisfied by any future major, so a breaking release can land with no change from you

">= 1.5.0"

A set nothing satisfies

Init fails every run, and the message sounds like a missing version in the registry

">= 2.0.0, < 1.0.0"

Common mistakes

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

  1. Writing ~> 5.2.0 when you meant to allow minor releases

    Three components pins the minor. 5.3.0 is excluded, so a minor release with a fix you want never arrives and the constraint looks like it should allow it.

    Instead:Write ~> 5.2 for minor freedom, and ~> 5.2.0 only when you genuinely want patches only.

  2. Leaving a provider constraint open-ended

    A major release can remove arguments, and with no upper bound the next init picks it up. Nothing in your repository changed, so the break is not attributable to any commit.

    Instead:Use ~> with two components. It allows everything useful and excludes the next major.

  3. Pinning a provider to an exact patch version

    The lock file already records the exact version, so the constraint adds nothing except blocking provider bug fixes.

    Instead:Constrain with ~> and let .terraform.lock.hcl hold the exact version. Commit the lock file.

~> 1.2 and ~> 1.2.0 are not the same constraint

The pessimistic operator lets the rightmost component you wrote increment. How much freedom that gives depends entirely on how many components you wrote, which is why two constraints that look alike behave differently.

Two components lets the minor move

~> 5.0 means at least 5.0.0 and less than 6.0.0. The minor is the rightmost component, so 5.1, 5.31 and 5.99 are all allowed and 6.0.0 is not. This is what most people want from a provider: bug fixes and new resources arrive, and a major cannot land without an edit.

Three components lets only the patch move

~> 5.2.0 means at least 5.2.0 and less than 5.3.0. Now the patch is the rightmost component, so 5.3.0 is excluded. That is a much tighter pin than it looks, and a minor release carrying a fix you need will not be picked up until somebody changes this line.

No upper bound means a major can arrive on its own

>= 1.5.0 is satisfied by 2.0.0 and by 9.0.0. A provider major is allowed to remove arguments, and a core major has removed syntax before. Because nothing changed in your repository, the failure lands on whoever runs init next and looks like their problem.

An exact pin is right for core and usually wrong for a provider

For a provider, .terraform.lock.hcl already records the exact version, so pinning the constraint too just stops patch fixes. For required_version an exact pin means every person and every pipeline must match, which is defensible when a container image or a .terraform-version file guarantees it and a support burden otherwise.

A contradiction reads like a registry problem

>= 2.0.0, < 1.0.0 admits nothing. Terraform reports that it could not find a matching version, which sounds like the registry is missing something rather than like the constraint being impossible. Bounds that merely touch, such as >= 2.0.0, < 2.0.0, fail the same way.

A prerelease is never matched by a range

1.0.0-beta1 is only selected by an exact constraint. So >= 1.0.0-beta1 will not pick up beta2, and once the final release exists it is not what you get either. Pin exactly while you need a prerelease, and move off it when there is a release.

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 Resource Count Calculator How many objects, not how many blocks 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 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