Terraform interview Questions/Answers

Terraform interview Questions/Answers

Table of contents

No heading

No headings in the article.

Basic Questions:

  • What is Terraform and what problem does it solve?

Terraform is an infrastructure as a code tool, it lets you define resources and infrastructure in human-readable, declarative configuration files and manages your infrastructure's lifecycle.

Terraform has several solutions over manually managing infrastructure such as,

Terraform can manage infrastructure on multiple cloud platforms(AWS, Azure, GCP, etc. – using a single tool).

Human readable configuration language helps to write your code quickly.

Terraform provides state file to track resource changes throughout your deployment.

Version control tool can be used to commit your configurations and safely collaborate on infrastructure.

  • What are the key features of Terraform?

Terraform helps you manage all of your infrastructures as code and construct it as and when needed. Here are its key main features:

Infrastructure as Code (IaC): Terraform allows you to define your infrastructure as code using a declarative language. This enables you to version control, review, and collaborate on infrastructure changes.

Execution Plan:It generates an execution plan that shows the changes to be made before applying them.

A module count that keeps track of the number of modules applied to the infrastructure.

State Management: Terraform maintains a state file that tracks the state of your infrastructure.

  • How does Terraform differ from other infrastructure provisioning tools?

Terraform differentiates itself by providing a declarative, multi-cloud, and infrastructure-as-code approach, along with a resource graph, state management, plan-driven execution, and a robust provider ecosystem. These terms make Terraform a powerful and versatile tool for infrastructure provisioning, management, and automation.

  • What is the basic structure of a Terraform configuration file?

e.g.

