Deploy AWS Private Subnet, Nat Gateway, Elastic Ip, Private Route Table & Associate Using Terraform

Deploy AWS Private Subnet, Nat Gateway, Elastic Ip, Private Route Table & Associate Using Terraform

Welcome back to the series of Deploying On AWS Cloud Using Terraform 👨🏻‍💻. In this entire series we will focus on our core concepts of Terraform by launching important basic services from scratch which will take your infra-as-code journey from beginner to advanced. This series would start from beginner to advance with real life Usecases and Youtube Tutorials.

If you are a beginner for Terraform and want to start your journey towards infra-as-code developer as part of your devops role buckle up 🚴‍♂️ and lets get started and understand core Terraform concepts by implementing it...🎬

❗️❗️Pre-Requisite❗️❗️

1️⃣ Deploying On AWS Cloud Using Terraform Series Pre-Requisites

2️⃣ Deploy VPC, IGW & Associate [Mandatory]

3️⃣ Deploy only public subnet template from below blog [Mandatory]

4️⃣ Terraform Naming Conventions & Best Practices

🎨 Diagrammatic Representation🎨

image.png

🔎Basic Terraform Configurations🔍

As part of the basic configuration we are going to set up 3 terraform files

  1. Providers File:- Terraform relies on plugins called "providers" to interact with cloud providers, SaaS providers, and other APIs.
    Providers are distributed separately from Terraform itself, and each provider has its own release cadence and version numbers.
    The Terraform Registry is the main directory of publicly available Terraform providers, and hosts providers for most major infrastructure platforms. Each provider has its own documentation, describing its resource types and their arguments.
    We would be using AWS Provider for our terraform series. Make sure to refer Terraform AWS documentation for up-to-date information.
    Provider documentation in the Registry is versioned; you can use the version menu in the header to change which version you're viewing.

     provider "aws" {
       region                  = "var.AWS_REGION"
       shared_credentials_file = "<Your AWS Credentials File path>"
     }
    
  2. Variables File:- Terraform variables lets us customize aspects of Terraform modules without altering the module's own source code. This allows us to share modules across different Terraform configurations, reusing same data at multiple places.
    When you declare variables in the root terraform module of your configuration, you can set their values using CLI options and environment variables. When you declare them in child modules, the calling module should pass values in the module block.

     variable "AWS_REGION" {
       default = "us-east-1"
     }
     data "aws_vpc" "GetVPC" {
     filter {
         name   = "tag:Name"
         values = ["CustomVPC"]
               }
     }
     data "aws_subnet" "GetPublicSubnet" {
     filter {
         name   = "tag:Name"
         values = ["PublicSubnet1"]
               }
     }
    
  3. Versions File:- It's always a best practice to maintain a version file where you specific version based on which your stack is testing and live on production.

     terraform {
       required_version = ">= 0.12"
     }
    

Configure Private Subnet

As a part of this code block, we are going to create 1 subnet with the below configurations.

🔳 Resource

aws_subnet:- This resource is used to launch a subnet associated with a PVC and tied up with the availability zone. This subnet is nothing but a segregation of the IP address range of your VPC.

🔳 Arguments

vpc_id:- Refers to id of a VPC to which it would be associated to utilize its CIDR IP range.
cidr_block- This IPv4 CIDR block for the VPC is an optional argument. CIDR can be explicitly set or it can be derived from IPAM using ipv4_netmask_length.
availability_zone - This is an optional argument to mention AZ for the subnet for a specific region under which it is launched.
tags:- One of the most important property used in all resources. Always make sure to attach tags for all your resources.

resource "aws_subnet" "PrivateSubnet" {
  vpc_id     = data.aws_vpc.GetVPC.id
  cidr_block = "10.0.128.0/18"
  availability_zone = "us-east-1a"
  #map_public_ip_on_launch = true

  tags = {
    Name = "PrivateSubnet"
  }
}

Configure Nat Gateway

As part of this code block, we will create NAT Gateway but before that, we need to make sure to create elastic IP as it is a mandatory attribute to be passed.

🔳 Resource

aws_eip:- This resource is to define create route tables and define routes within it.

🔳 Arguments

✦ vpc_id:- Refers to the id of a VPC to which it would be associated.
tags:- One of the most important property used in all resources. Always make sure to attach tags for all your resources.

resource "aws_eip" "CustomEIP" {
  vpc      = true
  tags = {
    "Name" = "CustomEIP"
  }
}

As we have elastic ip ready with the previous code block let's go ahead and create NAT Gateway.

🔳 Resource

aws_nat_gateway:- This resource is to create NAT Gateway in association with a public subnet.

