Ad Code

Responsive Advertisement

Ticker

6/recent/ticker-posts

Sep-06-AWS-Day-09-AWS-Private-Link

 VPCE(VPC Endpoint Service) Realtime(Private Link).

Steps:

Please refer the below script before start the activity



#!/bin/bash

# Set variables
VPC_CIDR="10.0.0.0/16"
PUBLIC_SUBNET_CIDR="10.0.1.0/24"
PRIVATE_SUBNET_CIDR="10.0.2.0/24"
REGION="us-east-1"
KEY_NAME="test"
INSTANCE_TYPE="t2.micro"
AMI_ID="ami-0182f373e66f89c85"  # Amazon Linux 2 AMI for the region
VPC_NAME="PrivateLinkVPC-Prod"
IGW_NAME="IGW-Prod"
PUBLIC_SUBNET_NAME="PublicSubnet-Prod"
PRIVATE_SUBNET_NAME="PrivateSubnet-Prod"
RT_PUBLIC_NAME="PublicRT-Prod"
RT_PRIVATE_NAME="PrivateRT-Prod"
SEC_GROUP_NAME="WebSG-Prod"
INSTANCE_PRIVATE_NAME="PrivateWebServer-Prod"
INSTANCE_PUBLIC_NAME="PublicWebServer-Prod"
VPCE_NAME="VPCE-Prod"
NAT_GW_NAME="NATGW-Prod"
EIP_NAME="ElasticIP-Prod"

# Create a VPC
echo "Creating VPC..."
VPC_ID=$(aws ec2 create-vpc \
    --cidr-block $VPC_CIDR \
    --region $REGION \
    --query 'Vpc.VpcId' \
    --output text)
echo "VPC ID: $VPC_ID"

# Assign a name to the VPC
aws ec2 create-tags --resources $VPC_ID --tags Key=Name,Value=$VPC_NAME
echo "VPC named: $VPC_NAME"

# Enable DNS support and DNS hostnames
aws ec2 modify-vpc-attribute --vpc-id $VPC_ID --enable-dns-support
aws ec2 modify-vpc-attribute --vpc-id $VPC_ID --enable-dns-hostnames

# Create a public subnet
echo "Creating public subnet..."
PUBLIC_SUBNET_ID=$(aws ec2 create-subnet \
    --vpc-id $VPC_ID \
    --cidr-block $PUBLIC_SUBNET_CIDR \
    --availability-zone ${REGION}a \
    --query 'Subnet.SubnetId' \
    --output text)
echo "Public Subnet ID: $PUBLIC_SUBNET_ID"

# Tag the public subnet
aws ec2 create-tags --resources $PUBLIC_SUBNET_ID --tags Key=Name,Value=$PUBLIC_SUBNET_NAME
echo "Public Subnet named: $PUBLIC_SUBNET_NAME"

# Create a private subnet
echo "Creating private subnet..."
PRIVATE_SUBNET_ID=$(aws ec2 create-subnet \
    --vpc-id $VPC_ID \
    --cidr-block $PRIVATE_SUBNET_CIDR \
    --availability-zone ${REGION}a \
    --query 'Subnet.SubnetId' \
    --output text)
echo "Private Subnet ID: $PRIVATE_SUBNET_ID"

# Tag the private subnet
aws ec2 create-tags --resources $PRIVATE_SUBNET_ID --tags Key=Name,Value=$PRIVATE_SUBNET_NAME
echo "Private Subnet named: $PRIVATE_SUBNET_NAME"

# Create an Internet Gateway and attach it to the VPC
echo "Creating Internet Gateway..."
IGW_ID=$(aws ec2 create-internet-gateway \
    --query 'InternetGateway.InternetGatewayId' \
    --output text)
aws ec2 attach-internet-gateway --vpc-id $VPC_ID --internet-gateway-id $IGW_ID
echo "Internet Gateway ID: $IGW_ID"

# Tag the Internet Gateway
aws ec2 create-tags --resources $IGW_ID --tags Key=Name,Value=$IGW_NAME
echo "Internet Gateway named: $IGW_NAME"

# Create a route table for the public subnet and associate it
echo "Creating route table for public subnet..."
PUBLIC_ROUTE_TABLE_ID=$(aws ec2 create-route-table \
    --vpc-id $VPC_ID \
    --query 'RouteTable.RouteTableId' \
    --output text)
