HashiCorp Terraform Associate (004) Question 149
Single answer5c Use modules in configurationYour team maintains a reusable Terraform module named network in a private Git repository. The module creates a VPC and subnets and exposes outputs such as vpc_id and private_subnet_ids. A root configuration needs to consume this module for a new environment and then pass the resulting subnet IDs into an aws_instance resource defined in the root module. Which configuration best uses the module correctly and follows Terraform module usage patterns?
- A
module "network" { source = "git::https://example.com/terraform-modules/network.git?ref=v1.2.0" cidr_block = "10.20.0.0/16" }
resource "aws_instance" "app" { ami = "ami-123456" instance_type = "t3.micro" subnet_id = module.network.private_subnet_ids[0] }
- B
module "network" { source = "git::https://example.com/terraform-modules/network.git?ref=v1.2.0" cidr_block = "10.20.0.0/16" }
resource "aws_instance" "app" { ami = "ami-123456" instance_type = "t3.micro" subnet_id = network.private_subnet_ids[0] }
- C
resource "module" "network" { source = "git::https://example.com/terraform-modules/network.git?ref=v1.2.0" cidr_block = "10.20.0.0/16" }
resource "aws_instance" "app" { ami = "ami-123456" instance_type = "t3.micro" subnet_id = resource.module.network.private_subnet_ids[0] }
- D
module "network" { source = "git::https://example.com/terraform-modules/network.git?ref=v1.2.0" cidr_block = "10.20.0.0/16" }
resource "aws_instance" "app" { ami = "ami-123456" instance_type = "t3.micro" subnet_id = module.network.aws_subnet.private[0].id }
Show answer and explanation
Correct answer: A
Explanation
Terraform modules are used by declaring a module block in the calling configuration, often called the root module when it is the top-level configuration. Inputs are passed into the module as arguments in the module block, and values are returned from the child module only through output values. The caller then references those outputs with the syntax module.<MODULE_NAME>.<OUTPUT_NAME>. This abstraction is intentional: callers should not depend on internal resource names inside a module. For version control and repeatability, Terraform supports sourcing modules from VCS locations such as Git and pinning them with a ref. These patterns align with Terraform module documentation and recommended best practices for reusable infrastructure code.
- A. Correct.
Correct. A child module is declared with a
moduleblock, and the root module accesses values from that child module through its declared outputs using themodule.<NAME>.<OUTPUT>syntax. Referencingmodule.network.private_subnet_ids[0]is valid if the child module exportsprivate_subnet_idsas an output. Using a Git source URL with?ref=v1.2.0is also a valid way to pin a specific module version from a VCS source, which is a common best practice for predictable deployments. - B. Incorrect.
Incorrect. Terraform does not expose module outputs directly by the module name alone. The correct syntax is
module.network.private_subnet_ids[0], notnetwork.private_subnet_ids[0]. This option reflects a common misconception that modules behave like top-level objects without themodule.namespace. - C. Incorrect.
Incorrect. Modules are not created with a
resourceblock. Terraform has a dedicatedmoduleblock type for calling child modules. Likewise,resource.module.network...is not valid Terraform syntax. This distractor targets confusion between resources and modules, which are distinct constructs in Terraform configurations. - D. Incorrect.
Incorrect. A root module cannot directly reference resources inside a child module unless the child module explicitly exposes the needed values through outputs. Accessing
module.network.aws_subnet.private[0].idattempts to reach into the internals of the child module, which Terraform's module abstraction does not allow. The correct pattern is for the child module to define an output such asprivate_subnet_ids, and the root module should consume that output.