0
0
AWScloud~5 mins

Public vs private subnets in AWS - CLI Comparison

Choose your learning style9 modes available
Introduction
When you build a network in the cloud, you need to decide which parts are open to the internet and which parts are kept safe inside. Public subnets let resources talk to the internet directly, while private subnets keep resources hidden and secure, only reachable through special paths.
When you want your web servers to be accessible by anyone on the internet.
When you want your databases to be hidden from the internet for security.
When you need to run backend services that only your app servers can access.
When you want to control internet access for different parts of your application.
When you want to reduce security risks by limiting exposure of sensitive resources.
Config File - vpc-subnets.yaml
vpc-subnets.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: AWS VPC with Public and Private Subnets
Resources:
  MyVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: my-vpc

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: my-igw

  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref MyVPC
      InternetGatewayId: !Ref InternetGateway

  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.1.0/24
      MapPublicIpOnLaunch: true
      AvailabilityZone: us-east-1a
      Tags:
        - Key: Name
          Value: public-subnet

  PrivateSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MyVPC
      CidrBlock: 10.0.2.0/24
      MapPublicIpOnLaunch: false
      AvailabilityZone: us-east-1a
      Tags:
        - Key: Name
          Value: private-subnet

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyVPC
      Tags:
        - Key: Name
          Value: public-rt

  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachGateway
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  PublicSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref PublicRouteTable

  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MyVPC
      Tags:
        - Key: Name
          Value: private-rt

  PrivateSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet
      RouteTableId: !Ref PrivateRouteTable

This file creates a VPC with two subnets: one public and one private.

The InternetGateway connects the VPC to the internet.

The PublicSubnet has MapPublicIpOnLaunch: true so instances get public IPs.

The PublicRouteTable routes internet traffic through the Internet Gateway.

The PrivateSubnet does not assign public IPs and uses a separate route table without internet access.

Commands
This command creates the VPC, subnets, and routing setup from the configuration file.
Terminal
aws cloudformation deploy --template-file vpc-subnets.yaml --stack-name my-vpc-stack
Expected OutputExpected
Waiting for stack create/update to complete... Successfully created/updated stack - my-vpc-stack
--template-file - Specifies the CloudFormation template file to use
--stack-name - Names the CloudFormation stack for management
This command lists the subnets in the created VPC to verify public and private subnets exist.
Terminal
aws ec2 describe-subnets --filters Name=vpc-id,Values=$(aws ec2 describe-vpcs --query 'Vpcs[?Tags[?Key==`Name` && Value==`my-vpc`]].VpcId' --output text)
Expected OutputExpected
{ "Subnets": [ { "SubnetId": "subnet-0a1b2c3d4e5f6g7h8", "VpcId": "vpc-1234567890abcdef0", "CidrBlock": "10.0.1.0/24", "MapPublicIpOnLaunch": true, "AvailabilityZone": "us-east-1a" }, { "SubnetId": "subnet-1h2g3f4e5d6c7b8a9", "VpcId": "vpc-1234567890abcdef0", "CidrBlock": "10.0.2.0/24", "MapPublicIpOnLaunch": false, "AvailabilityZone": "us-east-1a" } ] }
This command shows the route tables to confirm the public subnet routes to the internet gateway and the private subnet does not.
Terminal
aws ec2 describe-route-tables --filters Name=vpc-id,Values=$(aws ec2 describe-vpcs --query 'Vpcs[?Tags[?Key==`Name` && Value==`my-vpc`]].VpcId' --output text)
Expected OutputExpected
{ "RouteTables": [ { "RouteTableId": "rtb-0a1b2c3d4e5f6g7h8", "VpcId": "vpc-1234567890abcdef0", "Routes": [ { "DestinationCidrBlock": "0.0.0.0/0", "GatewayId": "igw-12345678", "State": "active" } ] }, { "RouteTableId": "rtb-1h2g3f4e5d6c7b8a9", "VpcId": "vpc-1234567890abcdef0", "Routes": [ { "DestinationCidrBlock": "10.0.0.0/16", "State": "active" } ] } ] }
Key Concept

Public subnets have a route to the internet gateway and assign public IPs, while private subnets do not, keeping resources isolated from direct internet access.

Common Mistakes
Not attaching the internet gateway to the VPC.
Without the internet gateway attached, public subnets cannot route traffic to the internet.
Always create and attach an internet gateway to your VPC before setting up public subnets.
Setting MapPublicIpOnLaunch to false on public subnets.
Instances launched in the public subnet won't get public IPs and won't be reachable from the internet.
Set MapPublicIpOnLaunch to true for public subnets to assign public IPs automatically.
Assigning a route to the internet gateway in the private subnet's route table.
This exposes private subnet resources to the internet, defeating the purpose of isolation.
Do not add internet gateway routes to private subnet route tables; use NAT gateways if internet access is needed.
Summary
Use CloudFormation to create a VPC with separate public and private subnets.
Public subnets have a route to the internet gateway and assign public IPs to instances.
Private subnets have no direct internet route and do not assign public IPs, keeping resources secure.