Skip to content

Exam questions


When using constraint expressions to signify a version of a provider, which of the following are valid provider versions that satisfy the expression found in the following code snippet: (select two)

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version ~> "5.36.0"
  • AWS provider version: 5.36.9
  • AWS provider version: 5.37.0
  • AWS provider version: 5.36.3
  • AWS provider version: 5.3.1

In Terraform, required_providers act as traffic controllers for your infrastructure tools. They ensure all modules use the right versions of providers like AWS or Azure, avoiding compatibility issues and guaranteeing everyone plays by the same rules. Think of them as a clear roadmap for your infrastructure setup, leading to consistent, predictable, and secure deployments.

A version constraint is a string literal containing one or more conditions, which are separated by commas.

Each condition consists of an operator and a version number.

Version numbers should be a series of numbers separated by periods (like 1.2.0), optionally with a suffix to indicate a beta release:

~>: Allows only the rightmost version component to increment. This format is referred to as the pessimistic constraint operator. For example, to allow new patch releases within a specific minor release, use the full version number:

~> 1.0.4: Allows Terraform to install 1.0.5 and 1.0.10 but not 1.1.0.

~> 1.1: Allows Terraform to install 1.2 and 1.10 but not 2.0.

Migration to terraform cloud version

After many years of using Terraform Community (Free), you decide to migrate to Terraform Cloud. After the initial configuration, you create a workspace and migrate your existing state and configuration. What Terraform version would the new workspace be configured to use after the migration?

  • the latest major release of Terraform
  • the most recent version of Terraform available
  • the same Terraform version that was used to perform the migration
  • whatever version is defined in the terraform block

When you create a new workspace, Terraform Cloud automatically selects the most recent version of Terraform available. If you migrate an existing project from the CLI to Terraform Cloud, Terraform Cloud configures the workspace to use the same version as the Terraform binary you used when migrating. Terraform Cloud lets you change the version a workspace uses on the workspace's settings page to control how and when your projects use newer versions of Terraform.

It's worth noting that Terraform Cloud also provides the ability to upgrade your Terraform version in a controlled manner. This allows you to upgrade your Terraform version in a safe and predictable way, without affecting your existing infrastructure or state.

Publishing on the terraform registry

Anyone can publish and share modules on the Terraform Public Registry, and meeting the requirements for publishing a module is extremely easy.

What are some of the requirements that must be met in order to publish a module on the Terraform Public Registry? (select three)

  • The module must be on GitHub and must be a public repo.
  • The module must be PCI/HIPPA compliant.
  • Module repositories must use this three-part name format, terraform-<PROVIDER>-<NAME>.
  • The registry uses tags to identify module versions. Release tag names must be for the format x.y.z, and can optionally be prefixed with a v .

The list below contains all the requirements for publishing a module. Meeting the requirements for publishing a module is extremely easy. The list may appear long only to ensure we're detailed, but adhering to the requirements should happen naturally.

  • GitHub. The module must be on GitHub and must be a public repo. This is only a requirement for the public registry. If you're using a private registry, you may ignore this requirement
  • Named terraform-<PROVIDER>-<NAME>. Module repositories must use this three-part name format, where <NAME> reflects the type of infrastructure the module manages and <PROVIDER> is the main provider where it creates that infrastructure. The <NAME> segment can contain additional hyphens. Examples: terraform-google-vault or terraform-aws-ec2-instance.
  • Repository description. The GitHub repository description is used to populate the short description of the module. This should be a simple one-sentence description of the module.
  • Standard module structure. The module must adhere to the standard module structure. This allows the registry to inspect your module and generate documentation, track resource usage, parse submodules and examples, and more.
  • x.y.z tags for releases. The registry uses tags to identify module versions. Release tag names must be a semantic version, which can optionally be prefixed with a v. For example, v1.0.4 and 0.9.2. To publish a module initially, at least one release tag must be present. Tags that don't look like version numbers are ignored.

Implicit dependency

From the code below, identify the implicit dependency:

