Deploy Wordpress+Mysql on AWS and Create a NAT Gateway and Bastion host for management.

Deploy Wordpress+Mysql on AWS and Create a NAT Gateway and Bastion host for management.

What is a VPC?

A virtual private cloud (VPC) is an on-demand configurable pool of shared computing resources allocated within a public cloud environment, providing a certain level of isolation between the different organizations using the resources.A virtual private cloud is a private cloud computing environment contained within a public cloud. Essentially, a VPC provisions logically isolated sections of a public cloud in order to provide a virtual private environment.

After creating a VPC, you can add one or more subnets in each Availability Zone. You can optionally add subnets in a Local Zone, which is an AWS infrastructure deployment that places compute, storage, database, and other select services closer to your end users. A Local Zone enables your end users to run applications that require single-digit millisecond latencies.

Task:-

We have to create a web portal for our company with all the security as much as possible.

So, we use Wordpress software with dedicated database server.

Database should not be accessible from the outside world for security purposes.

We only need to public the WordPress to clients.

So here are the steps for proper understanding!

Steps:

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. Create a NAT gateway for connect our VPC/Network to the internet world and attach this gateway to our VPC in the public network

6. Update the routing table of the private subnet, so that to access the internet it uses the nat gateway created in the public subnet

7. Launch an ec2 instance which has Wordpress setup already having the security group allowing port 80 sothat our client can connect to our wordpress site. Also attach the key to instance for further login into it.

8. 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. Also attach the key with the same.


Note: Wordpress instance has to be part of public subnet so that our client can connect our site. 

mysql instance has to be part of private subnet so that outside world can't connect to it.

Don't forgot to add auto ip assign and auto dns name assignment option to be enabled.

Solution:-

No alt text provided for this image



Step 1:-

First we will login to our AWS account using :

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

Step 2:-

Now create a VPC with dns_hostnames as enabled.

resource "aws_vpc" "myvpc1" {
  cidr_block = "192.168.0.0/16"
  enable_dns_hostnames = "true"


  tags = {
    Name = "MyVpc"
  }

}

Step 3:-

Now we have to create 2 subnets.

(i) Public for Wordpress site.

(ii)Private for MySql .

resource "aws_subnet" "public_subnet" {
  depends_on = [
    aws_vpc.myvpc1,
  ]
  vpc_id     = aws_vpc.myvpc1.id
  cidr_block = "192.168.2.0/24"
  availability_zone = "ap-south-1a"
  map_public_ip_on_launch = "true"


  tags = {
    Name = "Public Subnet"
  }
}


resource "aws_subnet" "private_subnet" {
  depends_on = [
    aws_vpc.myvpc1,
  ]
  vpc_id     = aws_vpc.myvpc1.id
  cidr_block = "192.168.1.0/24"
  availability_zone = "ap-south-1b"


  tags = {
    Name = "Private Subnet"
  }
}

Step 4:-

Now our Subnets are created, we have to create a Public facing Internet gateway and attach it to our VPC for outside connectivity.

resource "aws_internet_gateway" "gw" {
  depends_on = [
    aws_vpc.myvpc1,
  ]
  vpc_id = aws_vpc.myvpc1.id


  tags = {
    Name = "Internet gateway"
  }
}

Step 5:-

Now we have to create a routing table for Internet gateway so that instance can connect to outside world, update and associate it with public subnet.

resource "aws_route_table" "my_route_table1" {
  depends_on = [
    aws_vpc.myvpc1,
  ]
  vpc_id = aws_vpc.myvpc1.id


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


  
  tags = {
    Name = "Routing Table"
  }
}


resource "aws_route_table_association" "Route_association" {
  depends_on = [
    aws_route_table.my_route_table1,
  ]
  subnet_id      = aws_subnet.public_subnet.id
  route_table_id = aws_route_table.my_route_table1.id
}

Step 6:-

Now, we create a NAT Gateway in public subnet and attach it to private subnet.

You can use a network address translation (NAT) gateway to enable instances in a private subnet to connect to the internet or other AWS services, but prevent the internet from initiating a connection with those instances. 

//Creating Elastic IP

resource "aws_eip" "myeip" {


  vpc      = true


  depends_on = [aws_internet_gateway.gw,]


}
//Creating NAT Gateway

resource "aws_nat_gateway" "nat_gateway" {


  depends_on = [aws_vpc.myvpc1]


  allocation_id = aws_eip.myeip.id


  subnet_id     = aws_subnet.public_subnet.id


  tags = {


    Name = "nat gateway"


    }


}


// Create Routing Table for NGW


resource "aws_route_table" "nat_routing_table" {


    depends_on = [aws_vpc.myvpc1]


    vpc_id = aws_vpc.myvpc1.id


    route {


    cidr_block = "0.0.0.0/0"


    nat_gateway_id = aws_nat_gateway.nat_gateway.id


  }


    tags = {


        Name = "nat routing table"


    }


}