aws ec2 create-route --route-table-id $PUBLIC_ROUTE_TABLE_ID --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID
aws ec2 associate-route-table --subnet-id $PUBLIC_SUBNET_ID --route-table-id $PUBLIC_ROUTE_TABLE_ID
echo "Public Route Table ID: $PUBLIC_ROUTE_TABLE_ID"

# Tag the public route table
aws ec2 create-tags --resources $PUBLIC_ROUTE_TABLE_ID --tags Key=Name,Value=$RT_PUBLIC_NAME
echo "Public Route Table named: $RT_PUBLIC_NAME"

# Create a security group for the web server
echo "Creating security group..."
SECURITY_GROUP_ID=$(aws ec2 create-security-group \
    --vpc-id $VPC_ID \
    --group-name $SEC_GROUP_NAME \
    --description "Security group for web server in production" \
    --query 'GroupId' \
    --output text)
echo "Security Group ID: $SECURITY_GROUP_ID"

# Tag the security group
aws ec2 create-tags --resources $SECURITY_GROUP_ID --tags Key=Name,Value=$SEC_GROUP_NAME
echo "Security Group named: $SEC_GROUP_NAME"

# Allow inbound SSH and HTTP traffic
aws ec2 authorize-security-group-ingress --group-id $SECURITY_GROUP_ID --protocol tcp --port 22 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id $SECURITY_GROUP_ID --protocol tcp --port 80 --cidr 0.0.0.0/0

# Create an Elastic IP for the NAT Gateway
echo "Creating Elastic IP for NAT Gateway..."
EIP_ALLOC_ID=$(aws ec2 allocate-address --query 'AllocationId' --output text)
echo "Elastic IP Allocation ID: $EIP_ALLOC_ID"

# Tag the Elastic IP
aws ec2 create-tags --resources $EIP_ALLOC_ID --tags Key=Name,Value=$EIP_NAME
echo "Elastic IP named: $EIP_NAME"

# Create a NAT Gateway in the public subnet
echo "Creating NAT Gateway in public subnet..."
NAT_GW_ID=$(aws ec2 create-nat-gateway \
    --subnet-id $PUBLIC_SUBNET_ID \
    --allocation-id $EIP_ALLOC_ID \
    --query 'NatGateway.NatGatewayId' \
    --output text)
echo "NAT Gateway ID: $NAT_GW_ID"

# Tag the NAT Gateway
aws ec2 create-tags --resources $NAT_GW_ID --tags Key=Name,Value=$NAT_GW_NAME
echo "NAT Gateway named: $NAT_GW_NAME"

# Wait for the NAT Gateway to become available
echo "Waiting for NAT Gateway to become available..."
aws ec2 wait nat-gateway-available --nat-gateway-ids $NAT_GW_ID
echo "NAT Gateway is available."

# Create a route table for the private subnet and associate it
echo "Creating route table for private subnet..."
PRIVATE_ROUTE_TABLE_ID=$(aws ec2 create-route-table \
    --vpc-id $VPC_ID \
    --query 'RouteTable.RouteTableId' \
    --output text)
aws ec2 associate-route-table --subnet-id $PRIVATE_SUBNET_ID --route-table-id $PRIVATE_ROUTE_TABLE_ID
echo "Private Route Table ID: $PRIVATE_ROUTE_TABLE_ID"

# Tag the private route table
aws ec2 create-tags --resources $PRIVATE_ROUTE_TABLE_ID --tags Key=Name,Value=$RT_PRIVATE_NAME
echo "Private Route Table named: $RT_PRIVATE_NAME"

# Add a route to the private route table for internet traffic via the NAT Gateway
echo "Creating route in private route table for internet access via NAT Gateway..."
aws ec2 create-route --route-table-id $PRIVATE_ROUTE_TABLE_ID --destination-cidr-block 0.0.0.0/0 --nat-gateway-id $NAT_GW_ID
echo "Route to NAT Gateway added in private route table."



# Launch an EC2 instance in the public subnet
echo "Launching EC2 instance in public subnet..."
INSTANCE_PUBLIC_ID=$(aws ec2 run-instances \
    --image-id $AMI_ID \
    --instance-type $INSTANCE_TYPE \
    --key-name $KEY_NAME \
    --subnet-id $PUBLIC_SUBNET_ID \
    --security-group-ids $SECURITY_GROUP_ID \
    --associate-public-ip-address \
    --query 'Instances[0].InstanceId' \
    --output text)
echo "Public EC2 Instance ID: $INSTANCE_PUBLIC_ID"

