An Amazon Web Services (AWS) Virtual Private Cloud (VPC) is a virtual network dedicated to your AWS account. In this post, I will explain how to create an AWS VPC with PowerShell.
Latest posts by David O´Brien (see all)

You can define several VPCs. A VPC pretty much looks and feels like a traditional on-premises network, with subnets, route tables, and gateways, but it benefits from AWS's cloud infrastructure. Virtual Machines (EC2) in particular require a network, but other services such as AWS RDS or AWS Lambda are also now deployable into a VPC. A VPC can be used to communicate with your on-premises network, and VPCs can also communicate with each other via VPC Peering.

Typical AWS VPC design

A typical VPC design includes multiple subnets, routing tables, and usually an internet gateway to enable services in your VPC to communicate with the internet.

Typical AWS VPC

Typical AWS VPC

In this sample design, we see the concept of a public subnet and a private subnet. Technically, the subnets are the same; the public subnet is public because it has an Internet Gateway attached to it and a route table configured that routes to the gateway. EC2 instances deployed into this subnet require public IPs attached to them to communicate to the internet. A private subnet has a route table configured that routes to a NAT Gateway.

Creating an AWS VPC

To follow AWS best practices, we will create the following resources via PowerShell:

  • Internet gateway
  • NAT gateway + AWS elastic IP
  • 2 subnets
    • one private, one public
  • 2 route tables
    • one for each subnet

Note: Every AWS account and region already comes with a default VPC, which is perfectly suitable for getting started quickly. However, it doesn't follow best practices and most users actually delete the default VPCs.

I assume you have already authenticated your PowerShell to your AWS account. If not and you want to know how, just follow this article and then come back to continue with our scenario.

For this article, all resources will be created in the ap-southeast-2 (Sydney, Australia) region. Make sure you select one that fits your use case. We will also ignore the fact that you should build your infrastructure across multiple availability zones (as depicted in the screenshot). Now, we will require the VPC's ID for most of the following steps. We can either just remember it from the cmdlet's output or assign it to a variable. I will opt for the variable.

$vpc = New-EC2Vpc -CidrBlock -Region ap-southeast-2
Creating an AWS VPC

Creating an AWS VPC

Next, we need to create an internet gateway and attach it to the VPC.

$igw = New-EC2InternetGateway
Add-EC2InternetGateway -VpcId $vpc.VpcId -InternetGatewayId $igw.InternetGatewayId
Creating an Internet Gateway

Creating an Internet Gateway

Our new VPC will now have internet connectivity. Right now, however, we don't have any subnets or route tables. We also need to create the NAT gateway in our private subnet. A NAT gateway must always be associated with an AWS elastic IP, which is a public IP address. We can do this all in one go. Creating the NAT gateway might take a couple of minutes, even though PowerShell will complete straightaway. In the AWS Console, you should wait with the next steps until the NAT gateway status changes to available (see the screenshot below).

$publicSubnet = New-EC2Subnet -VpcId $vpc.VpcId -CidrBlock
$privateSubnet = New-EC2Subnet -VpcId $vpc.VpcId -CidrBlock
$eip = New-EC2Address -Domain Vpc
$natgw = New-EC2NatGateway -SubnetId $privateSubnet.SubnetId -AllocationId $eip.AllocationId
Viewing AWS NAT gateway status

Viewing AWS NAT gateway status

These subnets now have enough room to host 251 IPv4 addresses each; for all intents and purposes, they are currently identical. We assigned one subnet to our $publicSubnet variable and the other one to the $privateSubnet variable. We also created an elastic IP address inside our VPC and a NAT gateway inside the private subnet that uses this elastic IP. Next, let's create some route tables and attach them to our subnets. First, we create a route table inside the VPC. Then we add a route and associate it with our subnet.

$publicRouteTable = New-EC2RouteTable -VpcId $vpc.VpcId
$privateRouteTable = New-EC2RouteTable -VpcId $vpc.VpcId
New-EC2Route -RouteTableId $publicRouteTable.RouteTableId -DestinationCidrBlock -GatewayId $igw.InternetGatewayId
New-EC2Route -RouteTableId $privateRouteTable.RouteTableId -DestinationCidrBlock -NatGatewayId $natgw.NatGateway.NatGatewayId

This has created two route tables, which we can also see inside our AWS Console now.

Viewing AWS route tables in the AWS Console

Viewing AWS route tables in the AWS Console

Finally, we associate these route tables with the correct subnets.

Register-EC2RouteTable -RouteTableId $publicRouteTable.RouteTableId -SubnetId $publicSubnet.SubnetId
Register-EC2RouteTable -RouteTableId $privateRouteTable.RouteTableId -SubnetId $privateSubnet.SubnetId

Once this is all executed without errors, you can check the AWS Console and see that you have two subnets in your VPC, each associated with the correct route table.

Subscribe to 4sysops newsletter!

Viewing AWS Subnets in AWS Console

Viewing AWS Subnets in AWS Console

Your VPC is now ready to have workloads deployed into it.

1 Comment
  1. PowerMe! (Rank 3) 4 years ago

    Thank you, very useful. 

Leave a reply

Your email address will not be published. Required fields are marked *


© 4sysops 2006 - 2023


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account