Skip to main content
Module versioning is the final piece to understand when working with Terraform modules. Modules (for example, those published to the Terraform Registry) are released and versioned independently from the root configuration that consumes them. This separation allows module authors to iterate—adding features, fixing bugs, or responding to provider API changes—while giving consumers control over when to adopt those changes. Below is a simple usage example that references a community VPC module from the Terraform Registry without pinning a version:
If you do not pin module versions, a future terraform init could fetch a newer module release that contains breaking changes, which may cause your configuration to fail.
A purple infographic titled "Module Versioning" showing an Application Module with stacked version blocks (v5.10.0 through v5.14.0) on the left. Arrows point from those versions to three configuration diagrams on the right labeled "Baseline Configuration", "Added New Functionality", and "Provider API Changed."

Pinning a module version

To ensure repeatable behavior, add the version argument to the module block for Registry sources. For example, require exactly v5.12.0:
When you run terraform init, Terraform will download the specified version (5.12.0) and continue to use it until you change the version constraint.

Semantic version constraints

Semantic versioning (semver) lets you control which updates are acceptable. Use the appropriate constraint depending on your risk tolerance and testing processes. The table below summarizes common constraints and their meanings: Choose a constraint that balances stability and the ability to receive non-breaking updates.

Upgrading module versions

When you’ve tested a newer module version in development or staging and want to adopt it in your environment:
  • Download and upgrade modules to satisfy updated constraints: terraform init -upgrade
  • Or run terraform init, which will download module versions that conform to the existing constraint.
Example workflows:
  • Lock to a tested exact version for production, and update the version attribute only after validation.
  • Use ~> constraints in non-production environments to receive safe updates automatically, and lock exact versions in production.
Always pin module versions for production code. Test upgrades in non-production environments before applying them in production.

Key takeaways

  • Modules are versioned independently of the root configuration—pin versions to ensure repeatable, stable deployments.
  • Use semantic version constraints to control acceptable updates and reduce the risk of unexpected breaking changes.
  • Test new module releases in non-production environments. When ready, update the version and run terraform init -upgrade to fetch newer releases.
I will next demonstrate how to author a local module and how to consume modules from the official Terraform Registry so you can practice writing, consuming, and managing module versions.

Watch Video