Terraform Certification Study Guide

Key Points for Terraform Associate Certification

Manjit Singh
12 min readNov 28, 2020

This article aims to give you a quick glance on the Terraform. I strongly recommend to go through this if you are planning to appear for terraform certification.

About Certification

  • 60 Minutes
  • 50~60 Questions
  • 70 $

Exam Structure

Terraform Course

  1. Infrastructure as Code?
Process by which we automate the provisioning, deployment, update and management of infrastructure via code.

2. Infrastructure as Code Benefits?

a. Automation
Infra provisioning is automated which helps in faster deployments and minimizing human error.
b. Reusability of the code
We can reuse the same code to deploy multiple infra.
c. Versioning and Sharing
Code can be version controlled to track changes and even can be shared with other teams.

Providers in terraform

  • It handles the API interactions from client to servers. A provider is responsible for understanding API interactions and exposing resources.
  • Terraform has a separate providers for each platform like AWS, Azure, GCP, VMware. Here are the list of Providers.
  • To get the plugins via providers, we will have to define the provider block in .tf file and then run terraform init command.
  • We can have multiple provider block in a .tf file. The second provider block can be accessed via alias.
provider "aws" {
region = "us-west-1"
}
provider "aws" {
region = "us-west-1"
alias = "dev_cluster"
}
resource "aws_vpc" "myvpc"{
cidr_block = "10.0.0.0/16"
}
resource "aws_vpc" "myvpc1"
cidr_block = "10.0.0.0/16"
provider = aws.dev_cluster
}
  • When you run terraform init, plugins gets downloaded in the below locations. You can also manually put the plugins at the below location.
Windows                     %APPDATA%\terraform.d\plugins
All other systems ~/.terraform.d/plugins
  • Provider versioning- You can specify a Provider version. Providers are released frequently and it’s a good idea to mention provider version as it can avoid any breaking changes in the newer version.
provider "aws" {
region = "us-west-1"
version = "~> 3.0"
}
  • terraform init command only downloads the providers distributed by Hashicorp. Third party plugins should be manually downloaded and installed.
  • With Terraform 0.13, terraform init will automatically download and install partner and community providers in the HashiCorp Terraform Registry.
  • version and alias are the two arguments defined by terraform and is available for all Providers.
  • There are two ways to configure Provider Version.
1. With required_providers blocks under terraform block.terraform {
required_providers {
aws = "~> 1.0"
}
}
2. Provider version constraints can also be specified using a version argument within a provider blockprovider {
version= "1.0"
}
  • CLI configuration File- Used to configure per user setting for CLI behaviors, which apply across all Terraform working directories. It is either named terraform.rc (For Windows) or .terraformrc (For other systems).
    On Windows, terraform.rc is stored in %APPDATA% directory. On other systems, .terraformrc is placed directly in the home directory of the relevant user.
  • Provider Plugin Cache- To download and cache the plugin at a common directory that can be used by multiple terraform configuration, instead of downloading the provider for each configuration. To enable the plugin cache, use the plugin_cache_dir setting in CLI configuration file.
plugin_cache_dir = “$HOME/.terraform.d/plugin-cache”Alternatively, the TF_PLUGIN_CACHE_DIR environment variable can be used to enable caching or to override an existing cache directory

Variables in terraform

a) String
b) Number
c) Boolean
d) List
e) Map

