CoStudy

HomeCertificationsTerraform Associate 004 › Modules

Modules — Terraform Associate 004 practice questions

25 multiple-choice questions and 12 flashcards on Modules, about 10% of the Terraform Associate 004 bank. Every one carries a written rationale.

Written and maintained by Nick Burton · last updated 2026-08-22 · how we write and review questions

What this chapter covers

Modules is one of 8 chapters in CoStudy's Terraform Associate (004) bank, and it holds 25 of the bank's 250 multiple-choice questions — roughly 10% of the total. That proportion is not arbitrary: chapters follow the certifying body's published exam outline, and the number of questions in each is set by that domain's published weight, so the share of your practice time this chapter takes matches the share of the real exam it accounts for.

Studying by chapter is worth doing once you have a diagnostic score. A single overall percentage tells you whether you are close; it does not tell you which domain is dragging. Working a weak chapter in isolation, and re-testing it in isolation, is the fastest way to move a score that has stalled — and it is why the mock exams in CoStudy report by domain rather than as one number.

Free Modules practice questions

10 questions drawn from this chapter, with the full rationale shown — the controlling principle behind the right answer, and why each wrong option tempts and fails.

Which statement about the public Terraform Registry is correct?

  1. Only HashiCorp employees are permitted to publish modules to the public registry
  2. Every module in the public registry requires a paid subscription before it can be downloaded
  3. Anyone may publish; a Verified badge marks modules maintained by a HashiCorp partner
  4. Registry modules cannot be pinned, because semantic version tags are not supported

Answer: C — Anyone may publish; a Verified badge marks modules maintained by a HashiCorp partner

C is right: the public registry is open to anyone whose module lives in a suitably named public repository, and the Verified badge is a curation signal indicating a partner-maintained module, not a precondition for publishing. A and B invert that openness. D is the opposite of how the registry works: modules are versioned from the repository's semantic version tags, and you pin one with the version argument in the module block — pinning module and provider versions is standard practice.

Which 'source' value points a module call to the public Terraform Registry?

  1. github.com/terraform-aws-modules/terraform-aws-vpc
  2. https://registry.terraform.io/terraform-aws-modules/vpc/aws
  3. registry://terraform-aws-modules/vpc/aws
  4. terraform-aws-modules/vpc/aws

Answer: D — terraform-aws-modules/vpc/aws

Trick: the registry shorthand is NAMESPACE/NAME/PROVIDER (no scheme). The GitHub URL form works but doesn't pull from the registry (so version constraints work differently).

A team calls one module once per team, driven by a map of settings keyed by team name. Which approach and reference style are correct?

  1. Use `count` with `length(var.teams)` and reference instances as `module.team["platform"]`
  2. Use `for_each` over the map and reference an instance's output as `module.team[0].vpc_id`
  3. Duplicate the module block once per team, since neither `for_each` nor `count` is permitted on a module block
  4. Use `for_each` over the map, read settings via `each.value`, and reference `module.team["platform"].vpc_id`

Answer: D — Use `for_each` over the map, read settings via `each.value`, and reference `module.team["platform"].vpc_id`

D) Correct — `for_each` over a map produces instances keyed by the map key, `each.value` supplies the per-instance settings, and instances are addressed by key. A) mixes the two: `count` produces integer-indexed instances, which cannot be addressed by a string key. B) does the reverse, applying integer indexing to a `for_each` result. C) is factually wrong — both `count` and `for_each` are supported meta-arguments on `module` blocks.

A child module creates a subnet, and the root module needs that subnet's id. Which pair of steps is required?

  1. Declare an `output` in the child, then reference `module.<name>.<output>` in the root
  2. Reference `module.<name>.aws_subnet.main.id` directly from the root, with no change to the child
  3. Declare an `output` in the root and a matching `variable` in the child, then let Terraform bind them
  4. Add the subnet resource address to the child's `depends_on` so the value is exported to the caller

Answer: A — Declare an `output` in the child, then reference `module.<name>.<output>` in the root

A) Correct — outputs are a module's published interface, and the caller reads them through the `module.<name>.<output>` reference. B) assumes resources inside a module are addressable from outside for expressions; module internals are encapsulated and only outputs are exposed. C) reverses the direction of flow — variables carry values in, outputs carry values out. D) misuses `depends_on`, which affects ordering and never exports values.

A child module declares no provider blocks but uses aws resources. Which is true?

  1. The child module implicitly creates its own default aws provider configuration at init
  2. The child module bypasses providers and calls the AWS API with ambient credentials
  3. Terraform reports an error during init, because the child declares no provider block
  4. The child module inherits the default aws provider configuration from its calling module

Answer: D — The child module inherits the default aws provider configuration from its calling module