# Tag the private EC2 instance
aws ec2 create-tags --resources $INSTANCE_PUBLIC_ID --tags Key=Name,Value=$INSTANCE_PUBLIC_NAME
echo "Private EC2 instance named: $INSTANCE_PUBLIC_NAME"

# Launch an EC2 instance in the private subnet
echo "Launching EC2 instance in private subnet..."
INSTANCE_PRIVATE_ID=$(aws ec2 run-instances \
    --image-id $AMI_ID \
    --instance-type $INSTANCE_TYPE \
    --key-name $KEY_NAME \
    --subnet-id $PRIVATE_SUBNET_ID \
    --security-group-ids $SECURITY_GROUP_ID \
    --query 'Instances[0].InstanceId' \
    --output text)
echo "Private EC2 Instance ID: $INSTANCE_PRIVATE_ID"

# Tag the private EC2 instance
aws ec2 create-tags --resources $INSTANCE_PRIVATE_ID --tags Key=Name,Value=$INSTANCE_PRIVATE_NAME
echo "Private EC2 instance named: $INSTANCE_PRIVATE_NAME"


Step-1:

Open cloudshell by searching in search button of aws portal:

Copy the variable's content like below.

# Set variables
VPC_CIDR="10.0.0.0/16"
PUBLIC_SUBNET_CIDR="10.0.1.0/24"
PRIVATE_SUBNET_CIDR="10.0.2.0/24"
REGION="us-east-1"
KEY_NAME="test"
INSTANCE_TYPE="t2.micro"
AMI_ID="ami-0182f373e66f89c85"  # Amazon Linux 2 AMI for the region
VPC_NAME="PrivateLinkVPC-Prod"
IGW_NAME="IGW-Prod"
PUBLIC_SUBNET_NAME="PublicSubnet-Prod"
PRIVATE_SUBNET_NAME="PrivateSubnet-Prod"
RT_PUBLIC_NAME="PublicRT-Prod"
RT_PRIVATE_NAME="PrivateRT-Prod"
SEC_GROUP_NAME="WebSG-Prod"
INSTANCE_PRIVATE_NAME="PrivateWebServer-Prod"
INSTANCE_PUBLIC_NAME="PublicWebServer-Prod"
VPCE_NAME="VPCE-Prod"
NAT_GW_NAME="NATGW-Prod"
EIP_NAME="ElasticIP-Prod"

Step-2:

Verify the variables:

[cloudshell-user@ip-10-134-46-239 ~]$ echo $VPC_NAME

PrivateLinkVPC-Prod

Step-3:

Create a vpc:

# Create a VPC
echo "Creating VPC..."
VPC_ID=$(aws ec2 create-vpc \
    --cidr-block $VPC_CIDR \
    --region $REGION \
    --query 'Vpc.VpcId' \
    --output text)
echo "VPC ID: $VPC_ID"

# Assign a name to the VPC
aws ec2 create-tags --resources $VPC_ID --tags Key=Name,Value=$VPC_NAME
echo "VPC named: $VPC_NAME"
# Enable DNS support and DNS hostnames
aws ec2 modify-vpc-attribute --vpc-id $VPC_ID --enable-dns-support
aws ec2 modify-vpc-attribute --vpc-id $VPC_ID --enable-dns-hostnames


Step-4:
Create a subnets(Private & Public):
# Create a public subnet
echo "Creating public subnet..."
PUBLIC_SUBNET_ID=$(aws ec2 create-subnet \
    --vpc-id $VPC_ID \
    --cidr-block $PUBLIC_SUBNET_CIDR \
    --availability-zone ${REGION}a \
    --query 'Subnet.SubnetId' \
    --output text)
echo "Public Subnet ID: $PUBLIC_SUBNET_ID"

# Tag the public subnet
aws ec2 create-tags --resources $PUBLIC_SUBNET_ID --tags Key=Name,Value=$PUBLIC_SUBNET_NAME
echo "Public Subnet named: $PUBLIC_SUBNET_NAME"

# Create a private subnet
echo "Creating private subnet..."
PRIVATE_SUBNET_ID=$(aws ec2 create-subnet \
    --vpc-id $VPC_ID \
    --cidr-block $PRIVATE_SUBNET_CIDR \
    --availability-zone ${REGION}a \
    --query 'Subnet.SubnetId' \
    --output text)
echo "Private Subnet ID: $PRIVATE_SUBNET_ID"

