Courseiva

CCNA Interact with Terraform modules Questions

49 questions · Interact with Terraform modules · All types, answers revealed

1
MCQhard

You have two modules that create resources in different providers. Module A creates a VPC in AWS, Module B creates a Kubernetes cluster that requires the VPC ID. You want to ensure Module B runs after Module A but avoid hardcoding the VPC ID. Which approach is most appropriate?

A.Use a data source in Module B to look up the VPC.
B.Output the VPC ID from Module A and pass it as input to Module B.
C.Use terraform graph to order modules.
D.Use module dependency via depends_on in the root module.
AnswerB

The correct approach involves Module A exposing the VPC ID through an `output` block, making it accessible to the root module. This output is then referenced in the root module and explicitly passed as an `input variable` to Module B. Terraform's dependency graph automatically infers that Module A must successfully provision the VPC before Module B can consume its ID, ensuring both correct data flow and proper execution order.

Why this answer

It establishes an explicit data dependency between modules without hardcoding values. By outputting the VPC ID from Module A and passing it as an input variable to Module B, Terraform's dependency graph automatically ensures Module A is created before Module B, and the VPC ID is dynamically available at plan time.

Exam trap

Candidates often confuse dependency ordering (via depends_on) with data passing (via outputs/inputs). In Terraform, depends_on only ensures creation order but does not pass data; outputs and input variables are required to share values between modules.

How to eliminate wrong answers

Option A is wrong because using a data source to look up the VPC assumes the VPC already exists outside of Terraform management, which contradicts the requirement that Module A creates the VPC; data sources cannot create dependencies on resources defined in the same configuration. Option C is wrong because terraform graph only visualizes the dependency graph and does not enforce execution order or pass data between modules. Option D is wrong because depends_on only ensures ordering but does not pass the VPC ID value; Module B would still need the VPC ID as an input, which depends_on alone cannot provide.

2
MCQhard

An organization stores their Terraform modules in a private Git repository. They need to reference a module that resides in a subdirectory called 'modules/rds' within the repository 'infra-modules' on the main branch. Which source argument should be used?

A.source = "git::https://github.com/org/infra-modules.git//modules/rds"
B.source = "git::https://github.com/org/infra-modules.git"
C.source = "git::https://github.com/org/infra-modules.git:modules/rds"
D.source = "git::https://github.com/org/infra-modules.git//rds"
AnswerA

This module source declaration is correctly formatted for a Git repository. The `git::` prefix explicitly tells Terraform to use the Git protocol. Crucially, the double-slash `//` acts as the required delimiter, separating the main repository URL from the subdirectory path `modules/rds` where the actual module code resides. This ensures Terraform fetches the specific module from its intended location within the repository.

Why this answer

Terraform's module source syntax for Git repositories uses a double slash (`//`) to specify a subdirectory within the repository. The format `git::https://github.com/org/infra-modules.git//modules/rds` tells Terraform to clone the repository at the main branch and then use the module located in the `modules/rds` subdirectory. This is the standard way to reference a module in a subdirectory of a Git repository.

Exam trap

The key trap in this question is that candidates confuse the double-slash (`//`) syntax with a colon (`:`) or forget to include the subdirectory path entirely, leading them to pick options that either point to the root or use incorrect separators.

How to eliminate wrong answers

Option B is wrong because it references the root of the repository, not the subdirectory `modules/rds`, so Terraform would look for the module in the repository root, which is incorrect. Option C is wrong because it uses a colon (`:`) to separate the repository URL from the subdirectory path, but Terraform requires a double slash (`//`) for subdirectory references in Git sources. Option D is wrong because it specifies `//rds` instead of `//modules/rds`, which would point to a non-existent subdirectory named `rds` at the repository root, not the correct path.

3
MCQmedium

What is the most likely cause of this error?

A.The module requires a version constraint.
B.The module source path does not exist.
C.The required_version is incompatible with the module.
D.The module input variable 'vpc_id' is not defined in the module.
AnswerB

When a local module is referenced using a relative or absolute file system path, Terraform attempts to locate and read the module's configuration files within that specified directory. If the directory indicated by the `source` attribute, such as './modules/networking', does not exist on the file system, Terraform cannot proceed with loading the module. This directly results in an error indicating that the module source path is invalid or cannot be found, preventing any further processing of the module's contents.

Why this answer

The error message indicates that the module source path does not exist. Terraform cannot find the specified local path for the module. Option A is incorrect because version constraints are not required for local module sources; they are used for registry modules.

Option C is incorrect because the `required_version` setting in Terraform configuration controls the Terraform version, not module sourcing. Option D is incorrect because the error is about locating the module source, not about an undefined input variable.

4
Multi-Selecthard

Which THREE of the following are valid ways to reference a module output value within the same Terraform configuration?

Select 4 answers
A.In the count or for_each of another module or resource.
B.In a resource argument, e.g., subnet_id = module.vpc.public_subnet_ids
C.In a data source definition as a filter.
D.In a provider block to set endpoints.
E.In a locals block to perform transformations.
AnswersA, B, C, E

Module outputs can control the number of instances or the iteration set of other resources.

Why this answer

Options A, B, C, and E are correct ways to reference a module output value within the same Terraform configuration. Module outputs can be used in `count` or `for_each` meta-arguments (A), directly in resource arguments (B), in data source filter blocks (C), and in `locals` blocks for transformation (E). Option D is incorrect because provider blocks require static configuration and cannot reference module outputs; provider configurations are resolved before any resources or modules.

Exam trap

Module outputs are valid in resource arguments, count/for_each, data source filter blocks, and locals blocks. They cannot be used in provider blocks because provider configurations are static and resolved before any other resources are evaluated.

5
MCQhard

