Deep Dive into Terraform - P7 (Deployment of AWS NACL, Inbound & Outbound Routes, Security Group & associating it with the Subnet Using Terraform)


In the previous parts of the Terraform series we had discussed about each and every important topic of Terraform along with an example of Deploying of AWS EC2 instance with the Security Group & the User Data using Terraform.
So, in this part of the terraform series we will be discussing about one more example of the terraform in which we will be going to Deploy the AWS NACL, Inbound & Outbound Routes, Security Group & associating it with the Subnet Using Terraform.
This time also we are deploying the following resources on AWS. So, that means will be using the AWS provider again.
Let's Go....
provider "aws" {
region = "ap-south-1" # AWS region
}
# Creation of a network access control list
resource "aws_network_acl" "example" {
vpc_id = aws_vpc.example.id
}
# Creation of the inbound and the outbound rules for the network access control list
resource "aws_network_acl_rule" "example_inbound" {
network_acl_id = aws_network_acl.example.id
rule_number = 100
protocol = "tcp"
rule_action = "allow"
cidr_block = "0.0.0.0/0"
egress = false
from_port = 80
to_port = 80
network_acl_id = aws_network_acl.example.id
rule_number = 200
protocol = "tcp"
rule_action = "allow"
cidr_block = "0.0.0.0/0"
egress = false
from_port = 22
to_port = 22
network_acl_id = aws_network_acl.example.id
rule_number = 300
protocol = "tcp"
rule_action = "allow"
cidr_block = "0.0.0.0/0"
egress = false
from_port = 3001
to_port = 64317
}
resource "aws_network_acl_rule" "example_outbound" {
network_acl_id = aws_network_acl.example.id
rule_number = 400
protocol = "tcp"
rule_action = "allow"
cidr_block = "0.0.0.0/0"
egress = true
from_port = 0
to_port = 65535
}
# Creation of a security group
resource "aws_security_group" "example_name" {
name = "example"
description = "Example Security Group"
vpc_id = aws_vpc.example.id
ingress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
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"]
}
ingress {
from_port = 23
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
# Associate security group with subnet
resource "aws_security_group_association" "example" {
subnet_id = aws_subnet.example.id
security_group = aws_security_group.example.id
}
# Define your VPC and subnet
resource "aws_vpc" "example" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "example" {
vpc_id = aws_vpc.example.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-south-1a" # AZ of your choice
}
Make sure to replace the following values like ap-soth-1
, 10.0.0.0/16
, 10.0.1.0/24
, etc., with your desired values according to your AWS environment and requirements. Moreover, adjust the inbound and outbound rules, security group settings, and other parameters as needed for your specific use cases.
Run
terraform fmt
command to rewrite the Terraform configuration files to a canonical format:terraform fmt
Run
terraform init
command to initialize the Terraform directory and download all the necessary plugins:terraform init
Console Output of
terraform init
command:-Initializing the backend... Initializing provider plugins... - Checking for available provider plugins... - Downloading plugin for provider "aws" (hashicorp/aws) 3.62.0... Terraform has been successfully initialized!
Run
terraform plan
command to see what Terraform is planning to do upon running the apply command:terraform plan
Console output of
terraform plan
command:-Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # aws_network_acl.example will be created + resource "aws_network_acl" "example" { + arn = (known after apply) + default_egress = (known after apply) + default_egress_action = (known after apply) + default_egress_cidr_block = (known after apply) + default_egress_ipv6_cidr_block = (known after apply) + default_egress_port_range { + from_port = (known after apply) + to_port = (known after apply) } + default_egress_protocol = "-1" + default_egress_rule_id = (known after apply) + default_ingress = (known after apply) + default_ingress_action = (known after apply) + default_ingress_cidr_block = (known after apply) + default_ingress_ipv6_cidr_block = (known after apply) + default_ingress_port_range { + from_port = (known after apply) + to_port = (known after apply) } + default_ingress_protocol = "-1" + default_ingress_rule_id = (known after apply) + id = (known after apply) + owner_id = (known after apply) + subnet_ids = (known after apply) + tags = { + "Name" = "example" } + vpc_id = (known after apply) }
# aws_network_acl_rule.example_inbound will be created + resource "aws_network_acl_rule" "example_inbound" { + cidr_block = "0.0.0.0/0" + egress = false + from_port = 3001 + id = (known after apply) + icmp_type = "" + ipv6_cidr_block = "" + network_acl_id = (known after apply) + protocol = "6" + rule_action = "allow" + rule_number = 300 + to_port = 64317 } # aws_network_acl_rule.example_outbound will be created + resource "aws_network_acl_rule" "example_outbound" { + cidr_block = "0.0.0.0/0" + egress = true + from_port = 0 + id = (known after apply) + icmp_type = "" + ipv6_cidr_block = "" + network_acl_id = (known after apply) + protocol = "6" + rule_action = "allow" + rule_number = 400 + to_port = 65535 }
# aws_security_group.example_name will be created + resource "aws_security_group" "example_name" { + arn = (known after apply) + description = "Example Security Group" + egress = (known after apply) + id = (known after apply) + ingress = (known after apply) + name = "example" + owner_id = (known after apply) + revoke_rules_on_delete = false + tags = (known after apply) + vpc_id = (known after apply) } # aws_security_group_association.example will be created + resource "aws_security_group_association" "example" { + id = (known after apply) + security_group_id = (known after apply) + subnet_id = (known after apply) + vpc_id = (known after apply) } # aws_subnet.example will be created + resource "aws_subnet" "example" { + arn = (known after apply) + assign_ipv6_address_on_creation = false + availability_zone = "ap-south-1a" + availability_zone_id = (known after apply) + cidr_block = "10.0.1.0/24" + id = (known after apply) + ipv6_cidr_block = (known after apply) + ipv6_cidr_block_association_id = (known after apply) + map_public_ip_on_launch = false + owner_id = (known after apply) + vpc_id = (known after apply) } # aws_vpc.example will be created + resource "aws_vpc" "example" { + arn = (known after apply) + assign_generated_ipv6_cidr_block = false + cidr_block = "10.0.0.0/16" + default_network_acl_id = (known after apply) + default_route_table_id = (known after apply) + default_security_group_id = (known after apply) + dhcp_options_id = (known after apply) + enable_classiclink = (known after apply) + enable_classiclink_dns_support = (known after apply) + id = (known after apply) + instance_tenancy = (known after apply) + ipv6_association_id = (known after apply) + ipv6_cidr_block = (known after apply) + main_route_table_id = (known after apply) + owner_id = (known after apply) + tags = (known after apply) } Plan: 7 to add, 0 to change, 0 to destroy.
Run
terraform apply
command to apply the changes and create the resources:terraform apply --auto-approve
Console output of
terraform apply --auto-approve
command:-aws_vpc.example: Creating... aws_vpc.example: Creation complete after 5s [id=vpc-0123456789abcdef0] aws_subnet.example: Creating... aws_subnet.example: Creation complete after 3s [id=subnet-0123456789abcdef1] aws_network_acl.example: Creating... aws_network_acl.example: Creation complete after 1s [id=acl-0123456789abcdef2] aws_security_group.example_name: Creating... aws_security_group.example_name: Creation complete after 2s [id=sg-0123456789abcdef3] aws_network_acl_rule.example_inbound: Creating... aws_network_acl_rule.example_inbound: Creation complete after 1s [id=acl-0123456789abcdef2-100] aws_network_acl_rule.example_inbound: Creating... aws_network_acl_rule.example_inbound: Creation complete after 1s [id=acl-0123456789abcdef2-200] aws_network_acl_rule.example_inbound: Creating... aws_network_acl_rule.example_inbound: Creation complete after 1s [id=acl-0123456789abcdef2-300] aws_network_acl_rule.example_outbound: Creating... aws_network_acl_rule.example_outbound: Creation complete after 1s [id=acl-0123456789abcdef2-400] aws_security_group_association.example: Creating... aws_security_group_association.example: Creation complete after 1s [id=sga-0123456789abcdef4] Apply complete! Resources: 7 added, 0 changed, 0 destroyed.
And once we are done with our work we will now destroy all the resources that we had created:
terraform destroy --auto-approve
This command will remove all the resources created by Terraform.
<-- In this part we created the AWS NACL, Inbound & Outbound Routes, Security Group & associating it with the Subnet Using Terraform-->
<-- In the next part of Terraform Series we will see the another example of Terraform. -->
Subscribe to my newsletter
Read articles from Yash Varma directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Yash Varma
Yash Varma
As a final year undergraduate with a passion for Cloud DevOps Engineering, I bring a strong foundation in cloud computing and automation to the table. I have a solid understanding of cloud platforms such as AWS or Google Cloud and have honed my skills in infrastructure as code (IaC) using tools like Terraform and CloudFormation. I am eager to apply my knowledge of CI/CD pipelines, containerization, and version control systems to contribute to efficient and automated software development processes. I am a quick learner, highly motivated, and excited to embark on a career in Cloud & DevOps, where I can leverage my technical expertise to drive innovation and streamline operations. In addition to my proficiency in cloud technologies, I bring a wealth of experience in crafting efficient CI/CD pipelines, implementing containerization strategies, and managing version control systems. My eagerness to learn, coupled with my inherent motivation, fuels my drive to continually enhance processes and drive innovation in software development. I am poised to make a significant impact in Cloud, DevOps and DevSecOps leveraging my technical prowess to streamline operations and catalyze organizational growth. Well i am a part-time competitive Coder too, I have a solid understanding of Data Structure and Algorithms as well as of Object Oriented Programming. I usually code in C++ and have the familiarity with Java and Python as well as i also have the intermediate knowledge of Rust Programming language too. Some of my coding achievements are 5🌟 @HackerRank || 4🌟 @CodeChef(Max.Rating->1845) || Knight🔰 @LeetCode(Max.Rating->1858). Along with all these stuffs i have the understanding of Cloud Platforms like Amazon Web Services (AWS) and Google Cloud Platform (GCP). I was also a Google Cloud's Arcade Facilitator in 2k23 where i had mentored 150+ student's and professional's in gaining knowledge about the Google Cloud Platform (GCP). Moreover I had also won some of the Google Cloud's events like Google CRFP'22 || Google CCP'23.