You are currently viewing How To Create A Custom VPC Using AWS CLI

How To Create A Custom VPC Using AWS CLI

How to create a custom VPC using AWS CLI

Hello Everyone

Welcome to CloudAffaire and this is Debjeet.

In the last blog post, we have discussed how to configure AWS CLI.

In this blog post, we will discuss how to create a custom VPC using AWS CLI. We will create one VPC, one subnet, one internet gateway, one security group and one route table.

Prerequisite for this demo:

  • One Linux instance with AWS CLI installed and configured.

How to create a custom VPC using AWS CLI:

Step 1: Configure AWS CLI.

Step 2: Create a VPC.

Step 3: Modify your custom VPC and enable DNS hostname.

Step 4: Create a subnet.

Step 5: Enable Auto-assign Public IP on the subnet.

Step 6: Create an Internet Gateway.

Step 7: Attach the Internet gateway to your VPC.

Step 8: Create a custom route table.

Step 9: Create a route to Internet Gateway in your custom route table.

Step 10: Associate the subnet with route table, making it a public subnet.

Step 11: Create a custom security group.

Step 12: Get security group ID’s.

Step 13: Create ingress rules for your custom security group.

Step 14: Add tags to the resources in your VPC.

Cleanup (Do not delete, if you want to continue with next demo):

Hope you have enjoyed this article. In the next blog post, we will create an EC2 instance in our VPC.

To get more details on AWS CLI, please refer below AWS documentation


