What Import Does—and Does Not Do

Scenario: A team successfully imports an existing production server into Terraform, sees the import command finish without error, and assumes Terraform has now generated a perfect, clean, maintainable configuration for it - which is not what actually happened.

Import solves a very specific problem: real infrastructure that already exists, created by hand or by some other tool, that you now want Terraform to manage going forward. Concretely, import binds an already-existing remote object's ID to a Terraform resource address inside state - it teaches Terraform "this address and this real object are the same thing," nothing more. The traditional terraform import ADDRESS ID command requires you to have already written a matching (even if minimal or empty-ish) resource block yourself; it does not write that configuration for you. A newer, declarative alternative - an import block right inside your .tf files - makes the whole operation plannable and reviewable like any other change, and some tooling can even generate a starting point for the resource's configuration from the live object's attributes - but that generated starting point still needs real human review, not blind trust.

A rule worth holding onto from this section alone: each real-world object should map to exactly one Terraform resource address. Importing the same object into two different configurations recreates the exact "who owns this" ambiguity you learned about with data sources back in Module 4 - two systems both believing they're the authoritative manager of one real thing.

Analogy: Import registers an existing building in your company's official asset-management system - it records "we now formally own and are responsible for this building." It does not, on its own, produce the architect's original construction drawings, and it certainly doesn't certify the building currently meets code. Someone still has to go inspect it and document what's actually there.

A worked configuration

import {
  to = fakecloud_server.legacy
  id = "srv-legacy-42"
}
resource "fakecloud_server" "legacy" {
  name = "legacy-api"
}

Before importing anything, especially something already serving production traffic, take stock: what other resources depend on it, does it have independent backups outside Terraform's reach, who has actually been responsible for it up to now, which of its settings are provider defaults you've never consciously chosen, and what's the real risk if Terraform's first plan against it proposes something destructive by mistake? When the provider's exact behavior for that resource type is unfamiliar to you, practice the import into a disposable, throwaway state or a non-production copy first, so a mistake there costs nothing.

Common mistakes in production

Goal: Treat the plan as a change contract: understand every create, update, replacement, and destroy before approving it. Reinforce this lesson in the tf-import-existing-resource Terraform lab. Open /labs/terraform and choose slug tf-import-existing-resource; the lab runs real Terraform against the offline FakeCloud provider.