A large organization uses Terraform to manage infrastructure across multiple AWS accounts. They have a shared module for VPC stored in a private Git repository (git::https://github.com/org/terraform-aws-vpc.git?ref=v1.0.0). After updating the module source to ref=v1.2.0, they run terraform init and then terraform plan. The plan still shows the old module's resources and behavior. They confirm the new tag exists and the module code has changed. The root module source line is correct. What is the most likely cause?

A.They forgot to run terraform get.
B.The module source URL is incorrect.
C.Terraform cached the previous module version and did not download the new one.
D.The module's outputs changed and they need to update the root module.
AnswerC

Terraform caches modules; running terraform init with -upgrade or clearing the .terraform directory forces a fresh download.

Why this answer

Terraform caches modules in the `.terraform/modules` directory after `terraform init`. When the module source version is updated (e.g., from `ref=v1.0.0` to `ref=v1.2.0`), Terraform does not automatically re-download the module unless the lock file changes or `terraform init -upgrade` is used. Running `terraform init` without the `-upgrade` flag will not overwrite the cached module, so the plan still reflects the old version's resources and behavior.

Exam trap

Terraform caches modules in the `.terraform/modules` directory after `terraform init`. Running `terraform init` without the `-upgrade` flag will not re-download the module even if the source version has changed. You must use `terraform init -upgrade` to force a fresh download and update the lock file.

How to eliminate wrong answers

Option A is wrong because `terraform get` is used to download and update modules in a configuration, but it is essentially a subset of `terraform init`; the core issue is not about running a separate command but about the caching mechanism that prevents re-downloading. Option B is wrong because the question explicitly states the module source line is correct and the new tag exists, so the URL is not incorrect. Option D is wrong because changes to module outputs do not affect the plan's resource behavior; outputs are only used for root module references and do not cause the plan to show old resources.

6
Multi-Selectmedium

Which TWO module source types support version constraints in Terraform?

Select 2 answers
A.HTTP URL to a zip archive
B.Terraform Public Registry
C.Local file path
D.Git URL with a branch reference
E.Terraform Cloud Private Registry
AnswersB, E

The Terraform Public Registry is purpose-built to host and serve modules with robust semantic versioning. When a module is sourced from the registry, Terraform utilizes the `version` argument to evaluate and select the highest compatible module version based on the specified constraint, such as `~> 1.0` or `>= 2.0.0`. This integral feature allows for controlled updates and dependency management.

Why this answer

The Terraform Public Registry supports version constraints via the `source` argument using the `registry.terraform.io` namespace, allowing you to specify a version range (e.g., `~> 1.0`) in the module block. Option E is correct because the Terraform Cloud Private Registry also supports version constraints, enabling you to pin or constrain module versions from private repositories using the same syntax as the public registry.

Exam trap

A common misconception is that Git URLs with branch or tag references support version constraints, but in reality, they only support fixed references and cannot enforce semantic version ranges like `~>` or `>=`.

7
MCQhard

A DevOps team manages Terraform configurations for a multi-environment infrastructure (dev, staging, prod). They maintain a central repository of reusable modules stored in a Git repository. Developers often update modules in the master branch to add features or fix bugs. Recently, after a developer updated the 'vpc' module in the master branch, the staging environment's infrastructure was destroyed and recreated during a terraform apply, causing an outage. The team needs to prevent such unintended changes across environments. They currently reference modules using the source argument with a git URL pointing to the master branch: source = "git::https://github.com/org/terraform-modules//vpc?ref=master". The team is looking for a solution that allows controlled updates and ensures each environment uses a fixed version of a module until explicitly upgraded.

A.Use module version constraints in the configuration, such as source = "git::https://github.com/org/terraform-modules//vpc?ref=v1.0.0" and update the ref tag when ready.
B.Create separate Git branches for each environment and reference the branch in the module source.
C.Use Terragrunt to manage module dependencies and lock versions.
D.Use the Terraform Registry to host modules with semantic versioning and pin versions.
AnswerA

This approach directly pins the module source to an immutable Git tag (e.g., "v1.0.0"). By referencing a specific tag, each environment's configuration explicitly declares the exact module version it requires, preventing unintended updates when the main branch or other tags evolve. Updates to the module are then a deliberate action, requiring a change to the `ref` attribute in the configuration, ensuring controlled and predictable deployments across environments. This provides strong version control without external tools.

Why this answer

Referencing a specific Git tag (e.g., v1.0.0) ensures that each environment uses a fixed version of the module until the tag is explicitly updated. This prevents unintended changes from the master branch affecting environments. Option B is incorrect because separate branches can still receive updates that may cause unintended changes; it does not solve the version pinning problem.

Option C is incorrect because Terragrunt is an additional tool that manages dependencies but does not inherently enforce module version pinning without additional configuration, and it adds complexity. Option D is incorrect in this context because the team already uses a Git repository; migrating to the Terraform Registry is not an immediate solution and may not be feasible, whereas using Git tags is a straightforward native approach.

8
MCQhard

A module block references a module with version constraint '>= 2.0, < 3.0'. An older version 1.5 is already cached from a previous init. The team wants to ensure they use a newer version. After running terraform init -upgrade, what happens?

A.Terraform upgrades to version 3.0 because it is the latest.
B.Terraform returns an error because version 1.5 is incompatible with the constraint.
C.Terraform uses the cached version 1.5 because it is already present.
D.Terraform upgrades to the latest version in the range 2.x that is not yet cached.
AnswerD

When `terraform get -upgrade` is executed, Terraform first evaluates the module's version constraint, such as `~> 2.0` (meaning `>= 2.0.0, < 3.0.0`). It then queries the module source to identify the absolute newest version available that falls within this specified range. Finally, it downloads this newly identified, latest compatible version, effectively upgrading the module if a newer one exists within the constraint and is not yet cached.

Why this answer

`terraform init -upgrade` instructs Terraform to ignore any cached versions and re-check the registry for the newest available version that satisfies the version constraint `>= 2.0, < 3.0`. Since the constraint excludes 3.0, the latest version in the 2.x series will be selected and downloaded, overwriting the cached 1.5 version.

Exam trap

HashiCorp often tests the misconception that `terraform init -upgrade` will always install the absolute latest version (like 3.0) regardless of constraints, or that a cached version will be used if it is present, when in fact the flag forces a fresh resolution within the defined range.

How to eliminate wrong answers

Option A is wrong because version 3.0 does not satisfy the constraint `< 3.0`; Terraform will never select a version outside the specified range. Option B is wrong because version 1.5 is simply ignored during the upgrade process; Terraform does not return an error for a cached incompatible version—it just fetches a compliant one. Option C is wrong because `-upgrade` explicitly tells Terraform to disregard the cached version and fetch the latest matching version from the registry.

9
MCQhard

A team renamed a module from 'module.network' to 'module.vpc' in their configuration. They run 'terraform plan' and see that Terraform wants to destroy the old network resources and create new ones. They want to preserve the existing resources without downtime. What should they do?

A.Add a 'moved' block to the configuration to map the old module address to the new one.
B.Use 'terraform state mv' to move the resources to the new module address.
C.Update the module source to a new version.
D.Accept the destroy and recreate since it's the only way.
AnswerA

Adding a 'moved' block to the configuration is the correct and declarative approach for handling resource address refactoring, such as renaming a module. This block explicitly informs Terraform that a resource or module previously known by one address should now be tracked under a new address. During the next 'terraform plan' and 'apply', Terraform will update the state file to reflect this change without destroying and recreating the underlying infrastructure, thus preserving existing resources and their attributes.

Why this answer

The `moved` block in Terraform allows you to refactor module addresses without destroying and recreating resources. By adding a `moved` block that maps the old module address (`module.network`) to the new one (`module.vpc`), Terraform will automatically update the state to reflect the new address during the next plan and apply, preserving the existing infrastructure and avoiding downtime.

Exam trap

HashiCorp often tests the distinction between declarative (`moved` block) and imperative (`terraform state mv`) refactoring, trapping candidates who think manual state manipulation is the correct approach for configuration-driven changes.

How to eliminate wrong answers

Option B is wrong because `terraform state mv` is a manual, imperative command that moves resources in the state file, but it does not update the configuration itself; the configuration still references the old module address, leading to drift and potential future issues. Option C is wrong because updating the module source to a new version does not address the module address rename; it would only change the module's source code, not the state mapping, and could still trigger resource recreation if the new version changes resource configurations. Option D is wrong because accepting destroy and recreate is unnecessary and would cause downtime; Terraform provides the `moved` block as a first-class refactoring mechanism to avoid this.

10
MCQhard

A developer runs `terraform plan` and receives the error: "Error: Unsupported argument; An argument named 'enable_vpn_gateway' is not expected here." What is the most likely cause?

A.The source address is misspelled 'vpc' instead of 'vpc/aws'.
B.The source module is not pinned to a specific version, so it may have changed.
C.The module must be sourced from a different registry or repository.
D.The module version 5.0.0 does not support the 'enable_vpn_gateway' argument.
AnswerD

This option is correct because an error stating an argument like 'enable_vpn_gateway' is 'unexpected' or 'not expected' for a specific module version (e.g., 5.0.0) is a direct indication of an API change. Module developers often introduce breaking changes, such as removing, renaming, or altering input variables, especially in major version increments. This means the argument was likely supported in a previous version but has since been deprecated or removed in version 5.0.0, requiring the user to update their configuration to align with the module's current interface.

Why this answer

The error 'Unsupported argument' indicates that the module version currently in use does not define an input variable named 'enable_vpn_gateway'. In Terraform, each module version has a fixed set of input variables; if you attempt to pass an argument that is not declared in the module's variables.tf, Terraform will reject it. The most common reason for this is that the module version has been updated or changed, and the argument was removed or renamed in that version.

Exam trap

HashiCorp often tests the distinction between errors caused by module version changes versus errors caused by source configuration issues, trapping candidates who confuse a missing variable error with a source path or registry problem.

How to eliminate wrong answers

Option A is wrong because the error message specifically says 'An argument named 'enable_vpn_gateway' is not expected here', which is about an unexpected argument, not about a misspelled source address; a misspelled source would cause a 'source not found' or 'module not found' error. Option B is wrong because while not pinning a version can lead to unexpected changes, the error itself is about the current module's input schema, not about version drift; the error would occur even if the version is pinned to a version that lacks the argument. Option C is wrong because the source registry or repository does not affect which arguments are supported; the argument support is determined by the module's code, not its location.

11
MCQmedium

A developer creates a module in a subdirectory of their Terraform configuration and wants to reference it from the root module. The directory structure is: /terraform-project/modules/networking. Which source argument should they use in the module block?

A.source = "file:///terraform-project/modules/networking"
B.source = "/terraform-project/modules/networking"
C.source = "./modules/networking"
D.source = "hashicorp/networking/aws"
AnswerC

This source string correctly uses a relative path, starting with `./`, indicating that the module is located in a `modules/networking` subdirectory relative to the current Terraform configuration file. This is the standard and most portable method for referencing local modules within the same repository. Terraform resolves this path from the directory containing the calling module, ensuring consistency across different execution environments.

Why this answer

Terraform resolves local module paths relative to the root module's directory. The path `./modules/networking` correctly references the `networking` subdirectory within the `modules` folder, starting from the root of the Terraform configuration. This is the standard syntax for referencing a local module in a subdirectory.

Exam trap

HashiCorp often tests the distinction between local module paths (which must start with `./` or `../`) and registry module paths (which use a namespace/name/provider format), causing candidates to mistakenly choose an absolute path or a registry-style source for a local module.

How to eliminate wrong answers

Option A is wrong because `file://` is not a valid Terraform module source protocol; Terraform uses `./` or absolute paths for local modules, not file URIs. Option B is wrong because `/terraform-project/modules/networking` is an absolute filesystem path that would only work if the root module were at the filesystem root, which is not the case here; Terraform expects relative paths starting with `./` or `../` for local modules. Option D is wrong because `hashicorp/networking/aws` is a Terraform Registry source format, which would attempt to download a public module from the registry, not reference a local directory.

12
MCQmedium

A developer creates a directory structure with a module located at './modules/networking'. The root configuration references it with source = './modules/networking'. What is the behavior when running terraform init from the root directory?

A.Terraform uses the module directly from the local filesystem.
B.Terraform requires a network connection to verify the module.
C.Terraform attempts to download the module from the public registry.
D.Terraform returns an error because the module path is not absolute.
AnswerA

When a module source is specified as a relative or absolute path, Terraform directly accesses the module's contents from the local filesystem. During `terraform init`, Terraform simply ensures the directory exists and contains valid configuration files, without any download operations. This direct access means the module is immediately available for use within the configuration, leveraging the local directory structure.

Why this answer

When a module source is a relative path like './modules/networking', Terraform interprets it as a local filesystem path. During `terraform init`, Terraform reads the module directly from the specified directory without any network access, downloading, or registry interaction. This is the standard behavior for local module references in Terraform.

Exam trap

HashiCorp often tests the misconception that Terraform always requires network access or absolute paths for modules, but the trap here is that local relative paths are fully supported and require no network, no registry, and no absolute path specification.

How to eliminate wrong answers

Option B is wrong because local module paths do not require any network connection; Terraform accesses the filesystem directly. Option C is wrong because Terraform only attempts to download from the public registry when the source is a registry address (e.g., 'hashicorp/consul/aws'), not a local path. Option D is wrong because Terraform accepts relative paths for local modules; absolute paths are not required, and relative paths are resolved from the root module's directory.

13
MCQeasy

A Terraform module defines an output 'instance_ips'. In the root module, how should this value be referenced?

A.var.instance_ips
B.local.instance_ips
C.resource.my_module.instance_ips
D.module.my_module.instance_ips
AnswerD

This is the correct and standard syntax for referencing an output value from a child module. When a module is declared and given a local name (e.g., `my_module`) in a `module` block, its defined output values become accessible using the `module.<MODULE_NAME>.<OUTPUT_NAME>` pattern. This allows the root module or other child modules to consume the computed results exposed by `my_module`, such as a list of instance IPs.

Why this answer

Outputs from a child module are accessed in the root module using the `module.<module_name>.<output_name>` syntax. The `module` keyword is a reserved reference that Terraform uses to expose all outputs defined within a module block, allowing the root configuration to consume values like `instance_ips` as `module.my_module.instance_ips`.

Exam trap

Terraform certification exams often test the distinction between `var.*`, `local.*`, `resource.*`, and `module.*` references, and the trap here is that candidates confuse module outputs with resource attributes, incorrectly using `resource.my_module.instance_ips` instead of the correct `module.my_module.instance_ips` syntax.

How to eliminate wrong answers

Option A is wrong because `var.instance_ips` would reference an input variable defined in the root module, not an output from a child module. Option B is wrong because `local.instance_ips` refers to a local value computed within the root module's configuration, not a module output. Option C is wrong because `resource.my_module.instance_ips` incorrectly uses the `resource` keyword; module outputs are not resources and cannot be referenced with a resource address syntax.

14
MCQmedium

A team is using a private module registry from a third-party vendor. When running terraform init, they receive an error: 'Error downloading module: could not download module... server responded with 401 Unauthorized'. What is the most likely cause?

A.The module source URL is incorrect.
B.The registry credentials are missing or invalid.
C.The Terraform version is too old for the module.
D.The network firewall is blocking outbound connections.
AnswerB

An HTTP 401 Unauthorized response explicitly indicates that the request lacks valid authentication credentials for the target resource. When interacting with a private module registry, Terraform requires specific credentials, often an API token or username/password, configured via a `credentials.tfrc.json` file or environment variables. If these credentials are either missing from Terraform's configuration or are invalid/expired, the registry server will correctly deny access with a 401 status.

Why this answer

The 401 Unauthorized error indicates that the request to the private module registry was received but authentication failed. Private registries require valid credentials (such as an API token or username/password) to be configured, typically via a `.terraformrc` or `credentials` block in the CLI configuration. Without these, Terraform cannot authenticate and the download is rejected.

Exam trap

HashiCorp often tests the distinction between authentication errors (401) and authorization errors (403) or network connectivity errors, so candidates may incorrectly attribute a 401 to a wrong URL or firewall issue instead of missing or invalid credentials.

How to eliminate wrong answers

Option A is wrong because an incorrect module source URL would typically result in a 'not found' (404) or 'invalid source' error, not a 401 authentication error. Option C is wrong because an outdated Terraform version would cause compatibility warnings or syntax errors, not an HTTP 401 response from the registry. Option D is wrong because a network firewall blocking outbound connections would produce a timeout or connection refused error, not an HTTP 401 status code.

15
MCQhard

What is the correct way to resolve this provider version conflict?

A.Ignore the module's required_providers and force install the root version.
B.Remove the required_providers block from the root module.
C.Change the root module's required version to ~> 2.70.
D.Manually edit the .terraform/modules/consul/main.tf to change the version.
AnswerC

This is the correct approach because it directly addresses the version conflict by aligning the constraints. If the module requires `~> 2.70` (meaning any patch version within 2.70, e.g., `2.70.0` up to `2.70.x` but less than `2.71.0`), then setting the root module's requirement to `~> 2.70` ensures both the root and the nested module can successfully use the same provider version. This modification makes both `required_providers` blocks compatible, allowing Terraform's dependency resolver to find a mutually acceptable version.

Why this answer

The root module's required_providers version constraint must be compatible with the version constraints declared in any child modules. The error indicates the root module requires a provider version that conflicts with the consul module's constraint (e.g., ~> 2.70). Changing the root constraint to ~> 2.70 aligns it with the child module, satisfying Terraform's version resolution logic during `terraform init`.

Exam trap

HashiCorp often tests the misconception that you can override or ignore a child module's provider version constraint, when in fact Terraform enforces compatibility across all modules and the correct fix is to align the root module's constraint with the child module's requirement.

How to eliminate wrong answers

Option A is wrong because ignoring a module's required_providers and forcing installation bypasses Terraform's dependency resolution, leading to unpredictable behavior or runtime errors. Option B is wrong because removing the required_providers block from the root module does not resolve the conflict; it removes the root's constraint but the child module's constraint still applies, and Terraform will still enforce the child's version requirement. Option D is wrong because manually editing the .terraform/modules/consul/main.tf is not a supported workflow; the .terraform directory is managed by Terraform and changes will be overwritten on the next `terraform init`, and it violates the principle of immutable module sources.

16
MCQeasy

A developer wants to create multiple instances of a module that provisions a single EC2 instance. They want to create 3 EC2 instances. Which approach is most efficient and concise?

A.Set the source argument to a list of three URLs.
B.Use the 'count' meta-argument in the module block.
C.Use the 'for_each' meta-argument with a list of numbers.
D.Copy the module block three times with different names.
AnswerB

The `count` meta-argument is specifically designed to create multiple identical instances of a resource or module block. By setting `count` to an integer value, such as `3`, Terraform will instantiate the module three times, creating separate, distinct instances. This method is highly efficient and concise for provisioning a fixed number of similar components, as it avoids repetition and leverages Terraform's built-in lifecycle management for each instance.

Why this answer

The `count` meta-argument in a module block allows you to create multiple instances of the entire module (including its EC2 instance) by specifying a number. This is the most efficient and concise approach when you need a fixed number of identical module instances, as it avoids code duplication and leverages Terraform's built-in iteration.

Exam trap

In the Terraform Associate exam, candidates are often tested on understanding that `count` is the most concise and efficient way to create a fixed number of identical module instances, while `for_each` is better for creating instances from a set of distinct keys or when you need to manage each instance independently with a unique identifier.

How to eliminate wrong answers

Option A is wrong because the `source` argument in a module block must be a single string pointing to the module's source location (e.g., a local path, registry, or Git URL); it cannot accept a list of URLs. Option C is wrong because while `for_each` can create multiple module instances, using it with a list of numbers is less concise than `count` when the goal is simply to create a specific number of identical instances; `for_each` is better suited for creating instances from a set of distinct keys or complex objects. Option D is wrong because copying the module block three times violates the DRY (Don't Repeat Yourself) principle, introduces maintenance overhead, and is neither efficient nor concise compared to using `count`.

