Area 07 // DeploymentLesson 114 / 14014 min read
Infrastructure as code
Infrastructure as code means describing servers, databases, networks, buckets and permissions in version-controlled files that a tool such as OpenTofu or Terraform turns into real cloud resources, so environments are reproducible, reviewed like code and changed by plan and apply instead of by clicking in a console.
Think of it like this
Analogy
An architect's blueprint versus building a house by shouting instructions on site. With a blueprint, anyone can see what the house should be, changes are drawn and approved before builders touch anything, and you can build an identical second house. Infrastructure as code is the blueprint for your cloud setup; plan is the builder telling you exactly what they'll knock down and put up before starting.
The problem it solves
Your AI app needs a container service, a Postgres database, a vector store, object storage, secrets, DNS, permissions and GPU nodes, for both staging and production. Set up by clicking in a console, nobody remembers exactly how, staging and production slowly drift apart, a teammate's "small tweak" breaks things with no record, and rebuilding after a disaster takes days. Infrastructure needs the same version control, review and automation as code.
How it works, step by step
- Pick a tool: OpenTofu (the open-source fork of Terraform) or Terraform use the HCL language; Pulumi and AWS CDK use normal programming languages; clouds also have their own template formats.
- Declare resources in files:
resource "aws_s3_bucket" "uploads" { ... }. You describe what should exist, not the steps to create it. - Providers are plugins that talk to each platform's API (AWS, Google Cloud, Azure, Cloudflare, GitHub, Kubernetes...).
- Variables and outputs make one configuration serve several environments (
-var environment=staging) (environments). initdownloads providers;plancompares the files with the state (what exists now) and shows every create, change and destroy;applymakes those changes.- State lives in a remote, locked, encrypted backend (a bucket with locking, or a managed service), never only on a laptop; it can contain secrets.
- Workflow: changes go through pull requests; CI runs
planand posts it for review; after merge, CI runsapply(GitHub Actions). - Drift: manual console changes make reality differ from the code; regular plans detect it.
- Modules package reusable pieces (a "RAG service" module with its database, bucket and permissions).
See it in code
- Install
OpenTofu (opentofu.org) or Terraform- Needs
- No cloud account: this example uses the local provider, which just writes a file. The file is examples/iac/main.tf in the course repository.
A deliberately tiny configuration whose only "resource" is a config file, so the init → plan → apply cycle can run anywhere.
terraform {
required_providers {
local = { source = "hashicorp/local", version = "~> 2.5" }
}
}
variable "environment" {
type = string
default = "staging"
}
variable "replicas" {
type = number
default = 2
}
# One resource = one thing the tool creates, updates or deletes for you.
resource "local_file" "app_config" {
filename = "${path.module}/out/${var.environment}.env"
content = <<-EOT
APP_ENV=${var.environment}
REPLICAS=${var.replicas}
LLM_PROVIDER=mock
EOT
}
output "config_file" {
value = local_file.app_config.filename
}$ tofu apply -auto-approve -var environment=staging
# local_file.app_config will be created
+ resource "local_file" "app_config" {
+ content = <<-EOT
APP_ENV=staging
REPLICAS=2
LLM_PROVIDER=mock
EOT
+ filename = "./out/staging.env"
}
Plan: 1 to add, 0 to change, 0 to destroy.
local_file.app_config: Creation complete after 0s [id=2e07aab1c207f2a7235c9f504446b864797fc07a]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
$ tofu plan -var environment=staging -var replicas=4
# local_file.app_config must be replaced
-/+ resource "local_file" "app_config" {
~ content = <<-EOT # forces replacement
APP_ENV=staging
- REPLICAS=2
+ REPLICAS=4
LLM_PROVIDER=mock
EOT
}
Plan: 1 to add, 0 to change, 1 to destroy.This is real output from the course's GitHub Actions run (checksum lines trimmed). Note the second plan: changing one number replaces the resource rather than editing it. With a real database, a plan saying "must be replaced" means data loss, which is exactly why plans are reviewed before anyone runs apply.
A real example
Example
Rebuilding staging in twenty minutes
A team's staging environment had been set up by hand over a year. When an engineer accidentally deleted its database subnet, nobody knew all the settings, and recovery took three days. Afterwards they wrote the whole environment in OpenTofu modules (network, Postgres with pgvector, object storage, container service, secrets, DNS), with remote state in a locked bucket, plans posted on every pull request and applies run by CI. Six months later they created a separate load-testing environment from the same code in twenty minutes, and drift checks every night caught two "quick fixes" made in the console.
The easy way
Start here
If you're on a managed platform, start by putting its configuration file in git. When you add cloud resources (a bucket, a database), write them in OpenTofu or Terraform from day one, run plan before every apply, and store state remotely.
When you grow: the production setup
Teams use modules per component, separate state per environment, remote state with locking and encryption, plan-in-PR and apply-from-CI with OIDC credentials, policy checks (no public buckets, required tags), drift detection on a schedule, cost estimates on plans, and careful handling of destructive changes (prevent_destroy on databases).
Trade-offs
What you gain
- Reproducible environments; disaster recovery from code.
- Every change reviewed and recorded.
- Staging and production stay alike.
What it costs you
- Learning curve; state management needs care.
- Some changes force replacement, which can be destructive if not noticed.
- Provider and tool versions need maintenance.
When not to use it
- A single managed app with no extra cloud resources: the platform's own config file is enough.
Common mistakes
- Applying without reading the plan.
- State only on a laptop, or committed to git.
- Mixing console changes with code-managed resources.
- Secrets hard-coded in
.tffiles. - One giant configuration for every environment and team.
Interview questions
Try answering out loud first, then open the model answer.
What is infrastructure as code and why use it?
Model answer
Defining infrastructure (networks, compute, databases, storage, permissions) declaratively in version-controlled files that a tool applies to real providers. It makes environments reproducible and consistent, puts changes through review and CI, documents the system, enables quick recovery and duplication of environments, and detects drift.
Explain plan, apply and state in Terraform or OpenTofu.
Model answer
Plan reads the configuration, refreshes the state against real resources, and shows the changes needed to match (create, update in place, replace, destroy). Apply executes them and records results in the state. State maps configuration to real resource IDs and attributes; it must be stored remotely with locking and protected because it may contain secrets.
How do you safely change infrastructure for a production AI system?
Model answer
Make the change in code on a branch, have CI post the plan to the pull request, review it for replacements and destroys (especially of data stores), test in staging from the same modules, apply from CI with least-privilege credentials, protect critical resources from deletion, and monitor after the change.
Quiz
Pick an answer to see whether it’s right and why.
0 of 5 answered
Key terms
- Infrastructure as code (IaC)
- Describing cloud resources (servers, databases, networks, permissions) in version-controlled files that a tool turns into real infrastructure.
- OpenTofu
- An open-source infrastructure-as-code tool (a fork of Terraform) that creates, changes and deletes resources from configuration files.
- Plan (Terraform / OpenTofu)
- A preview of exactly what an infrastructure tool will create, change, replace or destroy before anything is applied.
- State file
- The record an infrastructure tool keeps of which real resources it manages, used to work out the changes needed next time. Must be stored safely.
- Drift
- When real infrastructure no longer matches its code, usually because someone changed it by hand.
Before and after
Progress is saved in this browser only.