AWS VPC with public, private subnets, internet gateway and NAT gateway

AWS VPC with public, private subnets, internet gateway and NAT gateway

VPC(Virtual Private Network)

Amazon Virtual Private Cloud (Amazon VPC) lets you provision a logically isolated section of the AWS Cloud where you can launch AWS resources in a virtual network that you define. You have complete control over your virtual networking environment, including selection of your own IP address range, creation of subnets, and configuration of route tables and network gateways. You can use both IPv4 and IPv6 in your VPC for secure and easy access to resources and applications.

Steps:

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 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.

Pre-requisites:

  • You should have an AWS account,
  • Create an IAM user and download the credentials file in which they have provided the Access and secret key which we use for logging in through CLI.
  • Download AWS CLI and give the path for the same by editing the environment variables.
  • Use the credentials file for logging into AWS using aws configure command.
  • Download terraform and give the path for the same.
  • Create a profile using aws configure –profile ‘profilename’ command. We create a profile because if we want to share our code using some SCM(Source Code Management) Tool we don’t want to reveal the access and secret keys so it’s good practice to create a profile.

So Let's Begin:

Firstly we have to tell terraform about the provider and we can do so by using the following code->

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

Now we have to create our vpc and for doing so we have to provide a range of IP addresses which is also known as CIDR. Here I am providing cidr_block=”192.168.0.0/16”.

We can check form the AWS console that it has been created.

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

  tags = {
    Name = "t4vpc"
  }
}

No alt text provided for this image

Next we have to create two subnets in that VPC one is private and another one is public.

Subnets are a logical partition of an IP network into multiple, smaller network segments. They are like labs in which we can launch AWS resources in any of the specified subnet.

Public Subnet-It is the subnet which is connected to the internet. I have created this subnet in ap-south-1a region. We will launch our WordPress in this subnet and for connectivity we have to assign public IP to the instance and for doing so I have enabled auto assigning of public IP.

resource "aws_subnet" "pubsubnet" {
  vpc_id     =  aws_vpc.tvpc.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 cannot connect to the internet. I have created this subnet in ap-south-1b region. We will launch our MySQL database in this subnet.

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

  tags = {
    Name = "private_subnet"
  }
}

No alt text provided for this image

Now After creating the subnets we will create an Elastip IP for NAT Gateway.

Elastic IP: An Elastic IP address is a static IPv4 address designed for dynamic cloud computing. An Elastic IP address is associated with your AWS account. With an Elastic IP address, you can mask the failure of an instance or software by rapidly remapping the address to another instance in your account.

resource "aws_eip" "elasticip"{
  vpc = true
}

No alt text provided for this image

Now after creating elastic IP we will create the NAT gateway.

NAT Gateway: also known as Network Address Translation Gateway, is used to enable instances present in a private subnet to help connect to the internet or AWS services. In addition to this, the gateway makes sure that the internet doesn't initiate a connection with the instances.

resource "aws_nat_gateway" "nat" {
  allocation_id = aws_eip.elasticip.id
  subnet_id = aws_subnet.pubsubnet.id
  
  tags = {
    Name = "Natgw"
  }
}

No alt text provided for this image

Next we will create an internet gateway.

Internet gateway is a VPC component that helps in establishing a connection between VPC and internet.

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

  tags = {
    Name = "In_gateway"
  }
}

No alt text provided for this image

Now we will create two route tables one for public subnet and another one for private subnet.

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. To put it simply, a route table tells network packets which way they need to go to get to their destination. We have to associate the route tables with the subnets for controlling the routing of the subnets.

resource "aws_route_table" "igwrt" {
  vpc_id =  aws_vpc.tvpc.id
  
  tags = {
    Name = "internet_gw_rt"
  }
}

resource "aws_route" "r1" {
  route_table_id            =  aws_route_table.igwrt.id
  destination_cidr_block    = "0.0.0.0/0"
  gateway_id =  aws_internet_gateway.gw.id
  
}

