Cloud  /  Terraform

IaC Terraform 50 guides · updated 2026

Infrastructure as code done right — providers, state, reusable modules, and the workflow patterns that keep multi-cloud deployments sane in 2026.

terraform apply

terraform apply executes the changes needed to bring your infrastructure to the desired state. It’s the command that actually creates, modifies, or destroys real cloud resources. Understanding how to use it safely — especially in production — is one of the most critical Terraform skills.


Basic Usage

Terminal window
terraform apply

By default, apply generates a fresh plan and prompts for confirmation:

Plan: 2 to add, 1 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes

The Safe Production Pattern: Plan File

The most reliable production workflow separates planning from applying:

Terminal window
# Step 1: Generate a plan and save it
terraform plan -out=tfplan
# Step 2: Review the plan (show it or post it to a PR)
terraform show tfplan
# Step 3: Apply exactly that plan — no re-planning, no surprises
terraform apply tfplan

When you apply a saved plan file:

This is essential for: change approvals, audit requirements, and preventing race conditions where another change lands between your plan and apply.


Key Flags

Terminal window
# Skip confirmation prompt (use in CI/CD, never manually on production)
terraform apply -auto-approve
# Apply only specific resource(s) — useful for debugging
terraform apply -target=aws_instance.web
terraform apply -target=module.vpc.aws_subnet.public
# Override variables at apply time
terraform apply -var="instance_count=5"
terraform apply -var-file="prod.tfvars"
# Control parallelism (default: 10 concurrent operations)
terraform apply -parallelism=20
# Skip state refresh before applying
terraform apply -refresh=false
# Non-interactive mode for CI
terraform apply -input=false -auto-approve
# Compact output for large applies
terraform apply -compact-warnings

Apply Output Explained

aws_vpc.main: Creating...
aws_vpc.main: Creation complete after 2s [id=vpc-0abc123def456789]
aws_security_group.web: Creating...
aws_subnet.public["a"]: Creating...
aws_subnet.public["b"]: Creating... ← runs in parallel with ["a"]
aws_security_group.web: Creation complete after 3s [id=sg-0abc123]
aws_subnet.public["a"]: Creation complete after 5s [id=subnet-0abc]
aws_subnet.public["b"]: Creation complete after 5s [id=subnet-0def]
aws_instance.app: Creating...
aws_instance.app: Still creating... [10s elapsed]
aws_instance.app: Creation complete after 18s [id=i-0abc123def456789]
Apply complete! Resources: 5 added, 0 changed, 0 destroyed.
Outputs:
public_ip = "54.123.45.67"

Resources that don’t depend on each other are created in parallel — notice both subnets created simultaneously. Terraform automatically determines the execution order from the dependency graph.


Apply Behaviors by Resource Change Type

Change TypeApply BehaviorImpact
New resourceCreates resourceSafe
Attribute update (in-place)Modifies resourcePossible brief disruption
Attribute update (forces replace)Destroys then createsPotential downtime
Resource removed from configDestroys resourceData loss if not backed up
No changeNo action takenZero impact

Handling apply Failures

When apply fails partway through, Terraform updates state with successfully-created resources and then stops:

aws_vpc.main: Creation complete after 2s [id=vpc-0abc123]
aws_instance.app: Creating...
aws_instance.app: Still creating... [10s elapsed]
│ Error: creating EC2 Instance: InsufficientInstanceCapacity
│ There is no Spot capacity available in the specified availability zone.
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

After fixing the issue, re-run terraform apply — Terraform knows which resources were already created (from state) and won’t duplicate them.


CI/CD Apply Pattern

# GitHub Actions — apply only on merge to main
- name: Terraform Apply
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: |
terraform apply -input=false -auto-approve tfplan
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

Principle of least surprise: in automated pipelines, always apply a saved plan file from the PR’s plan step. Never run a fresh apply -auto-approve in production — the plan could be different from what the team reviewed.


Apply with Workspaces

Terminal window
# Ensure you're in the right workspace before applying
terraform workspace select production
terraform workspace show # Verify: "production"
terraform apply -var-file="environments/production.tfvars"

What Happens to State After Apply

After a successful apply:

  1. State file is updated with the new resource IDs and attributes
  2. If using a remote backend (S3, Terraform Cloud), state is written there
  3. State lock is released

After a failed apply:

  1. State reflects only the successfully-created resources
  2. Terraform will detect partially-created infrastructure on next plan