17
MCQeasy

After adding a new module sourced from a Git repository with a specific tag, terraform init reports that the module is being downloaded. What is the best practice to ensure the team uses the same version of this module consistently?

A.Use a version constraint in the module block, e.g., version = 1.0.0.
B.Specify the source as the branch name 'main'.
C.Use the 'latest' tag in the source URL.
D.Use a Git tag, like '?ref=v1.0.0', to pin the version.
AnswerD

Using a specific Git tag, such as `?ref=v1.0.0`, is the recommended and most robust method for pinning a module's version when sourcing directly from a Git repository. Git tags are immutable pointers to a specific commit in the repository's history, ensuring that the exact same module code is fetched every time Terraform runs. This immutability is crucial for achieving consistent and reproducible infrastructure deployments across all environments and team members, preventing unexpected changes and simplifying debugging.

Why this answer

Using a Git tag (e.g., `?ref=v1.0.0`) in the module source URL pins the module to a specific, immutable commit. This ensures that every team member downloads the exact same version of the module, regardless of future changes to the default branch. Terraform resolves the tag to a commit hash and caches it, providing deterministic and reproducible infrastructure.

Exam trap

In Terraform, candidates often confuse version constraints (for registry modules) with source URL parameters (for Git, Mercurial, or other VCS sources), leading them to incorrectly apply registry-style versioning to Git-sourced modules.

How to eliminate wrong answers

Option A is wrong because Terraform modules sourced from Git repositories do not support a `version` argument in the module block; version constraints are only valid for modules from the Terraform Registry. Option B is wrong because specifying a branch name (e.g., 'main') points to a moving target; the branch can receive new commits, causing different team members to get different module code over time. Option C is wrong because there is no 'latest' tag in Git; using 'latest' as a tag would require the repository to explicitly create and maintain such a tag, and it would still be mutable if updated.

18
Multi-Selecthard

Which THREE statements about module configuration are correct?

Select 3 answers
A.Module sources can be local paths or remote URLs.
B.Version constraints can be specified for any module source.
C.The outputs of a module are available after apply only.
D.A module block can contain multiple resources and child modules.
E.Module inputs can be optional if the module uses a default.
AnswersA, D, E

Terraform supports various source types including local, registry, Git, HTTP, etc.

Why this answer

Terraform module sources can be either local file paths (e.g., `./modules/network`) or remote URLs (e.g., `git::https://example.com/repo.git`, `registry.terraform.io/hashicorp/consul/aws`). The `source` argument supports multiple protocols including local, Git, HTTP, and the Terraform Registry, making it flexible for version control and distribution.

Exam trap

A common misconception is that version constraints can be applied to any module source, but they only work with registry modules that support semantic versioning.

19
Multi-Selectmedium

Which TWO statements are correct when refactoring a monolithic Terraform configuration into modules?

Select 2 answers
A.All modules must reside in a separate directory outside the root module.
B.A module should contain only one resource to keep it simple.
C.Module outputs are necessary to expose values to the root module.
D.Variables are optional in modules if hardcoded values are acceptable.
E.Modules help to organize and reuse infrastructure code.
AnswersC, E

