Task 3: Launching AWS VPC, Public and Private Subnets using Terraform

Task 3: Launching AWS VPC, Public and Private Subnets using Terraform

Task Description:-

1) Write an Infrastructure as code using Terraform, which automatically creates 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 connecting our VPC/Network to the internet world and attach this gateway to our VPC.

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

5) Launch an ec2 instance that 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 that has MYSQL set up already with the security group allowing port 3306 in a 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 the outside world can't connect to it.

Terraform Code :-

1. 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 = "tanmay2"
}
        

2. VPC -

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

Here, we are providing the IP address range or CIDR = 192.168.0.0/16

resource "aws_vpc" "myvpc" {
  cidr_block           = "192.168.0.0/16"
  instance_tenancy     = "default"
  enable_dns_hostnames = true
}
        
No alt text provided for this image

3. 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" "subnet1" {
  vpc_id                  = aws_vpc.myvpc.id
  cidr_block              = "192.168.0.0/24"
  availability_zone       = "ap-south-1a"
  map_public_ip_on_launch = true


  tags = {
    Name = "subnet_public"
  }
}
        
No alt text provided for this image

4. Private Subnet -

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

resource "aws_subnet" "subnet2" {
  vpc_id            = aws_vpc.myvpc.id
  cidr_block        = "192.168.1.0/24"
  availability_zone = "ap-south-1b"


  tags = {
    Name = "subnet_private"
  }
}
        
No alt text provided for this image

5. Internet Gateway -

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

resource "aws_internet_gateway" "gw" {
  vpc_id = aws_vpc.myvpc.id


  tags = {
    Name = "IGw"
  }
}
        
No alt text provided for this image

6. Route Tables -

Created 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" {
  vpc_id = aws_vpc.myvpc.id


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


  tags = {
    Name = "route"
  }
}




resource "aws_route_table_association" "asso" {
  subnet_id      = aws_subnet.subnet1.id
  route_table_id = aws_route_table.route.id
}
        
No alt text provided for this image

7. MySQL AMI using snapshot -

First, we launched an instance manually using Amazon Linux AMI, then installed docker and httpd, then pulled MySQL image from docker. Run following commands sequentially :

#sudo su - root

#yum install docker

#systemctl start docker

#systemctl enable docker

#yum install httpd

#systemctl start httpd

#systemctl enable httpd

#yum install mysql

#docker pull mysql:5.7

Then we created a snapshot using this instance and then our own AMI using this snapshot.

No alt text provided for this image

8. 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-0f443923b22ba17c3"
  instance_type     = "t2.micro"
  availability_zone = "ap-south-1b"
  subnet_id         = aws_subnet.subnet2.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=***** -e MYSQL_DATABASE=data -e MYSQL_USER=tanmay -e MYSQL_PASSWORD=***** -p 8080:3306 --name dbos mysql:5.7
  EOF
  
  tags = {
    Name = "mysql1"
  }
}
        
No alt text provided for this image

Security Group for MySQL instance:

resource "aws_security_group" "sg1" {
  name          = "sg1"
  description   = "Allow tcp inbound traffic"
  vpc_id        = aws_vpc.myvpc.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 = "mysqlhttp"
  }
}
        

9. WordPress Instance -

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

resource "aws_instance" "wordpress"{
  ami                         = "ami-0f443923b22ba17c3"
  instance_type               = "t2.micro"
  availability_zone           = "ap-south-1a"
  associate_public_ip_address = "true"
  subnet_id                   = aws_subnet.subnet1.id
  key_name                    = "mykey"
  vpc_security_group_ids      = [ aws_security_group.wp1.id ]
  connection {
    type        = "ssh"
    user        = "ec2-user"
    private_key = file("C:/Users/dell/Downloads/mykey.pem")
    host        = aws_instance.wordpress.public_ip
  }




  provisioner "remote-exec" {
    inline = [
      "sudo yum install docker -y",
      "sudo service docker start",
      "sudo docker pull wordpress:5.1.1-php7.3-apache",
      "sudo docker run -dit -e WORDPRESS_DB_HOST=${aws_instance.mysql.private_ip}:8080 -e WORDPRESS_DB_USER=tanmay -e WORDPRESS_DB_PASSWORD=***** -e WORDPRESS_DB_NAME=data -p 8000:80 --name mywp wordpress:5.1.1-php7.3-apache"
    ]
  }


  tags = {
    Name = "wordpress1"
  }
}
        
No alt text provided for this image

Security Group for WordPress instance:

resource "aws_security_group" "wp1" {
  name          = "wp1"
  description   = "Allow tcp inbound traffic"
  vpc_id        = aws_vpc.myvpc.id


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


  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   = 22
    to_port     = 22
    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 = "wphttp"
  }
}
        

Now we will run our terraform code, run the following commands in the windows command prompt.

1. terraform init (it will download necessary plugins from the internet)

No alt text provided for this image

2. terraform validate (it will check the syntax and keyword error in our code)

No alt text provided for this image

3. terraform apply -auto-approve (it will run our terraform code without asking permission "yes")

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

OUTPUT :

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

1.Select the desired language and click on continue.

No alt text provided for this image

2. Fill in the details, set username and password, and install WordPress.

No alt text provided for this image

3. Login to WordPress.

No alt text provided for this image

We are in.

No alt text provided for this image


Thank You !!!



To view or add a comment, sign in

More articles by Tanmay Sharma

Insights from the community

Others also viewed

Explore topics