variable "region" {
type = string
default = "us-west-1"
}
variable "http_port" {
type = number
default = 80
}
variable "is_public" {
default = true
}
variable "availability_zone" {
type = list(string)
default = ["us-west-1a","us-west-1b"]
}
variable "ami_id" {
type = map
default = {
us-west-1 = "ami-6hgqyag7"
us-west-2 = "ami-78hggv5"
}

Variables Declaration in terraform

  1. Environment Variables- To declare a variable using environment variables, you need to prefix the variable name with TF_VAR_.
    Environment variables does not support list and map types.
export TF_VAR_aws_region = “us-west-1”

2. Passing Variable at CLI on runtime- We can pass the variable at CLI while running the terraform commands.

terraform plan -var=”aws_region=us-west-1"

3. From a File- We can also pass variables by declaring them in a separate tfvars file and then passing the file on runtime with terraform.

terraform plan -var-file=dev_vars.tfvars

Variable Precedence

  1. Environment variables — — — — — — Least precedence
  2. Terraform.tfvars
  3. Terraform.tfvars.json
  4. Any .auto.tfvars
  5. -var or -var-file options — — — — — — — Highest Precedence

Output Variables

  • These variables are shown back to the user after apply operation is performed. Output can also be queried.
output "public_ip" {
value = aws_eip.ip.public_ip
}
  • To query the above resource output, we can use terraform output public_ip
  • An output variable can be marked as sensitive by using sensitive parameter. Terraform will not show this variable in outputs, however they will still be recorded in state.
output "db_password" {
value = aws_db_instance.db.password
sensitive = true
}

Terraform Workflow

  • terraform init- This command initializes the working directory. This will download the plugins mentioned in the provider block. It will also download the modules if we are using any.
terraform init --upgrade ---- To upgrade modules or plugins
terraform init -backend=false -- To skip backend initialization
terraform init -get=false -- To skip the child module installation
terraform init -get-plugins=false -- Skip plugin installation
  • terraform validate- This command checks and validates the terraform configuration. It checks whether configuration is syntactically correct or not.
  • terraform plan- This command generates the execution plan and shows us the changes that terraform is going to perform. These changes can be resource creation, modification, destruction.
  • terraform apply- This command will actually run the script and apply the changes.
  • terraform destroy- This command will destroy the infrastructure created with terraform.
terraform plan -destroy  -- To see the behavior of terraform destroy
terraform plan -out=tfplan -- To save the execution plan
terraform plan -target=resource -- To target a particular resource
terraform plan -refresh=true -- To update the state file

Terraform General Commands

  1. fmt- To format the terraform code. It rewrites the Terraform configuration files to a canonical format and style. By default, it scans the current directory. We can also specify a directory path to format the code.
terraform fmt [options] [DIR]terraform fmt -recursive    --- Formats the subdirectories as well
terraform fmt -diff --- To format and check the differences
terraform fmt -list=false --- Does not shows the list of files formatted by terraform.

2. taint- Marks a specific resource for re-creation on next apply. To manually taint a resource, use terraform taint resource.id .

terraform taint [options] [resource address]terraform taint -state=path   --To taint a state file from a path
terraform taint aws_instance.dev_vm -- To taint a single resource

3. untaint- To untaint the previously tainted resource

4. Terraform State- To check the details of the current state of infrastructure.

General State Commands
1)terraform state list -- To list the resources in state file.
2)terraform state pull -- To download the state file.
3)terraform state mv -- To move items from terraform state.
4)terraform state rm -- To remove items from terraform state.

5. Debugging- We can debug the terraform output by changing the log levels.

Different Log Levels-
1) TRACE -------> The most Verbose logging.
2) DEBUG
3) INFO
4) WARN
5) ERROR
export TF_LOG=DEBUGTF_LOG_PATH=/some/path ----> can be used to store the logs in a file specified under TF_LOG_PATH.

Importing an Existing Resource in Terraform

To bring the manually created resources inside terraform configuration. To import a resource, you need to do 2 steps-

  • Create a resource block in terraform code
  • Run the terraform import command giving its resource id.
terraform import aws_instance.dev_server i-129i9mij9u

Terraform Modules

  • A module is one or more terraform file in a single directory. Terraform can support local and remote modules.
  • Every Terraform configuration has at least one module.
  • It is recommended(not mandatory) to mention version number in module. Version constraints are only supported for modules installed from module registry.
  • Remote module is present in Terraform Registry where all the verified modules are present.
  • When using a new module, you should either use terraform init or terraform get to download the module.
Syntax For referencing a Registry Module- <NAMESPACE>/<NAME>/<PROVIDER>Syntax For referencing a Registry Module- <HOSTNAME>/<NAMESPACE>/<NAME>/<PROVIDER>
  • By default, terraform clones the default branch referenced by HEAD. You can override using ref argument. The value of ref argument can be a branch name or tag names. The syntax is url?ref=v1.2.3
