Search code examples
amazon-web-servicesaws-cloudformationamazon-vpccidr

Standard formula to determine or calculate Cidr for VPC in AWS


I am learning AWS CloudFormation. Now, I am trying to create a template for VPC and Subnets. I am now creating a VPC.

This is my template:

AWSTemplateFormatVersion: '2010-09-09'
Description: "Template for Networks and IAM Roles"
Resources:
  Vpc:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: '10.0.0.0/16'
      EnableDnsHostnames: True
      EnableDnsSupport: True

What I don't understand here is that CidrBlock. Now, I specified it as, 10.0.0.0/16. To be honest, how does it work exactly. Is setting it as 10.0.0.0/16 always going to work? What is that for? How does that IP address range work exactly? How does it help? How can I determine which value to set for it? Is there a formula to calculate it? How? I saw an existing VPC in my console. The IP address is different.

Also, how can I calculate to split it to assign to subnets?

I am seeking an understanding of the following template, especially Cidr for subnets.

AWSTemplateFormatVersion: '2010-09-09'
Description: "Template for Networks and IAM Roles"
Parameters:
  VpcCidr:
    Default: '10.0.0.0/16'
    Type: String
    AllowedPattern: '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})'
Resources:
  Vpc:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      EnableDnsHostnames: True
      EnableDnsSupport: True
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 0, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      MapPublicIpOnLaunch: True
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref "AWS::Region"
  PublicSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref Vpc
      CidrBlock: !Select [ 1, !Cidr [ !Ref VpcCidr, 12, 8 ] ]
      MapPublicIpOnLaunch: True
      AvailabilityZone: !Select
        - 0
        - Fn::GetAZs: !Ref "AWS::Region"

Solution

  • There are way too many sub-questions to answer each of them individually here. Instead I can write this.

    CIDRs for VPC are selected from three common ranges:

    • 10.0.0.0 - 10.255.255.255 (10/8 prefix)

    • 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)

    • 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)

    These ranges are used because they are not-routable over the internet.

    10.0.0.0/16 - is the most commonly used CIDR used for VPC. This give you 65535 private IP addresses to work with in your VPC.

    You commonly divide it to subnets of size /24, each with 255 private addresses. For example:

    • 10.0.1.0/24
    • 10.0.2.0/24
    • 10.0.3.0/24
    • 10.0.4.0/24

    If you use the above pattern for VPC and subnets, you don't have to do any calculations or memorize any formals. Of course if you want to have more specific subnets, or subnets of different sizes, you have to learn how to calculate subnets. There are many resources and tools on the internet for that. Examples are:

    Update

    The template uses intristic function Fn::Cidr.

    The construct:

     !Cidr [ !Ref VpcCidr, 12, 8 ]
    

    Will create a list of 12 CIDR ranges, of size of /24 (32-8). Each subnet will have 255 addresses. The Select is used to chose individual CIDRs from the list:

    !Select [ 0, !Cidr [ !Ref VpcCidr, 12, 8 ] ] # 10.0.0.0/24 
    !Select [ 1, !Cidr [ !Ref VpcCidr, 12, 8 ] ] # 10.0.1.0/24
    !Select [ 2, !Cidr [ !Ref VpcCidr, 12, 8 ] ] # 10.0.2.0/24
    !Select [ 11, !Cidr [ !Ref VpcCidr, 12, 8 ] ] # 10.0.11.0/24