John

Senior Cloud Engineer & Technical Lead

Using VS Code Copilot to Decode and Learn Complex Terraform AWS Infrastructure

I inherited a massive Terraform codebase with 47 modules, nested data sources, and complex AWS infrastructure patterns that would have taken me weeks to fully understand. Instead of drowning in documentation, I discovered that VS Code Copilot could become my personal infrastructure tutor, transforming overwhelming code into digestible learning opportunities.

The Problem

When you’re dropped into an existing Terraform project, especially one that’s grown organically over years, you face several challenges:

  • Module interdependencies - Understanding how module.vpc.private_subnet_ids connects to module.eks.subnet_ids
  • Data source chains - Following the flow from data.aws_caller_identity through multiple locals and variables
  • Implicit AWS knowledge - Why does this security group reference port 2049? (NFS, but you have to know that)
  • Complex conditionals - Nested for_each loops and dynamic blocks that control resource creation
  • Missing context - What business problem does this 200-line locals block actually solve?

Traditional approaches like reading AWS documentation or tracing through code manually are time-intensive and often leave gaps in understanding.

The Solution: Copilot as Your Infrastructure Tutor

VS Code Copilot excels at explaining complex code patterns and can accelerate infrastructure learning in ways I didn’t expect. Here’s how I use it systematically:

1. Code Annotation and Explanation

Instead of guessing what complex Terraform expressions do, I ask Copilot to explain them directly:

# Original confusing code
locals {
  subnet_groups = {
    for az, subnets in local.availability_zones : az => {
      private = [for s in subnets : s.private_subnet_id if s.private_subnet_id != null]
      public  = [for s in subnets : s.public_subnet_id if s.public_subnet_id != null]
    }
  }
}

# After asking Copilot to explain, I add comments:
locals {
  # Creates a map structure grouped by availability zone
  # Each AZ contains arrays of private and public subnet IDs
  # Filters out null values to ensure clean subnet lists
  subnet_groups = {
    for az, subnets in local.availability_zones : az => {
      private = [for s in subnets : s.private_subnet_id if s.private_subnet_id != null]
      public  = [for s in subnets : s.public_subnet_id if s.public_subnet_id != null]
    }
  }
}

2. Learning AWS Service Patterns

When I encounter unfamiliar AWS resources, I ask Copilot to explain the broader context:

# Found this in the codebase
resource "aws_efs_file_system" "this" {
  creation_token = var.creation_token
  
  lifecycle_policy {
    transition_to_ia = "AFTER_30_DAYS"
  }
}

# Copilot explains: "This creates an AWS Elastic File System (EFS) 
# which provides shared, scalable file storage for EC2 instances. 
# The lifecycle policy moves files to Infrequent Access (IA) storage 
# after 30 days to reduce costs. Port 2049 is used for NFS traffic."

This context helps me understand not just what the resource does, but why it’s configured that way.

3. Mental Model Building with Diagrams

For complex infrastructure patterns, I ask Copilot to create Mermaid diagrams that show relationships:

graph TB VPC[VPC: 10.0.0.0/16] subgraph AZA["Availability Zone A"] PubA[Public Subnet A
10.0.1.0/24] PrivA[Private Subnet A
10.0.101.0/24] NATA[NAT Gateway A] end subgraph AZB["Availability Zone B"] PubB[Public Subnet B
10.0.2.0/24] PrivB[Private Subnet B
10.0.102.0/24] NATB[NAT Gateway B] end IGW[Internet Gateway] EKS[EKS Cluster] RDS[RDS Instance] EFS[EFS File System] VPC --> PubA VPC --> PubB VPC --> PrivA VPC --> PrivB PubA --> NATA PubB --> NATB PrivA --> NATA PrivB --> NATB PubA --> IGW PubB --> IGW EKS --> PrivA EKS --> PrivB RDS --> PrivA RDS --> PrivB EFS --> PrivA EFS --> PrivB style EKS fill:#ff9999 style RDS fill:#99ccff style EFS fill:#99ff99

This visual representation helps me understand how all the pieces fit together in the AWS account.

4. Security Group Analysis

Security groups are often the most confusing part of AWS infrastructure. Copilot helps decode them:

# Original security group rule
resource "aws_security_group_rule" "eks_cluster_ingress_workstation_https" {
  cidr_blocks       = [local.workstation_external_cidr]
  from_port         = 443
  protocol          = "tcp"
  security_group_id = aws_security_group.eks_cluster.id
  to_port           = 443
  type              = "ingress"
}

# Copilot explains: "This allows HTTPS access (port 443) to the EKS 
# cluster API server from your workstation's external IP address. 
# This enables kubectl commands and cluster management from your local machine."

5. Variable Tracing and Dependencies

For complex variable flows, I ask Copilot to trace dependencies:

# Ask: "Trace how var.environment flows through this module"
# Copilot maps out:
var.environment 
   local.name_prefix = "${var.environment}-${var.project_name}"
   aws_eks_cluster.name = local.name_prefix
   module.node_groups.cluster_name = aws_eks_cluster.cluster_id
   Tags on all resources include Environment = var.environment

6. Learning Terraform Best Practices

When I see unfamiliar patterns, I ask Copilot to explain the reasoning:

# Why use this pattern?
lifecycle {
  create_before_destroy = true
  ignore_changes = [
    desired_size,
  ]
}

# Copilot explains: "create_before_destroy prevents downtime during 
# resource replacement. ignore_changes on desired_size prevents 
# Terraform from reverting auto-scaling group size changes made 
# by AWS auto-scaling policies."

Practical Workflow

Here’s my systematic approach for learning new Terraform codebases:

  1. Start with main.tf - Ask Copilot to explain the overall architecture
  2. Follow data sources - Understand how external resources are referenced
  3. Trace module connections - Map how outputs become inputs
  4. Decode locals blocks - These often contain the core business logic
  5. Security group deep dive - Understanding network access patterns
  6. Variable flow analysis - How configuration cascades through modules

Advanced Techniques

Interactive Code Comments

I use Copilot to generate comprehensive comments that serve as documentation:

# Generated with Copilot's help
# EKS Node Group Configuration:
# - Uses launch templates for custom AMI and user data
# - Implements spot instances for cost optimization  
# - Configures taints for workload isolation
# - Sets up proper IAM roles for AWS Load Balancer Controller
resource "aws_eks_node_group" "this" {
  # ... configuration
}

Learning Path Creation

When encountering new AWS services, I ask Copilot to create learning roadmaps:

“I found AWS Systems Manager Parameter Store in this Terraform. What should I learn about this service?”

Copilot provides structured learning suggestions focusing on the specific use case in the code.

Key Learnings

  • Code explanation accelerates understanding - Copilot can decode complex Terraform expressions instantly
  • Context matters more than syntax - Understanding why resources are configured helps more than just knowing what they do
  • Visual diagrams build mental models - Mermaid diagrams help visualize complex infrastructure relationships
  • Security groups need special attention - Network access patterns are often the most business-critical
  • Variable tracing reveals architecture decisions - Following data flow shows how modules are designed to work together
  • Interactive documentation is powerful - Generated comments become living documentation
  • Pattern recognition develops faster - Seeing similar patterns across modules with explanations builds intuition
  • AWS service knowledge compounds - Understanding one service helps with related services and integration patterns

The biggest shift was treating Terraform code not as something to memorize, but as a conversation starter with Copilot about AWS architecture patterns. Instead of spending hours in documentation rabbit holes, I can focus on understanding the business problems the infrastructure solves and how all the pieces work together to deliver value.