resource "aws_route_table_association" "rta1" {
  subnet_id      = aws_subnet.pubsubnet.id
  route_table_id = aws_route_table.igwrt.id
}

resource "aws_route_table" "ngwrt" {
  vpc_id =  aws_vpc.tvpc.id
  
  tags = {
    Name = "nat_gw_rt"
  }
}

resource "aws_route" "r2" {
  route_table_id            =   aws_route_table.ngwrt.id
  destination_cidr_block    = "0.0.0.0/0"
  gateway_id =  aws_nat_gateway.nat.id
  
}

resource "aws_route_table_association" "rta2" {
  subnet_id      = aws_subnet.prisubnet.id
  route_table_id = aws_route_table.ngwrt.id
}

No alt text provided for this image

Next we have to launch two instances of WordPress and MySQL . For launching these instances we have to first create a key-pair and also we have to create different security groups for these instances.

Key-pair-A key pair is a combination of a public key that is used to encrypt data and a private key that is used to decrypt data. We need a key-pair to connect to our instances.

resource "aws_key_pair" "key" {
key_name = "mykeyy"
public_key="ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAryh7wbLe3IvfHCLmrc1fbXw1d1dwM7VQN029wAphsKi/gzzWdTLlafUi+Teuo1Ze84sPAb3IxUw5ewwED/N0hTy/7YgvBEX08FTU8X1eH06AtD8Zyf6kAbwXrjO2SGkz/TJ3gebhqfrDu3iYEG1Uo1JKgg284ce8cAd9G3/U5FD/LKdajGmLTAHLIoxp3WHBpRW9ciOK9+JQL9SGnYYF62+++h4fMCc/lyX4A/Sy7UJ7pCFP+ZjsRZ8V6SOXTpy+4PrrdqoDC/NMqs/5pBdBn8ORRk43WjUP8LsvTBEw3AvkMSMgazWl/Ov68tVN3UiwUE9vEQbB0mExsZrixvNYJw== rsa-key-20200713"
}

No alt text provided for this image

Security group-A security group acts as a virtual firewall for your instance to control incoming and outgoing traffic. Inbound rules control the incoming traffic to your instance, and outbound rules control the outgoing traffic from your instance.

Security group for WordPress instance- In this security group I have added two inbound rules, one for port 22(ssh) so that we can connect to our instance through ssh and another of port 80(HTTP) so that we can connect to WordPress through internet. I have allowed all the outbound traffic.

resource "aws_security_group" "wpsg" {
  name        = "wordpress"
  description = "Allow TLS inbound traffic"
  vpc_id      =   aws_vpc.tvpc.id

  ingress {
    description = "ssh"
    from_port   = 0
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    description = "http"
    from_port   = 0
    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 = "wordpress"
  }
}

Security group for MySQL instance- In this security group I have added a port 3306 which is a default port for MySQL protocol. I have also added security group which we use for wordpress instance so we can connect our wordpress instance with mysql instance.

