Octet

What is Terraform, what is the state file, and where does Terraform fit next to Ansible?

Show the answer

Say this first

Terraform is a declarative infrastructure as code tool. You describe resources in HCL, providers translate them into API calls, terraform plan shows the difference between your code and reality, and apply makes it so. The state file maps each resource in the code to the real object ID and lets Terraform know what it manages. It must be stored remotely with locking, kept private because it can hold secrets, and never edited by hand. Terraform shines on API-driven platforms (cloud, ACI, firewall managers); Ansible is stronger for configuring CLI-based devices.

Go deeper

A small example (ACI tenant)

Terraform
terraform {
  required_providers {
    aci = {
      source = "CiscoDevNet/aci"
    }
  }
}

variable "apic_password" {
  type      = string
  sensitive = true
}

provider "aci" {
  username = "admin"
  password = var.apic_password
  url      = "https://apic1.example.com"
}

resource "aci_tenant" "prod" {
  name        = "Prod"
  description = "Managed by Terraform"
}

The workflow

Shell
terraform init               # download providers, set up the backend
terraform plan -out tfplan   # compare code, state and reality
terraform apply tfplan       # apply exactly that plan
terraform state list         # resources Terraform manages

State rules

  • Remote backend (S3, Azure Storage, GCS, HCP Terraform, GitLab) with locking, so two people cannot apply at once.
  • Treat it as sensitive: attributes, including some passwords, are stored in plain text.
  • Change it only with terraform state mv, state rm and import (or import blocks).
  • If someone changes a managed object by hand, the next plan shows the drift and offers to put it back.

Terraform vs Ansible

TerraformAnsible
StyleDeclarative, whole desired stateOrdered tasks, each module declarative
StateState fileNo state file; reads the device each run
StrengthAPIs: cloud, controllers, firewall managersDevice config over SSH, NETCONF, APIs
DeletesRemoving code destroys the resourceRemoving a task removes nothing

Since version 1.6 Terraform uses the Business Source License; OpenTofu is the open source fork with the same workflow.

Traps

  • Committing terraform.tfstate to Git. It holds secrets and causes conflicting copies.
  • Thinking removing a resource block is harmless. Terraform destroys the real object on the next apply.
How did you do?