liveBook · Manning

Refactoring

As explained in Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu

Internal refactoring is structural change confined within a program or module that preserves its external behavior and interfaces.

A Terraform module can become hard to navigate even when it works correctly. Internal refactoring changes its structure to make future work easier without changing its external behavior or interface. A test suite provides a safety net: if an internal change breaks tests, investigate for unintended consequences. section 9.5.1 section 9.5.2

A module’s input variables and outputs form its external interface. Changing an existing input or output is an external change that users may notice; reorganizing code without changing either is most likely internal. This distinction matters because breaking changes need more careful management. section 9.5.2 section 9.7

For a straightforward reorganization:

  • Keep inputs in variables.tf and outputs in outputs.tf; group related declarations with clear headers. section 9.5.3
  • When main.tf grows unwieldy, use headers or split resources into files by function, such as networking, load balancing, and logging. Apply the same convention across modules. section 9.5.3
  • Check the plan. Terraform’s dependency graph does not depend on resource order or which file contains a resource, so a file-only move should produce no planned changes. section 9.5.3
Listing 9.32 Variable file with group headers
#########################
# Networking
#########################
 
variable "vpc_id" {
  type        = string
  description = "The ID of the VPC to deploy the resources into."
}
 
variable "subnet_ids" {
  type        = list(string)
  description = "A list of subnet IDs to deploy the resources into."
}
 
#########################
# Load Balancing
#########################
 
variable "acm_certificate_arn" {
  type        = string
  description = "The ARN of the ACM certificate to use for the 
load balancer."
}
 
#########################
# Logging
#########################
 
variable "cloudwatch_log_group_name" {
  type        = string
  description = "The name of the CloudWatch log group to send logs to."
}

Grouped variable declarations show how to improve navigation while retaining the same inputs. section 9.5.3

Moving code between files is different from changing a resource’s address by renaming its block or moving it into a module. For an address change, a Terraform moved block associates the existing resource with its new location without re-creating it. Refactor regularly to limit technical debt, but keep interface changes separate from work intended to be invisible to users. section 2.9 section 9.5.1

How Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu covers it

How deep it goes
Defines the interface boundary and gives file-reorganization guidance, plan expectations, and test checks; it does not provide a full refactoring procedure.
Examples
Uses grouped networking, load-balancing, and logging variables, plus splitting an oversized main.tf by function.
What it assumes
Assumes familiarity with Terraform resources, modules, variables, and outputs; defines how inputs and outputs mark the external interface.
What you can do after
Practice/perform internal module reorganization and check for unintended changes with tests and a Terraform plan.
How it connects
Connects refactoring to test suites, technical debt, module inputs and outputs, dependency graphs, and Terraform moved blocks.

Also explained in

Compare how 22 books explain refactoring →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Terraform in Depth: Infrastructure as Code with Terraform and OpenTofu. The section links point to the parts of the book it draws on.