Import manually-created resources before the next apply

The best way to avoid this entirely is to define resources in Terraform from the start — terraform apply will create them automatically and they’ll always be tracked. See reserving a static IP via Terraform for a concrete example.

If you create a resource manually (e.g. in the GCP Console) and Terraform doesn’t know about it, you have two options: destroy the manual resource and let Terraform recreate it, or import the existing one into Terraform state.

Destroying causes downtime and changes identifiers (IP addresses, resource IDs). Importing preserves everything.

# zsh requires quoting import IDs that contain slashes
terraform import google_compute_address.static_ip \
  'projects/my-project/regions/us-east1/addresses/my-static-ip'

The import ID format is provider-specific — check the Terraform registry docs for the resource you’re importing. After importing, run terraform plan to confirm Terraform sees no diff between your config and the imported state.

Warning

An untracked resource is invisible to Terraform. It will either be ignored (silent drift between config and reality) or destroyed and recreated on the next apply that touches it.

Tip

Rule — Any infrastructure created manually must be imported into Terraform state before the next terraform apply.

Read plan output for # forces replacement before applying

Certain field changes cause Terraform to destroy the existing resource and create a new one — not update it in place. Terraform marks these in plan output with # forces replacement:

  # google_compute_instance.vm must be replaced
+/- resource "google_compute_instance" "vm" {
      ~ metadata_startup_script = "..." -> "..."  # forces replacement
    }

The +/- symbol on the resource block means destroy + create, not update. If you see this on a production resource, stop and verify:

  • Is your data backed up outside the VM (GCS, Cloud SQL)?
  • Is your IP static (google_compute_address)? If not, it will change.
  • Is the replacement safe to do right now?

Warning

# forces replacement means the old resource is deleted first. There is no in-place swap, and there is no rollback once the destroy step completes.

Tip

Rule — Read every line of terraform plan before applying on a production resource. Never terraform apply a plan you haven’t fully read.

See also