Converging Imported Configuration
Scenario: Immediately after a successful import, the very first plan proposes changing ten separate attributes - not because anything about the real object needs to change, but because the hand-written configuration simply omitted fields that the provider had quietly filled in with its own defaults.
Binding an object's identity (the previous section) is only step one of adoption; step two is converging your configuration until a plan against the newly-imported object proposes genuinely nothing, which is usually the correct outcome for a first apply on something that already works fine in production. Run a plan and go through every proposed difference one at a time, classifying each: is this a change you actually want to make (a real desired-state update)? Is it a provider default that simply needs to be written explicitly in your configuration so the plan stops flagging it? Is it a computed, read-only attribute that shouldn't even be in your .tf file at all? Or is it a field that's intentionally owned by something else, which should get an ignore_changes entry (Module 7) rather than a hardcoded value?
A mistake worth calling out explicitly, because it's tempting: do not simply copy every attribute you see in terraform state show into your HCL. State includes computed values, legacy internal details, and provider-generated fields that are not valid or meaningful things to write as configuration input - copying blindly can itself introduce a plan-time conflict. Iterate - plan, adjust, plan again - until the diff matches your actual adoption intent.
Analogy: Adopting existing infrastructure into Terraform is like a new manager interviewing a long-tenured employee and writing an accurate job description based on what they actually do, before changing anything about their role. You wouldn't hand them a generic template job description and immediately start holding them to duties they've never actually performed.
A worked configuration
terraform plan
terraform state show fakecloud_server.legacy
# edit configuration, plan again, repeat until understood
During this convergence process, freeze any manual changes to the object elsewhere - a console edit made mid-convergence will show up as yet another confusing diff and make it much harder to tell which differences are "provider defaults I need to write down" versus "something just changed underneath me." Have the object's actual service owner peer-review the final converged plan before the first apply - they may recognize a setting that looks like a harmless default but is actually load-bearing. In practice, the safest, most reassuring first Terraform action on a genuinely critical imported object is an apply that changes precisely nothing.
Common mistakes in production
- Copying every attribute from
terraform state showdirectly into the resource's HCL block - state includes computed and legacy fields that aren't valid or intended as configuration input. - Making manual changes to the object in the provider's console while still in the middle of convergence - it's now impossible to tell which diffs are "defaults to document" versus "a fresh, unrelated change".
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/terraformand choose slugtf-import-existing-resource; the lab runs real Terraform against the offline FakeCloud provider.