Module outputs serve as the explicit interface for a child module to return specific values, such as resource IDs, IP addresses, or connection strings, back to its calling module or the root configuration. Without defining these outputs, any values computed or created within the module remain encapsulated and inaccessible to parent modules, preventing them from being used as inputs for other resources or modules in the overall infrastructure. This mechanism ensures controlled data flow and clear dependencies between different infrastructure components.

Why this answer

Module outputs are the mechanism by which a root module accesses values from child modules. Without outputs, any resource attributes created inside a module remain encapsulated and inaccessible to the calling configuration, making it impossible to use those values for interpolation or to pass them to other resources or modules.

Exam trap

A common misconception is that modules must be physically separated from the root module or that they must contain only one resource, when in fact modules are about logical grouping and can be nested locally.

20
Multi-Selecteasy

Which TWO options are valid ways to reference a Terraform module from a registry?

Select 2 answers
A.source = "hashicorp/consul/aws"
B.source = "consul/aws"
C.source = "hashicorp/consul/aws" version = "~> 0.1"
D.from = "hashicorp/consul/aws"
E.source = "hashicorp/consul/aws?ref=v1.0.0"
AnswersA, C

Correct; omitting the version defaults to the latest.

Why this answer

The Terraform registry module source syntax requires the format `namespace/name/provider`, and `hashicorp/consul/aws` follows this exactly. This tells Terraform to fetch the module from the public registry, using the `hashicorp` namespace, the `consul` module name, and the `aws` provider. The `version` constraint in option C is also valid, as it pins the module to a compatible version range using the `~>` operator, which is a standard Terraform version constraint syntax.

Exam trap

HashiCorp often tests the distinction between registry module syntax and Git-based module references, so the trap here is that candidates mistakenly apply Git-style `?ref=` syntax to registry modules, not realizing that registry modules require the `version` argument instead.

21
MCQhard

A module defines an input variable with 'sensitive = true'. The root module tries to use that variable in an output block. What happens when running 'terraform apply'?

A.The output value is hidden in the CLI output but still available in the state.
B.The apply fails with an error because sensitive variables cannot be used in outputs.
C.The output is displayed normally because outputs are always visible.
D.The output is removed from the plan entirely to protect the sensitive value.
AnswerA

When an output value is marked as sensitive = true, Terraform intentionally obfuscates its display in CLI operations like terraform plan, terraform apply, and terraform output. This prevents accidental exposure of secrets in terminal logs or shared screens. However, for Terraform to manage and track the infrastructure correctly, the actual sensitive value is still persisted unencrypted within the terraform.tfstate file, making it accessible to Terraform itself for subsequent operations.

Why this answer

When a variable is marked `sensitive = true`, Terraform prevents its value from being displayed in CLI output for any output that references it. However, the value is still stored in the state file and can be used within the module. Therefore, `terraform apply` succeeds, but the output value is hidden in the CLI output while remaining available in the state.

Exam trap

The Terraform exam often tests the misconception that sensitive variables cause errors or are completely removed from the plan, when in fact they are only hidden from CLI output but persist in the state.

How to eliminate wrong answers

Option B is wrong because Terraform does not prevent sensitive variables from being used in outputs; it only hides the value from CLI display. Option C is wrong because outputs that reference sensitive variables are not displayed normally; they are redacted in the CLI output. Option D is wrong because the output is not removed from the plan; it remains in the plan and state, but its value is masked in the CLI output.

22
MCQhard

After running 'terraform apply', the user sees that the 'aws_s3_bucket_object' is created successfully, but the bucket name is not as expected. What is the most likely reason?

A.The module variable 'bucket_name' is not consumed by the resource; the resource uses a hardcoded name.
B.The module output is incorrectly defined; it should use 'bucket' attribute instead of 'id'.
C.The module does not have an output for the bucket name, so the reference fails silently.
D.The output 'bucket_name' in the module is set to 'aws_s3_bucket.this.id', which is the bucket name, so the bucket name should be as expected.
AnswerD

The configuration appears correct; if the bucket name is not as expected, the issue might be elsewhere, but the output is correct.

Why this answer

The module output 'bucket_name' is defined as 'aws_s3_bucket.this.id', and in Terraform, the 'id' attribute of an 'aws_s3_bucket' resource is exactly the bucket name (not a generated ID). Since the user sees the object created successfully, the module is being called and the output is correctly referencing the bucket name, so the bucket name should be as expected. The question implies the user's expectation is wrong or the bucket name is actually correct, making D the only statement that aligns with Terraform's behavior.

Exam trap

HashiCorp often tests the misconception that 'id' is a random or internal identifier rather than the actual resource name, leading candidates to incorrectly think the output is wrong when it is actually correct.

How to eliminate wrong answers

Option A is wrong because if the resource used a hardcoded name, the bucket would still be created with that name, but the user would see a mismatch only if they expected a different name; the module variable not being consumed would cause a different bucket name, but the question states the bucket name is 'not as expected', not that it failed. Option B is wrong because the 'bucket' attribute of 'aws_s3_bucket' is the bucket name as well, but using 'id' is also correct and does not cause a mismatch; the output definition is not the issue here. Option C is wrong because if the module had no output for the bucket name, the reference would fail with an error during 'terraform apply', not silently succeed; Terraform requires explicit outputs to be defined for module references.

23
MCQmedium

A root module uses a module that creates an AWS EC2 instance. The module outputs the instance ID. The root module then uses this output in a null_resource provisioner. After modifying the module, terraform plan shows that the EC2 instance will be destroyed and recreated. What is the impact on the null_resource?

A.The null_resource prompts the user to confirm before any changes.
B.The null_resource will remain unchanged because it is not directly attached to the module.
C.The null_resource will fail to run because the output is temporarily unavailable during destroy.
D.The null_resource will be destroyed and recreated alongside the EC2 instance.
AnswerD

The `null_resource` is specifically designed to execute its `provisioners` whenever a value within its `triggers` map changes. Since the `null_resource` depends on an output from the module that creates the EC2 instance, any recreation or significant modification to that EC2 instance will alter the associated module output. This detected change in the output value will then cause the `null_resource` to be marked for destruction and subsequent recreation, ensuring its provisioners run again with the updated context of the new instance.

Why this answer

The null_resource's triggers typically depend on the module's output (the instance ID). When the EC2 instance is destroyed and recreated, its ID changes, which updates the trigger value. Terraform interprets this change as a need to destroy and recreate the null_resource along with its provisioner, ensuring the provisioner runs again with the new instance ID.

Exam trap

The trap here is that candidates assume null_resource is immutable or independent because it is a HashiCorp-specific resource with no real infrastructure, but Terraform treats any change in its triggers as a recreation signal, making it tightly coupled to upstream dependencies.

How to eliminate wrong answers

Option A is wrong because null_resource does not prompt for user confirmation; it follows standard Terraform planning and applies without interactive prompts. Option B is wrong because the null_resource is indirectly attached via the output dependency; Terraform tracks all resource dependencies through the graph, so a change in the module's output triggers recreation of dependent resources. Option C is wrong because the output is not temporarily unavailable during destroy; Terraform resolves the new output value after the instance is recreated, and the null_resource is recreated after that, so the provisioner runs with the new value.

24
MCQhard

Your team is developing a custom module for creating EC2 instances with attached EBS volumes. The module variables are: instance_type (default "t2.micro"), ami (required), volume_size (default 8), volume_type (default "gp2"). Another team uses this module to create a web server. In their root module, they call the module without any explicit instance_type override, but they do set other variables. After applying, the web server is created with instance_type "t2.nano" instead of the expected "t2.micro". They confirm that the module still has the default "t2.micro". What is the most likely explanation?

A.The module's instance_type variable uses a default that is "t2.nano" but the root module overrode it with a variable from its own context.
B.The instance_type variable is not defined in the module's variables.tf, so it uses a default from the AWS provider.
C.The root module has a variable called instance_type set to "t2.nano" that is being passed to the module.
D.The module's variable default was changed to "t2.nano" in a new version.
AnswerC

If the root module defines or inherits an instance_type variable with value "t2.nano", and the module block passes it (e.g., instance_type = var.instance_type), that overrides the module's default.

Why this answer

In Terraform, when a module is called, any variable with the same name in the root module that is explicitly passed to the module block (e.g., instance_type = var.instance_type) will override the module's default value, even if the module itself has a default. The root module likely declared a variable instance_type with a default of 't2.nano' and is passing it to the module call. Option A is incorrect because the module's default is 't2.micro', not 't2.nano'.

Option B is incorrect because if the variable is not defined in the module's variables.tf, passing it would cause an error; it cannot fall back to an AWS provider default. Option D is incorrect because the scenario explicitly states the module default remains 't2.micro'.

25
MCQeasy

A module 'web_app' defines an input variable 'instance_count' with type = number and a validation block ensuring it is between 1 and 10. What happens if a user sets instance_count = 0?

A.Terraform returns an error during validation and stops execution.
B.Terraform applies the module with zero instances, as a value of 0 is allowed.
C.Terraform ignores the validation if the variable is explicitly set.
D.Terraform uses the default value for instance_count from the module.
AnswerA

When a variable's custom validation condition fails, Terraform immediately halts execution and returns an error. This occurs during the planning phase (e.g., `terraform plan` or `terraform apply`), before any infrastructure changes are proposed or applied. The explicit error message defined in the validation block provides clear feedback, preventing the deployment of invalid configurations.

Why this answer

HashiCorp Terraform validates input variables against their declared type and any validation blocks before applying configuration. When `instance_count = 0` is set, the validation block's condition `var.instance_count >= 1 && var.instance_count <= 10` evaluates to `false`, causing HashiCorp Terraform to halt with an error during the `terraform plan` or `terraform validate` phase, preventing any further execution.

