Skip to main content

Apply

The terraform apply command executes the actions proposed in a Terraform plan to create, update, or delete infrastructure to match your configuration.

What It Does

When you run terraform apply, Terraform:
  • Generates an execution plan (unless applying a saved plan)
  • Prompts for approval (unless using -auto-approve or a saved plan)
  • Executes the plan by making API calls to providers
  • Updates the state file to reflect the new infrastructure state
  • Displays resource changes and outputs after completion

When to Use It

Run terraform apply when you want to:
  • Create new infrastructure resources
  • Update existing infrastructure to match configuration changes
  • Apply a previously saved plan file
  • Provision infrastructure in a new environment
  • Roll out configuration changes to production

Basic Usage

1

Run terraform apply

Apply changes to your infrastructure:
terraform apply
Terraform will generate a plan and prompt for approval:
Terraform will perform the following actions:

  # aws_instance.web will be created
  + resource "aws_instance" "web" {
      + ami           = "ami-0c55b159cbfafe1f0"
      + instance_type = "t2.micro"
      + id            = (known after apply)
      + public_ip     = (known after apply)
    }

Plan: 1 to add, 0 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:
2

Review and approve

Type yes to proceed:
  Enter a value: yes

aws_instance.web: Creating...
aws_instance.web: Still creating... [10s elapsed]
aws_instance.web: Still creating... [20s elapsed]
aws_instance.web: Creation complete after 25s [id=i-0123456789abcdef]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

instance_public_ip = "54.123.45.67"
3

Verify the changes

Check that resources were created successfully:
terraform state list
Example output:
aws_instance.web
aws_security_group.web

Applying Saved Plans

1

Generate a plan

First, create and save a plan:
terraform plan -out=tfplan
2

Apply the saved plan

Execute the exact plan without prompting:
terraform apply tfplan
Example output:
aws_instance.web: Creating...
aws_instance.web: Creation complete after 28s [id=i-0123456789abcdef]

Apply complete! Resources: 1 added, 0 to changed, 0 destroyed.
Note: Terraform does not prompt for approval when applying a saved plan.

Common Flags and Options

Auto-Approval

-auto-approve Skip the interactive approval prompt:
terraform apply -auto-approve
Example output:
aws_instance.web: Creating...
aws_instance.web: Creation complete after 30s [id=i-0123456789abcdef]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Warning: Use with caution, especially in production environments.

Destroy Mode

-destroy Destroy all managed infrastructure:
terraform apply -destroy
This is equivalent to:
terraform destroy
Example output:
Plan: 0 to add, 0 to change, 5 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

aws_instance.web: Destroying... [id=i-0123456789abcdef]
aws_instance.web: Destruction complete after 15s

Apply complete! Resources: 0 added, 0 changed, 5 destroyed.

Targeting Resources

-target=RESOURCE Apply changes only to specific resources:
terraform apply -target=aws_instance.web
Example output:
Plan: 1 to add, 0 to change, 0 to destroy.

Warning: Resource targeting is in effect

You are creating a plan with the -target option. This means that Terraform
will only manage the targeted resources and their dependencies.

Do you want to perform these actions?
  Enter a value: yes

aws_instance.web: Creating...
aws_instance.web: Creation complete after 25s [id=i-0123456789abcdef]
Multiple targets:
terraform apply \
  -target=aws_instance.web \
  -target=aws_security_group.web
-replace=RESOURCE Force replacement of a specific resource:
terraform apply -replace=aws_instance.web
Example output:
aws_instance.web: Destroying... [id=i-old]
aws_instance.web: Destruction complete after 20s
aws_instance.web: Creating...
aws_instance.web: Creation complete after 30s [id=i-new]

Apply complete! Resources: 1 added, 0 changed, 1 destroyed.

Variables

-var Set variable values from the command line:
terraform apply -var="environment=production" -var="instance_count=3"
-var-file Load variables from a file:
terraform apply -var-file="production.tfvars"

State Management

-backup=PATH Path to backup the state file (default: -state-out path with “.backup” extension):
terraform apply -backup=terraform.tfstate.backup
-lock=false Disable state locking (dangerous):
terraform apply -lock=false
Warning: Only use when absolutely necessary and you’re certain no one else is running Terraform. -lock-timeout=DURATION Wait for a state lock:
terraform apply -lock-timeout=5m
-state=PATH and -state-out=PATH Legacy options for local backend only:
terraform apply -state=terraform.tfstate -state-out=terraform.tfstate.new

Output Control

-compact-warnings Show warnings in compact form:
terraform apply -compact-warnings
-no-color Disable colored output:
terraform apply -no-color
-input=false Disable interactive prompts:
terraform apply -input=false

