I usually start by importing networking first because it is the fastest way to prove Terraform matches reality. Converting a live stack to Terraform and Kubernetes is a control problem, not a tooling problem. The goal is to make infrastructure repeatable and auditable without taking production down. The safest approach is incremental and measured.
Start by capturing a baseline of your current infrastructure. Document network layout, identity structure, storage, and security groups. These are the hardest to change later. Decide which resources must be managed by code and which can remain outside for now. That clarity prevents scope creep.
Import and map before refactor. Create a resource map between existing infrastructure and your planned modules. Use import tooling to pull current resources into state. Avoid refactors until you can reproduce the current state with code. The first milestone is not a cleaner design. It is a faithful representation of reality.
Once the baseline is stable, move in slices. Convert one service end to end, validate in staging, and release to production. Then move the next service. This reduces risk and makes rollback clearer. Track drift regularly and pause if drift grows. Drift is a signal that the system is not under control.
Treat the conversion as a program of changes, not a single change. Limit parallel work so the team can focus on a clean audit trail. Use a short change log and link it to the runbook for deployment. Continuous validation: Add drift detection and a clear review process for infrastructure changes. Ensure code reviews include cost and security implications. Keep a simple change log so teams know what changed and why.
Document operational ownership for each module and service. If a resource is managed by code, the owners should know who approves changes. This avoids last-minute blockers during releases. IaC conversion succeeds when the focus is control and repeatability. A slow, disciplined rollout beats a fast and fragile one every time.
Treat state files as production assets. Back them up, restrict access, and document recovery steps. A lost or corrupted state file can create more downtime than a failed deployment. Plan the interface between Terraform and Kubernetes carefully. Decide what is provisioned by Terraform and what is managed by Kubernetes controllers. Overlapping ownership leads to drift and hidden conflicts.
Keep module design boring. Avoid deep abstraction at the start. A plain module that maps to one service is easier to review, test, and maintain during a migration program.
Example migration path: incremental conversion by layer
Start with the networking layer. Import the VPC, subnets, and security groups into Terraform state, then run a no-op plan to ensure Terraform matches reality. Next, move stateless services like web servers to managed instance groups with rolling updates. Finally, convert stateful services like databases, after backups and restore tests are in place. By moving layer by layer, each change is smaller and easier to validate. Teams can pause after each stage and measure drift.
Gotchas to avoid
- Attempting a full rewrite and losing track of current resources.
- Importing resources without cleaning up naming or tagging conventions.
- Allowing manual console changes that create configuration drift.
- Storing state without encryption or access control.
- Skipping staged environments, which hides change risk.
Conversion checklist
- Inventory all infrastructure and mark what will be imported vs replaced.
- Establish state storage with encryption, locking, and backups.
- Define module boundaries and naming conventions early.
- Require changes through code only to prevent drift.
- Use a staging environment to validate before production.
- Document rollback steps for each migration phase.
State and drift management: State is the heart of any IaC conversion. Store state in a remote backend with locking and access control. Limit who can run apply in production and require code reviews for changes. If drift is found, decide whether to import the change or to revert it, and document that decision.
Run a regular drift detection job in non-production environments. This catches manual changes before they become a surprise in production. Testing and validation: Use a staged rollout for infrastructure too. Run plans in CI, apply to a dev environment, and then to staging. Validate that critical services still start, that networking rules are correct, and that monitoring works. A small validation checklist prevents infrastructure changes from silently breaking deployments.
Change management during migration: Infrastructure changes should be predictable. Use small, frequent changes and avoid large weekend cutovers. If a change affects production traffic, communicate it in advance and coordinate with application teams. Track each change in a shared log so you can correlate infrastructure updates with incidents.
Rollback and recovery: Plan for rollback like any other change. Keep previous configuration versions and document the steps to revert. If a Terraform apply introduces an issue, the team should be able to roll back quickly or redeploy the previous state. This is especially important for network and IAM changes, where mistakes can block access.



