Terraform: Getting Started
📚 Table of Contents
🧠 Key Concepts
- Declarative: define what you want, not how to do it
- Providers: AWS, Azure, etc.
- Resources: actual infrastructure components (e.g.,
aws_instance
) - State: Terraform tracks what it manages via
terraform.tfstate
📂 Terraform State
Terraform uses a state file (terraform.tfstate
) to keep track of the real infrastructure it manages. This file records the current state of all resources created, updated, or destroyed by Terraform, allowing it to determine what actions are required during future operations.
The state file can contain sensitive data (e.g., passwords, secrets, or cloud resource metadata). For this reason, it should be stored securely with access strictly controlled — for example, in an encrypted S3 bucket with restricted permissions, accessible only to team members responsible for infrastructure management.
The current state can be inspected using the terraform show
command. This displays all information that Terraform has about the infrastructure, including metadata returned by the provider for each resource (e.g., EC2 instance details, IP addresses, or ARNs).
Terraform creates a single backup of the previous state file (terraform.tfstate.backup
) before modifying the current state. This allows a rollback to the immediately prior state version if needed, but it does not store a full version history.
💡 Using a remote backend like AWS S3 with versioning enabled allows every past version of the state file to be preserved. This enables recovery of any previous state using S3’s versioning interface or API.
💻 Everyday Commands
terraform init
terraform fmt
terraform validate
terraform plan
terraform apply
terraform destroy
terraform show
terraform init
Initializes a Terraform working directory. It downloads the necessary provider plugins, sets up the backend (if configured), and prepares the directory for future commands such as plan
and apply
.
💡 Without running
terraform init
, Terraform commands such asplan
orapply
will not function, as required dependencies and configurations are not yet available.
❗ Danger: Running
terraform init
within an empty directory would be like instructing Terraform to destroy the whole infrastructure which nine out of ten is not what we want that is why it will throw a warning.
terraform fmt
Formats Terraform configuration files to a canonical style. This command ensures consistent indentation and alignment across .tf
files in a project.
💡
terraform fmt
modifies files in place unless used with the-check
or-diff
flags.
terraform validate
Checks the syntax and internal consistency of Terraform configuration files. It does not interact with remote services.
💡 While editors like VS Code may catch syntax errors live,
terraform validate
provides more thorough validation.
terraform plan
Performs a dry run of the execution process. It compares the desired state from the .tf
files with the current state (tracked in terraform.tfstate
or by querying the provider).
+
Created~
Modified-
Destroyed
💡
terraform plan
acts as a safety step, allowing verification and review before execution.
terraform apply
Applies the planned changes to infrastructure. Terraform shows a summary of what will be created, modified, or destroyed and requires confirmation (unless -auto-approve
is used).
Fields marked as "known after apply"
indicate attributes that will only be available after the resource is created.
💡 Think of
terraform plan
as a dry-run, andterraform apply
as the “commit & push” to the cloud.
terraform destroy
Terminates all resources tracked in the current Terraform state. Use with caution.
💡 If a resource has already been manually deleted, Terraform will detect that it no longer exists and skip deletion.
🛠️ Advanced Commands
terraform refresh
terraform state list
terraform state show <resource>
terraform state rm <resource>
terraform import
terraform taint
terraform refresh
Updates the Terraform state file to match the real-world infrastructure. Useful when infrastructure has been modified outside of Terraform.
💡 In most workflows,
plan
,apply
, anddestroy
already include an automatic refresh making the command obsolete and anyhow a tool to use in very speciic cases.
terraform import
Enables Terraform to begin managing existing infrastructure that was created outside of Terraform.
🧠 Example Use Case
An S3 bucket was created manually via the AWS Console and must now be brought under Terraform management.
terraform import aws_s3_bucket.my_bucket my-bucket-name
💡 After importing, it is recommended to run terraform plan to confirm the state matches the configuration.
terraform taint
Marks a specific resource as needing to be destroyed and recreated during the next terraform apply
, even if the configuration hasn’t changed.
🧠 Example Use Case
If you manually shut down an EC2 instance via the AWS Console, Terraform won’t detect that as a change — the configuration still matches.
However, if you want to restore that instance to a clean state, you can run:
terraform taint aws_instance.example
terraform apply
💡 A taint operation will force terraform to reprovision the resource, EC2 instance in this case, but it will of course get a new instance id, IP Address etc.
terraform state rm
Removes a resource from Terraform’s state without affecting the real infrastructure.
🧠 Example Use Case
A resource is no longer managed by Terraform (e.g., a CloudWatch alarm), but it should not be destroyed when executing terraform destroy
.
terraform state rm aws_cloudwatch_metric_alarm.cpu_alarm