Terraform Professional study materials
Terraform Professional study resources

Terraform Professional: Designing, Publishing, and Consuming Reusable Modules

Terraform Professional · Work through your exam, one topic at a time.

All guide sections

Designing, Publishing, and Consuming Reusable Modules

Contracts

A module is an interface: input variables, outputs, and a provider contract. Every module should declare required_providers (with configuration_aliases for multi-region patterns) and required_version, and should never contain a backend block or a provider block - those belong to the root module. Callers pass alternate providers explicitly with providers = { aws = aws.us_east_1 }.

Sources and call sites

A local source must begin with ./ or ../; otherwise Terraform resolves it as a registry address or a URL. The version argument is valid only for registry modules, so pin git sources with ?ref=v1.4.0. Modules accept count and for_each, but keys must be known at plan time - never derive them from resource attributes. Outputs marked sensitive stay sensitive through every consumer.

Publication

Terraform Registry naming is terraform-<PROVIDER>-<NAME>, and versions come from git tags such as v1.2.0, which must be valid semantic versions. A consumable module ships main.tf, variables.tf, outputs.tf, a README, examples/ that double as fixtures, and ideally .tftest.hcl files. Commit the lock file for root modules; many teams omit it in shared modules so providers resolve in the consumer. Providers are cached under .terraform/modules, and terraform init -upgrade only updates modules within their declared constraints.

Trap

The classic trap is provider scoping: for_each over a module creates distinct instances, yet each still receives the default provider unless you pass an alias explicitly. The second is expecting terraform init -upgrade to bump a module whose version constraint already pins it - it will not.

Rule of thumb

Design around one responsibility, expose only the variables callers genuinely vary, and prefer a module output over terraform_remote_state for intra-configuration data flow.