# Tag the private subnet
aws ec2 create-tags --resources $PRIVATE_SUBNET_ID --tags Key=Name,Value=$PRIVATE_SUBNET_NAME
echo "Private Subnet named: $PRIVATE_SUBNET_NAME"


Step-5:

Create IGW & public route tables & SG's

# Create an Internet Gateway and attach it to the VPC
echo "Creating Internet Gateway..."
IGW_ID=$(aws ec2 create-internet-gateway \
    --query 'InternetGateway.InternetGatewayId' \
    --output text)
aws ec2 attach-internet-gateway --vpc-id $VPC_ID --internet-gateway-id $IGW_ID
echo "Internet Gateway ID: $IGW_ID"

# Tag the Internet Gateway
aws ec2 create-tags --resources $IGW_ID --tags Key=Name,Value=$IGW_NAME
echo "Internet Gateway named: $IGW_NAME"

# Create a route table for the public subnet and associate it
echo "Creating route table for public subnet..."
PUBLIC_ROUTE_TABLE_ID=$(aws ec2 create-route-table \
    --vpc-id $VPC_ID \
    --query 'RouteTable.RouteTableId' \
    --output text)
aws ec2 create-route --route-table-id $PUBLIC_ROUTE_TABLE_ID --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID
aws ec2 associate-route-table --subnet-id $PUBLIC_SUBNET_ID --route-table-id $PUBLIC_ROUTE_TABLE_ID
echo "Public Route Table ID: $PUBLIC_ROUTE_TABLE_ID"

# Tag the public route table
aws ec2 create-tags --resources $PUBLIC_ROUTE_TABLE_ID --tags Key=Name,Value=$RT_PUBLIC_NAME
echo "Public Route Table named: $RT_PUBLIC_NAME"

# Create a security group for the web server
echo "Creating security group..."
SECURITY_GROUP_ID=$(aws ec2 create-security-group \
    --vpc-id $VPC_ID \
    --group-name $SEC_GROUP_NAME \
    --description "Security group for web server in production" \
    --query 'GroupId' \
    --output text)
echo "Security Group ID: $SECURITY_GROUP_ID"

# Tag the security group
aws ec2 create-tags --resources $SECURITY_GROUP_ID --tags Key=Name,Value=$SEC_GROUP_NAME
echo "Security Group named: $SEC_GROUP_NAME"

# Allow inbound SSH and HTTP traffic
aws ec2 authorize-security-group-ingress --group-id $SECURITY_GROUP_ID --protocol tcp --port 22 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id $SECURITY_GROUP_ID --protocol tcp --port 80 --cidr 0.0.0.0/0

Step-6:

Create NAT with EIP & Private route tables:

# Create an Elastic IP for the NAT Gateway
echo "Creating Elastic IP for NAT Gateway..."
EIP_ALLOC_ID=$(aws ec2 allocate-address --query 'AllocationId' --output text)
echo "Elastic IP Allocation ID: $EIP_ALLOC_ID"

# Tag the Elastic IP
aws ec2 create-tags --resources $EIP_ALLOC_ID --tags Key=Name,Value=$EIP_NAME
echo "Elastic IP named: $EIP_NAME"

# Create a NAT Gateway in the public subnet
echo "Creating NAT Gateway in public subnet..."
NAT_GW_ID=$(aws ec2 create-nat-gateway \
    --subnet-id $PUBLIC_SUBNET_ID \
    --allocation-id $EIP_ALLOC_ID \
    --query 'NatGateway.NatGatewayId' \
    --output text)
echo "NAT Gateway ID: $NAT_GW_ID"

# Tag the NAT Gateway
aws ec2 create-tags --resources $NAT_GW_ID --tags Key=Name,Value=$NAT_GW_NAME
echo "NAT Gateway named: $NAT_GW_NAME"

# Wait for the NAT Gateway to become available
echo "Waiting for NAT Gateway to become available..."
aws ec2 wait nat-gateway-available --nat-gateway-ids $NAT_GW_ID
echo "NAT Gateway is available."

# Create a route table for the private subnet and associate it
echo "Creating route table for private subnet..."
PRIVATE_ROUTE_TABLE_ID=$(aws ec2 create-route-table \
    --vpc-id $VPC_ID \
    --query 'RouteTable.RouteTableId' \
    --output text)
aws ec2 associate-route-table --subnet-id $PRIVATE_SUBNET_ID --route-table-id $PRIVATE_ROUTE_TABLE_ID
echo "Private Route Table ID: $PRIVATE_ROUTE_TABLE_ID"