Performance

-parallelism=N Limit concurrent operations (default: 10):
terraform apply -parallelism=20

Best Practices

Plan Before Apply

Always review changes before applying:
# Best practice: Review before applying
terraform plan -out=tfplan
# Review the plan output carefully
terraform apply tfplan

Use Auto-Approve Sparingly

Avoid -auto-approve in production:
# Good for development/testing
terraform apply -auto-approve

# Better for production
terraform plan -out=prod.tfplan
# Review plan with team
terraform apply prod.tfplan

State Backups

Terraform automatically creates backups, but you can create manual backups:
# Before major changes
cp terraform.tfstate terraform.tfstate.backup.$(date +%Y%m%d)
terraform apply

Incremental Rollouts

Use -target for incremental deployments:
# Deploy infrastructure layer by layer
terraform apply -target=module.network
terraform apply -target=module.database
terraform apply -target=module.application

# Finally, apply everything
terraform apply

Handle Sensitive Outputs

Be aware that outputs are displayed after apply:
output "database_password" {
  value     = aws_db_instance.main.password
  sensitive = true  # Prevents display in output
}

CI/CD Integration

In automated pipelines:
# CI/CD pipeline example
terraform init -input=false
terraform plan -out=tfplan -input=false

# Wait for approval (manual gate)

terraform apply tfplan

Error Recovery

If apply fails mid-execution, Terraform updates state for completed resources:
# State reflects partial changes
terraform state list

# Fix the error and re-run
terraform apply

Resource Replacement Awareness

Be cautious with resources marked for replacement:
  # aws_db_instance.main will be replaced
-/+ resource "aws_db_instance" "main" {
      # Replacing will cause data loss!
    }
Consider:
  • Backing up data before replacement
  • Using lifecycle rules to prevent replacement:
resource "aws_db_instance" "main" {
  # ...
  lifecycle {
    prevent_destroy = true
  }
}

Workspace Awareness

Verify you’re in the correct workspace:
terraform workspace show
# Output: production

terraform apply

Understanding Apply Output

Progress Indicators

aws_instance.web: Creating...
aws_instance.web: Still creating... [10s elapsed]
aws_instance.web: Still creating... [20s elapsed]
aws_instance.web: Creation complete after 25s [id=i-0123456789abcdef]

Resource Actions

ActionDescriptionExample
Creating…Resource is being createdaws_instance.web: Creating...
Modifying…Resource is being updatedaws_instance.web: Modifying...
Destroying…Resource is being deletedaws_instance.web: Destroying...
Reading…Data source is being readdata.aws_ami.ubuntu: Reading...

Summary Line

Apply complete! Resources: 5 added, 2 changed, 1 destroyed.
This shows:
  • 5 added: New resources created
  • 2 changed: Existing resources updated
  • 1 destroyed: Resources deleted

Outputs Display

After apply, Terraform displays outputs:
Outputs:

instance_public_ip = "54.123.45.67"
instance_private_ip = "10.0.1.25"
db_endpoint = "mydb.us-east-1.rds.amazonaws.com:5432"

Troubleshooting

Apply Hangs

If apply seems stuck:
# Enable debug logging
TF_LOG=DEBUG terraform apply

# Check provider API rate limits
# Check network connectivity

State Lock Errors

Error: Error acquiring the state lock

Lock Info:
  ID:        abc123
  Path:      s3://my-bucket/terraform.tfstate
  Operation: OperationTypeApply
  Who:       user@hostname
  Version:   1.6.0
  Created:   2024-01-15 10:30:00 UTC
Solution:
# Wait for lock to be released
terraform apply -lock-timeout=10m

# Or force unlock (dangerous)
terraform force-unlock abc123

Failed Apply with Partial Changes

Error: Error creating instance

Apply complete! Resources: 3 added, 1 changed, 0 destroyed.
State is updated for completed resources. Fix errors and re-run:
# Check what was created
terraform state list

# Fix the error in configuration
terraform apply

Provider Authentication Errors

Error: Error configuring AWS Provider:
  no valid credentials sources found
Solution:
# Set credentials
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"

terraform apply

Cannot Destroy Dependencies

Error: Instance cannot be destroyed

aws_instance.web depends on aws_security_group.web
Solution: Terraform handles dependencies automatically. If this occurs, check for circular dependencies.

Next Steps

After successful apply:
  1. Verify resources in your cloud provider console
  2. Test your infrastructure
  3. Commit state file changes (if using version control for state)
  4. Document any manual post-apply steps
  5. Use terraform output to retrieve output values

Build docs developers (and LLMs) love