module "vpc" {
source = "git::https://www.example.com/vpc.git?ref=v1.2.0"
}
  • Two ways to Load Modules-
    1) Local Module- Loaded from local filesystem
    2) Remote Module- Loaded from remote sources.

Module Arguments

  1. source- (required) Every module should have this components. This is the location where the module is present. Its a mandatory argument.
  2. version- (Optional) Specifies the version of module referenced.

Terraform State Management

State file stores the current state of the infrastructure.

  1. Local State- By default, terraform creates a local state file called terraform.tfstate in current directory. This is called local Backend.
  2. Backends- Place where the state file is stored.
  • Local backend- The local backend stores state on the local filesystem, locks that state using system APIs, and performs operations locally.
terraform {
backend "local" {
path = "relative/path/to/terraform.tfstate"
}
}
  • remote backend- The remote backend stores Terraform state in a remote location. This can allow multiple team members to work on same piece of code and manage same infrastructure.

Benefits of remote Backend

  1. Remote state storage makes collaboration easier and keeps state and secret information off your local disk.
  2. It also provides high availability by storing the state file at remote location. In case our local disk fails or crashes, our state file will not be affected.

Types Of backends

Standard: State management, functionality covered in State Storage & LockingEnhanced: Everything in standard plus remote operations.
  1. Terraform refresh
  • It refreshes the state files and checks if any configuration has changed since the last run. If yes, then it modifies the state file.
  • This can be used to detect any drift from the last-known state, and to update the state file.
  • The command terraform refresh does not modify infrastructure. It only modifies the state file.

2. State Locking- This locks the state file when someone executes any terraform command. This feature is used when multiple team members are working on same terraform script. To unlock a state locking, execute

terraform force-unlock

3. State Push- To push the local state file in remote backend.

terraform state push

4. terraform state mv- This command can move the resources in state file. It can move items to a different state file.
This command can also be used to rename a resource in state file.

5. terraform show- This command is used to provide human-readable output from a state or plan file. It helps to inspect the current state of infrastructure.

terraform state list -- To list the resources present in state file.

Purpose of Terraform State

  1. Mapping to real World
  2. Track Metadata which helps in determining the correct order to destroy resources.
  3. Improves Performance
  4. Syncing in case of remote state.

Partial Backend Configuration

Here, we don not need to specify each and every argument inside backend block. We can omit certain fields like secrets. However, the omitted argument must be provided as part of initialization process.

Terraform Workspace

  1. Workspace logically separates the state files and allows us to create infra in different environment with same piece of code.
  2. Terraform contains a workspace called default which is a default workspace and cannot be deleted.
  3. Each terraform workspace has its own state file.
  4. For local state, Terraform stores the workspace states in a directory called terrafrom.tfstate.d
  5. ${terraform.workspcae} returns the name of current workspace.
Terraform Workspace Commands
1) terraform workspace list --- Lists all workspace
2) terraform workspace new dev -- Creates a workspace named dev
3) terraform workspace show --- Shows the current workspace.
4) terraform workspace select default --- to switch workspace
5) terraform workspace delete dev --- To delete a workspace

Terraform Functions

  • Terraform has a number of Built-in functions that you can call from within expressions to transform and generate the required values.
  • Terraform does not support user-defined functions.

Resource Dependency in Terraform

When one resource depends on other resource for creation, this is called resource dependency. Most of the times, Terraform handles the dependency by itself.

1. Implicit Dependency

This dependency is automatically handled by Terraform. Terraform uses this dependency information to determine the correct order in which to create the different resources.

Implicit Dependencyprovider "aws" {
profile = "default"
region = "us-east-1"
}

resource "aws_instance" "dev" {
ami = "ami-d744da96"
instance_type = "t2.small"
}
resource "aws_eip" "ip" {
vpc = true
instance = aws_instance.dev.id
}

2. Explicit Dependency

This type of dependency is not visible to terraform. User has to specify this dependency using depends_on keyword. This argument accepts a list of resource to create the explicit dependencies for.

