Skip to main content
Terraform Basics
CHAPTER 11

Networking with Terraform

Updated: May 15, 2026
30 min read

# CHAPTER 11

Networking with Terraform

1. Introduction

The foundation of any cloud architecture is the network. You cannot launch a secure server, database, or container without first defining the virtual highways that connect them. Designing networks manually via the cloud console is terrifyingly complex; a single misconfigured routing table can expose your internal database to the public internet. By defining networks as code, we can peer-review our security posture before deployment. In this chapter, we will use Terraform to construct a robust Virtual Private Cloud (VPC), complete with public subnets, private subnets, and internet gateways.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Define the core components of cloud networking (VPC, Subnets, Route Tables).
  • Provision a Virtual Private Cloud (VPC) using Terraform.
  • Differentiate between Public and Private Subnets in HCL.
  • Create an Internet Gateway and attach it to a routing table.
  • Utilize the official AWS VPC Terraform Module for complex architectures.

3. Beginner-Friendly Explanation

Imagine building a medieval castle.
  • VPC (The Castle Walls): The overarching boundary. Nothing gets in or out unless you explicitly allow it.
  • Public Subnet (The Courtyard): Inside the walls, but open to visitors. This is where you put your Web Servers so customers can access your website.
  • Private Subnet (The Royal Vault): Deep inside the castle. No doors lead directly to the outside. This is where you put your Database. The only way to access the Database is to first enter the Courtyard (Web Server) and ask permission.
  • Internet Gateway (The Drawbridge): The physical mechanism that allows traffic from the Courtyard to reach the outside world.

4. Building the Network (Hard Way)

To understand how networks work, let's look at the raw resources required to build a simple public network in AWS.
hcl
12345678910111213141516171819202122232425262728293031323334
# 1. The Castle Walls
resource "aws_vpc" "main_network" {
  cidr_block = "10.0.0.0/16" # Provides 65,536 IP addresses
}

# 2. The Courtyard (A slice of the VPC)
resource "aws_subnet" "public_subnet" {
  vpc_id     = aws_vpc.main_network.id
  cidr_block = "10.0.1.0/24" # Provides 256 IP addresses
  
  # Automatically give servers in this subnet a public IP
  map_public_ip_on_launch = true 
}

# 3. The Drawbridge
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main_network.id
}

# 4. The Map (Route Table) - Telling the Courtyard how to find the Drawbridge
resource "aws_route_table" "public_rt" {
  vpc_id = aws_vpc.main_network.id

  route {
    cidr_block = "0.0.0.0/0" # Target: The Internet
    gateway_id = aws_internet_gateway.igw.id
  }
}

# 5. Attaching the Map to the Courtyard
resource "aws_route_table_association" "public_assoc" {
  subnet_id      = aws_subnet.public_subnet.id
  route_table_id = aws_route_table.public_rt.id
}

*That is 5 separate resources just to get a single server onto the internet!*

5. Building the Network (The Easy Way)

In Chapter 7, we learned about the Terraform Registry. The brilliant engineers at AWS have already written the complex 5-step code above and packaged it into an official Module.
hcl
123456789101112131415
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.0.0"

  name = "production-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["us-east-1a", "us-east-1b"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24"] # Royal Vaults
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24"] # Courtyards

  # Creates the Internet Gateways and Route Tables automatically!
  enable_nat_gateway = true 
  single_nat_gateway = true
}

*Always use the official VPC module for production. It is mathematically tested and handles highly complex multi-Availability Zone routing seamlessly.*

6. Mini Project: Build a Secure Cloud Network

Let's place a Web Server in the Public Subnet and a Database in the Private Subnet.

Step-by-Step Architecture Concept:

hcl
123456789101112131415161718192021
# 1. Create the Network using the Module (from above)
module "vpc" { ... }

# 2. Web Server (In the Public Subnet)
resource "aws_instance" "web" {
  ami           = "ami-12345"
  instance_type = "t2.micro"
  
  # We ask the module for the ID of the first public subnet!
  subnet_id     = module.vpc.public_subnets[0]
}

# 3. Database Server (In the Private Subnet)
resource "aws_db_instance" "database" {
  engine         = "mysql"
  instance_class = "db.t3.micro"
  
  # The database goes in the private subnet group. 
  # It has NO public IP address. It is unhackable from the outside internet.
  db_subnet_group_name = module.vpc.database_subnet_group_name
}

7. Real-World Scenarios

A junior developer was asked to spin up a new Redis cache server. They used the AWS Console, clicked through the wizard rapidly, and hit "Launch." They didn't realize the console defaulted to placing the server in a Public Subnet. Within 4 hours, automated bots scanning the internet found the exposed Redis port, bypassed authentication, and deleted all the company's cached data, holding it for a Bitcoin ransom. Following the incident, the DevOps team revoked all manual console access. They mandated that all infrastructure must be deployed via Terraform using the official VPC module, strictly enforcing that data-layer resources are hardcoded to deploy exclusively into privatesubnets.

8. Best Practices

  • CIDR Math: IP addressing (10.0.0.0/16) is notoriously difficult. If you accidentally overlap the IP range of your AWS VPC with the IP range of your corporate office Wi-Fi, the two networks will never be able to communicate via VPN. Always consult with a network engineer before hardcoding CIDR blocks into your variables.tf.

9. Security Recommendations

  • NAT Gateways: In the VPC module example, we used enablenatgateway = true. Servers in a Private Subnet cannot be accessed from the internet, but what if they need to download a security update *from* the internet? A NAT Gateway acts as a one-way mirror. It allows the private server to reach out to the internet to download updates, but physically blocks any hacker on the internet from reaching in.

10. Troubleshooting Tips

  • Module Array Syntax: Notice the syntax module.vpc.publicsubnets[0]. The VPC module creates *multiple* subnets (an array). If you try to assign subnetid = module.vpc.publicsubnets, Terraform will throw a type-mismatch error because an EC2 instance can only live in ONE subnet. You must use the [0] index to grab the first ID in the array.

11. Exercises

  1. 1. What is the security advantage of placing an RDS Database in a Private Subnet rather than a Public Subnet?
  1. 2. Explain the difference between defining raw networking resource blocks versus utilizing the official Terraform vpc module.

12. FAQs

Q: Is Terraform creating a physical router somewhere? A: No. In modern cloud computing (Software Defined Networking), there are no physical routers or switches for your specific account. Terraform is making API calls to AWS's hypervisors, instructing them to logically route traffic according to your rules.

13. Interview Questions

  • Q: Architect a highly available, multi-tier VPC using Terraform. Explain the routing relationship between Public Subnets, Private Subnets, Internet Gateways, and NAT Gateways.
  • Q: A developer complains that an EC2 instance provisioned via Terraform in a newly created VPC cannot connect to the internet to download packages. Identify the missing Terraform resources required to establish outbound internet connectivity.

14. Summary

In Chapter 11, we laid the concrete foundation of our cloud data center. We demystified the terrifying complexity of Software Defined Networking, translating abstract concepts like Subnets, CIDR blocks, and Route Tables into declarative HCL code. We recognized the immense value of the Terraform Registry, utilizing the official AWS VPC module to abstract away dozens of verbose resource blocks into a clean, parameter-driven architectural blueprint. Most importantly, we enforced the Zero-Trust security paradigm, demonstrating how to shield our databases within the impregnable walls of private subnets.

15. Next Chapter Recommendation

Our network is secure, and our virtual machines are running. But modern applications rarely run directly on virtual machines anymore. They run in containers. Proceed to Chapter 12: Terraform and Docker.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·