terraform {
         required_providers {
                aws = {
                source  = "hashicorp/aws"
                version = "~> 4.16"
        }
        }
                required_version = ">= 1.2.0"
        }
        provider "aws" {
        region = "us-east-1"
        }

        resource "aws_instance" "web_server" {
          ami           = "ami-053b0d53c279acc90"
          instance_type = "t2.micro"
          key_name      = "my_newkey"

output "instance_ip" {
  description = "The public IP address of the created instance."
  value       = aws_instance.web_server.public_ip
}

main.tf

The next port of call for anyone looking at your code. I like to specify the backend storage method for the state file and the required providers here. Locals and Data blocks could also be included here if needed.

provider.tf

Some people like to put the providers in a separate providers.tf file which might be a good idea if you have lots of them, or maybe the same providers but with different versions.

variables.tf

Defines the variables needed.

resources

Resources are the most important element in the Terraform language. Each resource block describes one or more infrastructure objects, such as virtual networks, compute instances, or higher-level components such as DNS records.

What is a Terraform provider?

Terraform relies on plugins called providers to interact with cloud providers, SaaS providers, and other APIs.

Terraform configurations must declare which providers they require so that Terraform can install and use them.

  • How do you initialize a Terraform project?

Command to Initialize:Terraform init

What are Terraform workspaces and how are they useful?

Workspaces allows you to separate your state and infrastructure without changing anything in your code when you wanted the same exact code base to deploy to multiple environments without overlap. i.e. Workspaces help to create multiple state files for set of same terraform configuration files.

In your Terraform configuration, you can use the terraform.workspace variable to reference the current workspace:

resource "aws_instance" "example" {
  ami           = "ami-0c94855ba95b798c7"
  instance_type = "t2.micro"

  tags = {
    Name = "example-instance-${terraform.workspace}"
  }
}

With Workspaces, we can set deploy different environment with same terraform configuration files.

To manage multiple distinct sets of infrastructure resources (e.g. multiple environments), we can use Workspaces.

Workspaces isolate Terraform state. It is a best practice to have separate state per environment. Workspaces are technically equivalent to renaming your state file.

Workspaces ensure that the environments are isolated and mirrored.

Workspaces are the successor to old Terraform Environments.

  • What is a Terraform state file and why is it important?

Terraform creates a state file called “terraform.tfstate”. This State File contains full details of resources in our terraform code. When you modify something on your code and apply it on cloud, terraform will look into the state file, and compare the changes made in the code from that state file and the changes to the infrastructure based on the state file.

State is important to keep a record of why and how infra was created at the first place. state is like blueprint of the Real world infra with some unique ids and attributes.

  • How do you manage and store sensitive data in Terraform?

Terraform requires credentials to communicate with your cloud provider's API. But most of the time, these credentials are saved in plaintext on your desktop. GitHub is exposed to thousands of API and cryptographic keys every day. Hence, your API keys should never be stored in Terraform code directly. You should use encrypted storage to store all your passwords, TLS certificates, SSH keys, and anything else that shouldn't be stored in plain text.

Advanced Questions:

  • Explain the concept of infrastructure as code (IaC) and how Terraform fits into it.

Infrastructure as code (IaC) tools allow you to manage infrastructure with configuration files rather than through a graphical user interface. IaC allows you to build, change, and manage your infrastructure in a safe, consistent, and repeatable way by defining resource configurations that you can version, reuse, and share.

Terraform is HashiCorp's infrastructure as code tool. It lets you define resources and infrastructure in human-readable, declarative configuration files, and manages your infrastructure's lifecycle. Using Terraform has several advantages over manually managing your infrastructure:

  • Terraform can manage infrastructure on multiple cloud platforms.

  • The human-readable configuration language helps you write infrastructure code quickly.

  • Terraform's state allows you to track resource changes throughout your deployments.

  • You can commit your configurations to version control to safely collaborate on infrastructure.

  • What is a Terraform module and how do you create and use one?

Modules are like containers for multiple resources that are used together. A module consists of a collection of .tf and/or .tf.json files kept together in a directory. A module can call other modules, which lets you include the child module's resources in the root/main configuration file concisely. Modules can also be called multiple times, either within the same configuration or in separate configurations, allowing resource configurations to be packaged and re-used.

To create a Terraform module, you'll need to create a new directory containing a set of .tf files that define the resources and variables for your module. Here's an example of a simple module that creates an AWS S3 bucket:

modules/s3_bucket/main.tf:

resource "aws_s3_bucket" "this" {
  bucket = var.bucket_name
  acl    = var.acl
}

variable "bucket_name" {
  description = "The name of the S3 bucket"
  type        = string
}

variable "acl" {
  description = "The access control list for the S3 bucket"
  type        = string
  default     = "private"
}

To use this module in your Terraform configuration, you'll need to add a module block that references the module's directory:

main.tf:

provider "aws" {
  region = "us-west-2"
}

module "s3_bucket" {
  source      = "./modules/s3_bucket"
  bucket_name = "my-example-bucket"
}
  • Describe how Terraform handles dependencies between resources.

Terraform has built-in dependency management. Terraform has two kinds of dependencies between resources- implicit and explicit dependencies.

Implicit dependencies, as the name suggests, are detected by Terraform automatically. This is when the output of a “resource A” is used in “resource B”. Terraform automatically detects that “resource B” needs to be created only after “resource A”

Explicit dependencies can be specified in cases where two resources are internally dependent on each other without sharing any outputs. This can be done by using the depends_on parameter in the configuration block.

  • How does Terraform handle the lifecycle of resources?

the lifecycle meta-argument is used to manage the lifecycle of a resource. It provides a way to specify additional behavior that affects how Terraform handles changes to a resource. Examples of these sub-arguments include create_before_destroy, prevent_destroy, ignore_changes, and depends_on.

The lifecycle meta-argument supports several sub-arguments, including:

  1. create_before_destroy: This boolean value determines whether Terraform creates a new resource before destroying the old one. If set to true, Terraform will create a new resource before destroying the old one. This is useful for resources that can’t be updated in place, such as databases.

  2. prevent_destroy: This boolean value determines whether Terraform can destroy a resource. If set to true, Terraform will prevent the resource from being destroyed. This is useful for resources that should never be deleted, such as production databases or key management systems.

  3. ignore_changes: This list of attributes determines which resource attributes Terraform should ignore when determining whether a change has occurred. If an attribute is listed here, Terraform will ignore changes to that attribute and not try to update it.

  • What is the difference between Terraform's provisioners and remote-exec provisioners?

local-exec provisioners and remote-exec provisioners is the execution context. Local-exec provisioners run on the Terraform host machine, while remote-exec provisioners execute commands on the provisioned resource itself. This difference allows you to perform different types of actions based on your requirements.

  • What are Terraform backends and why are they important?

There are two types of Terraform backends: local and remote.

1. Local Backend

A local backend stores the state file on the machine where Terraform is running. This is the default backend that is used if you don’t specify a backend in your Terraform configuration. The local backend is useful for testing and development environments, but it’s not recommended for production environments since it can lead to inconsistencies if the state file is lost or corrupted.

2. Remote Backend

A remote backend stores the state file in a centralized location, such as a cloud object storage service or a database. Remote backends provide several benefits, such as enabling collaboration between team members, versioning state files, and providing a history of changes. There are several remote backend providers available, such as Amazon S3, Azure Storage, Google Cloud Storage, and HashiCorp Consul.

Terraform Backend is a configuration option in Terraform that allows you to store and manage the state of your infrastructure in a remote or local location. The backend is responsible for storing the state file and providing an interface for reading and writing state data. When you run Terraform, it checks the backend to see if there are any changes to the state file, and if there are, it applies those changes to your infrastructure.

  • Explain the concept of Terraform remote state and how it can be shared among team members.

Terraform remote state is a feature that allows you to store and share the state of your infrastructure managed by Terraform in a centralized and remote location. The state represents the current state of the resources created by Terraform, including metadata, resource dependencies, and attribute values. Storing the state remotely is crucial for collaboration and consistency among team members working on the same infrastructure.

Here's an explanation of the concept of Terraform remote state and how it can be shared among team members:

Remote State Backend: Terraform remote state uses a remote backend to store the state information. The remote backend can be a supported storage service like AWS S3, Azure Blob Storage, Google Cloud Storage, or a version control system like Git. The backend provides a secure and centralized location to store the state, ensuring that all team members can access and update it.

To configure Terraform to use remote state, you define the backend configuration in the backend block within your Terraform configuration files. The backend configuration specifies the type of backend to use (e.g., S3, Azure Blob Storage) and the necessary connection details, such as credentials and bucket or container names.

By leveraging Terraform remote state and a shared remote backend, team members can work collaboratively on infrastructure changes, maintain consistency, prevent conflicts, and improve overall coordination and efficiency in managing infrastructure-as-code projects.

  • How do you manage Terraform state when working with a team of developers?

    Remote State Storage: Store the Terraform state in a remote backend. Use a supported storage service like AWS S3, Azure Blob Storage, Google Cloud Storage, or a version control system like Git. Storing the state remotely allows team members to access and update it from a centralized location, promoting collaboration and preventing state file conflicts.

    Enable State Locking: Configure your remote state backend to support state locking. State locking ensures that only one team member can modify the infrastructure state at a time, preventing conflicts and maintaining consistency. Locking prevents simultaneous modifications and provides a mechanism for coordination among team members.

    Configure Backend Configuration: Each team member should configure their Terraform backend configuration to use the shared remote backend. This includes specifying the backend type, connection details, and any necessary authentication or access credentials. The backend configuration ensures that all team members are working with the same remote state.

    Use Version Control: Store your Terraform configuration files in a version control system like Git.

  • What are some best practices for organizing and structuring Terraform code?

Structuring

Naming Convention

Use Shared Modules

Latest Version

Backup System State

Lock State File

User Docker

  • How can you test Terraform configurations before applying them in production?

    Terraform fmt — to format the code correctly.

    Terraform validate — to verify the syntax.

    Terraform plan — to verify the config file will work as expected.

  • How do you handle Terraform state locking to prevent conflicts in a team environment?

    Remote State Backend: Store the Terraform state in a remote backend that supports state locking. Common choices include AWS S3, Azure Blob Storage, or HashiCorp Consul. Using a remote backend ensures that the state is stored in a centralized and accessible location for all team members.

    Enable Locking: Configure your remote state backend to enable locking. Terraform automatically uses the locking mechanism provided by the backend to manage concurrent access. When a team member runs a Terraform command that modifies the state, Terraform acquires a lock on the state file, preventing others from modifying it until the lock is released.

    Terraform Commands: Encourage team members to follow best practices when working with Terraform commands. When modifying the infrastructure, team members should always run commands such as terraform plan, terraform apply, or terraform destroy within a lock-aware environment. Terraform automatically checks for a lock and waits for it to be released before proceeding.

  • Describe how you can use Terraform to manage multiple environments (e.g., development, staging, production).

Setting up environments using workspaces

Let’s say you have the following Terraform configuration:

provider "aws" {
  region = "us-east-2"
}resource "aws_instance" "example" {
  ami           = "ami-0fb653ca2d3203ac1"
  instance_type = "t2.micro"  tags = {
    Name = "example-server"
  }
}

This code deploys a single virtual server, called an EC2 instance, in AWS in the us-east-2 (Ohio) region and gives it the name tag example-server.

Now, imagine you want to deploy this server in three environments: dev, stage, prod. To do this using workspaces, you first create a workspace called dev using the terraform workspace new command:

$ terraform workspace new devCreated and switched to workspace "dev"!You're now on a new, empty workspace. Workspaces isolate their state, so if you run "terraform plan" Terraform will not see any existing state for this configuration.

And now you can deploy the server in dev using terraform apply:

$ terraform applyTerraform will perform the following actions:  # aws_instance.example will be created
  + resource "aws_instance" "example" {
      + ami                          = "ami-0fb653ca2d3203ac1"
      + instance_type                = "t2.micro"
      (...)
    }Plan: 1 to add, 0 to change, 0 to destroy.Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.  Enter a value:

The plan output shows Terraform will deploy a new EC2 instance, which is exactly what you want, so you enter yes, and Terraform will deploy your server.

To deploy to staging, you create a new workspace called stage:

$ terraform workspace new stage
$ terraform apply
And run apply again:
$ terraform applyTerraform will perform the following actions:  # aws_instance.example will be created
  + resource "aws_instance" "example" {
      + ami                          = "ami-0fb653ca2d3203ac1"
      + instance_type                = "t2.micro"
      (...)
    }Plan: 1 to add, 0 to change, 0 to destroy.Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.  Enter a value:

Even though you just deployed an EC2 instance in dev, the plan output shows Terraform wants to deploy a totally new EC2 instance. That’s because you’re now in the stage workspace, so Terraform is using a separate state file, and knows nothing about the instance already deployed in dev. Enter yes and Terraform will deploy the new instance in stage.

Repeat this process one more time for the prod environment:

$ terraform workspace new prod
$ terraform apply

At this point, you have three environments (three workspaces), with one EC2 instance deployed in each one, and exactly one copy of your Terraform code to manage it all.

Switching between environments

To switch between environments, you need to switch between workspaces using CLI commands. You can see all your workspaces using the terraform workspace list command:

$ terraform workspace list
  default
  dev
  stage
* prod

You can switch to a different workspace using the terraform workspace select command:

$ terraform workspace select dev
Switched to workspace "dev".

Now, any command you run on this code (e.g., terraform apply) will run against the dev workspace.

Question/Answers list:

  1. What are the key components of Terraform?

Terraform has two important components: Terraform Core and Terraform Plugins.

Terraform Core oversees the reading and interpolation of resource plan executions, resource graphs, state management features and configuration files. Core is composed of compiled binaries written in the Go programming language. Each compiled binary acts as a command-line interface (CLI) for communicating with plugins through remote procedure calls (RPC).

Terraform Plugins are responsible for defining resources for specific services. This includes authenticating infrastructure providers and initializing the libraries used to make API calls. Terraform Plugins are written in Go as executable binaries that can either be used as a specific service or as a provisioner. (Provisioner plugins are used to execute commands for a designated resource.)

2.What is the purpose of Terraform's execution plan?

The terraform plan command creates an execution plan, which lets you preview the changes that Terraform plans to make to your infrastructure. By default, when Terraform creates a plan it: Reads the current state of any already-existing remote objects to make sure that the Terraform state is up-to-date.

3 .How does Terraform maintain the state of the infrastructure?

State files should be stored remotely as a general rule and isolated and organized so that separate state files exist for logical groups of resources and environments to reduce the “blast radius” if mistakes occur.

The terraform_remote_state data source can be used to reference outputs from state files. Finally the terraform state and terraform import commands can be used to manipulate the contents of the state file.

4.What are Terraform providers, and how do they work?

Terraform can provision infrastructure across public cloud providers such as Amazon Web Services (AWS), Azure, Google Cloud, and DigitalOcean, as well as private cloud and virtualization platforms such as OpenStack and VMWare.

# Configure the AWS provider
provider "aws" {
  access_key = "YOUR_AWS_ACCESS_KEY"
  secret_key = "YOUR_AWS_SECRET_KEY"
  region     = "us-west-2"
}

In the example above, we configure the AWS provider by specifying the AWS access key, secret key, and the desired AWS region. The access key and secret key are used to authenticate Terraform with your AWS account.

5.What are Terraform modules, and why are they useful?

A Terraform module is a collection of standard configuration files in a dedicated directory. Terraform modules encapsulate groups of resources dedicated to one task, reducing the amount of code you have to develop for similar infrastructure components.

three main categories of modules:

  1. Root Module

  2. Child Module

  3. Published Modules

Modules are useful for:

  • Organise Configuration: Easier to navigate, understand, and update your configuration

  • Encapsulate Configuration: Helps prevent unintended consequences

  • Re-use Configuration: Share modules that you have written with your team or the general public

  • Consistency: help to provide consistency in your configurations

6.How can you define and manage infrastructure resources in Terraform?

Terraform uses resource blocks to manage infrastructure, such as virtual networks, compute instances, or higher-level components such as DNS records. Resource blocks represent one or more infrastructure objects in your Terraform configuration.

Review the EC2 instance resource

The aws_instance.web resource block defines an aws_instance resource named web to create an AWS EC2 instance.

resource "aws_instance" "web" {
  ami                    = "ami-a0cfeed8"
  instance_type          = "t2.micro"


  tags = {
    Name = random_pet.name.id
  }
}

The arguments inside the aws_instance.web resource block specify what type of resource to create.

  • The instance_type and ami arguments tell the AWS provider to create a t2.micro EC2 instance using the ami-a0cfeed8 machine image.

    Note

  • The tags argument specifies this EC2 instance's name. Notice that the argument references the random_pet.name's ID attribute (random_pet.name.id) to give the EC2 instance a unique name. This defines an implicit dependency between the EC2 instance and the random_pet resource; Terraform cannot create the instance until it has a name for it

7.What is the Terraform configuration file called, and what does it contain?

The Terraform configuration file is typically called main.tf, although you can use multiple files with different names and organize them as per your needs. The main configuration file, main.tf, contains the declarative code that describes the desired state of your infrastructure. It includes the following elements:

Provider Configuration: The provider configuration block specifies the provider you want to use, such as AWS, Azure, or Google Cloud. It includes provider-specific settings, such as authentication credentials, region, or endpoint.

Resource Blocks: Resource blocks define the infrastructure resources you want to provision. Each resource block represents a specific resource type provided by the chosen provider. For example, you might have resource blocks for EC2 instances, VPCs, or S3 buckets. Inside each resource block, you set the necessary attributes and parameters to configure the resource.

Variables: Variables allow you to parameterize your Terraform code. They enable you to define values that can be dynamically assigned during runtime. Variable blocks define the variables used in the configuration and specify their type, default values, and optional constraints. Variables can be defined within the main.tf file or in separate .tf files.

Outputs: Output blocks define values that are exposed after provisioning the infrastructure. Outputs can be useful for retrieving information about the provisioned resources, such as their IP addresses or DNS names. These values can be referenced by other systems or scripts.

8.What are the differences between Terraform's "terraform apply" and "terraform destroy" commands?

terraform Apply – this is where you accept changes and apply them against real infrastructure. terraform Destroy – this is where to destroy all your created infrastructure.

9.How can you handle sensitive data or secrets in Terraform?

Types of Secrets in Terraform

Secrets can be classified into various types, such as:

  • API keys used for authentication with cloud providers and other services

  • Database credentials like usernames and passwords

  • SSH keys for secure server access,Below are the Best Practices for Managing Secrets in Terraform

Use environment variables

Store Secrets in a Secure External Storage

Encrypt sensitive data

Utilizing Secrets Management Tools(HashiCorp Vault and AWS Secrets Manager)

10.Explain the concept of Terraform workspaces and when they are useful.

If we use the local backend for storing Terraform state, Terraform creates a file called terraform.tfstate to store the state of the applied configuration. However, in scenarios where you want to use the same configuration for different contexts, separate states might be necessary with same configuration.

Workspaces allows you to separate your state and infrastructure without changing anything in your code when you wanted the same exact code base to deploy to multiple environments without overlap. i.e. Workspaces help to create multiple state files for set of same terraform configuration files.

Each of environments required separate state files to avoid collision. With the use of workspaces, you can prepend the workspace name to the path of the state file, ensuring each workspace (environment) had its own state.

11.How can you handle changes in infrastructure requirements or configurations in Terraform?

Assess the Required Changes: Determine the nature of the changes needed in your infrastructure. This could include adding or removing resources, modifying resource configurations, adjusting network settings, or updating variable values. Identify the specific aspects of your infrastructure that need modification.

Update Terraform Configuration: Make the necessary changes to your Terraform configuration files (.tf files) based on the assessed requirements. Modify the resource blocks, update attribute values, add or remove resources, and adjust any other relevant configuration elements. Ensure that your configuration accurately reflects the desired state of your infrastructure.

Plan the Changes: Run the terraform plan command to generate an execution plan. Terraform analyzes your updated configuration and compares it to the current state stored in the state file. The plan output provides a summary of the proposed changes, including additions, modifications, or deletions of resources. Review the plan to ensure it aligns with your expectations.

Review the Plan , Apply the Changes,Manage the state and Version Control and Release Management.

12.How can you reference outputs from one Terraform module in another module?

Syntax/module.<object-name>.<output-name>

module "network" {
  source = "./modules/aws-network"

  base_cidr_block = "10.0.0.0/8"
}

module "consul_cluster" {
  source = "./modules/aws-consul-cluster"

  vpc_id     = module.network.vpc_id       # < output of module.network
  subnet_ids = module.network.subnet_ids   # < output of module.network
}

13.What is the purpose of Terraform's "variable" block, and how can you use it?

Terraform variables are used to customize modules and resources without altering their source code. They allow you to define and manage reusable values in your Terraform configurations, making it easier to adapt to changes and maintain consistency across different environments.

Assigning Variable Values with a terraform.tfvars file

A terraform.tfvars file is used to assign variable values that are automatically loaded by Terraform during the apply or plan commands. This file should be created in the root directory of your Terraform project and should contain key-value pairs for your variables as shown below:

variable_name = "variable_value"

For example:

first_name = "John"
last_name = "Smith"

14.What are data sources in Terraform, and when would you use them?

Data sources in Terraform are used to get information about resources external to Terraform, and use them to set up your Terraform resources. For example, a list of IP addresses a cloud provider exposes.

Example usage

We can find examples of data source usage:

variable "vpc_id" {}

data "aws_vpc" "selected" {
  id = var.vpc_id
}

resource "aws_subnet" "example" {
  vpc_id            = data.aws_vpc.selected.id
  availability_zone = "us-west-2a"
  cidr_block        = cidrsubnet(data.aws_vpc.selected.cidr_block, 4, 1)
}

In this scenario, we may have created our aws_vpc manually, because it also contains other manually created resources, and now we want to start adding Terraform managed resources to it.

15.What are remote backends in Terraform, and why would you use them?

With remote state, Terraform writes the state data to a remote data store, which can be shared between all team members.

By default, Terraform stores its state in the file terraform.tfstate in local filesystem. This works well for personal projects, but working with Terraform in a team, use of a local file makes Terraform usage complicated because each user must make sure they always have the latest state data before running Terraform and make sure that nobody else runs Terraform at the same time.

The best way to do this is by running Terraform in a remote environment with shared access to state. Remote state solves those challenges. Remote state is simply storing that state file remotely, rather than on your local filesystem. With a single state file stored remotely, teams can ensure they always have the most up to date state file.

Thank you!