Module Sources and Versions

Scenario: A registry module releases a breaking change and an unpinned consumer selects it during the next init.

Registry modules support a version constraint; VCS sources should pin immutable tags or commit SHAs rather than mutable branches. Local sources are coupled to the repository version. terraform init downloads modules, while the provider lock file does not lock remote module versions in the same way—source pinning remains essential. Review third-party code because modules execute with the caller's provider credentials.

Analogy: A module source is a software dependency delivered with authority to modify infrastructure. Pinning it is choosing a reviewed edition, not grabbing whatever is on the shelf tomorrow.

A worked configuration

module "network" {
  source  = "app.terraform.io/platform/network/fakecloud"
  version = "~> 3.2"
  cidr    = var.cidr
}

Use an internal registry or curated source policy for discoverability and governance. Record upgrade notes, test plans, and state migrations. A module upgrade deserves the same rigor as an application library with database migration code.

Note: Treat the plan as a change contract: understand every create, update, replacement, and destroy before approving it.
Goal: Reinforce this lesson in the tf-version-lockfile Terraform lab. Open /labs/terraform and choose slug tf-version-lockfile; the lab runs real Terraform against the offline FakeCloud provider.