This Post Has 3 Comments

  1. Avatar

    Here is a bash script to do this and even support deletion.

    set -eo pipefail

    write_vpc_to_file() {
    echo $AWS_VPC >> $vpcs_file

    ([[ ! -z $(tail -n 1 $vpcs_file) ]] && $[[ $(tail -n 1 $vpcs_file | tr -cd ‘ \t’ | wc -c ) != 8 ]]) && echo “Something went wrong with the last vpc creation and not all of the required information is available. You need to delete and re-create the last VPC before creating a new one.” && exit

    if [[ $1 == “–create” ]]; then

    [[ -z $2 ]] && echo “ARG 2 (after –create) needs to be the availability zone you want the VPC in” && exit

    trap write_vpc_to_file EXIT

    ## Create a VPC
    AWS_VPC_ID=$(aws ec2 create-vpc \
    –cidr-block \
    –query ‘Vpc.{VpcId:VpcId}’ \
    –output text)

    ## Enable DNS hostname for your VPC
    aws ec2 modify-vpc-attribute \
    –vpc-id $AWS_VPC_ID \
    –enable-dns-hostnames “{\”Value\”:true}”

    ## Create a public subnet
    AWS_SUBNET_PUBLIC_ID=$(aws ec2 create-subnet \
    –vpc-id $AWS_VPC_ID –cidr-block \
    –availability-zone $AZ –query ‘Subnet.{SubnetId:SubnetId}’ \
    –output text)

    ## Enable Auto-assign Public IP on Public Subnet
    aws ec2 modify-subnet-attribute \
    –subnet-id $AWS_SUBNET_PUBLIC_ID \

    ## Create an Internet Gateway
    AWS_INTERNET_GATEWAY_ID=$(aws ec2 create-internet-gateway \
    –query ‘InternetGateway.{InternetGatewayId:InternetGatewayId}’ \
    –output text)

    ## Attach Internet gateway to your VPC
    aws ec2 attach-internet-gateway \
    –vpc-id $AWS_VPC_ID \
    –internet-gateway-id $AWS_INTERNET_GATEWAY_ID

    ## Create a route table
    AWS_CUSTOM_ROUTE_TABLE_ID=$(aws ec2 create-route-table \
    –vpc-id $AWS_VPC_ID \
    –query ‘RouteTable.{RouteTableId:RouteTableId}’ \
    –output text)

    ## Create route to Internet Gateway
    aws ec2 create-route \
    –route-table-id $AWS_CUSTOM_ROUTE_TABLE_ID \
    –destination-cidr-block \
    –gateway-id $AWS_INTERNET_GATEWAY_ID

    ## Associate the public subnet with route table
    AWS_ROUTE_TABLE_ASSOID=$(aws ec2 associate-route-table \
    –subnet-id $AWS_SUBNET_PUBLIC_ID \
    –route-table-id $AWS_CUSTOM_ROUTE_TABLE_ID \
    –output text | head -1)

    ## Create a security group
    aws ec2 create-security-group \
    –vpc-id $AWS_VPC_ID \
    –group-name myvpc-security-group \
    –description ‘My VPC non default security group’

    ## Get security group ID’s
    AWS_DEFAULT_SECURITY_GROUP_ID=$(aws ec2 describe-security-groups \
    –filters “Name=vpc-id,Values=$AWS_VPC_ID” \
    –query ‘SecurityGroups[?GroupName == default].GroupId’ \
    –output text)

    AWS_CUSTOM_SECURITY_GROUP_ID=$(aws ec2 describe-security-groups \
    –filters “Name=vpc-id,Values=$AWS_VPC_ID” \
    –query ‘SecurityGroups[?GroupName == myvpc-security-group].GroupId’ \
    –output text)

    ## Create security group ingress rules
    aws ec2 authorize-security-group-ingress \
    –ip-permissions ‘[{“IpProtocol”: “tcp”, “FromPort”: 22, “ToPort”: 22, “IpRanges”: [{“CidrIp”: “”, “Description”: “Allow SSH”}]}]’

    aws ec2 authorize-security-group-ingress \
    –ip-permissions ‘[{“IpProtocol”: “tcp”, “FromPort”: 80, “ToPort”: 80, “IpRanges”: [{“CidrIp”: “”, “Description”: “Allow HTTP”}]}]’

    ## Add a tag to the VPC
    aws ec2 create-tags \
    –resources $AWS_VPC_ID \
    –tags “Key=Name,Value=myvpc”

    ## Add a tag to public subnet
    aws ec2 create-tags \
    –resources $AWS_SUBNET_PUBLIC_ID \
    –tags “Key=Name,Value=myvpc-public-subnet”

    ## Add a tag to the Internet-Gateway
    aws ec2 create-tags \
    –resources $AWS_INTERNET_GATEWAY_ID \
    –tags “Key=Name,Value=myvpc-internet-gateway”

    ## Add a tag to the default route table
    AWS_DEFAULT_ROUTE_TABLE_ID=$(aws ec2 describe-route-tables \
    –filters “Name=vpc-id,Values=$AWS_VPC_ID” \
    –query ‘RouteTables[?Associations[0].Main != flase].RouteTableId’ \
    –output text)

    aws ec2 create-tags \
    –resources $AWS_DEFAULT_ROUTE_TABLE_ID \
    –tags “Key=Name,Value=myvpc-default-route-table”

    ## Add a tag to the public route table
    aws ec2 create-tags \
    –resources $AWS_CUSTOM_ROUTE_TABLE_ID \
    –tags “Key=Name,Value=myvpc-public-route-table”

    ## Add a tags to security groups
    aws ec2 create-tags \
    –tags “Key=Name,Value=myvpc-security-group”

    aws ec2 create-tags \
    –tags “Key=Name,Value=myvpc-default-security-group”

    elif [[ $1 == “–delete” ]]; then

    AWS_VPC=$(tail -n 1 $vpcs_file)
    [[ -z $AWS_VPC ]] && echo “nothing to delete!” && exit

    AWS_VPC_ID=$(echo $AWS_VPC | cut -d ‘ ‘ -f1)
    AWS_CUSTOM_SECURITY_GROUP_ID=$(echo $AWS_VPC | cut -d ‘ ‘ -f7)
    AWS_INTERNET_GATEWAY_ID=$(echo $AWS_VPC | cut -d ‘ ‘ -f3)
    AWS_ROUTE_TABLE_ASSOID=$(echo $AWS_VPC | cut -d ‘ ‘ -f5)
    AWS_CUSTOM_ROUTE_TABLE_ID=$(echo $AWS_VPC | cut -d ‘ ‘ -f4)
    AWS_SUBNET_PUBLIC_ID=$(echo $AWS_VPC | cut -d ‘ ‘ -f2)

    ## Delete custom security group
    aws ec2 delete-security-group \
    –group-id $AWS_CUSTOM_SECURITY_GROUP_ID || true

    ## Delete internet gateway
    aws ec2 detach-internet-gateway \
    –internet-gateway-id $AWS_INTERNET_GATEWAY_ID \
    –vpc-id $AWS_VPC_ID || true

    aws ec2 delete-internet-gateway \
    –internet-gateway-id $AWS_INTERNET_GATEWAY_ID || true

    ## Delete the custom route table
    aws ec2 disassociate-route-table \
    –association-id $AWS_ROUTE_TABLE_ASSOID || true

    aws ec2 delete-route-table \
    –route-table-id $AWS_CUSTOM_ROUTE_TABLE_ID || true

    ## Delete the public subnet
    aws ec2 delete-subnet \
    –subnet-id $AWS_SUBNET_PUBLIC_ID || true

    ## Delete the vpc
    aws ec2 delete-vpc \
    –vpc-id $AWS_VPC_ID

    sed -i ” “/$AWS_VPC/d” $vpcs_file

    echo “–create or –delete…”

  2. Avatar

    I am new to aws cli. This site was of great help for me. I have a small question. can someone tell me how to use the –filter option and –query what’s the theory behind it? I can’t seem to find out how to use it for any new requirements.

  3. Avatar
    Don Doerner

    Minor error in both text and script, when identifying the default router. Used ‘flase”, want ‘false’.

Comments are closed.