Bird
Raised Fist0
Terraformcloud~5 mins

Module versioning in Terraform - Commands & Configuration

Choose your learning style10 modes available
Introduction
When you use Terraform modules, you want to control which version of the module your infrastructure uses. Module versioning helps you pick a specific version so your setup stays stable and predictable.
When you want to reuse a module from the Terraform Registry but need a specific version to avoid unexpected changes.
When you maintain your own modules and want to update your infrastructure only after testing a new module version.
When working in a team and you want everyone to use the same module version for consistency.
When you want to roll back to a previous module version if a new one causes issues.
When you want to track which module version your infrastructure is currently using.
Config File - main.tf
main.tf
terraform {
  required_version = ">= 1.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 4.0"
    }
  }
}

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "3.14.2"

  name = "example-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["us-east-1a", "us-east-1b", "us-east-1c"]
  public_subnets  = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  private_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]

  enable_nat_gateway = true
}

The terraform block sets the Terraform and provider versions to ensure compatibility.

The module block pulls the VPC module from the Terraform Registry at version 3.14.2. This fixed version ensures your infrastructure uses a tested and stable module release.

The rest of the module configuration defines the VPC settings like CIDR and subnets.

Commands
This command initializes the Terraform working directory. It downloads the specified module version and provider plugins.
Terminal
terraform init
Expected OutputExpected
Initializing the backend... Initializing provider plugins... - Finding hashicorp/aws versions matching ">= 4.0"... - Installing hashicorp/aws v4.50.0... - Installed hashicorp/aws v4.50.0 (signed by HashiCorp) Initializing modules... - module.vpc Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work.
This command shows what Terraform will do to create or update your infrastructure using the specified module version.
Terminal
terraform plan
Expected OutputExpected
Refreshing Terraform state in-memory prior to plan... An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # module.vpc.aws_vpc.main will be created + resource "aws_vpc" "main" { + cidr_block = "10.0.0.0/16" + enable_dns_support = true + enable_dns_hostnames = true + tags = { + "Name" = "example-vpc" } } Plan: 1 to add, 0 to change, 0 to destroy.
This command applies the planned changes and creates the infrastructure using the module version specified.
Terminal
terraform apply -auto-approve
Expected OutputExpected
module.vpc.aws_vpc.main: Creating... module.vpc.aws_vpc.main: Creation complete after 5s [id=vpc-0a1b2c3d4e5f6g7h8] Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
→
-auto-approve - Automatically approves the apply without asking for confirmation
This command lists all resources Terraform manages, showing that the module's resources are tracked.
Terminal
terraform state list
Expected OutputExpected
module.vpc.aws_vpc.main
Key Concept

If you remember nothing else from this pattern, remember: specifying a module version locks your infrastructure to a tested module release, preventing unexpected changes.

Common Mistakes
Not specifying the module version in the module block.
Terraform will use the latest module version, which may introduce breaking changes or unexpected behavior.
Always include the 'version' argument in the module block to lock to a specific module version.
Using an invalid or non-existent module version.
Terraform will fail to download the module, causing initialization errors.
Check the module's available versions on the Terraform Registry and use a valid version string.
Changing the module version without running 'terraform init' again.
Terraform will not download the new module version, so your infrastructure will still use the old one.
Run 'terraform init' after changing the module version to download the new version.
Summary
Define the module source and version in your Terraform configuration to control which module release is used.
Run 'terraform init' to download the specified module version and providers.
Use 'terraform plan' and 'terraform apply' to preview and apply infrastructure changes with the locked module version.
Check managed resources with 'terraform state list' to confirm module resources are tracked.

Practice

(1/5)
1. What is the main purpose of specifying a version when using a Terraform module from a registry?
easy
A. To speed up Terraform plan execution
B. To enable local module usage
C. To automatically update the module to the latest version
D. To keep your infrastructure stable by locking the module version

Solution

  1. Step 1: Understand module versioning purpose

    Specifying a version locks the module to a specific release, preventing unexpected changes.
  2. Step 2: Compare options

    Only locking the version ensures stability; automatic updates or speed improvements are not guaranteed by versioning.
  3. Final Answer:

    To keep your infrastructure stable by locking the module version -> Option D
  4. Quick Check:

    Module versioning = Stability [OK]
