Lab: infrastructure as code with Terraform basics
In short: Terraform describes infrastructure in text files and makes the real world match them. This lab uses the Docker provider so you can practise init, plan, apply and destroy on your own computer before spending anything in the cloud.
Aim and what you need
Infrastructure as code (IaC) means describing servers, networks and services in version-controlled files instead of clicking in a console. The aim of this lab is to learn the Terraform workflow safely: you will manage an nginx container on your own machine, which costs nothing, then apply the same habits to cloud resources later.
- Docker installed and running.
- Terraform installed from HashiCorp's official packages. OpenTofu, an open-source fork, accepts the same commands with
tofuin place ofterraform. - A text editor and Git if you want to version your work.
Steps
- Create an empty folder
tf-laband a filemain.tfwith the content below. - Run
terraform initto download the Docker provider. - Format and validate the file.
- Run
terraform planand read every line: it should say two resources to add. - Apply, type
yes, then browse tohttp://localhost:8085. - Change the external port to 8086, plan again and notice it will replace the container.
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0"
}
}
}
provider "docker" {}
resource "docker_image" "nginx" {
name = "nginx:alpine"
}
resource "docker_container" "web" {
name = "tf-web"
image = docker_image.nginx.image_id
ports {
internal = 80
external = 8085
}
}
output "container_name" {
value = docker_container.web.name
}
terraform init
terraform fmt
terraform validate
terraform plan
terraform apply
terraform state list
terraform show
terraform output
How to verify and troubleshoot
After apply, docker ps should show tf-web and the browser should show the nginx page. terraform state list shows the two resources Terraform now tracks. Try deleting the container by hand with docker rm -f tf-web, then run terraform plan: Terraform notices the drift and offers to recreate it.
- Provider download fails: check internet access and proxy settings, then rerun init.
- Cannot connect to Docker: start Docker; on Windows you may need to set the provider's host setting.
- Port already in use: change the external port.
- State confusion: never edit
terraform.tfstateby hand. Add it to.gitignore, because in cloud projects it can contain secrets.
Clean-up and moving to the cloud
terraform plan -destroy
terraform destroy
When you later use a cloud provider, the same workflow applies, but with extra rules: set a budget alert first, protect the account with MFA, never put access keys in .tf files (use the provider's CLI login or environment variables), keep state in a protected remote backend for team work, and always finish with terraform destroy and a console check that nothing is left behind.
Tip: a small Terraform repository with a clear README is an excellent portfolio piece. See building a GitHub portfolio.
Practice
What does terraform plan do?
Why should terraform.tfstate not be committed to a public repository?
You changed only a port and the plan says the container must be replaced. Why?
Key takeaways
- Terraform makes real infrastructure match your code.
- The core loop is init, plan, apply, and destroy.
- Always read the plan before you apply.
- Protect the state file and never hard-code credentials.
- In the cloud, budget first and destroy when finished.
Original content written by Mohamed Fayas for FM TecHub. © 2026 FM TecHub. You're welcome to share a link to this page; please don't copy the text elsewhere without permission.