Deploy AWS NACL, Inbound & Outbound Routes, Security Group & Associate With Subnet Using Terraform

Deploy AWS NACL, Inbound & Outbound Routes, Security Group & Associate With Subnet 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>"
}
  1. 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"]
          }
}
  1. 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 NACL, Inbound & Outbound Routes And Associate With Subnet

🔳 Resource

aws_network_acl:- This resource is define traffic inbound and outbound rules on the subnet level.

🔳 Arguments

vpc_id:- This is a mandatory argument and refers to id of a VPC to which it would be associated.
subnet_ids:- List of subnet ids to which this acl would be applicable.
EGRESS & INGRESS are processed in attribute-as-blocks mode.
from_port - This is a mandatory argument for from port to match.
to_port - This is a mandatory argument for to port to match.
rule_no - This is a mandatory argument as rule number. Used for ordering.
action- This is a mandatory argument to define the action to be taken.
protocol- This is a mandatory argument for protocol to match. If using the -1 'all' protocol, you must specify a from and to port of 0.
tags:- One of the most important property used in all resources. Always make sure to attach tags for all your resources.

resource "aws_network_acl" "aws_nacl" {
  vpc_id = data.aws_vpc.GetVPC.id
  subnet_ids = [ data.aws_subnet.GetPublicSubnet.id ]
# allow ingress port 22
  ingress {
    protocol   = "tcp"
    rule_no    = 100
    action     = "allow"
    cidr_block = data.aws_subnet.GetPublicSubnet.cidr_block 
    from_port  = 22
    to_port    = 22
  }

  # allow ingress port 80 
  ingress {
    protocol   = "tcp"
    rule_no    = 200
    action     = "allow"
    cidr_block = data.aws_subnet.GetPublicSubnet.cidr_block
    from_port  = 80
    to_port    = 80
  }

  # allow ingress ephemeral ports 
  ingress {
    protocol   = "tcp"
    rule_no    = 300
    action     = "allow"
    cidr_block = data.aws_subnet.GetPublicSubnet.cidr_block
    from_port  = 1024
    to_port    = 65535
  }

  # allow egress port 22 
  egress {
    protocol   = "tcp"
    rule_no    = 100
    action     = "allow"
    cidr_block = data.aws_subnet.GetPublicSubnet.cidr_block
    from_port  = 22 
    to_port    = 22
  }

  # allow egress port 80 
  egress {
    protocol   = "tcp"
    rule_no    = 200
    action     = "allow"
    cidr_block = data.aws_subnet.GetPublicSubnet.cidr_block
    from_port  = 80  
    to_port    = 80 
  }

  # allow egress ephemeral ports
  egress {
    protocol   = "tcp"
    rule_no    = 300
    action     = "allow"
    cidr_block = data.aws_subnet.GetPublicSubnet.cidr_block
    from_port  = 1024
    to_port    = 65535
  }
tags = {
    Name = "Custom_NACL"
}
}

Configure Security Group

Another method acts as a virtual firewall to control your inbound and outbound traffic flowing to your EC2 instances inside a subnet.

🔳 Resource

aws_security_group:- This resource is define traffic inbound and outbound rules on subnet level.

🔳 Arguments

name:- This is an optional argument to define name of the security group.
description:- This is an optional argument to mention details about security group that we are creating.
vpc_id:- This is a mandatory argument and refers to 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. EGRESS & INGRESS are processed in attribute-as-blocks mode.

resource "aws_security_group" "ec2_sg" {
  name        = "allow_http"
  description = "Allow http inbound traffic"
  vpc_id      = data.aws_vpc.GetVPC.id

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port       = 0
    to_port         = 0
    protocol        = "-1"
    cidr_blocks     = ["0.0.0.0/0"]
  }
  tags = {
    Name = "terraform-security-group"
  }
}

🔳 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 "NACL" {
  value       = aws_network_acl.aws_nacl.id
  description = "A reference to the created NACL"
}
output "SID" {
  value       = aws_security_group.ec2_sg.id
  description = "A reference to the created NACL Inbound Rule"
}

🔊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❗️❗️

⛔️ Hashicorp Terraform
⛔️ AWS CLI
⛔️ Hashicorp Terraform Extension Guide
⛔️ Terraform Autocomplete Extension Guide
⛔️ AWS Network Access Control Layer
⛔️ Security Group

🥁🥁 Conclusion 🥁🥁

In this blog we have configured below resources
✦ AWS NACL for the Public Subnet we had created previously.
✦ AWS Security Group for the EC2 instances which needs to be provisioned inside subnets we have launched.
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.

📢 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")

👨🏻‍💻Terraform Github Repository👨🏻‍💻

Did you find this article valuable?

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