Terraform HashiCorp certification - Infrastructure as Code

Last updated Feb 15, 2026 Published Aug 7, 2021

The content here is under the Attribution 4.0 International (CC BY 4.0) license

TLDR

This comprehensive guide covers the essential concepts and skills required for the HashiCorp Terraform Associate certification. Whether you’re preparing for the exam or building a strong foundation in Infrastructure as Code, this reference covers state management, resource provisioning, providers, variables, and the core Terraform workflow using current best practices with Terraform 1.14+.

Introduction

Infrastructure as Code (IaC) is fundamental to modern DevOps practices. It enables organizations to manage infrastructure through version-controlled code rather than manual, click-through interfaces, creating repeatable, auditable, and scalable infrastructure deployments (Zarour et al., 2019).

Terraform is HashiCorp’s open-source solution for infrastructure automation. It provides a unified way to provision resources across any cloud provider—AWS, Azure, Google Cloud, and hundreds of others—through a simple, declarative configuration language. Rather than manually managing infrastructure or writing vendor-specific CLI commands, you write Terraform code that describes your desired state. Terraform then handles the provisioning, ensuring consistency and repeatability (Brikman, 2019).

This guide provides a comprehensive reference for understanding Terraform fundamentals and preparing for the HashiCorp Terraform Associate certification exam.

Certification Exam Overview

The HashiCorp Terraform Associate certification validates your ability to:

  • Understand IaC concepts: Recognize the benefits of infrastructure as code and when to use it
  • Manage Terraform configuration: Write, maintain, and organize Terraform code effectively
  • State management: Understand how Terraform manages and stores infrastructure state
  • Providers and resources: Work with cloud provider plugins and declare infrastructure components
  • Variables and outputs: Use Terraform’s parameterization and exposure of computed values
  • Workflow management: Execute the init, plan, apply, and destroy workflow
  • Modules and reusability: Build modular, reusable infrastructure components

Key Areas Covered:

  • Terraform CLI and configuration syntax
  • Resource declaration, providers, and data sources
  • State file management and remote backends
  • Variables, locals, and outputs
  • Functions, conditionals, and expressions
  • Provisioners and null resource patterns
  • Terraform modules and module sources
  • Import and auto-generated infrastructure

This guide covers all essential topics needed to confidently pass the certification exam.

Important Notes

Terraform Version: This guide reflects Terraform 1.14+ best practices. Most concepts in this guide are version-agnostic and apply to earlier versions as well. However, always verify syntax and available options for your specific Terraform version using the official documentation.

Deprecations & Changes: Terraform has evolved significantly from earlier versions (0.13, 0.15). Notable changes include:

  • terraform refresh was deprecated in v0.15.4 (use terraform apply -refresh-only)
  • HCL syntax refinements for better clarity
  • Enhanced module and backend features

Consult the Terraform upgrade guides if migrating from older versions.

What is Terraform?

  • Open-Source: Terraform’s source code is publicly available and community-driven.
  • Human-Readable Configuration: Uses HashiCorp Configuration Language (HCL) or JSON—no programming background required.
  • Universal Workflow: One consistent syntax and workflow for managing infrastructure across any provider (AWS, Azure, GCP, etc.).
  • Provisioning vs. Configuration: Terraform provisions infrastructure (creates, updates, deletes resources). For post-deployment configuration (package installation, service setup), use complementary tools like Ansible or cloud-init.
your *.tf/*.tf.json       -->       desired configuration      -->    Cloud providers
files                                    terraform                  (aws, azure, google)

Terraform uses a plan to manage execution flow, it gives the admin a repeatable flow and confidence to manage infrastructure. Following this section another way of consuming the basics of terraform is to watch this YouTube video that gives an introduction in fifteen minutes.

Core Benefits of Terraform

  • Declarative: You describe the desired end state. Terraform automatically determines what changes are needed.
  • Immutable Infrastructure: Infrastructure changes are reproducible and trackable, not cumulative modifications.
  • Idempotent: Running the same Terraform code multiple times produces the same result—no unintended duplications or conflicts.

Getting Started with Terraform

Best Practice: Create a dedicated service account (user) for Terraform with programmatic access only. In AWS, this might be an IAM user with administrator permissions; in Azure, a service principal; in GCP, a service account. This isolates Terraform’s permissions and simplifies auditing and credential rotation.

Terraform under the hood

  • Terraform is plugin architecture based (Micro kernel as per (Mark, 2015))
  • Terraform uses RPC to call plugins (providers) and then each provider calls upstream APIs

Core

Terraform core manages the workflow for terraform (plan and apply), it’s a single binary written in go language and it’s available for the major operating systems.

               STATE

              ________
TF CONFIG --> | CORE | -->  PLAN/APPLY
              |______|

               GRAPH

Plugin

Manages communication with infrastructure providers, for creating, deleting, updating or deleting a resource.

Syntax

# this is a comment

block_type "label" "label" {
  "key" = "value" # value can be a hard coded value, or a expression (reference to some resource)
}

Nested blocks

block_type "label" "label" {
  "key" = "value"

  block_type "label" "label" {
    "key" = "value"
  }
}
  • Terraform uses arguments and attributes to create a configuration for resources.
  • Arguments assigns a value to a name
  • Attributes are piece of data associated with a resource such as: name, address, it depends on the provider

Expressions

Expressions are used to compute a value that will be available in the future.

resource "resource_name" "my_custom_label_for_the_resource" {
  "key" = "value"
}

Resources are made available via terraform itself or contributed by the community. Those resources can be found under hashicorp providers page, each cloud vendor will provide different sets of resources.

Providers

Terraform providers are unique, the following code is not valid:

provider "aws" {
  region = "us-east-1"
}

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

Defining multiple providers, can be achieved using alias:

provider "aws" {
  region = "us-east-1"
}

provider "aws" {
  alias = "myprovider"  # <-- now it is valid to be used
  region = "us-east-2"
}

State

Terraform maintains a state file (terraform.tfstate) that tracks the current state of your infrastructure. By comparing this state against your configuration, Terraform determines exactly what changes are needed. This is the foundation of idempotency—without state, Terraform couldn’t know what already exists, and would recreate everything on each apply.

  • State and backups are created automatically in JSON format
  • Custom state file paths: use the -state flag to specify a different location
  • State storage: By default, state is stored locally; for team environments, use remote backends (S3, Terraform Cloud, etc.)
  • Security: State files are not encrypted at rest by default and contain sensitive data; always protect state file access and consider encryption

Terraform offers a command to evaluate the real world state and update the local state to reflect current infrastructure conditions.

terraform apply -refresh-only

Note: The terraform refresh command was widely used in older versions but was deprecated in Terraform v0.15.4. Use terraform apply -refresh-only instead for current versions.

Key Takeaways:

  1. Don’t manually edit state files — State is Terraform’s source of truth; manual edits cause inconsistencies
  2. State doesn’t provision — It only tracks what exists; changes to state alone won’t create or modify infrastructure
  3. Use terraform show — For a cleaner JSON view of your current state

Resources

Resources are one of the most important concepts in Terraform. A resource block declares a service or infrastructure component you want to deploy. For example: an EC2 instance in AWS, an App Service in Azure, or a Virtual Machine in Google Cloud.

Resource syntax:

resource_type "local_name" {
  key = "value" # or an expression
}

Example of AWS resource:

resource "aws_instance" "myvirtualmachine" {
  ami = "ami-*******"
  instance_type= "t2.small"
}

Resources also have meta-arguments that can be used when provisioning the resource, a few of them are listed below.

  • provider
  • count
  • depends_on
  • for_each
  • life cycle
  • provisioner and connection

Provisioners

Provisioners allow you to execute actions after a resource is created—such as running scripts or configuration commands on instances. Use provisioners as a last resort. Prefer cloud-init (AWS), custom scripts (Azure), or startup scripts (GCP) for post-deployment configuration.

Provisioner types:

  • local-exec: Executes commands on your local machine
  • remote-exec: Executes commands on the newly created remote resource (requires SSH/WinRM connectivity)
  • file: Transfers files to the remote resource

Important: Terraform has no automatic rollback mechanism. If provisioning fails, the resource is marked as taint (flagged for deletion on the next apply). This can lead to incomplete infrastructure.

local-exec

resource "aws_instance" "my_vm" {
  provisioner "local-exec" {
    command = "echo ${self.id} >> myvmid"
  }
}

remote-exec

Two types of connection supported:

  • ssh
  • winrm
resource "aws_instance" "my_vm" {
  provisioner "remove-exec" {
    command = ""
  }
}

Import Infrastructure to Terraform

Importing existing infrastructure brings it under Terraform management. This is useful when migrating from manual infrastructure to IaC.

Import Command:

terraform import resource_type.name id

Import Workflow:

  1. Define the resource skeleton in your Terraform file (without values)
  2. Locate the resource’s ID in the cloud provider console
  3. Run terraform import to populate the state
  4. Fill in the configuration details to match what’s deployed

Example (AWS EC2):

resource "aws_instance" "imported_vm" {
  ami           = "ami-xxxxxxxx"
  instance_type = "t2.small"
  tags = {
    Name = "imported VM"
  }
}
terraform import aws_instance.imported_vm i-xxxxxxxxxxxxxxxx

After import, verify the state matches your configuration, then manage the resource as usual.

Terraform console

Terraform console is a interactive shell to interact with the infrastructure.

terraform console

Terraform workflow

  • How terraform manages life cycle of a resource
  • All the steps from code to resource creation
write code --> plan --> apply --> destroy -> repeat

Init

Terraform init download plugins and save to .terraform/plugins.

Validate

Terraform validate verifies your current files.

Plan

Terraform plan creates a plan to execute the changes based on the real world state and the desired configuration

Symbol Description
+ means create
- means destroy
-/+ destroy and then create (taint)
~ update in place
<= read from data source
  • -out save the plan on a file, good for auditing.

Variables

Terraform variables are defined centrally and referenced throughout your configuration, making it easy to reuse code with different values. Variables can be supplied in three ways, with this precedence:

  1. Command line: -var "key=value"
  2. Variable file: terraform.tfvars (automatically loaded) or -var-file=custom.tfvars
  3. Environment variables: Prefix with TF_VAR_ (e.g., TF_VAR_region=us-east-1). Good for secrets

Reserved variable names (cannot be used):

  • source, count, for_each, version, provider, lifecycle, locals, depends_on

Outputs

Output values expose infrastructure details (IPs, endpoints, etc.) after provisioning. Best practice: define outputs in a dedicated outputs.tf file.

Outputs create implicit dependencies between resources, ensuring correct creation order.

Resource:

Data source

Data sources are accessed via resources by terraform. It is not recommended to:

  • Refer to data in the terraform block that has not created yet
  • Configure an explicit dependency with terraform data with depends_on

Functions

Terraform includes built-in functions for common operations—reading files, manipulating strings, operating on lists, and more. These functions are essential for dynamic configurations.

Note: Terraform does not support custom user-defined functions.

resource "resource_type" "example" {
  prop1 = replace("my value", "my", "your")
}

Conditionals

Terraform supports conditional expressions using the ternary operator (condition ? true_value : false_value). Conditionals must be inline—they’re evaluated as expressions, not statements.

variable "instance_type" {
  default = "free-tier"
}

resource "resource_type" "example" {
  machine_type = var.instance_type == "free-tier" ? "t2.small" : "t5.large"
}

Dependencies

Terraform has two different types of dependencies, the first is known as implicit. For example, one resource depends on the other and it is not declared.

Logging

Enable detailed logging in Terraform using the TF_LOG environment variable. This is useful for debugging provisioning issues.

Log Levels (in order of verbosity):

  • TRACE (most detailed; recommended for debugging)
  • DEBUG
  • INFO
  • WARN
  • ERROR
# Option 1: Export as environment variable
export TF_LOG=TRACE
terraform apply

# Option 2: Set inline
TF_LOG=TRACE terraform apply

Important: If an unsupported log level is provided, Terraform defaults to TRACE. HashiCorp recommends TRACE for reliable debugging output.

References

  1. Zarour, M., Alhammad, N., Alenezi, M., & Alsarayrah, K. (2019). A research on DevOps maturity models. Int. J. Recent Technol. Eng, 8(3), 4854–4862.
  2. Brikman, Y. (2019). Terraform Up & Running - Writing Infrastructure as Code. O’Reilly Media, Inc.
  3. Mark, R. (2015). Software Architecture Patterns. O’Reilly Media, Inc.

Appendix

Terraform 1.14+ and Recent Evolution

Terraform has matured significantly since its 1.0 release in June 2021. Version 1.14+ builds on this stability with incremental improvements while maintaining backward compatibility for the configuration language.

Key milestones:

  • 1.0 Release (2021): Stability guarantee for configuration language and command-line interfaces
  • 1.14+ Evolution: Continued refinements in performance, testing capabilities, and security features
  • Terraform Cloud/Enterprise Integration: Enhanced remote state and collaboration workflows
  • Testing Framework: Official Terraform testing capabilities for validating modules and configurations

Recent Highlights:

  • Improved error messages and diagnostics
  • Enhanced security in credential handling
  • Better module testing and validation
  • Expanded cloud provider support

For detailed release notes and features, see the official Terraform releases.

Learning Resources

Certification Preparation:

Community & Real-World Applications:

Hands-On Learning:

Changelog

  • Feb 15, 2026 - Updated for Terraform 1.14+, transformed into standalone certification guide (removed course-specific references)
  • Nov 21, 2023 - Added “The Terraform AWS Provider” to related subjects

You also might like