# Tag the private route table
aws ec2 create-tags --resources $PRIVATE_ROUTE_TABLE_ID --tags Key=Name,Value=$RT_PRIVATE_NAME
echo "Private Route Table named: $RT_PRIVATE_NAME"

# Add a route to the private route table for internet traffic via the NAT Gateway
echo "Creating route in private route table for internet access via NAT Gateway..."
aws ec2 create-route --route-table-id $PRIVATE_ROUTE_TABLE_ID --destination-cidr-block 0.0.0.0/0 --nat-gateway-id $NAT_GW_ID
echo "Route to NAT Gateway added in private route table."





Step-7:

Create an Bastion Ec2 machine:

# Launch an EC2 instance in the public subnet
echo "Launching EC2 instance in public subnet..."
INSTANCE_PUBLIC_ID=$(aws ec2 run-instances \
    --image-id $AMI_ID \
    --instance-type $INSTANCE_TYPE \
    --key-name $KEY_NAME \
    --subnet-id $PUBLIC_SUBNET_ID \
    --security-group-ids $SECURITY_GROUP_ID \
    --associate-public-ip-address \
    --query 'Instances[0].InstanceId' \
    --output text)
echo "Public EC2 Instance ID: $INSTANCE_PUBLIC_ID"

# Tag the private EC2 instance
aws ec2 create-tags --resources $INSTANCE_PUBLIC_ID --tags Key=Name,Value=$INSTANCE_PUBLIC_NAME
echo "Private EC2 instance named: $INSTANCE_PUBLIC_NAME"


SSH into the Bastion.

shiva@BhagathSingh MINGW64 ~/Downloads
$ ssh -i test.pem ec2-user@54.234.109.58

before performing any activity we need private subnet machine.

Step-8:

Create an Private Ec2 machine:

Name: Private ec2 machine
Keypair: Choose your key pair
Ensure network configuration is same like below


Step:9:
Access the private machine from bastion:

Before we need to configure the keypair in bastion machine 

touch test.pem + vi test.pem(Paste the content in this file) + wq!
chmod 400 test.pem


Step-10:

Setup a webserver for testing.

[ec2-user@ip-10-0-2-192 ~]$ sudo systemctl status httpd
● httpd.service - The Apache HTTP Server
     Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; preset: disabled)
     Active: active (running) since Thu 2024-09-05 18:25:02 UTC; 5s ago
       Docs: man:httpd.service(8)
   Main PID: 25806 (httpd)
     Status: "Started, listening on: port 80"
      Tasks: 177 (limit: 1112)
     Memory: 12.9M
        CPU: 65ms
     CGroup: /system.slice/httpd.service
             ├─25806 /usr/sbin/httpd -DFOREGROUND
             ├─25807 /usr/sbin/httpd -DFOREGROUND
             ├─25808 /usr/sbin/httpd -DFOREGROUND
             ├─25809 /usr/sbin/httpd -DFOREGROUND
             └─25810 /usr/sbin/httpd -DFOREGROUND

Sep 05 18:25:02 ip-10-0-2-192.ec2.internal systemd[1]: Starting httpd.service - The Apache HTTP Server...
Sep 05 18:25:02 ip-10-0-2-192.ec2.internal systemd[1]: Started httpd.service - The Apache HTTP Server.
Sep 05 18:25:02 ip-10-0-2-192.ec2.internal httpd[25806]: Server configured, listening on: port 80
[ec2-user@ip-10-0-2-192 ~]$ history
    1  yum install httpd
    2  sudo yum install httpd
    3  sudo systemctl enable httpd
    4  sudo systemctl start httpd
    5  sudo systemctl status httpd

From public machine try to access private ip of private subnet machine it should work like below

[root@ip-10-0-1-165 ~]# curl 10.0.2.192
Private link demo
[root@ip-10-0-1-165 ~]#


Step-11:

Create a target group for NLB:





Click on create TG

Now Create NLB:





Copy the DNS for testing

Make sure TG is Healthy:


Verify the NLB DNS from Bastion:


Step-12:

Create VPCE(Private link):

Click on Create VPCE

Copy the VPCE Service Name


Step-13:

Create VPC Endpoint:


After ensure in VPCE service you need to accept the endpoint like below





Now lunch a machine in VPC2 to access the endpoint service securely.

Ensure you can lunch a new machine in VPC2 

Step-14:

Finally test private communication

Copy the DNS name go to the VPC2 machine and curl the private dns name which you copied






Post a Comment

0 Comments

Ad Code

Responsive Advertisement