🔳 Arguments

allocation_id:- Refers to elastic IP to which it would be associated.
subnet_id:- Refers to the elastic id to which it would be associated.
tags:- One of the most important property used in all resources. Always make sure to attach tags for all your resources.

resource "aws_nat_gateway" "CustomNAT" {
  allocation_id = aws_eip.CustomEIP.id
  subnet_id     = data.aws_subnet.GetPublicSubnet.id
  tags = {
    Name = "CustomNAT"
  }
}

Configure Private Route Table & Associate

Let's first focus on the code to create a custom route table for a private subnet and add a NAT gateway route to that table.

🔳 Resource

aws_route_table:- This resource is to define create route tables and define routes within them.

🔳 Arguments

vpc_id:- Refers to the id of a VPC to which it would be associated.
route:- This is an optional argument which to define a list of routes to be added to the route table we are creating. As part of this route, we are going to pass our NAT Gateway id to add it as a route.
tags:- One of the most important properties used in all resources. Always make sure to attach tags for all your resources.

resource "aws_route_table" "PrivateRouteTable" {
  vpc_id = data.aws_vpc.GetVPC.id

  route {
    cidr_block = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.CustomNAT.id
  }

  tags = {
    Name = "PrivateRouteTable"
  }
}

As you can see above we have created our custom route table and also added routes to that custom route table. Now we have to associate this route table to our subnet.

🔳 Resource

aws_route_table_association:- This resource is used to create an association between the route table and a subnet/internet gateway.

🔳 Arguments

✦ **subnet_id **:- Refers to id of a subnet to which it needs to be associated.
route_table_id:- Refers to route table id to which we have to associate our subnet.

resource "aws_route_table_association" "PrivateSubnetRouteTableAssociation" {
  subnet_id      = aws_subnet.PrivateSubnet.id
  route_table_id = aws_route_table.PrivateRouteTable.id
}

🔳 Output File

Output values make information about your infrastructure available on the command line, and can expose information for other Terraform configurations to use. Output values are similar to return values in programming languages.

output "PrivateSubnet" {
  value       = aws_subnet.PrivateSubnet.id
  description = "This is private subnet id."
}
output "CustomEIP" {
  value       = aws_eip.CustomEIP.id
  description = "Custom elastic ip we created."
}
output "CustomNAT" {
  value       = aws_nat_gateway.CustomNAT.id
  description = "NAT Gateway ID."
}
output "PrivateRouteTable" {
  value       = aws_route_table.PrivateRouteTable.id
  description = "List custom privateroute table id."
}

🔊To view the entire GitHub code click here

1️⃣ The terraform fmt command is used to rewrite Terraform configuration files to a canonical format and style👨‍💻.

 terraform fmt

2️⃣ Initialize the working directory by running the command below. The initialization includes installing the plugins and providers necessary to work with resources. 👨‍💻

terraform init

3️⃣ Create an execution plan based on your Terraform configurations. 👨‍💻

terraform plan

4️⃣ Execute the execution plan that the terraform plan command proposed. 👨‍💻

terraform plan -auto-approve

👁‍🗨👁‍🗨 YouTube Tutorial 📽

ELB (2).png

destroy.png

❗️❗️Important Documentation To Be Viewed❗️❗️

⛔️ Hashicorp Terraform
⛔️ AWS CLI
⛔️ Hashicorp Terraform Extension Guide
⛔️ Terraform Autocomplete Extension Guide
⛔️ AWS Subnet
⛔️ AWS Route Table
⛔️ AWS Route Table Association
⛔️ NAT Gateway
⛔️ Elastic IP

🥁🥁 Conclusion 🥁🥁

In this blog, we have launched below resources
✦ AWS Subnet and associated that subnet to our VPC.
✦ AWS Elastic IP.
✦ AWS NAT Gateway and associated it with EIP.
✦ AWS Custom Route Table and added our NAT Gateway route to this table.
✦ AWS Route Table Association to link out custom route tables and subnets we have created.
I have also referenced what arguments and documentation we are going to use so that while you are writing the code it would be easy for you to understand terraform official documentation. Stay with me for next blog where we will be doing deep dive .

📢 Stay tuned for my next blog.....

🎊**So, did you find my content helpful? If you did or like my other content, feel free to buy me a coffee. Thanks. **🎊

![](https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=Dheeraj3&button_colour=5F7FFF&font_colour=ffffff&font_family=Cookie&outline_colour=000000&coffee_colour=FFDD00 align="left")

Did you find this article valuable?

Support Dheeraj Choudhary by becoming a sponsor. Any amount is appreciated!