0
0
TerraformHow-ToBeginner · 4 min read

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 version for registry modules, which can cause unexpected upgrades.
  • Using ref incorrectly 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

ConceptUsageNotes
sourceDefines module locationCan be registry, Git URL, or local path
versionLocks module version (registry only)Use semantic version constraints like "~> 1.2"
refGit reference (tag/branch/commit)Use in Git source URL query string, e.g. ?ref=v1.0.0
Local modulesUse relative pathsNo versioning support, changes tracked by VCS
Version constraintsControl module upgradesAvoid 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.