How to secure AWS VPC using public and private subnets

Key takeaways:

  • Security in AWS is a shared responsibility: AWS secures the cloud infrastructure while customers secure their resources within it.

  • Public subnets are for resources that require internet access, like web servers, and connect directly via an internet gateway.

  • Private subnets are for resources that shouldn’t have direct internet access, like databases, and use NAT gateways for controlled data exchange.

  • Route tables manage traffic rules, ensuring proper routing between subnets, internet gateways, and NAT gateways.

  • Security groups and Network Access Control Lists (NACLs) add extra layers of security to control traffic flow at instance and subnet levels.

  • Proper configuration of subnets and gateways ensures both security and efficient communication between resources.

According to the AWS Shared Responsibility model, security and compliance are achieved by the joint effort of the customer and the cloud service provider. As a general rule, the security of the cloud is the responsibility of the service provider, which in our case is AWS. However, security in the cloud is the customer’s responsibility, which can be achieved by creating private and public subnets inside our VPC.

Resources that can be made available to cloud users without any security threat can be placed inside a public subnet. However, those resources that shouldn’t be given direct access via the internet are kept inside private subnets and secured with a Network Access Control List — NACLSubnet level security which contains rules to control inbound and outbound traffic., and NAT gatewayA VPC component that allows instances within a private subnet to connect to external services. applied at the subnet level.

Public subnets

A subnet is a subset of allowed IP addresses inside the VPC. We can place AWS resources like EC2 instances inside subnets and assign them an IP address from the range allowed in that subnet. Public subnets can access the public internet directly via the Internet gatewayA VPC component that allows communication with the internet.. The internet gateway is associated with a route table that contains rules allowing or denying incoming or outgoing traffic. This route table will always contain a route to the internet gateway. Keeping resources that require public access inside public subnets is a good security practice. For example, if we were running a web server on an EC2 instance that has to be accessed by people all across the globe, then it’s safe to place it here.

EC2 placed inside a public subnet
EC2 placed inside a public subnet

Private subnets

A private subnet is similar to a public subnet accept that it is not directly connected with the internet gateway to inhibit direct access to the resources within it by the world outside. A simple example could be a database server or an S3 storage bucket. Instead, these resources exchange data with the World Wide Web using the NAT gateway—the NAT gateway is placed in a public subnet, as shown below.

Private subnet
Private subnet

If a device inside the private subnet requests data from the internet, the request is first forwarded to the NAT gateway, and the NAT gateway sends it to the internet gateway. The internet gateway directs the data back from the internet to the NAT gateway, which further redirects it to the device that requested it. For this communication to occur, we must ensure that incoming traffic to the public subnet is allowed from the private one in our Network Access Control List (NACL). We must also update our private subnet’s route table to ensure internet traffic travels to the NAT gateway. We could use security groups at the instance level inside both public and private subnets for added security. They control both inbound and outbound traffic from that instance.

Try it yourself

Let's create a VPC with public and a private subnet in us-east-1.

# Define CIDR blocks and region
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"

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

# Create a public subnet
PUBLIC_SUBNET_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $PUBLIC_SUBNET_CIDR --query 'Subnet.SubnetId' --output text --region $REGION)

# Create a private subnet
PRIVATE_SUBNET_ID=$(aws ec2 create-subnet --vpc-id $VPC_ID --cidr-block $PRIVATE_SUBNET_CIDR --query 'Subnet.SubnetId' --output text --region $REGION)

# Create an Internet Gateway
IGW_ID=$(aws ec2 create-internet-gateway --query 'InternetGateway.InternetGatewayId' --output text --region $REGION)

# Attach the Internet Gateway to the VPC
aws ec2 attach-internet-gateway --vpc-id $VPC_ID --internet-gateway-id $IGW_ID --region $REGION

# Create a route table for the public subnet
PUBLIC_ROUTE_TABLE_ID=$(aws ec2 create-route-table --vpc-id $VPC_ID --query 'RouteTable.RouteTableId' --output text --region $REGION)

# Create a route to the Internet Gateway in the public route table
aws ec2 create-route --route-table-id $PUBLIC_ROUTE_TABLE_ID --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID --region $REGION

# Associate the public subnet with the route table
aws ec2 associate-route-table --subnet-id $PUBLIC_SUBNET_ID --route-table-id $PUBLIC_ROUTE_TABLE_ID --region $REGION

# Enable auto-assign public IP on the public subnet
aws ec2 modify-subnet-attribute --subnet-id $PUBLIC_SUBNET_ID --map-public-ip-on-launch --region $REGION

# Print the IDs of created resources
echo "VPC ID: $VPC_ID"
echo "Public Subnet ID: $PUBLIC_SUBNET_ID"
echo "Private Subnet ID: $PRIVATE_SUBNET_ID"
echo "Internet Gateway ID: $IGW_ID"
echo "Public Route Table ID: $PUBLIC_ROUTE_TABLE_ID"
Bash script to create public ans private subnets

Explanation

Lets take a look at the above line by line:

Line 2–5: Create the CIDR blocks for the VPC, public subnet, and private subnet, as well as the AWS region where these resources will be created.

  • Line 11: Creates a Virtual Private Cloud (VPC) with the specified CIDR block. The VPC ID is extracted from the response and stored in the VPC_ID variable.

  • Line 14: Creates a private subnet within the VPC using the specified CIDR block. The subnet ID is extracted and stored in the PRIVATE_SUBNET_ID variable.

  • Line 17: Creates an Internet Gateway (IGW). The IGW ID is extracted and stored in the IGW_ID variable.

  • Line 20: Attaches the created Internet Gateway to the VPC, enabling internet access for the resources in the VPC.

  • Line 23: Creates a route table for the VPC. The route table ID is extracted and stored in the PUBLIC_ROUTE_TABLE_ID variable.

  • Line 26: Adds a route to the route table, directing all traffic destined for the internet (0.0.0.0/0) to the Internet Gateway.

  • Line 29: Associates the public subnet with the created route table, enabling the subnet to use the routes defined in the table.

  • Line 32: Configures the public subnet to automatically assign public IP addresses to instances launched within it.

  • Line 35–39: Echoes the IDs of the created VPC, public subnet, private subnet, Internet Gateway, and public route table, providing a summary of the resources created by the script.

Conclusion

In conclusion, AWS provides several ways to secure resources and services. One is partitioning our VPC into private and public subnets and then securing them with VPC components like NAT, internet gateways, NACL, and security groups.

Frequently asked questions

Haven’t found what you were looking for? Contact Us


Why would a VPC use private and public subnets?

To separate resources that require internet access (public subnets) from those that need restricted access, like databases (private subnets), ensuring security and efficient resource management.


How do I create a secure VPC?

By partitioning it into private and public subnets, using components like NAT gateways, internet gateways, route tables, NACLs, and security groups to control traffic and restrict access.


Can AWS VPC have multiple subnets?

Yes, a VPC can have multiple subnets, both public and private, to segregate resources across different availability zones for security and scalability.


Free Resources

Copyright ©2025 Educative, Inc. All rights reserved