//AWS_Route_Table_Association for NAT Gateway


resource "aws_route_table_association" "nat_route_asction" {


    depends_on = [ aws_subnet.private_subnet, aws_nat_gateway.nat_gateway ]


    subnet_id = aws_subnet.private_subnet.id


    route_table_id = aws_route_table.nat_routing_table.id


}

Step 7:-

we have to create a security group for Wordpress allowing port 80.

resource "aws_security_group" "Wordpress_sg" {


  name        = "Wordpress_sg"
  description = "Allow Tcp $ Ssh inbound traffic"
  vpc_id      = aws_vpc.myvpc1.id
  


  ingress {
    description = "Ssh"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
 ingress {
    description = "http"
    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 = "allow_SSh_http"
  }
}


also create a security group form MySql allowing port 3306 for wordpress.

resource "aws_security_group" "MySql_sg" {
  name        = "MySq_sg"
  description = "Allow Wordpress inbound traffic"
  vpc_id      = aws_vpc.myvpc1.id
  


  
 ingress {
    description = "Allow MySql"
    from_port   = 3306
    to_port     = 3306
    protocol    = "tcp"
    
  }
 ingress {
    description = "Ssh"
    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 = "allow_MySql"
  }
}

and Security group for Bastion host

resource "aws_security_group" "Bastion_host_sg" {


  name        = "Bastion_host_sg"
  description = "Allow Tcp $ Ssh inbound traffic"
  vpc_id      = aws_vpc.myvpc1.id
  


  ingress {
    description = "Ssh"
    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 = "allow_SSh"
  }
}

Step 8:-

Now , we create a instance for Wordpress in public subnet

//Creating AWS instance for MySql
resource "aws_instance" "mysql"{
   depends_on = [
    aws_vpc.myvpc1,aws_security_group.MySql_sg,aws_route_table_association.nat_route_asction,
  ]
ami   = "ami-0e306788ff2473ccb"
instance_type = "t2.micro"
vpc_security_group_ids = [ aws_security_group.MySql_sg.id]
subnet_id = aws_subnet.private_subnet.id
user_data = <<-EOF
#!/bin/bash
sudo yum update -y
sudo yum install docker -y
sudo systemctl start docker
sudo systemctl enable docker
sudo su root
docker run -dit -p 80:3306 --name mysql -e MYSQL_ROOT_PASSWORD=pushkar121 -e MYSQL_DATABASE=DB -e MYSQL_USER=pushkar -e MYSQL_PASSWORD=redhat mysql:5.6
EOF
tags = {
 Name = "MySqlOS"
  }

and a instance for MySql

//Creating AWS instance for MySql
resource "aws_instance" "mysql"{
   depends_on = [
    aws_vpc.myvpc1,aws_security_group.MySql_sg,aws_route_table_association.nat_route_asction,
  ]
ami   = "ami-0e306788ff2473ccb"
instance_type = "t2.micro"
vpc_security_group_ids = [ aws_security_group.MySql_sg.id]
subnet_id = aws_subnet.private_subnet.id
user_data = <<-EOF
#!/bin/bash
sudo yum update -y
sudo yum install docker -y
sudo systemctl start docker
sudo systemctl enable docker
sudo su root
docker run -dit -p 80:3306 --name mysql -e MYSQL_ROOT_PASSWORD=pushkar121 -e MYSQL_DATABASE=DB -e MYSQL_USER=pushkar -e MYSQL_PASSWORD=redhat mysql:5.6
EOF
tags = {
 Name = "MySqlOS"
  }

}

also a instance for bastion host

resource "aws_instance" "Bastion_host" {
  depends_on = [
    aws_vpc.myvpc1,aws_security_group.Bastion_host_sg,
  ]
  ami = "ami-0e306788ff2473ccb"
  instance_type = "t2.micro"
  key_name = var.mykey
  associate_public_ip_address = true
  subnet_id = aws_subnet.public_subnet.id
  availability_zone = "ap-south-1a"
  vpc_security_group_ids = [ aws_security_group.Bastion_host_sg.id]
 
  tags = {
    Name = "bastion"
  }
}



resource "null_resource" "nullremote2"  {
  depends_on = [
    aws_instance.webpage,
  ]



provisioner "local-exec" {
      command = "start chrome  ${aws_instance.webpage.public_ip}"
    }
}

Finally with the local provisioner the wordpress site will automatically open in chrome in our machine.

To run this program first run:

terraform init

After that:

terraform apply

and to delete this complete infrastructure:

terraform destroy

Proof of Work:-

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
No alt text provided for this image
No alt text provided for this image
No alt text provided for this image




To view or add a comment, sign in

More articles by Pushkar Kumar

Explore content categories