Welcome to Part 2 of the series: Terraform for Beginners
Previously, we learned how to create a VPC in AWS using Terraform. In this blog, we'll learn about subnets and how to create them using Terraform.
What is a subnet?
According to AWS documentation,
A subnet is a range of IP addresses in your VPC. You can create AWS resources, such as EC2 instances, in specific subnets.
Here's a breakdown of the key aspects of a subnet:
Segmentation: Subnets allow you to partition your VPC into isolated units. This enhances security by restricting resources within one subnet from directly accessing resources in another subnet by default. If needed, you can configure specific routing rules to allow controlled communication between subnets.
Placement: You can create multiple subnets within your VPC, each with its own CIDR block (a range of IP addresses). When launching resources like EC2 instances within your VPC, you can specify their subnet. This placement determines their network access and security posture.
-
Public vs. Private: A common practice involves creating two main types of subnets:
- Public Subnet: Resources placed in a public subnet have direct access to the internet. This allows them to receive inbound traffic from the internet and potentially send outbound traffic. Public subnets are suitable for resources like web servers that need to be accessed publicly.
- Private Subnet: Resources in a private subnet don't have direct internet access by default. This improves security for resources that don't require exposure to the internet. However, if these resources need controlled outbound access (e.g., downloading updates), you can leverage a NAT Gateway (Network Address Translation Gateway) to provide it.
Let's look at the architecture diagram.
We have to create a public and private subnet inside the vpc we created in the previous blog.
Prerequisites
Complete the tutorial for creating a vpc as we will continue from there.
You can check out the tutorial here
Terraform Code to create Subnet in AWS
Step 1: In your vpc.tf file copy and paste the following piece of code:
resource "aws_subnet" "public_subnet" {
for_each = var.public_subnet
vpc_id = aws_vpc.vpc.id
cidr_block = each.value.cidr_block
availability_zone = each.value.availability_zone
map_public_ip_on_launch = true
tags = {
Name = "${var.env}-${local.project}-${each.key}"
CreatedByTer = true
}
}
resource "aws_subnet" "private_subnet" {
for_each = var.private_subnet
vpc_id = aws_vpc.vpc.id
cidr_block = each.value.cidr_block
availability_zone = each.value.availability_zone
tags = {
Name = "${var.env}-${local.project}-${each.key}"
CreatedByTer = true
}
}
Explanation:
for_each allows you to create multiple subnets with varying configurations based on the data provided in the variables named public_subnet and private_subnet.
-
cidr_block = each.value.cidr_block.
- This line defines the CIDR block for the subnets. However, it uses a dynamic approach by referencing each.value.cidr_block. This suggests that var.public_subnet and var.private_subnet is a map or list containing key-value pairs where the key is used for iteration (each.key) and the value (each.value) contains a nested object with a cidr_block key. This allows you to define multiple CIDR blocks for different subnets within the loop.
-
availability_zone = each.value.availability_zone
- Similar to the cidr_block, this line defines the availability zone for the subnets using a dynamic reference to the availability_zone key within the nested objects. This allows you to distribute your resources across zones for redundancy.
-
map_public_ip_on_launch
- This line sets the map_public_ip_on_launch attribute to true or false. When set to true, any EC2 instances launched within that subnet will automatically receive a public IP address, allowing them to be accessed directly from the internet. Similarly, when set to false, the instances will not be assigned a public IP during creation.
You will get an error as we have not yet created the public_subnet and private_subnet variables.
Step 2: In your variables.tf file copy and paste the following code:
variable "public_subnet" {
type = map(any)
description = "Public Subnets to be created"
}
variable "private_subnet" {
type = map(any)
description = "Private Subnets to be created"
}
Explanation:
This code block defines two Terraform variables named "public_subnet" and "private_subnet". It specifies that the variables will hold a collection of data in the form of a map.
While 'any' allows for flexibility, using more specific data types within the map can improve code readability and catch potential errors during configuration.
Step 3: In your terraform.tfvars file copy and paste the following code block
public_subnet = {
public-subnet-1 = {
cidr_block = "10.0.101.0/24"
availability_zone = "ap-south-1a"
}
}
private_subnet = {
private-subnet-1 = {
cidr_block = "10.0.1.0/24"
availability_zone = "ap-south-1a"
}
}
Explanation:
The value of the public_subnet and private_subnet variables are defined here.
This configuration defines the above variables as map of a map.
-
public-subnet-1 is the name of the first child map of the variable public_subnet. It consists of two key-value pairs:
- cidr_block specifies the CIDR range for the subnet
- availability_zone specifies the AWS availability zone the subnet will reside in. Here we are creating the subnet in the _Mumbai _region.
Similarly, private-subnet-1 is the name of the first child of the variable private_subnet. It consists of the same key-value pairs.
Deploy infrastructure to AWS
Follow the steps here to deploy the changes to AWS.
Congratulations! You have successfully created subnets in AWS using terraform.
Up next: Internet Gateway! Stay tuned. 👋
Top comments (0)