Exam trap

The trap here is that candidates may assume HashiCorp Terraform silently falls back to a default value or ignores validation when a variable is explicitly set, but in reality, explicit assignment overrides defaults and validation is always enforced, causing an immediate error for out-of-range values.

How to eliminate wrong answers

Option B is wrong because a value of 0 fails the validation condition, so Terraform does not allow the apply to proceed; it returns an error instead. Option C is wrong because validation blocks are always enforced regardless of how the variable is set—explicitly, via default, or through a `.tfvars` file—there is no mechanism to bypass them. Option D is wrong because a default value is only used when the variable is not assigned at all; when the user explicitly sets `instance_count = 0`, that value is used and must pass validation, which it does not.

26
MCQeasy

Refer to the exhibit. The configuration fails with an error indicating that the module does not support the 'enable_vpn_gateway' argument. What is the most likely cause?

A.The argument name is misspelled; it should be 'enable_vpn' instead.
B.The module version '3.18.0' does not include the 'enable_vpn_gateway' variable; it was added in a later version.
C.The module does not support VPN gateways at all.
D.The module source is incorrectly specified; it should use a git URL instead of the registry path.
AnswerB

This option correctly identifies the root cause. When a module is explicitly pinned to a specific version, such as '3.18.0', Terraform strictly adheres to the variables and outputs defined within that exact module release. The `enable_vpn_gateway` variable was introduced in a subsequent version of the `terraform-aws-vpc` module, meaning it is not recognized or available in version '3.18.0', leading to an 'Unsupported Argument' or 'Undefined Variable' error during plan or apply.

Why this answer

The error message indicates that the module does not support the 'enable_vpn_gateway' argument. In Terraform, module arguments are defined by the module's published variables. The module version '3.18.0' predates the introduction of the 'enable_vpn_gateway' variable, which was added in a later version.

Upgrading the module version to one that includes this variable resolves the error.

Exam trap

HashiCorp often tests the concept that module arguments are version-dependent, and the trap here is that candidates may assume the argument name is misspelled or that the module lacks the feature entirely, rather than recognizing that the module version simply does not include that variable yet.

How to eliminate wrong answers

Option A is wrong because the argument name 'enable_vpn_gateway' is not a misspelling of 'enable_vpn'; the error specifically states the module does not support the argument, not that the name is incorrect. Option C is wrong because the module does support VPN gateways, but the specific variable 'enable_vpn_gateway' was not available in version 3.18.0. Option D is wrong because the module source (registry path) is correctly specified; using a git URL would not change the available variables for a given module version.

27
MCQeasy

Which version of the module was downloaded and why?

A.3.0.0, because ~> 3.0 only allows the exact version 3.0.0.
B.3.19.0, because it is the latest version and version constraints are ignored.
C.3.19.0, because it is the latest version matching the constraint ~> 3.0, which allows any 3.x version.
D.3.0.0, because ~> 3.0 is limited to patch updates within 3.0.x.
AnswerC

This statement is correct because the pessimistic version constraint `~> 3.0` instructs Terraform to select the highest available module version that is greater than or equal to 3.0.0 but strictly less than 4.0.0. Given that 3.19.0 is the latest version within this `3.x` major release series, it is the one Terraform will download. This constraint allows for minor and patch updates while preventing unintended major version upgrades that could introduce breaking changes.

Why this answer

The constraint `~> 3.0` in Terraform's version constraint syntax allows only the rightmost element to increment. Since `3.0` is a two-part version, the constraint permits any version in the `3.x` range (i.e., `3.0.0` up to but not including `4.0.0`). Therefore, the latest version matching that constraint is `3.19.0`, which is the highest available 3.x version.

Exam trap

The trap here is that candidates often confuse the behavior of `~> 3.0` (which allows any 3.x version) with `~> 3.0.0` (which restricts to patch updates only within 3.0.x), leading them to incorrectly select option D.

How to eliminate wrong answers

Option A is wrong because `~> 3.0` does not pin to the exact version `3.0.0`; it allows any version in the `3.x` range, not just `3.0.0`. Option B is wrong because version constraints are never ignored in Terraform; the resolver always respects the declared constraints and will not download a version outside the allowed range. Option D is wrong because `~> 3.0` is not limited to patch updates within `3.0.x`; that behavior would apply to a three-part constraint like `~> 3.0.0`, which restricts to `3.0.x` only.

28
MCQeasy

After applying a module that creates a VPC, a user wants to use the VPC ID in another resource within the root configuration. How should they reference the output from the module?

A.vpc_id = module.vpc.vpc_id
B.vpc_id = module_vpc.vpc_id
C.vpc_id = data.module.vpc.vpc_id
D.vpc_id = local.vpc_id
AnswerA

This syntax, `module.<NAME>.<OUTPUT_NAME>`, is the canonical and correct way to reference an output value exported by a child module in Terraform. Here, `module.vpc` refers to the specific instance of the module named 'vpc' as defined in the calling configuration's `main.tf` or similar file. The `.vpc_id` then accesses the output variable explicitly defined within that `vpc` module, making its value available for use in other resources or outputs within the parent configuration. This pattern ensures clear and explicit data flow between module boundaries.

Why this answer

In Terraform, module outputs are accessed using the syntax `module.<module_name>.<output_name>`. Since the module is named `vpc` and it exposes an output called `vpc_id`, the correct reference is `module.vpc.vpc_id`. This allows the root configuration to consume the VPC ID created by the module.

Exam trap

The TF-003 exam often tests the exact syntax for referencing module outputs, and the trap here is that candidates confuse module output references with data source references (`data.`) or local values (`local.`), or they incorrectly use underscores instead of dots in the module path.

How to eliminate wrong answers

Option B is wrong because it uses an underscore (`module_vpc.vpc_id`) instead of the required dot notation (`module.vpc.vpc_id`); Terraform uses dots to separate the module keyword, module name, and output name. Option C is wrong because `data.` is used to reference data sources, not module outputs; module outputs are always accessed via `module.<NAME>.<OUTPUT>`. Option D is wrong because `local.vpc_id` would only be valid if a local value had been explicitly defined in the root configuration; it does not automatically capture module outputs.

29
MCQhard

You are managing a Terraform configuration that uses a public module from the registry to deploy an AWS VPC. The module is defined with a version constraint of '~> 3.0'. After running 'terraform init', you run 'terraform plan' and notice that the plan output indicates the module will be updated from version 3.18.0 to 3.20.1. However, you are concerned because the module's changelog shows that version 3.19.0 introduced a breaking change: it removed the 'enable_dns_hostnames' variable and replaced it with 'enable_dns_support'. Your configuration currently uses the 'enable_dns_hostnames' variable. You want to avoid any breaking changes in the production environment while still receiving non-breaking updates. What should you do?

A.Fork the module repository and maintain a custom version that retains the 'enable_dns_hostnames' variable.
B.Change the version constraint to ">= 3.0.0, < 3.19.0" and run 'terraform init -upgrade'.
C.Change the version constraint to "~> 3.18.0" to stay within the 3.18.x releases.
D.Update the configuration to use the new 'enable_dns_support' variable and update the module to version 3.20.1.
AnswerC

This pins to the 3.18.x range, avoiding the breaking change in 3.19.0 while still getting patch updates.

Why this answer

The version constraint '~> 3.18.0' restricts updates to only patch versions within the 3.18.x series (e.g., 3.18.1, 3.18.2), which will never include the breaking change introduced in 3.19.0. This allows you to receive non-breaking bug fixes and security patches while avoiding the removal of the 'enable_dns_hostnames' variable. The pessimistic version constraint operator (~>) in Terraform locks the major and minor version when specified with three segments, ensuring no unexpected breaking changes from higher minor versions.

Exam trap

HashiCorp often tests the nuance of the pessimistic version constraint operator (~>) in Terraform, specifically that '~> 3.0' and '~> 3.18.0' have very different behaviors, and candidates mistakenly assume both only allow patch updates.

How to eliminate wrong answers

Option A is wrong because forking the module and maintaining a custom version introduces unnecessary overhead and defeats the purpose of using a public module; it also bypasses the version constraint mechanism entirely. Option B is wrong because the constraint '>= 3.0.0, < 3.19.0' would still allow Terraform to upgrade to any version from 3.0.0 up to 3.18.x, but running 'terraform init -upgrade' would upgrade to the latest allowed version (3.18.x), which is safe, but the constraint is overly broad and does not leverage the pessimistic operator for precise control; more importantly, it would not prevent a future upgrade to 3.19.0 if the upper bound were accidentally removed. Option D is wrong because updating the configuration to use 'enable_dns_support' and upgrading to 3.20.1 would require rewriting your code to adapt to the breaking change, which contradicts the goal of avoiding breaking changes in production.

30
Multi-Selecteasy

Which TWO statements about Terraform modules are correct?

Select 2 answers
A.The count meta-argument is not supported on module blocks.
B.Module outputs are automatically available as inputs to other modules in the same configuration.
C.Module sources must include a version constraint to ensure reproducibility.
D.A module can be called multiple times in the same configuration with different input variables.
E.The source attribute of a module can be a Git repository URL with a specific commit SHA.
AnswersD, E