resource "aws_security_group" "mysg" {
  name        = "mysql"
  description = "Allow MYSQL"
  vpc_id      =   aws_vpc.tvpc.id


  ingress {
    description = "MYSQL/Aurora"
    from_port   = 0
    to_port     = 3306
    protocol    = "tcp"
    security_groups = [ aws_security_group.wpsg.id ]
  }
   
   ingress {
    description = "ssh"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    security_groups = [ aws_security_group.wpsg.id ]
  }
 
   egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  

No alt text provided for this image

Now we will create our instances->

For launching an instance I have used the ami(image) of WordPress so that we can directly connect to it. I have attached the security group and the key-pair that I have created and I have launched this instance in public subnet.

resource "aws_instance" "wordpress" {
  ami                  = "ami-000cbce3e1b899ebd"
  instance_type  = "t2.micro"
  key_name        = "mykeyy"
  security_groups =  [aws_security_group.wpsg.id]  
  subnet_id =  aws_subnet.pubsubnet.id
  
  tags = {
    Name = "wordpress-os"
  }
}

Next I have launched an instance with MySQL/Aurora image. I have launched this instance in private subnet and attached the security group and key pair that I have created.

resource "aws_instance" "mysql" {
  ami                  = "ami-08706cb5f68222d09"
  instance_type  = "t2.micro"
  key_name        = "mykeyy"
  security_groups =  [aws_security_group.mysg.id]  
  subnet_id =  aws_subnet.prisubnet.id

  tags = {
    Name = "mysql-os"
  }

No alt text provided for this image

We can download the required plugins using the following command:

terraform init

We can also validate our code using the following command:

terrafrom validate
No alt text provided for this image

We can create the whole infrastructure using the following command:

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

Now after creating the whole infrastructure we will go inside our wordpress instance and then through this instance we can go inside our MySql instance and check whether there is an internet connectivity or not. In this case our wordpress instance would be our Bastion Host/Jump Box.

Bastion Host: A bastion host is a server whose purpose is to provide access to a private network from an external network. Because of its exposure to potential attack, a bastion host must minimize the chances of penetration.

For connecting to our mysql instance through wordpress instance we have to first transfer our key to that instance and for doing so I have used WinSCP.

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

After transferring the key we can connect to our instance but before connecting we have to give the permission to our key to execute and we can do so using the following command:

chmod 400 "key_name"

Now we can login to our mysql instance which is in private subnet and can check the outside connectivity.

No alt text provided for this image

We can successfully connect to internet through our mysql instance due to nat gateway but the outside world cannot connect to our instance.

No alt text provided for this image

We can destroy the complete infrastructure using the following command:

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

Github Repository for the code:

Thank You

要查看或添加评论,请登录

Ridham Dogra的更多文章

  • Launching WordPress integrated with AWS RDS using Kubernetes and Terraform

    Launching WordPress integrated with AWS RDS using Kubernetes and Terraform

    AWS RDS Amazon Relational Database Service (Amazon RDS) makes it easy to set up, operate, and scale a relational…

  • Flutter Media Player

    Flutter Media Player

    Flutter is Google’s UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from…

  • AWS Cloud Automation using Terraform

    AWS Cloud Automation using Terraform

    AWS Amazon Web Services(AWS) is a cloud service from Amazon, that provides on demand cloud computing platform and APIs…

    2 条评论
  • Launching AWS VPC with public and private subnets using Terraform

    Launching AWS VPC with public and private subnets using Terraform

    VPC(Virtual Private Network) Amazon Virtual Private Cloud (Amazon VPC) lets you provision a logically isolated section…

  • Deploy a Webapp over AWS-EKS Cluster

    Deploy a Webapp over AWS-EKS Cluster

    AWS-EKS ?Amazon Elastic Kubernetes Service (EKS) is a managed Kubernetes service that makes it easy for you to run…

    2 条评论
  • Launching Webserver on AWS cloud using Terraform

    Launching Webserver on AWS cloud using Terraform

    AWS Amazon Web Services(AWS) is a cloud service from Amazon, that provides on demand cloud computing platform and APIs…

    6 条评论
  • MlOps :Machine Learning Integrated with DevOps

    MlOps :Machine Learning Integrated with DevOps

    In the machine learning world one of the biggest problem is getting the desired accuracy and for this we have to use…

  • Facial recognition using Transfer learning

    Facial recognition using Transfer learning

    In today's world we have huge amount of data known as big data which creates a problem for us while training our model…

  • Devops Project:2

    Devops Project:2

    PROBLEM STATEMENT: 1. Create container image that’s has Jenkins installed using dockerfile 2.

    4 条评论
  • DevOps Project

    DevOps Project

    DevOps is Development and Operation's Collaboration, It's a Union of Process, People and Working Product that enable…

社区洞察

其他会员也浏览了