Launching AWS VPC, Public and Private Subnets using Terraform

Launching AWS VPC, Public and Private Subnets using Terraform

Task Description:-

1) Write a Infrastructure as code using terraform, which automatically create a VPC.

2) In that VPC we have to create 2 subnets:

  a) public subnet [ Accessible for Public World! ] 

  b) private subnet [ Restricted for Public World! ]

3) Create a public facing internet gateway for connect our VPC/Network to the internet world and attach this gateway to our VPC.

4) Create a routing table for Internet gateway so that instance can connect to outside world, update and associate it with public subnet.

5) Launch an ec2 instance which has Wordpress setup already having the security group allowing port 80 so that our client can connect to our wordpress site.

6) Launch an ec2 instance which has MYSQL setup already with security group allowing port 3306 in private subnet so that our wordpress vm can connect with the same.

Note: Wordpress instance is a part of public subnet so that our client can connect our site and MYSQL instance is a part of private subnet so that outside world can't connect to it.

Terraform Code :-

Provider -

Firstly, we will provide the Provider to the Terraform which is aws along with region and profile.

provider "aws" {
  region     = "ap-south-1"
  profile    = "yashika"
}

VPC -

We created a VPC that has certain range of IP address's which is also known as CIDR. This will be provided to the subnets.

Here, I am providing the IP address range or CIDR = 192.168.0.0/16

resource "aws_vpc" "vpc_task3" {
  cidr_block       = "192.168.0.0/16"
  instance_tenancy = "default"
  enable_dns_hostnames = true
  enable_dns_support = true


  tags = {
    Name = "vpc_task3"
  }
  
}


Now, we have to create two Subnets - one is Public and one is Private.

Public Subnet -

This Subnet is connected to the internet. This Subnet is launched in the availability zone ap-south-1a to launch the Wordpress. Also enable the auto public ip assign so that client can access the site.

resource "aws_subnet" "public_subnet" {
  vpc_id     = aws_vpc.vpc_task3.id
  cidr_block = "192.168.0.0/24"
  availability_zone = "ap-south-1a"
  map_public_ip_on_launch = true
  tags = {
    Name = "public_subnet"
  } 
}

Private Subnet -

This Subnet is not conneted to internet so that the MYSQL in it is secure and cannot be access by the outside. It is in the availability zone ap-south-1b region.

resource "aws_subnet" "private_subnet" {
  vpc_id     = aws_vpc.vpc_task3.id
  cidr_block = "192.168.1.0/24"
  availability_zone = "ap-south-1b"
  tags = {
    Name =  "private_subnet"
  }
}

Internet Gateway -

Next we created an internet gateway so that our public subnet can connect to outside world and client can access the Wordpress site.

resource "aws_internet_gateway" "igw_task3" {
  vpc_id = aws_vpc.vpc_task3.id




  tags = {
    Name = "igw_task3"
  }
}

Route Tables -

Creating a route table. A route table contains a set of rules, called routes, that are used to determine where network traffic from your subnet or gateway is directed. Also we have to associate the route table to our public subnet so that it can know where is the internet gateway to connect to the outside world.

resource "aws_route_table" "route_task3" {
  vpc_id = aws_vpc.vpc_task3.id




  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw_task3.id
  }


  tags = {
    Name = "task3_routeTable"
  }
}



resource "aws_route_table_association" "route_assosciation" {
  subnet_id      = aws_subnet.public_subnet.id     
  route_table_id = aws_route_table.route_task3.id
}

AMI -

For launching instances in the subnets we used our own created AMI which has docker and httpd installed. It also has docker images - wordpress:5.1.1-php7.3-apache and mysql:5.7

No alt text provided for this image

Mysql Instance -

We launched an instance in the private subnet using our own AMI. We will launch a docker container for MYSQL inside this instance.

The security group for MYSQL instance - two inbound rules, one for port 3306 as mysql runs on this port and another port 8080 as we will use this port to expose our mysql docker container.

resource "aws_instance" "mysql" {
  ami           = "ami-0b2bbc9c1b51a5544"
  instance_type = "t2.micro"
  subnet_id = aws_subnet.private_subnet.id
  key_name = "mykey"
  
  vpc_security_group_ids = [  aws_security_group.sg1.id ]
  user_data = <<-EOF
      
	#!/bin/bash
	sudo docker run -dit -e MYSQL_ROOT_PASSWORD=redhat -e MYSQL_DATABASE=mydb -e MYSQL_USER=yashika  -e MYSQL_PASSWORD=redhat -p 8080:3306 --name mysqlos mysql:5.7


  EOF


  tags = {
    Name = "mysql"
  }
}

Security Group :-

resource "aws_security_group" "sg1" {
  name        = "sg1"
  description = "Allow TCP inbound traffic"
  vpc_id      = aws_vpc.vpc_task3.id




  ingress {
    description = "TLS from VPC"
    from_port   = 3306
    to_port     = 3306
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }




  ingress {
    description = "TLS from VPC"
    from_port   = 8080
    to_port     = 8080
    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 = "mysql_http"
  }
}

Wordpress Instance -

We launched another instance in the public subnet for the WordPress. But again for this we have first create a security group which allows port 80 since WordPress runs on port 80. Then we launch EC2 instance using my AMI inside which we launch docker container for the WordPress.

resource "aws_instance" "wordpress1"{
 
 ami = "ami-0b2bbc9c1b51a5544"
  instance_type = "t2.micro"
  subnet_id = aws_subnet.public_subnet.id
  key_name = "mykey"
  vpc_security_group_ids = [ aws_security_group.wp.id ]
  user_data = <<-EOF
        #!/bin/bash
        sudo docker run -dit -p 8000:80 --name wp wordpress:5.1.1-php7.3-apache


  EOF


  tags = {
    Name = "wordpress1"
  }
}

Security Group :-

resource "aws_security_group" "wp" {
  name        = "wp"
  description = "Allow TLS inbound traffic"
  vpc_id      = aws_vpc.vpc_task3.id




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




  ingress {
    description = "TLS from VPC"
    from_port   = 8000
    to_port     = 8000
    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 = "allow_wp"
  }
}

Now to download the required plugins we will run the following command -

terraform init
No alt text provided for this image

For creating the whole infrastructure, run the following command -

terraform apply --auto-approve
No alt text provided for this image

So now we can access the WordPress using the public IP of the of the Wordpress instance, which stores all its data in the MYSQL which is running in the private subnet so that our data is secure.

We can see all the deployments in our AWS Management Console -

VPC
No alt text provided for this image
SUBNETS
No alt text provided for this image
INTERNET GATEWAY
No alt text provided for this image
ROUTE TABLE
No alt text provided for this image
INSTANCES
No alt text provided for this image
SECURITY GROUPS
No alt text provided for this image
No alt text provided for this image

After entering the IP of Wordpress, we have to do the setup.

No alt text provided for this image
No alt text provided for this image
No alt text provided for this image
No alt text provided for this image
No alt text provided for this image

GitHub Link:-

THANK YOU !!

To view or add a comment, sign in

More articles by Yashika Khandelwal

Insights from the community

Others also viewed

Explore topics