Explicit Dependencyresource "aws_s3_bucket" "example" {
bucket = "some_bucket"
acl = "private"
}
resource "aws_instance" "example" {
ami = "ami-2757f631"
instance_type = "t2.micro"

depends_on = [aws_s3_bucket.example]
}

Terraform Settings

  • The special terraform configuration block type is used to configure the behaviors of Terraform itself, such as requiring a minimum Terraform version to apply your configuration.
terraform {
# ...
}
  • Terraform block also contains the backend information nested inside, which determines which backend to use. Here is the syntax of Backend Configuration.
  • To constraint the provider version, add a required_providers block inside a terraform block.
terraform {
required_providers {
aws = "~> 1.0"
}
}
  • To set an upper and lower bound on version of a provider, we use ~>
  • The terraform block is also used to test experimental features. In releases where experimental features are available, you can enable them on a per-module basis by setting the experiments argument inside a terraform block:
terraform {
experiments = [example]
}

Terraform Security

  1. Never Hardcode credentials in tf file. Use Environment variable for passing credentials if needed. For passing aws access key, you can use- export aws_access_key="aws_access_key" instead of passing them into .tf files.
  2. You can also configure CLI before running commands. For Example- AWS or Azure CLI can be configured.
  3. You can also use Hashicorp Vault Provider for handling credentials. Vault stores our secret and we can access them later.
  4. Sentinel- A Hashicorp service for Policy as Code. We can create fine grained Policy and enforce them while running the code.

Terraform Provisioners

  • They are used to perform some initial setup on the infra created like running a script, copying a file etc.
  • Provisioners are of two types- Local exec and Remote Exec.
  • Local exec runs the command locally where the Terraform is running.
  • Remote exec runs the command on the new resource created from terraform. Remote exec supports ssh and winrm connection types.
By default, if Provisioner fails, then terraform apply will also fail. on_failure setting is used to change this behavior.on_failure=continue  ---->Ignores error and continue operation.
on_failure=fail ---->Raise an error and stop applying.
  • Provisioners are of two types- Creation Time and Destroy Time.
creation-time -- Runs only during create operation(Default)
destroy-time -- Runs during destroy operation

Terraform Enterprise and Cloud

  • Terraform Cloud always encrypts the state at rest and protects with TLS in transit.
  • Terraform Cloud also knows the identity of user requesting state and maintaining a history of state changes.
  • Terraform Enterprises provides feature such as Single Sign on, auditing, Private Data Center Networking and Clustering.
  • Team and Governance feature are available only in paid version.

Other Important Points

  • A dynamic block acts much like a for expression, but produces nested blocks instead of a complex typed value. It iterates over a given complex value and generates a nested block for each element of that complex value. Overuse of dynamic block can make configuration hard to read and maintain.
  • terraform output command is used to extract value of an output variable from state.
  • terraform apply can create, destroy and modify the resource but cannot import any resource.
  • Terraform workspace is not suitable for isolation for strong separation of workspace.
  • terraform console command provides an interactive console for evaluating expressions.
  • The name of a variable can be anything except- source version providers count for_each lifeycle depends_on locals .
  • Input variable make Terraform configuration dynamic and reusable.
  • terraform import command imports the resource one by one. Not all resources can be imported.

Important Notice

As of the day of posting this article, the information given above is true. However, some features might change in future as terraform is updated regularly. Do check out the official Documentation for this.

Important Links

My Experience with Exam

  • I appeared for the Terraform Certification and successfully cleared it. This article is based upon the my experiences and certification syllabus.
  • The exam will mostly test your basic knowledge about terraform. Topics like variable type maps and list, how to access them, IaC concepts.
  • Do check the changes happened in newer versions like accessing variables in 0.11.to 0.12, providers configurations, automatic downloading of community providers in 0.13 version.
  • Do check the extra features provided by Terraform Enterprise in free and paid versions.
  • Do check the various modules like public and private, their reference syntax.
  • Please have a clear understanding on commands like terraform fmt, show, validate, init, refresh, import.

--

--