Deploying a Test Web Page & Demilitarized Zone (DMZ) with NAT gateway using Terraform:

Bmwitcher
9 min readAug 28, 2020

Let’s start off by determining what in the world is a DMZ or a Demilitarized Zone:

In computer security, a DMZ network (sometimes referred to as a “demilitarized zone”) functions as a subnetwork containing an organization’s exposed, outward-facing services. It acts as the exposed point to an untrusted network, commonly the Internet.

The goal of a DMZ is to add an extra layer of security to an organization’s local area network. A protected and monitored network node that faces outside the internal network can access what is exposed in the DMZ, while the rest of the organization’s network is safe behind a firewall.

When implemented properly, a DMZ Network gives organizations extra protection in detecting and mitigating security breaches before they reach the internal network, where valuable assets are stored.

the Internet and the private network and, if its design is effective, allows the organization extra time to detect and address breaches before they would further penetrate into the internal networks (https://www.barracuda.com/glossary/dmz-network).

The purpose of a DMZ…

The DMZ Network exists to protect the hosts most vulnerable to attack. These hosts usually involve services that extend to users outside of the local area network, the most common examples being email, web servers, and DNS servers.

In this practical we will perform the following tasks:

Creating a Virtual Private Cloud(VPC).

Creating an Internet Gateway for VPC.

Creating a Public Subnet within our VPC.

Creating a Private Subnet within our VPC.

Creating a route table for Public Subnet.

Creating an association between the Route table and Public Subnet.

Creating an Elastic IP address for NAT gateway.

Creating a NAT Gateway.

Creating a route table for Private Subnet.

Creating an association between the Route table and Private Subnet.

Creating a Security Group for Web-App(Web page).

Creating a Security Group for Database(MariaDB).

Creating a Key-Pair for AWS EC2 instances.

Creating a Database EC2 instance(containing MariaDB).

Creating a Web-App EC2 instance(containing an Apache test Web page).

Modifying the Web page Configuration file.

Providing the Key to Web page Instance(Public Subnet) to SSH to Database Instance(Private Subnet).

For simplicity and modification for your environment please visit my GitHub and feel free to copy and paste into your environment and make the modifications necessary. When I receive errors I scour the internet for valid files and change them to fit the needs of the deployment I am aiming for.

Next, we will head to a code editor such as Visual Studio Code and ensure that you have the terraform extension downloaded and installed.

Step-1: Configure AWS CLI

Please find the above info from your AWS account IAM section under security credentials.

Step-2: Create a terraform file (provider.tf)

I am creating a provider.tf file and coding our cloud provider, i.e., AWS. I am choosing the availability zone (N. Virginia — us-east-1) with my AWS CLI profile name “default”.

provider.tf

Step-3: Creating a Virtual Private Cloud(VPC).

Amazon Virtual Private Cloud (Amazon VPC) is an isolated network that enables us to provision AWS resources.

aws_vpc.tf

Step-4: Creating an Internet Gateway for VPC.

An internet gateway is a VPC resource that allows communication between our VPC and the public internet. An internet gateway serves two purposes: to provide a target in our VPC route tables for internet-routable traffic and to perform network address translation (NAT) for instances that have been assigned public IPv4 addresses.

aws_internet_gateway.tf

Step-5: Creating a Public Subnet within our VPC.

Here we will create a Public subnet for Web-App(Apache test page).

aws_public_subnet.tf

Step-6: Creating a Private Subnet within our VPC.

Here we have created a Private subnet for Database(MariaDB).

aws_private_subnet.tf

Step-7: Creating a Route Table for Public Subnet.

A route table contains a set of rules, called routes, that are used to determine where network traffic from our subnet or gateway is directed. This route table is for inbound traffic to VPC through an internet gateway where our Ec2 instance will reside and the test page will be exposed to the internet through a NAT gateway.

aws_route_table_igw.tf

Step-8: Creating an association between the Route table and Public Subnet.

Each subnet in our VPC must be associated with a route table. A subnet can be explicitly associated with a custom route table or implicitly or explicitly associated with the main route table.

aws_route_assoc_public.tf

Step-9: Creating an Elastic IP address for NAT gateway.

Here we have created an Elastic IP Address for NAT Gateway so that we could establish outbound connectivity for the database instance in the private subnet.

aws_eip.tf

Step-10: Creating a NAT Gateway.

Here we are creating the NAT Gateway in the public subnet to establish the outbound connectivity to the AWS EC2 instances in the private subnet.

aws_nat_gateway.tf

Step-11: Creating a route table for Private Subnet.

Here we are creating a route table for the EC2 instances in the private subnet. You must have separate route tables for your private subnets.

aws_route_table_nat.tf

Step-12: Creating an association between the Route table and Private Subnet.

Here we explicitly associating the route table with the private subnet.

aws_route_assoc_private.tf

Step-13: Creating a Security Group (firewall) for Web-App:

Next, we are going to create a security group for our Web-App EC2 instance which will allow all SSH, ICMP, HTTP, HTTPS inbound traffic as well as all outbound traffic.

aws_security_group_wp.tf

Step-14: Creating a Security Group for Database(MariaDB).

We are going to create a security group for our Database EC2 instance which will allow all SSH inbound traffic from the public subnet as well as all outbound traffic from the internet.

aws_security_group_db.tf

Step-15: Creating a Key-Pair for AWS EC2 instances.

Here we have created a key-pair using Terraform tls_private_key generates a secure RSA 4096 bit private key and encodes it as PEM. This resource is primarily intended for easily bootstrapping throwaway development environments. This is a logical resource, so it contributes only to the current Terraform state and does not create any external managed resources. I learned this through this lab if you see my previous project I generated a key and imported using the terraform import command.

aws_key_pair.tf

Step-16: Creating a Database EC2 instance(containing MariaDB).

We will launch the Database EC2 instance before the Web EC2 instance because our Web Ec2 needed the Database in the background. If we do not launch the Database before our web page then our web page will not connect to the Database.

Aws_ec2_database.tf

Terraform is supposed to know the sequential order of creation so that you do not receive an error. However, from time to time you may need to run the terraform apply twice or check the order of creation of your resources.

Step-17: Creating a Web-App EC2 instance(containing a web page).

We are launching the web page (apache test page) EC2 Instance.

aws_ec2_web page.tf

Step-18: Modifying the Web Page Configuration file.

We have to provide the private IP of Database EC2 instance which is also the MySQL Hostname, to the Web page configuration file to store the data in our database present in Private Subnet.

Step 19: Providing the Key to the web page Instance(Public Subnet) to SSH to Database Instance(Private Subnet).

To access our Database Remotely from Public Subnet as the database instance is kept in the private subnet. So, we have to provide the private key to the web page EC2 instance to SSH to Database Instance.

key_to_web page.tf

Step-20: Initiate the working directory with Terraform Command

The terraform init command is used to initialize a working directory containing Terraform configuration files. This is the first command that should be run after writing a new Terraform configuration or cloning an existing one from version control.

terraform init

Step-21: Validate the terraform files

The terraform validate command validates the configuration files in a directory, referring only to the configuration and not accessing any remote services. Validate runs checks that verify whether a configuration is syntactically valid and internally consistent, regardless of any provided variables or existing state.

terraform validate

Step-22: Apply all the changes

The terraform apply command is used to apply the changes or the pre-determined set of actions generated by a terraform plan execution plan. The — auto-approve option helps us to skip the approval part where the terraform program prompts us whether to continue or cancel the process.

terraform apply — auto-approve

It will initiate the process of the creation of all the resources one by one.

After creating or modifying the changes, it will provide the output, i.e., the Public IP of the web page EC2 Instance and Private IP of Database EC2 Instance and it will launch the web page with the link to the Database stored in the private subnet.

Next, let’s navigate to your AWS account, and let’s verify a few resources and you can continue to verify ALL of them in your environment to ensure successful creation.

Our instances have created let’s test the apache test we page.

The test page successfully loads 😬.

Under your VPC services, you will see your VPC has created and I want you to pay special attention o the Nat Gateway that has been created along with the elastic Ip and it’s been associated with this resource.

I don’t want to overemphasize the point that all of our resources have created successfully and extend this lab any further than it already is 😂.

Finally, the beauty of automation is that it is really easy to destroy this infrastructure with one command.

  • Terraform destroy 🗣

….and it all comes down another hands-on lab complete!

--

--

Bmwitcher

DevSecOps Professional — AWS Certified DevOps Professional/Security Specialty/SA Pro, Gitlab Certified, Terraform Associate GCP-ACE Certfied and more…