resource "aws_eip" "public_ip" {
    vpc      = true
    instance =

resource "aws_instance" "web_server" {
  ami           = "ami-2757f631"
  instance_type = "t2.micro"
  depends_on    = [aws_s3_bucket.company_data]
  • The EC2 instance labeled web_server
  • The EIP with an id of ami-2757f631
  • The AMI used for the EC2 instance
  • The S3 bucket labeled company_data

The implicit dependency in the code is the EC2 instance labeled "web_server" because the aws_eip resource depends on the for its instance attribute.

Implicit dependencies are not explicitly declared in the configuration but are automatically detected by Terraform based on the relationships between resources. Implicit dependencies allow Terraform to automatically determine the correct order in which resources should be created, updated, or deleted, ensuring that resources are created in the right order, and dependencies are satisfied.

For example, if you have a resource that depends on another resource, Terraform will automatically detect this relationship and create the dependent resource after the resource it depends on has been created. This allows Terraform to manage complex infrastructure deployments in an efficient and predictable way.

The EC2 instance labeled web_server is the implicit dependency as the aws_eip cannot be created until the aws_instance labeled web_server has been provisioned and the id is available.

Note that aws_s3_bucket.company_data is an explicit dependency for the aws_instance.web_server

Init file locations

A user runs terraform init on their RHEL-based server, and per the output, two provider plugins are downloaded:

$ terraform init

Initializing the backend...

Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "aws" (hashicorp/aws) 2.44.0...
- Downloading plugin for provider "random" (hashicorp/random) 2.2.1...

Terraform has been successfully initialized!

Where are these plugins downloaded and stored on the server?

  • The .terraform.plugins directory in the current working directory
  • The .terraform.d directory in the current working directory
  • /etc/terraform/plugins
  • The .terraform/providers directory in the current working directory

By default, terraform init downloads plugins into a subdirectory of the working directory, .terraform/providers so that each working directory is self-contained.

See the example below, where I ran a terraform init and you can see the resulting directory (highlighted in the red box) and then the actual provider that was downloaded (highlighted by the green arrow)

Terraform init dir

Invalid naming of Variables

Which of the following is a valid variable name in Terraform?

  • lifecycle
  • count
  • version
  • invalid

In Terraform, variable names must follow a set of naming conventions to be considered valid. Here are some examples of invalid variable names:

Names that start with a number: 1_invalid_variable_name

Names that contain spaces or special characters (other than underscores): invalid variable name

Names that contain only numbers: 12345

Names that are the same as Terraform reserved words, such as source, version, providers, count, for_each, lifecycle, depends_on, locals.

State location for Workspaces in free

Where does Terraform Community (Free) store the local state for workspaces?

  • directory called terraform.tfstate.d/<workspace name>
  • a file called terraform.tfstate.backup
  • a file called terraform.tfstate
  • directory called terraform.workspaces.tfstate

Terraform Community (Free) stores the local state for workspaces in a file on disk. For local state, Terraform stores the workspace states in a directory called terraform.tfstate.d/<workspace_name>. Here's a screenshot of a Terraform run that was created using a workspace called training. You can see that Terraform created the terraform.tfstate.d directory, and then a directory with the namespace name underneath it.

Under each directory, you'll find the state file, which is name terraform.tfstate

Terraform refresh

True or False? The terraform plan -refresh-only command is used to create a plan whose goal is only to update the Terraform state to match any changes made to remote objects outside of Terraform.

  • False
  • True

The terraform plan -refresh-only command is used in Terraform to update the state of your infrastructure in memory without making any actual changes to the infrastructure. The -refresh-only flag tells Terraform to only update its understanding of the current state of the infrastructure and not to make any changes.

When you run terraform plan -refresh-only, Terraform will query the current state of your infrastructure and update its internal state to reflect what it finds. This can be useful if you want to ensure that Terraform has the most up-to-date information about your infrastructure before generating a plan, without actually making any changes.

It is important to note that while the terraform plan -refresh-only command updates Terraform's internal state, it does not modify the Terraform state file on disk. The Terraform state file is only updated when Terraform actually makes changes to the infrastructure.

Note that this command replaced the deprecated command terraform refresh

Unlocking state

What Terraform command can be used to remove the lock on the state for the current configuration?

  • terraform state-unlock Removing the lock on a state file is not possible
  • terraform force-unlock
  • terraform unlock

The terraform force-unlock command can be used to remove the lock on the Terraform state for the current configuration. Another option is to use the "terraform state rm" command followed by the "terraform state push" command to forcibly overwrite the state on the remote backend, effectively removing the lock. It's important to note that these commands should be used with caution, as they can potentially cause conflicts and data loss if not used properly.

Be very careful forcing an unlock, as it could cause data corruption and problems with your state file.

Terraform cloud vs Open source

Terraform Cloud provides organizations with many features not available to those running Terraform open-source to deploy infrastructure. Select the ADDITIONAL features that organizations can take advantage of by moving to Terraform Cloud. (select three)

  • Terraform registry
  • providers
  • VCS connection
  • private registry
  • remote runs

Terraform Init

Margaret is calling a child module to deploy infrastructure for her organization. Just as a good architect does (and suggested by HashiCorp), she specifies the module version she wants to use even though there are newer versions available. During a terrafom init, Terraform downloads v0.0.5 just as expected.

What would happen if Margaret removed the version parameter in the module block and ran a terraform init again?

  • Terraform would download the latest version of the module
  • Terraform would skip the module
  • Terraform would use the existing module already downloaded
  • Terraform would return an error, as the version parameter is required

Data Blocks

You are working with a cloud provider to deploy resources using Terraform. You've added the following data block to your configuration. When the data block is used, what data will be returned?

data "aws_ami" "amzlinux2" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-ebs"]
resource "aws_instance" "vault" {
  ami                         =
  instance_type               = "t3.micro"
  key_name                    = "vault-key"
  vpc_security_group_ids      =
  subnet_id                   = var.subnet
  associate_public_ip_address = "true"
  user_data                   = file("")

  tags = {
    Name = "vault"
  • a custom AMI for Amazon Linux 2
  • the IP address of an EC2 instance running in AWS
  • all possible data of a specific Amazon Machine Image(AMI) from AWS
  • the latest AMI you have previously used for an Amazon Linux 2 image

When you add a data block to your configuration, Terraform will retrieve all of the available data for that particular resource. It is then up to you to reference a specific attribute that can be exported from that data source. For example, if you include a data block for the aws_ami resource, Terraform will get a ton of attributes about that AMI that you can use elsewhere in your code - check out this link to see the list of attributes specific to the aws_ami, for example.

Within the block body (between { and }) are query constraints defined by the data source. Most arguments in this section depend on the data source, and indeed in this example most_recent, owners and tags are all arguments defined specifically for the aws_ami data source.

Terraform Cloud

When using Terraform Cloud, what is the easiest way to ensure the security and integrity of modules when used by multiple teams across different projects?

  • apply TFC organization permissions to all workspaces that allow them to only use certain modules
  • Create a list of approved modules and send them to your team to ensure they don't use modules that aren't approved by the team
  • use only modules that are published to the Terraform public registry
  • Use the TFC Private Registry to ensure only approved modules are consumed by your organization

Overall explanation

To simplify the management of approved modules, you can host all the approved Terraform modules in your organization's Private Registry on Terraform Cloud. The private registry allows you to control access to the modules and ensures they are not publicly available. By implementing a private registry, your organization can effectively control and restrict module consumption to only approved modules hosted in the Terraform Private Registry. This enhances security, maintains consistency in infrastructure deployments, and reduces the risk of using unverified or potentially harmful modules in your Terraform configurations.

Wrong Answers:

  • Creating a list is probably a bad idea as it doesn't simplify the management of modules that can be used

  • modules published to the public registry aren't "approved" modules, and these modules may not contain or implement security measures required by your organization

  • TFC permissions wouldn't work here since they wouldn't be used to control access to certain modules

Want to make this site better? Open a PR or help fund hosting costs