Refactoring Terraform into Modules Safely
At CraftSchoolship, I refactored an older Terraform project that managed our Amazon EKS (managed Kubernetes) stack: the VPC, the cluster and its node groups, storage, and around ten Kubernetes add-ons. All of it lived in one main.tf file of more than a thousand lines.
The code worked, but it was hard to change. Adding one add-on meant scrolling through networking, IAM, EKS, and Helm resources to find the right place.
.
├── main.tf # 1000+ lines: VPC, EKS, add-ons, storage
├── variables.tf
├── outputs.tf
├── providers.tf
├── backend.tf
└── vars.tfvars
I wanted to split it into modules without Terraform recreating the live VPC the EKS cluster was attached to. Terraform's state file records each real resource under its address in the code. Moving a resource into a module changes that address, and Terraform treats a changed address as one resource to destroy and a new one to create.
I moved one module at a time. For each module I copied the resource blocks over, moved their state entries to the new addresses with terraform state mv, and ran terraform plan. Every move ended with a plan showing no changes, meaning Terraform had nothing to create or destroy in AWS. The root main.tf ended up holding only module calls, and the modules now stand up a production-ready EKS cluster in under 15 minutes in each of our three AWS regions.