Hint: Version locks module to prevent unexpected changes [OK]
Common Mistakes:
  • Thinking version speeds up execution
  • Assuming version auto-updates modules
  • Confusing local modules with versioned modules
2. Which of the following is the correct syntax to specify a module version from the Terraform Registry?
easy
A. module "example" { source = "registry/module" version = "1.2.0" }
B. module "example" { source = "registry/module" ver = "1.2.0" }
C. module "example" { source = "registry/module" version: "1.2.0" }
D. module "example" { source = "registry/module" v = "1.2.0" }

Solution

  1. Step 1: Recall correct version attribute

    The correct attribute to specify module version is version with an equals sign.
  2. Step 2: Check syntax correctness

    module "example" { source = "registry/module" version = "1.2.0" } uses correct attribute and syntax; others use incorrect attribute names or syntax.
  3. Final Answer:

    module "example" { source = "registry/module" version = "1.2.0" } -> Option A
  4. Quick Check:

    Correct attribute is version = "x.y.z" [OK]
Hint: Use 'version = "x.y.z"' exactly for module versions [OK]
Common Mistakes:
  • Using 'ver' or 'v' instead of 'version'
  • Using colon instead of equals sign
  • Omitting quotes around version number
3. Given this Terraform module block:
module "network" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "3.0.0"
}

What happens if a newer version 3.1.0 is released and you run terraform init without changing the version?
medium
A. Terraform upgrades the module to version 3.1.0 automatically
B. Terraform uses version 3.0.0 and does not upgrade automatically
C. Terraform throws an error about version mismatch
D. Terraform ignores the version and uses the latest

Solution

  1. Step 1: Understand version locking behavior

    Specifying version "3.0.0" locks the module to that exact version.
  2. Step 2: Effect of terraform init

    Running terraform init downloads the locked version; it does not upgrade unless version is changed.
  3. Final Answer:

    Terraform uses version 3.0.0 and does not upgrade automatically -> Option B
  4. Quick Check:

    Locked version stays fixed until changed [OK]
Hint: Locked version stays fixed unless manually updated [OK]
Common Mistakes:
  • Assuming terraform init upgrades modules automatically
  • Expecting errors on version mismatch
  • Thinking latest version is always used
4. You have this module block:
module "db" {
  source = "git::https://github.com/example/db-module.git"
}

You want to use a specific version tag v1.4.2. What is missing?
medium
A. Add tag = "v1.4.2" inside the block
B. Add version = "v1.4.2" inside the block
C. Add ?ref=v1.4.2 to the source URL
D. Nothing, it uses latest by default

Solution

  1. Step 1: Understand versioning for Git modules

    Git modules use URL query parameter ?ref= to specify version or tag.
  2. Step 2: Identify correct way to specify tag

    Adding ?ref=v1.4.2 to source URL locks module to that tag.
  3. Final Answer:

    Add ?ref=v1.4.2 to the source URL -> Option C
  4. Quick Check:

    Git module version = source URL + ?ref=tag [OK]
Hint: Use ?ref=tag in Git source URL for versioning [OK]
Common Mistakes:
  • Using version attribute for Git modules
  • Using tag attribute which does not exist
  • Assuming latest is always used without specifying ref
5. You have a local module at ./modules/app and a remote module from the registry. You want to ensure only the remote module uses versioning. How should you configure the modules?
hard
A. Specify version only for the remote module; omit for local module
B. Specify version for both local and remote modules
C. Specify version only for the local module
D. Omit version for both modules

Solution

  1. Step 1: Recall versioning rules for local modules

    Local modules do not support versioning; version attribute is ignored or causes error.
  2. Step 2: Apply version only to remote modules

    Only remote modules from registries or Git support versioning and require version locking.
  3. Final Answer:

    Specify version only for the remote module; omit for local module -> Option A
  4. Quick Check:

    Version only for remote modules [OK]
Hint: Version attribute only for remote modules, never local [OK]
Common Mistakes:
  • Adding version to local modules causing errors
  • Omitting version for remote modules causing instability
  • Confusing local and remote module versioning rules
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard