Terraform is the most widely adopted infrastructure-as-code tool in the industry. It lets you define cloud infrastructure in human-readable configuration files, version it in Git, and deploy it consistently across any cloud provider. The HashiCorp Certified Terraform Associate exam tests your understanding of Terraform's workflow, language, state management, modules, and Terraform Cloud — making it one of the most valuable hands-on certifications for cloud engineers and DevOps practitioners.
Practice this topic
Terraform uses HCL (HashiCorp Configuration Language) — a declarative language that describes the desired state of infrastructure. You write what you want to exist; Terraform figures out how to create it. Core workflow: Write (define resources in .tf files), Plan (terraform plan — preview what will be created, modified, or destroyed), Apply (terraform apply — provision the infrastructure), Destroy (terraform destroy — remove all managed resources). Key HCL constructs: resource blocks (declare a real infrastructure object — resource 'aws_instance' 'web' { ami = '...', instance_type = 't3.micro' }), data sources (query existing infrastructure not managed by this config — data 'aws_ami' 'latest' { ... }), variables (input values — var.region), locals (computed values within the config — local.common_tags), outputs (export values after apply — useful for module consumers or cross-stack references). Providers: plugins that enable Terraform to talk to specific APIs (AWS, Azure, GCP, Kubernetes, GitHub, Datadog) — declared in required_providers block, downloaded by terraform init.
State is Terraform's memory — it maps your configuration to real-world resources. Without state, Terraform cannot know whether a resource already exists or needs to be created. Local state (terraform.tfstate) is the default — stored in the working directory, suitable only for solo experiments. Remote state is required for teams: Terraform Cloud/Enterprise, S3 bucket with DynamoDB locking (AWS), Azure Blob Storage, GCS bucket. State locking prevents two engineers from running apply simultaneously and corrupting state — DynamoDB provides this for S3 backends. Sensitive values in state: secrets end up in plaintext in state files (passwords, private keys) — always encrypt state storage and restrict access. Key state commands: terraform state list (show all managed resources), terraform state show resource.name (detail on one resource), terraform state mv (rename a resource in state), terraform state rm (remove a resource from state without destroying it — for importing or abandoning management), terraform import (bring an existing resource under Terraform management). Workspaces: isolated state files within the same backend — useful for dev/staging/prod environments from the same config.
Modules are the fundamental unit of code reuse in Terraform. Every Terraform configuration is a module — the root module is the directory you run Terraform from. Child modules are called from the root using module blocks. Public modules: Terraform Registry (registry.terraform.io) hosts community and verified modules — use them with a source = 'registry address' and version constraint. Module inputs: variables declared in the module, passed from the caller. Module outputs: values the module exposes to the caller. Module best practices: keep modules focused and small (one concern per module), pin to specific versions (not 'latest'), use semantic versioning, document variables and outputs. Terraform Cloud private registry: publish internal modules for your organisation — consume with the same source syntax. Meta-arguments that work inside modules and resources: count (create N identical copies), for_each (create one instance per item in a map or set — more powerful than count because resources have meaningful names), depends_on (explicit dependency when implicit dependency graph is insufficient), lifecycle (create_before_destroy, prevent_destroy, ignore_changes).
Terraform Cloud provides remote execution, state management, and collaboration features. Key features: remote runs (plan and apply execute in Terraform Cloud, not your laptop — consistent environment, audit log), VCS integration (trigger plans automatically on Git push, review plans in PRs before merging), workspace-level variables (store secrets in Terraform Cloud, not in repo), policy as code (OPA or Sentinel — enforce tagging standards, restrict instance types, require encryption — runs as a policy check step in the pipeline). Terraform Cloud workflow: create workspace > connect VCS repo > set variables > queue a plan > review and approve > apply. Free tier: up to five active workspaces, remote state storage, VCS integration. Team and Business tiers add: SSO, audit logging, self-hosted agents, policy sets, private module registry. Terraform Enterprise: self-hosted version for air-gapped environments or organizations with strict data residency requirements.
Testing Terraform code: terraform validate (checks HCL syntax and internal consistency — fast, runs without credentials), terraform plan (requires credentials — creates an execution plan, shows what will change), checkov (static analysis for security misconfigurations — checks for unencrypted S3, public security groups, missing encryption keys), tfsec (similar security scanner), terraform test (native testing framework in Terraform 1.6+ — write .tftest.hcl files that create temporary infrastructure, assert outputs, then destroy). The Terraform testing pyramid: static validation (validate, lint) > plan (preview changes) > apply in non-prod (integration test with real infrastructure) > apply in prod (production deployment with approval gates). Variable validation: add validation blocks inside variable declarations to enforce constraints (regex patterns, allowed values lists) before Terraform tries to create resources. Version constraints: use >= 1.0, < 2.0 style constraints in required_version and required_providers to prevent unexpected breaking changes.
Terraform is only for AWS
Terraform supports 3,000+ providers including Azure, GCP, Kubernetes, GitHub, Cloudflare, Datadog, and every major cloud and SaaS platform. It is the most cloud-agnostic IaC tool available.
Deleting a Terraform resource block deletes the resource immediately
Removing a resource block from your configuration marks it for deletion only during the next terraform apply. Terraform plan shows what will be destroyed before you commit to it. Use prevent_destroy lifecycle to protect critical resources.
Terraform workspaces are the same as environments in other tools
Workspaces share the same backend and the same code — they only provide isolated state. For true environment isolation (different cloud accounts, different IAM boundaries), use separate workspaces with separate backend configurations, or separate directories.
You should always use the latest Terraform version
In production, pin the Terraform version using required_version. Breaking changes between minor versions can affect resources. Test upgrades in non-production first and review the upgrade guide.
Try free Terraform IaC practice questions with explanations, topic links and progress tracking.