This statement is correct. One of the primary benefits of Terraform modules is their reusability, allowing a single module definition to be invoked multiple times within the same root configuration. Each invocation can be given a unique local name and supplied with different input variables, enabling the deployment of distinct instances of similar infrastructure components. This pattern promotes DRY (Don't Repeat Yourself) principles and simplifies managing complex, multi-environment, or multi-tenant infrastructure.

Why this answer

Terraform modules can be called multiple times with different input variables, enabling reuse. Option E is correct because module sources can be Git repository URLs with a specific commit SHA (e.g., using `?ref=<sha>`). Option A is incorrect because the `count` meta-argument is supported on module blocks in Terraform 0.13 and later.

Option B is incorrect because module outputs are not automatically available; they must be referenced explicitly as `module.<module_name>.<output_name>`. Option C is incorrect because version constraints are optional for reproducibility; they are recommended but not mandatory.

31
MCQeasy

A team is using a module from the Terraform Registry and wants to ensure they always get the latest patch version of the 3.2.x series. Which version constraint should they use?

A.~> 3.2
B.3.2.*
C.~> 3.2.0
D.>= 3.2, < 4.0
AnswerC

This allows only patch-level increments within 3.2.x (e.g., 3.2.0 to 3.2.1).

Why this answer

The `~>` (pessimistic constraint) operator in Terraform allows only the rightmost version component to increment. For `~> 3.2.0`, this means any version >= 3.2.0 and < 3.3.0, which precisely matches the requirement for the latest patch within the 3.2.x series. Option C is correct because it locks the major and minor versions while permitting patch-level updates.

Exam trap

A common trap in Terraform is confusing the `~>` operator with two versus three numbers. `~> 3.2` allows minor version updates (e.g., 3.3, 3.4), while `~> 3.2.0` restricts updates to only patch versions (e.g., 3.2.1, 3.2.2). Candidates often mistakenly choose `~> 3.2` thinking it constrains to the 3.2.x series, but it actually allows any 3.x version.

How to eliminate wrong answers

Option A is wrong because `~> 3.2` allows both minor and patch updates (i.e., >= 3.2.0 and < 4.0.0), which would permit 3.3.x or 3.4.x, not just the 3.2.x series. Option B is wrong because `3.2.*` is not a valid Terraform version constraint syntax; Terraform uses the pessimistic operator or range constraints, not glob patterns. Option D is wrong because `>= 3.2, < 4.0` allows any version from 3.2.0 up to but not including 4.0.0, which includes minor version bumps (e.g., 3.3.0, 3.4.0) and not just patches within 3.2.x.

32
MCQhard

A developer creates a module that provisions an AWS EC2 instance and an S3 bucket. The module outputs the instance ID and bucket ARN. When using this module, the root configuration references module.my_module.instance_id and module.my_module.bucket_arn. After running terraform apply, they notice that the bucket ARN is empty. What is the most likely cause?

A.The output is defined in the module but not in the root configuration.
B.The S3 bucket creation depends on another resource that hasn't been created yet.
C.The output value in the module is defined incorrectly, e.g., referencing a non-existent attribute.
D.The IAM role used by Terraform does not have permission to read the bucket ARN.
AnswerC

When an output block within a module attempts to reference an attribute that does not exist on the specified resource, or uses an incorrect attribute path, Terraform often evaluates this expression to an empty string or a null value. This results in the module's output appearing empty when consumed by the root configuration, as the requested data simply isn't found at the specified location within the resource object. This is a common cause of unexpected empty outputs.

Why this answer

The most likely cause of an empty output value is that the output block in the module references an attribute that does not exist on the resource. For example, if the output is defined as `output "bucket_arn" { value = aws_s3_bucket.my_bucket.arn }` but the resource is actually `aws_s3_bucket.my_bucket` and the correct attribute is `arn`, a typo like `arnn` or `id` would cause Terraform to return an empty string (or an error during plan). Terraform validates attribute references at plan time, but if the attribute is missing or misspelled, the output value will be empty or cause a failure.

Exam trap

HashiCorp often tests the misconception that missing outputs in the root configuration cause empty values, but the real issue is almost always a misconfigured output block in the module itself, such as referencing a wrong attribute name.

How to eliminate wrong answers

Option A is wrong because outputs defined in the root configuration are not required to reference module outputs; the root configuration can directly use module outputs without redefining them. Option B is wrong because dependency ordering does not cause an output to be empty; if the S3 bucket depends on another resource, Terraform will wait for that resource to be created before reading the bucket's attributes, so the output would still be populated. Option D is wrong because IAM permissions affect the ability to create or describe resources, not the ability to read an attribute that is already part of the Terraform state; the bucket ARN is computed by the provider and stored in state, so no read permission is needed to output it.

33
MCQeasy

Based on the error, what is the most likely reason the 'acl' argument is not expected?

A.The module version currently installed does not have an 'acl' variable.
B.The argument name is misspelled; it should be 'acl_control'.
C.The module requires the 'acl' to be set inside a separate block.
D.The 'bucket' argument is missing; 'acl' must follow it.
AnswerA

The error message "not expected here" for an argument within a module block directly indicates that the module's defined interface, specifically its `variables.tf` file, does not declare an input variable named 'acl'. This situation commonly arises when a module has been updated, and the 'acl' variable was either removed, renamed, or never existed in the specific version of the module currently being used. Terraform strictly validates all provided arguments against the module's explicit variable definitions.

Why this answer

The error indicates that the 'acl' argument is not recognized by the Terraform module. This typically occurs when the installed module version does not expose an 'acl' variable in its schema. Terraform validates arguments against the module's declared variables; if 'acl' is absent from the module's variables.tf, Terraform will reject it as an unexpected argument.

Exam trap

This question tests the distinction between 'unexpected argument' errors (caused by undeclared variables in the module) and 'missing required argument' errors (caused by omitting a declared variable without a default), leading candidates to confuse the two and select an option that addresses a missing argument rather than an unrecognized one.

How to eliminate wrong answers

Option B is wrong because there is no standard 'acl_control' argument in Terraform's AWS S3 bucket module; the correct argument for access control lists is 'acl', not a misspelling. Option C is wrong because the 'acl' argument is a top-level argument in the 'aws_s3_bucket' resource, not something that must be nested inside a separate block; Terraform does not require 'acl' to be set inside a sub-block. Option D is wrong because Terraform arguments are order-independent; the 'bucket' argument does not need to precede 'acl', and the absence of 'bucket' would cause a different error (e.g., missing required argument), not an unexpected argument error.

34
MCQmedium

After running `terraform plan`, the user receives an error: `Error: Missing required variable`. The variable 'vpc_cidr' is provided. What is the most likely cause?

A.The module requires a variable 'environment' that is not passed.
B.The module block syntax is incorrect.
C.The variable 'vpc_cidr' is misspelled.
D.The variable 'vpc_cidr' conflicts with a provider variable.
AnswerA

A Terraform module's `variables.tf` file likely declares a variable named 'environment' without specifying a `default` value. When a variable lacks a default, it becomes mandatory and must be explicitly provided when the module is called. The `terraform plan` command fails because it cannot resolve a value for this required input, preventing the configuration from being evaluated and a plan from being generated.

Why this answer

The error 'Missing required variable' indicates that a variable required by the module has not been provided. Even though 'vpc_cidr' is supplied, the module likely defines a required input variable named 'environment' without a default value, and the user did not pass it in the module block. Terraform enforces that all required variables without defaults must be explicitly set by the caller.

Exam trap

The trap here is that candidates assume the error is about the variable they did provide, rather than recognizing that other required variables may be missing.

How to eliminate wrong answers

Option B is wrong because a syntax error in the module block would produce a parsing error (e.g., 'Expected: identifier'), not a 'Missing required variable' error. Option C is wrong because if 'vpc_cidr' were misspelled, Terraform would report an 'Unsupported argument' error, not a missing variable error. Option D is wrong because variable names in Terraform are scoped to the module or root; a provider variable cannot conflict with a module input variable — they are separate namespaces.

35
MCQmedium

An engineer is refactoring a monolithic Terraform configuration into reusable modules. One module outputs a list of subnet IDs. Another module needs to use these subnet IDs to create resources. What is the best way to pass this data between modules?

A.Use a Terraform data source in the second module to query the subnets directly.
B.Define the subnet IDs as a variable in the first module and pass them to the second module via a remote state data source.
C.Store the subnet IDs in a local file and use the 'file' function to read them in the second module.
D.Output the subnet IDs from the first module and reference that output as an input variable in the second module's block.
AnswerD

This is the correct pattern: module outputs are consumed as module input variables.

Why this answer

Terraform modules communicate through explicit input and output variables. By outputting the subnet IDs from the first module and then referencing that output as an input variable in the second module's block, you create a clear, versionable, and dependency-aware data flow. This approach avoids hidden dependencies and ensures Terraform can properly graph the resource dependencies for parallel execution.

Exam trap

HashiCorp often tests the misconception that remote state data sources are the only way to pass data between modules, when in fact direct output-to-variable passing is the simplest and most maintainable approach within a single Terraform configuration.

How to eliminate wrong answers

Option A is wrong because using a data source in the second module to query subnets directly reintroduces tight coupling to the underlying infrastructure and bypasses the modular abstraction, defeating the purpose of refactoring into reusable modules. Option B is wrong because defining subnet IDs as a variable in the first module is nonsensical—variables are inputs, not outputs; the correct mechanism is to output the IDs from the first module and then use a remote state data source only if the modules are in separate configurations, but here they are in the same configuration, so direct output-to-variable passing is simpler and more idiomatic. Option C is wrong because storing data in a local file introduces an external, non-versioned artifact that can become stale, breaks Terraform's dependency tracking, and is an anti-pattern for passing runtime data between modules.

36
MCQmedium

A developer creates a module in a subdirectory called 'networking' relative to the root module. How should the module source be specified in the root module?

A../networking
B../modules/networking
C.../networking
D.networking
AnswerA

The path starts with './' indicating a relative path from the current directory.

Why this answer

When referencing a local module in a subdirectory relative to the root module, the correct path prefix is './' followed by the subdirectory name. Option A, './networking', correctly uses a relative path starting with './' to indicate the 'networking' directory is a child of the root module's directory. This is the standard Terraform convention for local module sources.

Exam trap

A common mistake on the Terraform exam is confusing local module paths (requiring './' or '../') with registry module references (bare name or 'namespace/name/provider'). Candidates often omit the './' prefix and incorrectly select a bare name like 'networking'.

How to eliminate wrong answers

Option B is wrong because './modules/networking' implies the module is inside a 'modules' subdirectory, but the question states the module is directly in a subdirectory called 'networking' relative to the root module, not nested under 'modules'. Option C is wrong because '../networking' uses a parent directory reference ('..'), which would look for the module in the directory above the root module, not in a subdirectory of the root. Option D is wrong because 'networking' without a path prefix is interpreted by Terraform as a Terraform Registry module reference, not a local filesystem path.

37
Matchingmedium

Match each Terraform function to its category.

Drag a concept onto its matching description — or click a concept then click the description.

Concepts
Matches

List function

Map function

IP network function

Encoding function

Date and time function

Why these pairings

Terraform functions are categorized by the type of data they operate on. The correct matches are: max() (numeric), lower() (string), and concat() (collection). Common confusions include misclassifying functions across categories.

38
MCQmedium

A team is using a module from the Terraform Registry. When they run 'terraform init', they receive an error stating that the module source cannot be downloaded. The module source is correct. What is the most likely cause?

A.The module output variable names are misspelled.
B.The provider version in the module conflicts with the root provider version.
C.The internet connection is down.
D.The user forgot to run 'terraform init' before 'terraform plan' or 'apply'.
AnswerC

Terraform init is the command responsible for downloading modules from their specified sources, including the public Terraform Registry. If the internet connection is down or unstable, Terraform cannot establish a connection to the registry to fetch the module's source code. This network connectivity issue directly prevents the initialization process from completing successfully, resulting in an error indicating a failure to download the module.

Why this answer

The error 'module source cannot be downloaded' occurs during terraform init when Terraform tries to fetch the module from the registry but cannot reach it. Since the module source is correct, the most likely cause is a network connectivity issue, such as the internet being down. The other options are less likely: A (output variable misspellings) would not prevent downloading; B (provider version conflict) would cause a different error later; D (forgotten init) is illogical because the error occurs while running init.

Exam trap

The trap is that candidates might think the issue is a typo in the source or a version conflict, but in this case the source is correct and the error occurs during init, so network issues are the primary suspect. Do not confuse this with forgetting to run init, as the error message itself indicates that init is being executed.

How to eliminate wrong answers

Option A is wrong because misspelled output variable names cause errors during 'terraform apply' when referencing outputs, not during 'terraform init' which handles module source downloads. Option B is wrong because provider version conflicts between root and module configurations are detected during 'terraform init' but result in a version constraint error, not a 'cannot be downloaded' error. Option C is wrong because while a down internet connection could prevent downloading, the question states the module source is correct and does not mention network issues; the most likely cause given the context is the missing 'terraform init' step.

39
MCQhard

An organization uses Terraform modules to provision multiple environments. They have a module 'vpc' that uses a for_each argument in the root module to create VPCs per environment. Each VPC requires a unique CIDR block passed via variable. What is the best practice to pass different CIDRs per instance?

A.Define a map variable with environment names as keys and CIDRs as values, then pass the entire map to the module.
B.Hardcode the CIDR within each module block.
C.Use a list variable for CIDRs and reference them with count.index and element().
D.Use a module output to fetch the CIDR from a data source.
AnswerA

This approach is ideal for provisioning multiple module instances, especially when using `for_each` on the module block. By defining a map variable, each key (e.g., "dev", "prod") can represent a distinct environment, and its corresponding value (the CIDR) can be passed directly to that specific module instance. This method ensures clear association, promotes reusability, and allows for dynamic scaling and configuration of environments without modifying the module's source code. It aligns perfectly with Terraform's declarative nature for managing distinct, yet similar, infrastructure components.

Why this answer

Using a map variable with environment names as keys and CIDRs as values allows Terraform's `for_each` to iterate over the map, creating one VPC per environment with its specified CIDR. This approach is clear, scalable, and maintains a direct key-value association. Option B (hardcoding) is not scalable and violates infrastructure as code best practices.

Option C uses `count.index` and `element()` on a list, which works but is less explicit and can lead to errors if list order changes. Option D is irrelevant because module outputs are read after creation and cannot be used to define input CIDRs.

Exam trap

The most common trap is to use `count` with a list and `element()` instead of `for_each` with a map. While both can work, `for_each` with a map is preferred because it creates a clear association between the key (environment name) and the value (CIDR), making the configuration more readable and less error-prone.

40
MCQmedium

A module outputs a map of security group IDs keyed by name. In the root module, a resource needs to reference the security group ID for the name 'web-sg'. How should the root configuration access this value?

A.module.sg["web-sg"]
B.module.sg.web-sg
C.data.module.sg["web-sg"]
D.module.sg[0]
AnswerA

This syntax correctly accesses an element within a map output named "sg" from a module. Terraform maps are key-value collections, and individual values are retrieved by enclosing their string key, such as "web-sg", in square brackets. This method is the standard and explicit way to reference a specific item when the key is known, ensuring the correct security group ID is retrieved.

Why this answer

To access a map output from a module, use the standard map index syntax with brackets and the key name. Option A correctly uses module.sg["web-sg"] to retrieve the security group ID for 'web-sg'. Option B is invalid because dot notation cannot be used with a map key containing a hyphen.

Option C incorrectly uses data source syntax; module outputs are accessed via module.<name>.<output> directly. Option D uses an index, which is only valid for list-type outputs, not maps.

41
Multi-Selectmedium

Which four of the following statements about interacting with Terraform modules are correct? (Choose four.)

Select 4 answers
.A module can reference outputs from another module using the syntax module.<MODULE_NAME>.<OUTPUT_NAME>.
.The source attribute in a module block can reference a local file path, a Git repository, the Terraform Registry, or an HTTP URL.
.Terraform automatically downloads module dependencies when running terraform init, including nested modules from the root module.
.Module inputs are defined as variables in the module's root directory, and outputs are defined as output values that can be consumed by the calling configuration.
.To use a module from a private registry, you must always specify a version constraint in the source attribute of the module block.
.A module can be used to create resources only in the same provider configuration as the root module; it cannot define its own provider configurations.

Why this answer

This statement is correct because Terraform modules expose outputs that can be referenced by the calling configuration using the syntax `module.<MODULE_NAME>.<OUTPUT_NAME>`. This allows values computed inside a module to be used elsewhere in the root module, enabling modular composition and data sharing between modules.

Exam trap

HashiCorp often tests the distinction between `source` and `version` attributes in module blocks, and the misconception that modules cannot override provider configurations, which leads candidates to incorrectly select the two wrong options.

42
MCQhard

In the configuration, what is the likely result of the resource block 'aws_flow_log'?

A.Terraform will error because for_each cannot be used with module outputs.
B.The resource will be created only for the last module instance due to overwriting.
C.It will create one flow log per network module instance, using the vpc_id output from each.
D.It will create one flow log for each VPC using a count based on length of module.networks.
AnswerC

for_each = module.networks iterates over each module instance, allowing access to its outputs via each.value.

Why this answer

`for_each` in Terraform iterates over each element in a map or set, creating one resource instance per element. When `for_each` is used with `module.networks`, it iterates over each module instance, and `each.value.vpc_id` references the `vpc_id` output from that specific module instance. This results in one `aws_flow_log` resource per network module instance, each associated with its respective VPC.

Exam trap

The TF-003 exam often tests the distinction between `for_each` and `count` in module contexts, trapping candidates who assume `for_each` cannot consume module outputs or that `count` is the only way to iterate over module instances.

How to eliminate wrong answers

Option A is wrong because `for_each` can be used with module outputs; Terraform supports `for_each` on any collection, including a map derived from module outputs, as long as the output values are known during planning. Option B is wrong because `for_each` does not overwrite resources; it creates distinct resource instances for each key in the map, unlike `count` which uses integer indices and can cause confusion with ordering. Option D is wrong because using `count` with `length(module.networks)` would create a flat list of resources indexed by number, but the correct approach for mapping to specific module instances is `for_each` with a map keyed by a unique identifier (e.g., module.networks).

43
MCQhard

A module requires a specific provider configuration with aliases. The root module has two provider configurations: provider 'aws' (default) and provider 'aws' with alias = 'uswest'. The module uses the us-west alias. How should the module block be configured to ensure the correct provider is used?

A.Set required_providers inside the module to include the alias.
B.Use the providers argument in the module block: providers = { aws = aws.uswest }.
C.Include a provider block inside the module block with alias = 'uswest'.
D.Do nothing; Terraform automatically uses the default provider.
AnswerB

The `providers` argument within a `module` block is the correct and explicit mechanism for passing specific provider configurations from the calling module to a child module. By using `providers = { aws = aws.uswest }`, the child module's expectation for an `aws` provider is satisfied by the `uswest` aliased `aws` provider configuration defined in the root module. This ensures the module operates with the intended, aliased provider configuration.

Why this answer

Terraform uses the `providers` argument in a module block to explicitly map provider configurations from the root module into the module. Since the root module has two AWS provider configurations (default and `uswest` alias), and the module requires the us-west alias, the mapping `providers = { aws = aws.uswest }` ensures the module uses the aliased provider. Without this explicit mapping, Terraform would default to the root module's default provider, which may not have the correct region or settings.

Exam trap

A common misconception is that required_providers inside a module can select an alias, when in fact it only declares provider requirements and version constraints.

How to eliminate wrong answers

Option A is wrong because `required_providers` inside a module only declares which providers the module needs and their version constraints, but does not map root-level aliased providers into the module; it cannot specify which alias to use. Option C is wrong because you cannot nest a `provider` block inside a `module` block; provider blocks are only valid at the top level of a configuration or in a `terraform` block, and modules inherit providers from the calling module. Option D is wrong because Terraform does not automatically use the default provider when a module requires a specific alias; without explicit mapping, the module will use the default provider, which may not match the intended region or configuration.

44
Drag & Dropmedium

Drag and drop the steps to manage Terraform state locking with a backend in the correct order.

Drag steps to the numbered slots on the right, or tap a step then tap a slot.

Steps
Order
1Step 1
2Step 2
3Step 3
4Step 4

Why this order

Backend config must include locking mechanism; init sets up backend, apply uses lock.

45
MCQmedium

A team is using a module from the Terraform Registry. They want to ensure that changes to the module's source version are tested in a non-production environment before being applied to production. Which approach best supports this workflow?

A.Fork the module repository and manage the module internally as a private module.
B.Pin the module to an exact version (e.g., version = "1.2.3") and update it manually after testing in isolation.
C.Configure the module source to reference the latest commit from the default branch of the repository.
D.Use a version constraint like ~> 1.0 in the module configuration and test the module in a non-production workspace before promoting to production.
AnswerD

Using a pessimistic version constraint like `~> 1.0` allows for automatic updates to minor and patch versions (e.g., `1.1.x`, `1.2.x`) while preventing potentially breaking major version upgrades. This strategy, combined with thorough testing in a dedicated non-production workspace, ensures controlled adoption of module improvements and bug fixes before safely promoting changes to critical production environments. It effectively balances stability with the ability to receive necessary updates.

Why this answer

Using a version constraint like `~> 1.0` allows Terraform to automatically select the latest compatible patch version within the specified minor version range. This enables safe, incremental updates that can be tested in a non-production workspace first, and then promoted to production by simply applying the same configuration. The constraint ensures that breaking changes (major version bumps) are not automatically pulled in, giving the team control over when to adopt them.

Exam trap

HashiCorp often tests the misconception that pinning to an exact version (Option B) is the safest approach for controlled testing, but the question specifically asks for a workflow that supports testing changes *before* production, which the pessimistic constraint enables automatically without manual version bumps.

How to eliminate wrong answers

Option A is wrong because forking the module repository and managing it internally as a private module adds significant overhead and defeats the purpose of using a public registry module; it also bypasses the version constraint workflow entirely. Option B is wrong because pinning to an exact version (e.g., version = "1.2.3") requires manual updates and does not automatically test newer compatible versions in a non-production environment before promotion. Option C is wrong because referencing the latest commit from the default branch introduces uncontrolled, potentially breaking changes directly into the configuration, with no versioning or testing gate before production.

46
MCQeasy

A team wants to use a networking module from the public Terraform Registry. They need to ensure they always get the latest patch version within the 1.2.x series. Which version constraint should they use in the module block?

A.version = "= 1.2.0"
B.version = ">= 1.2.0, < 2.0.0"
C.version = ">= 1.2.0"
D.version = "~> 1.2"
AnswerD

This "pessimistic" version constraint is the most appropriate choice for allowing only patch-level updates. It specifies that the module version must be greater than or equal to 1.2.0 but strictly less than 1.3.0 (i.e., `1.2.x`). This ensures that the team receives essential bug fixes and security patches (e.g., 1.2.1, 1.2.5) without inadvertently introducing new features or breaking changes that could arise from minor or major version increments, thus balancing stability with necessary maintenance.

Why this answer

Uses the pessimistic version constraint operator `~>`, which in Terraform allows only the rightmost version component to increment. When written as `~> 1.2`, it permits any version `>= 1.2.0` and `< 1.3.0`, effectively locking to the 1.2.x series while allowing patch updates. This matches the requirement to always get the latest patch within 1.2.x without accidentally upgrading to 1.3.0 or 2.0.0.

Exam trap

A common pitfall is confusing `~> 1.2` with `>= 1.2.0, < 2.0.0`. The pessimistic constraint `~> 1.2` restricts updates to patches within the 1.2.x series (`>= 1.2.0, < 1.3.0`), while `>= 1.2.0, < 2.0.0` permits any 1.x version, including minor upgrades. Another subtle trap: `~> 1.2.0` would lock to patches within 1.2.0, but that is not the same as `~> 1.2`.

How to eliminate wrong answers

Option A is wrong because `= 1.2.0` pins the module to exactly version 1.2.0, preventing any patch updates, which contradicts the requirement to always get the latest patch. Option B is wrong because `>= 1.2.0, < 2.0.0` allows minor version upgrades (e.g., 1.3.0, 1.4.0), not just patches within 1.2.x, which is too permissive. Option C is wrong because `>= 1.2.0` permits any version from 1.2.0 upward, including major version 2.0.0 and beyond, which could introduce breaking changes and fails to constrain to the 1.2.x series.

47
Multi-Selecthard

Which THREE files are considered part of the standard module structure?

Select 3 answers
A.main.tf
B.outputs.tf
C.backend.tf
D.terraform.tfvars
E.variables.tf
AnswersA, B, E

The main.tf file is conventionally used to define the primary resources, data sources, and local values that constitute the core functionality of a Terraform module. It serves as the central point for the module's infrastructure provisioning logic, making it an essential component for any standard module. Its presence is fundamental for the module to perform its intended infrastructure creation or management tasks, encapsulating the module's primary purpose.

Why this answer

`main.tf` is the primary entry point for defining the core resources and data sources in a Terraform module. It is one of the three mandatory files (along with `variables.tf` and `outputs.tf`) that constitute the standard module structure, as specified by HashiCorp's module best practices.

Exam trap

HashiCorp often tests the distinction between files that are part of the standard module structure versus files that are commonly used but not mandatory, such as `backend.tf` or `terraform.tfvars`, leading candidates to overcount or misidentify required files.

48
Multi-Selecteasy

Which TWO are benefits of using Terraform modules?

Select 2 answers
A.Encapsulation of complexity, providing a clean interface.
B.Faster execution of terraform plan and apply.
C.Reusability of infrastructure configurations across projects.
D.Reduction in state file size.
E.Enhanced security by automatically encrypting state files.
AnswersA, C

Terraform modules encapsulate a set of related resources, abstracting away their intricate configurations and interdependencies. This allows users to interact with a complex infrastructure pattern through a simplified interface defined by input variables and output values. By hiding the underlying implementation details, modules reduce cognitive load and potential errors for consumers, promoting clarity and maintainability in larger configurations.

Why this answer

Terraform modules encapsulate complex infrastructure logic into a single, reusable abstraction. By defining input variables and output values, modules provide a clean interface that hides internal resource configurations, making configurations easier to manage and maintain.

Exam trap

HashiCorp often tests the misconception that modules improve performance or security directly, when in fact their primary benefits are encapsulation and reusability, not execution speed or automatic encryption.

49
MCQhard

You are a DevOps engineer at a company that manages infrastructure for multiple environments (dev, staging, prod) using Terraform. The team has created a reusable module for deploying an AWS ECS Fargate service. The module accepts variables for environment name, container image tag, and desired count. The module is stored in a private Git repository. The root configurations for each environment are stored in separate directories, each with its own backend configuration. Recently, a developer added a new feature to the module that requires a new variable 'enable_xray' (boolean, default false). After updating the module source to point to the new commit, the developer runs 'terraform init' and 'terraform plan' in the dev environment. The plan shows that the ECS service will be updated, but the output does not show any changes related to X-Ray. The developer expected that setting 'enable_xray = true' in the dev root module would enable X-Ray tracing. However, the plan shows no changes to the task definition. What is the most likely cause?

A.The module source was not updated correctly; it still points to the old commit.
B.The developer forgot to run 'terraform init' after changing the module source.
C.The variable 'enable_xray' is not declared in the module's variables.tf file.
D.The module does not reference the 'enable_xray' variable in any resource, so setting it has no effect.
AnswerD

For a variable to influence the infrastructure managed by Terraform, it must be actively referenced within the module's resource configurations, data sources, or outputs. In this scenario, while 'enable_xray' was declared and passed a value, no resource block or data source within the module's implementation actually uses 'var.enable_xray' to conditionally create, modify, or configure any infrastructure component. Consequently, changing the variable's value has no effect on the desired state of any managed object, leading 'terraform plan' to correctly report "no changes to infrastructure."

Why this answer

The `enable_xray` variable, even when set to `true` in the root module, will not cause any changes in the plan unless the module's resources actually reference that variable. In Terraform, a variable declared in a module has no effect on infrastructure unless it is used in a resource argument. The developer saw no changes to the task definition because the module's code likely does not include a condition or argument that uses `enable_xray` to enable X-Ray tracing on the ECS task definition.

Exam trap

The trap here is that candidates assume declaring a variable and setting its value automatically triggers infrastructure changes, but Terraform only applies changes when the variable is actually consumed by a resource argument.

How to eliminate wrong answers

Option A is wrong because if the module source still pointed to the old commit, `terraform init` would not fetch the new variable definition, but the developer already ran `terraform init` and the plan showed an update to the ECS service, indicating the new module version was loaded. Option B is wrong because the developer explicitly ran `terraform init` after updating the module source, so the module was correctly initialized. Option C is wrong because the variable `enable_xray` is declared in the module's `variables.tf` (as stated in the scenario: 'requires a new variable'), and the developer set it to `true` in the root module; the issue is not the declaration but the lack of usage in resources.

Ready to test yourself?

Try a timed practice session using only Interact with Terraform modules questions.