How to Version Modules in Terraform: Simple Guide
To version a module in Terraform, specify the module source with a version constraint using
version or a versioned source URL like a Git tag or registry version. This ensures Terraform uses the exact module version you want for consistent deployments.Syntax
Terraform modules can be versioned by specifying a version argument when using modules from the Terraform Registry, or by referencing a specific Git tag, branch, or commit in the module source. This controls which module version Terraform downloads and uses.
- source: The location of the module (registry, Git repo, local path).
- version: (Optional) The version constraint for registry modules.
- ref: (Optional) Git reference like tag, branch, or commit hash.
terraform
module "example" { source = "terraform-aws-modules/vpc/aws" version = "~> 3.0" # module inputs here } # Or for Git source module "example_git" { source = "git::https://github.com/org/repo.git//modules/vpc?ref=v1.2.0" # module inputs here }
Example
This example shows how to use a specific version of a module from the Terraform Registry and a Git module with a version tag. It ensures Terraform uses the exact module code version for stable infrastructure.
terraform
terraform {
required_version = ">= 1.0"
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 3.14.0"
name = "my-vpc"
cidr = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b", "us-east-1c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
}
module "custom_module" {
source = "git::https://github.com/example/custom-terraform-modules.git//networking/vpc?ref=v1.0.1"
vpc_name = "custom-vpc"
cidr_block = "10.1.0.0/16"
}Output
Terraform will download version 3.14.0 of the AWS VPC module from the registry and version v1.0.1 of the custom module from Git, ensuring consistent module code.
Common Pitfalls
Common mistakes when versioning Terraform modules include:
- Not specifying a
versionfor registry modules, which can cause unexpected upgrades. - Using
refincorrectly in Git sources, like missing the?ref=query. - Referencing mutable branches (e.g.,
main) instead of fixed tags or commits, leading to unpredictable changes. - Mixing local paths with versioning, which does not support version constraints.
terraform
/* Wrong: No version constraint, can cause unexpected upgrades */ module "vpc" { source = "terraform-aws-modules/vpc/aws" } /* Right: Specify version to lock module */ module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "~> 3.14.0" } /* Wrong: Git source without ref, uses latest branch */ module "custom" { source = "git::https://github.com/example/repo.git//module" } /* Right: Git source with fixed tag ref */ module "custom" { source = "git::https://github.com/example/repo.git//module?ref=v1.0.0" }
Quick Reference
| Concept | Usage | Notes |
|---|---|---|
| source | Defines module location | Can be registry, Git URL, or local path |
| version | Locks module version (registry only) | Use semantic version constraints like "~> 1.2" |
| ref | Git reference (tag/branch/commit) | Use in Git source URL query string, e.g. ?ref=v1.0.0 |
| Local modules | Use relative paths | No versioning support, changes tracked by VCS |
| Version constraints | Control module upgrades | Avoid surprises by pinning versions |
Key Takeaways
Always specify a version constraint for modules from the Terraform Registry to ensure stable deployments.
Use Git source URLs with a fixed ref (tag or commit) to version modules stored in Git repositories.
Avoid using mutable branches like 'main' for module sources to prevent unexpected changes.
Local modules do not support versioning; use version control systems to track changes.
Versioning modules helps maintain consistent infrastructure and avoid surprises during terraform runs.