Shared modules save weeks of work, but unpinned ones change underneath you.
The source argument says where a module comes from:
- Local path:
./modules/vpc(no version; it's your code). - Registry:
terraform-aws-modules/vpc/awsfrom the public Terraform Registry, with aversionconstraint such as~> 6.0. - Git:
git::https://github.com/acme/tf-modules.git//network?ref=v1.4.0, where//networkis a subdirectory andrefa tag, branch or commit. SSH URLs (git::ssh://git@github.com/...) work too, using your SSH keys. - Private registries (HCP Terraform, Terraform Enterprise, Artifactory, GitLab), and archives over HTTP or in S3/GCS buckets.
Version pinning matters: registry modules use the version argument; git sources pin with ref. Tags are convenient but movable; a commit SHA is fully immutable.
Evaluate a public module before adopting it: maintainer, activity, how many inputs it has, and whether its abstractions fit you. The community terraform-aws-modules collection is a common choice for networking and EKS.
terraform init downloads modules into .terraform/modules; after changing a source or version, run terraform init -upgrade (or plain init for a new module).
Publishing your own: a git repo with semver tags (v1.4.0) is enough for git sources; the public registry requires the terraform-<PROVIDER>-<NAME> repository naming.
Example
module "vpc" {
source = "terraform-aws-modules/vpc/aws" # public registry
version = "~> 6.0"
name = "main"
cidr = "10.0.0.0/16"
azs = ["eu-west-1a", "eu-west-1b"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
}
module "service" {
# git source, subdirectory //ecs-service, pinned to a tag
source = "git::https://github.com/acme/tf-modules.git//ecs-service?ref=v1.4.0"
name = "shop-api"
vpc_id = module.vpc.vpc_id
}
# terraform init -> Downloading registry.terraform.io/terraform-aws-modules/vpc/aws 6.x.yRemember
- Registry sources take version; git sources pin with ?ref=
- // selects a subdirectory in a repo or archive
- Pin modules as carefully as providers
Watch out for
- Pointing a git source at a branch like main, so a merge elsewhere changes your next plan.