D is right: default (unaliased) provider configurations are inherited down the module tree, which is why most reusable modules contain no provider blocks at all. A is the misconception this item targets — the child does not conjure a configuration of its own. B misunderstands the architecture, since every resource is realised through a provider. C is wrong, and in fact declaring provider blocks inside shared modules is discouraged; aliased configurations are instead passed in explicitly with the providers argument.

A module manages application resources that must not be created until a separately managed platform module has finished, and the dependency runs through side effects rather than any passed value. Which meta-argument on the `module` block addresses this?

  1. depends_on, listing the other module so all of its resources complete first
  2. lifecycle, with create_before_destroy set on the module block
  3. providers, mapping the platform module's provider into the application module
  4. count, set from a value the platform module outputs to force ordering

Answer: A — depends_on, listing the other module so all of its resources complete first

A) Correct — `depends_on` on a module block makes every resource in that module wait for the referenced object, which is the documented tool for dependencies Terraform cannot infer. B) is invalid: `lifecycle` is a resource-level block and is not a module meta-argument. C) is a real module meta-argument but it selects provider configurations, not ordering. D) is a hack that also breaks: deriving `count` from another module's output creates a value dependency but is fragile and can make the count unknown at plan time.

Which is NOT a supported module source in Terraform?

  1. Terraform Registry (registry.terraform.io)
  2. A local path beginning with './' or '../'
  3. A GitHub repository URL
  4. A Slack workspace URL

Answer: D — A Slack workspace URL

Trick: Slack isn't a module source. Supported: Registry, local paths, Git (generic/GitHub/Bitbucket), HTTP(S), S3, GCS, Mercurial.

To call the same module three times with different inputs in a single configuration, you should:

  1. Write three module blocks with distinct names, each passing its own argument values.
  2. Use the count or for_each meta-argument on a single module block to make three instances.
  3. Either approach works — three named module blocks, or one block with count or for_each.
  4. Neither — a module source can only be instantiated once per configuration directory.

Answer: C — Either approach works — three named module blocks, or one block with count or for_each.

C is right because both forms are legal: repeated module blocks and a single block with count or for_each both produce three instances. A alone is incomplete, since it ignores the meta-arguments that exist precisely for this case. B alone is incomplete for the same reason in reverse. D is the outright misconception — module reuse is the point of modules. Prefer for_each when the instances are parameterised by data.

An organisation wants approved internal modules discoverable by their engineers but not by anyone outside the company. Which statement is correct?

  1. Publishing to the public registry with a private flag restricts visibility to the publishing organisation
  2. The public registry is the only registry Terraform supports, so internal sharing must use raw Git source URLs
  3. A private registry, such as the one in HCP Terraform, hosts internal modules with the versioned interface of the public registry
  4. Private modules must be vendored into each repository, since only the public registry supports the `version` argument

Answer: C — A private registry, such as the one in HCP Terraform, hosts internal modules with the versioned interface of the public registry

C) Correct — a private registry gives internal modules discoverability and registry-style versioned sourcing while keeping them inside the organisation. A) invents a private-publishing flag; the public registry is public by definition. B) is false — Terraform supports private registries, and while Git sources do work, they are not the only option. D) misstates the mechanism: `version` works for private registry sources too, which is one of the main reasons to run one.

What is a Terraform module?

  1. A reusable package of configuration - resources, variables and outputs - called by others
  2. A plugin binary that translates configuration into API calls against a particular platform
  3. The JSON document that records which real resources correspond to configuration addresses
  4. A named alias for a separate state file used to keep environments apart in one directory
  5. An editor extension that adds HCL syntax highlighting and completion to the configuration

Answer: A — A reusable package of configuration - resources, variables and outputs - called by others

A is right: a module packages resources behind declared inputs and outputs and is called with a module block and a source argument; the working directory is the root module. B is a provider, C is state, D is a workspace and E is tooling - each a different concept the exam likes to confuse with modules.

Modules flashcards

3 cards from the 12 in this chapter.

Module versioning?

version = "~> 2.0". Pin version for reproducibility.

Which module source types support the version argument, and how do you pin a Git-sourced module instead?

The version argument works only for modules sourced from a registry — the public Terraform Registry or a private registry. Modules sourced from Git, HTTP, or a local path must be pinned inside the source string itself, for example with a ?ref=v1.2.0 tag or commit reference on a Git URL. A local path module cannot be versioned at all.

Module?

Container for resources used together. Reusable. Either local or remote.

Practise the full chapter

These are a sample. The full Modules chapter runs 37 items with per-chapter progress tracking, on the web and in the iOS app.

Open Terraform Associate 004 in CoStudy →

Other Terraform Associate 004 chapters

All Terraform Associate 004 practice questions →