| Tested on | Ubuntu 26.04 LTS (Resolute Raccoon) |
|---|---|
| Package | terraform 1.15.8-1 |
| Applies to | Any host with Terraform installed |
| Lab environment | Single Ubuntu VM with Terraform — Terraform lab environment on Ubuntu |
| Privilege | Normal user |
| Scope | Conceptual introduction to Terraform and infrastructure as code — declarative configuration, providers, resources, state, the init plan apply workflow, benefits, comparison to scripts and configuration management, a local hands-on example, and when another tool may fit better. Does not cover installation, HCL syntax, backends, modules, or cloud provider tutorials. |
| Related guides | Install Terraform on Ubuntu Terraform lab environment on Ubuntu terraform init command Terraform state explained Terraform Associate certification course |
Terraform is an infrastructure-as-code (IaC) tool. You define infrastructure in configuration files, run a predictable workflow to plan and apply changes, and let Terraform track what it manages.
Instead of clicking through a web console for every server, network rule, or DNS record:
- You store the desired end state as code
- The tool reconciles reality with that declaration
Terraform can manage many kinds of infrastructure through providers — plugins that speak to an API on your behalf:
VMs
networks
DNS
containers
databases
SaaS/servicesThe same workflow applies whether the target is a public cloud, a private platform, or a local service on your laptop.
This article answers what Terraform is and how IaC works at a beginner level. It is the opening lesson in the Terraform Associate certification course Domain 1 material. For installation steps, see Install Terraform on Ubuntu. For command-by-command walkthroughs, follow the Core Workflow lessons linked from the course hub.
What is infrastructure as code?
Infrastructure as code stores desired infrastructure as configuration instead of relying on manual steps alone.
Manual / click-ops
→ administrator creates each resource in a console or with ad hoc commands
Infrastructure as code
→ desired infrastructure stored as configuration in version control
→ tool plans and applies changes against an API
→ result is repeatable and reviewableThe shift is not about eliminating humans. It is about making infrastructure changes:
- Reviewable — like application code in pull requests
- Repeatable — the same configuration in dev, test, and prod
- Automatable — CI/CD pipelines can run plan and apply on merge
Practical benefits teams cite most often:
- Repeatability — the same configuration produces the same resources in dev, test, and prod
- Version control — pull requests show exactly what configuration changed
- Reviewability — Terraform plans show the proposed infrastructure changes before apply
- Automation — CI/CD pipelines can run plan and apply on merge
- Reproducibility — rebuild an environment from files instead of memory
- Lifecycle management — update and destroy resources through the same tool that created them
IaC does not remove the need for architecture decisions or operational judgment. It gives those decisions a durable, shareable format.
How Terraform works
Terraform is declarative. You describe the end state you want — for example, one marker resource with a specific input string — and Terraform figures out the steps to reach that state. You do not write a script that says create, then update, then delete in order.
A minimal configuration uses the built-in terraform_data resource, which needs no cloud account:
resource "terraform_data" "example" {
input = "Hello Terraform"
}That single block is enough to walk through the core workflow:
Write configuration (.tf files)
↓
terraform init ← download providers, prepare working directory
↓
terraform plan ← preview create, update, destroy actions
↓
terraform apply ← make the changes
↓
state tracks managed objectsEach command has one job in this mental model:
terraform initprepares the directory and installs provider pluginsterraform plancompares configuration to state and shows a change setterraform applyexecutes the approved changes- State records which real object belongs to each resource block
Command flags, saved plans, and edge cases belong in the dedicated terraform init, terraform plan, and terraform apply lessons. Here the goal is vocabulary, not CLI mastery.
Terraform providers, resources, and state
Three ideas appear in almost every Terraform conversation: providers, resources, and state.
Terraform Core
│
▼
Provider ──► Resources / API objects
│
▼
Terraform state ↔ managed resource identity and attributes| Term | Meaning |
|---|---|
| Terraform Core | The terraform CLI and engine that load configuration, build a graph, and coordinate providers |
| Provider | Plugin for a platform or service — hashicorp/aws, kreuzwerker/docker, hashicorp/random, and hundreds more |
| Resource | One managed object declared with a resource block, such as terraform_data.example or aws_instance.web |
| State | Data file mapping resource addresses in configuration to real-world IDs and attributes |
When you run terraform plan, Core:
- Reads your
.tffiles and the current state - Asks providers what exists today
- Computes a diff
When you run terraform apply, Core tells each provider which API calls to make.
State is why Terraform knows a resource block from last week still refers to the same cloud object today. Lock files, remote backends, and state commands are intentionally out of scope here — see Terraform state explained when you are ready for that depth.
Why use Terraform?
Teams adopt Terraform for concrete workflow reasons, not slogans.
- One workflow across services — the same init → plan → apply rhythm whether you manage DNS, compute, or a container runtime
- Reusable configuration — modules let you package a standard pattern once and call it with different inputs
- Dependency handling — Terraform builds a graph from references and orders creates and destroys safely
- Execution plans before changes —
terraform planshows what would happen before anything is modified - Lifecycle management — update in place, replace, or destroy through the same configuration history
- Automation and Git integration — infrastructure changes ride the same review process as application code
Terraform is often described as multi-cloud capable because many providers coexist in one configuration. That does not mean every organization should spread workloads across AWS, Azure, and GCP by default. It means you can use one tool and one workflow for the platforms you actually run — including mixing cloud resources with on-premises or SaaS APIs where providers exist.
Terraform vs scripts and configuration management
Terraform overlaps with other automation tools, but the primary job differs.
| Approach | Typical focus |
|---|---|
| Shell or Python scripts | Imperative steps — run commands in sequence you write yourself |
| Terraform | Declarative infrastructure provisioning and lifecycle — declare desired resources, let Terraform reconcile |
| Configuration management (Ansible, Chef, Puppet, Salt) | Often emphasizes OS and application configuration after a host exists — packages, files, services |
A script can create a VM. Terraform can create the VM and track it in state so later runs know whether the VM needs an update or replacement.
Configuration management might install nginx on that VM after it boots. Many teams use Terraform plus a config-management tool — they solve different layers of the stack.
This article does not argue Terraform replaces every script. It replaces ad hoc click-ops for infrastructure that has a lifecycle worth tracking.
Simple local Terraform example
You can see the workflow end to end on Ubuntu without signing up for a cloud provider. Create an isolated lab directory:
mkdir -p ~/terraform-labs/what-is-terraformSave the minimal configuration as main.tf:
resource "terraform_data" "example" {
input = "Hello Terraform"
}Change into the directory and initialize the working directory. terraform init prepares Terraform's backend and working metadata. This example uses the built-in terraform_data resource, so there is no external provider plugin to download.
cd ~/terraform-labs/what-is-terraform && terraform initSample output:
Terraform has been successfully initialized!Preview the change Terraform would make. A first run shows one resource to create:
terraform planSample output:
Terraform will perform the following actions:
# terraform_data.example will be created
+ resource "terraform_data" "example" {
+ id = (known after apply)
+ input = "Hello Terraform"
+ output = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.Apply the plan to create the resource:
terraform apply -auto-approveSample output:
terraform_data.example: Creating...
terraform_data.example: Creation complete after 0s [id=a3edd5a1-0e64-0101-ddd4-8d89e9550d75]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.The UUID in id= changes every run; look for the Creation complete line and the apply summary.
Confirm Terraform recorded the object in state:
terraform state listSample output:
terraform_data.exampleThat address matches the resource block name in main.tf. State now links terraform_data.example in configuration to the object Terraform just created.
Remove the resource when you are done experimenting:
terraform destroy -auto-approveSample output:
terraform_data.example: Destroying...
terraform_data.example: Destruction complete after 0s
Destroy complete! Resources: 1 destroyed.You walked through the same cycle teams use for larger infrastructure — only the provider and resource type were minimal. The Terraform lab environment on Ubuntu lesson sets up a fuller practice VM when you are ready for Docker-backed examples.
When Terraform may not be the right tool
Terraform is a strong default for managed infrastructure with a clear API, but it is not universal.
- One-off manual tasks with no ongoing lifecycle — documenting a one-time console change in a ticket may be faster than codifying it
- Application configuration inside an OS — installing packages, templating config files, or orchestrating services on a host often fits configuration-management tools better
- Actions without a usable provider — if no provider exposes the API you need, Terraform cannot manage that surface until one exists or you wrap an external process
Saying no to Terraform for a specific task does not dismiss IaC as a practice. It means matching the tool to the layer of the stack you are automating.
Lab cleanup
Remove the practice directory when you no longer need it:
rm -rf ~/terraform-labs/what-is-terraformdestroy already removed managed resources; deleting the directory clears local state and configuration files.
References
- What is Terraform? — HashiCorp Developer
- Infrastructure as Code — HashiCorp Developer
- Terraform Glossary — Provider
- Terraform Glossary — State
Summary
Terraform is an infrastructure-as-code tool that lets you define infrastructure in configuration files and manage it through a consistent init → plan → apply workflow:
- You declare the desired end state
- Terraform computes how to reach it
- State tracks managed objects so later runs know what already exists
Infrastructure as code turns manual click-ops into version-controlled, reviewable configuration:
- Providers connect Terraform Core to cloud platforms, SaaS APIs, and local services
- Resources are the individual objects you declare
- State is the ledger that maps those declarations to real IDs
You do not need a cloud account to understand the idea — a terraform_data block on Ubuntu demonstrates the full cycle in one directory. Terraform complements scripts and configuration-management tools rather than replacing every form of automation.
When you are ready to go deeper:
- Install Terraform on your lab VM
- Work through HCL syntax and provider configuration
- Follow the Core Workflow lessons in the Associate course — each builds on the vocabulary introduced here

