Create a web portal on AWS through terraform also provide internet access to private subnet

Problem Statement

So here are the steps that we need to follow :

Bastion Host ?

Terraform Code:

1. We are using aws as provider so we need to setup region and profile.

provider “aws” {
region = “ap-south-1”
profile = “aditya”
}

2. Create the key pair.

resource “tls_private_key” “adikey” {
algorithm = “RSA”
}
resource “aws_key_pair” “generated_key” {
key_name = “adikey”
public_key = “${tls_private_key.adikey.public_key_openssh}”

depends_on = [
tls_private_key.adikey
]
}

resource “local_file” “key-file” {
content = “${tls_private_key.adikey.private_key_pem}”
filename = “adikey.pem”

depends_on = [
tls_private_key.adikey
]
}

3. Create the VPC.

resource “aws_vpc” “myVPC” {
cidr_block = “192.168.0.0/16”
instance_tenancy = “default”
enable_dns_hostnames = “true”
tags = {
Name = “myVPC”
}
}

//Elastic IP

resource “aws_eip” “elastic_ip” {
vpc = true
}

4. Create two subnets.

// Public Subnet

resource “aws_subnet” “My_Public_Subnet” {
vpc_id = “${aws_vpc.myVPC.id}”
availability_zone = “ap-south-1a”
cidr_block = “192.168.1.0/24”
map_public_ip_on_launch = true
tags = {
Name = “My_Public_Subnet”
}
}

//Private Subnet

resource “aws_subnet” “my_subnet_private” {
vpc_id = “${aws_vpc.myVPC.id}”
availability_zone = “ap-south-1b”
cidr_block = “192.168.2.0/24”
tags = {
Name = “my_subnet_private”
}
}

5. Create the Internet Gateway

resource “aws_nat_gateway” “nat_gateway” {
allocation_id = “${aws_eip.elastic_ip.id}”
subnet_id = “${aws_subnet.My_Public_Subnet.id}”
depends_on = [ aws_nat_gateway.nat_gateway ]
}

6. Create the route table.

resource “aws_route_table” “my_route_table” {
vpc_id = “${aws_vpc.myVPC.id}”
route {
cidr_block = “0.0.0.0/0”
gateway_id = “${aws_internet_gateway.My_IG.id}”
}
tags = {
Name = “my_route_table”
}
}

resource “aws_route_table” “nat_gateway_route” {
vpc_id = “${aws_vpc.myVPC.id}”
route {
cidr_block = “0.0.0.0/0”
gateway_id = “${aws_nat_gateway.nat_gateway.id}”
}
tags = {
Name = “nat_gateway_route”
}
}

7. Connect the route table to subnet.

//Connect to public subnet

resource “aws_route_table_association” “my_route_table_association” {
subnet_id = aws_subnet.My_Public_Subnet.id
route_table_id = aws_route_table.my_route_table.id
}

// Connect to private subnet

resource “aws_route_table_association” “nat_asso” {
subnet_id = aws_subnet.my_subnet_private.id
route_table_id = aws_route_table.nat_gateway_route.id
}

8. Create Security group for instance.

//Wordpress Security Group

resource “aws_security_group” “Security_Group_Word_Press” {
name = “Security_Group_Word_Press”
description = “Allow HTTP inbound traffic”
vpc_id = “${aws_vpc.myVPC.id}”

ingress {
description = “http”
from_port = 80
to_port = 80
protocol = “tcp”
cidr_blocks = [ “0.0.0.0/0” ]
}
ingress {
description = “ssh”
from_port = 22
to_port = 22
protocol = “tcp”
cidr_blocks = [ “0.0.0.0/0” ]
}
ingress {
description = “https”
from_port = 443
to_port = 443
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 = “Security_Group_Word_Press”
}
}

//Bastion Host Security Group

resource “aws_security_group” “Security_Group_BastionHost” {
name = “Security_Group_BastionHost”
description = “ssh_bh”
vpc_id = “${aws_vpc.myVPC.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 = “Security_Group_BastionHost”
}
}

//MySQL Security Group

resource “aws_security_group” “Security_Group_MySQL” {
name = “Security_Group_MySQL”
description = “mysql”
vpc_id = “${aws_vpc.myVPC.id}”

ingress {
description = “mysql”
from_port = 3306
to_port = 3306
protocol = “tcp”
cidr_blocks = [ “0.0.0.0/0” ]
}
ingress {
description = “ssh”
from_port = 22
to_port = 22
protocol = “tcp”
security_groups = [ “${aws_security_group.Security_Group_BastionHost.id}” ]
}
egress {
from_port = 0
to_port = 0
protocol = “-1”
cidr_blocks = [“0.0.0.0/0”]
}

tags = {
Name = “Security_Group_MySQL”
}
}

9. Launch instances.

//Launch Wordpress Instance

resource “aws_instance” “WP_OS” {
ami = “ami-000cbce3e1b899ebd”
instance_type = “t2.micro”
key_name = aws_key_pair.generated_key.key_name
subnet_id = “${aws_subnet.My_Public_Subnet.id}”
vpc_security_group_ids = [ “${aws_security_group.Security_Group_Word_Press.id}” ]
tags = {

Name = “WPOS”

}
}

//Launch Bastion Host Instance

resource “aws_instance” “BastionHost_OS” {
ami = “ami-0e306788ff2473ccb”
instance_type = “t2.micro”
key_name = aws_key_pair.generated_key.key_name
subnet_id = “${aws_subnet.My_Public_Subnet.id}”
vpc_security_group_ids = [ “${aws_security_group.Security_Group_BastionHost.id}” ]
tags = {

Name = “BastionHostOS”
}
}

//Launch MySQL Instance

resource “aws_instance” “MySQL_OS” {
ami = “ami-0019ac6129392a0f2”
instance_type = “t2.micro”
key_name = aws_key_pair.generated_key.key_name
subnet_id = “${aws_subnet.my_subnet_private.id}”
vpc_security_group_ids = [ “${aws_security_group.Security_Group_MySQL.id}” ]
tags = {

Name = “MySQLOS”
}
}

terraform init

terraform apply -auto-approve

Here is the final output:

Thank You !!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store