Skip to content

Instantly share code, notes, and snippets.

Last active Jul 20, 2021
What would you like to do?
2021-07-15 Use PowerShell Imperative Commands to Create EC2 VPC with Two Public Subnets and Two Private Subnets with Internet Access
- Creates an Amazon Web Services (AWS) Virtual Private Cloud (VPC) in the us-west-2 (Oregon) region.
- VPC contains two public subnets and two private subnets.
- NAT Gateway is created to handle outbount Internet traffic from private subnets.
- Internet Gateway is created to handle in/outbound Internet traffic for public subnets.
- iex (iwr
function Add-EC2NameTag {
Helper function that adds a Name tag to an EC2 resource ID.
param (
[Parameter(Mandatory = $true)]
[string] $Name,
[Parameter(Mandatory = $true)]
[string] $ResourceId
$Tag = [Amazon.EC2.Model.Tag]::new('Name', $Name)
New-EC2Tag -Tag $Tag -Resource $ResourceId
$Region = 'us-west-2'
$VPC = New-EC2Vpc -CidrBlock
Write-Host -Object ('Created new VPC {0}' -f $VPC.VpcId)
$PublicSubnet1 = New-EC2Subnet -VpcId $VPC.VpcId -CidrBlock -Region $Region -AvailabilityZone us-west-2a
$PublicSubnet2 = New-EC2Subnet -VpcId $VPC.VpcId -CidrBlock -Region $Region -AvailabilityZone us-west-2c
$PrivateSubnet1 = New-EC2Subnet -VpcId $VPC.VpcId -CidrBlock -Region $Region -AvailabilityZone us-west-2b
$PrivateSubnet2 = New-EC2Subnet -VpcId $VPC.VpcId -CidrBlock -Region $Region -AvailabilityZone us-west-2c
Write-Host -Object ('Created VPC subnets: {0} {1} {2} {3}' -f $PublicSubnet1.SubnetId, $PublicSubnet2.SubnetId, $PrivateSubnet1.SubnetId, $PrivateSubnet2.SubnetId)
# Create VPC Internet Gateway and attach to VPC
$InternetGateway = New-EC2InternetGateway -Region $Region
Add-EC2InternetGateway -InternetGatewayId $InternetGateway.InternetGatewayId -VpcId $VPC.VpcId
Write-Host -Object ('Created Internet Gateway {0}' -f $InternetGateway.InternetGatewayId)
# Add route to Internet to public subnets
$MainRouteTableFilter = [Amazon.EC2.Model.Filter]::new()
$MainRouteTableFilter.Name = 'association.main'
$MainRouteTableFilter.Values = @('true')
$RouteTable = Get-EC2RouteTable -Filter $MainRouteTableFilter | ? VpcId -eq $VPC.VpcId
$null = New-EC2Route -GatewayId $InternetGateway.InternetGatewayId -DestinationCidrBlock -RouteTableId $RouteTable.RouteTableId
# For private subnets to access Internet, create a NAT Gateway
$ElasticIP = New-EC2Address
$NATGateway = New-EC2NatGateway -Region $Region -SubnetId $PublicSubnet1.SubnetId -AllocationId $ElasticIP.AllocationId
while ((Get-EC2NatGateway -NatGatewayId $NATGateway.NatGateway.NatGatewayId).State -ne 'Available') {
Write-Host -Object ('Waiting for NAT Gateway {0} to be available ...' -f $NATGateway.NatGateway.NatGatewayId)
Start-Sleep -Seconds 10
# We need a separate EC2 VPC Route Table to enable private subnets to route outbound to Internet
$PrivateRouteTable = New-EC2RouteTable -VpcId $VPC.VpcId
$null = New-EC2Route -DestinationCidrBlock -NatGatewayId $NATGateway.NatGateway.NatGatewayId -RouteTableId $PrivateRouteTable.RouteTableId
# Associate the private subnets with the route table pointing to the NAT Gateway
Register-EC2RouteTable -SubnetId $PrivateSubnet1.SubnetId -RouteTableId $PrivateRouteTable.RouteTableId
Register-EC2RouteTable -SubnetId $PrivateSubnet2.SubnetId -RouteTableId $PrivateRouteTable.RouteTableId
# Add tags to VPC resources
$TagName = 'Trevor'
Add-EC2NameTag -Name $TagName -Resource $VPC.VpcId
Add-EC2NameTag -Name $TagName -Resource $InternetGateway.InternetGatewayId
Add-EC2NameTag -Name $TagName -Resource $RouteTable.RouteTableId
Add-EC2NameTag -Name $TagName -Resource $NATGateway.NatGateway.NatGatewayId
# Tag the subnets that were created earlier
Add-EC2NameTag -Name Trevor-PublicSubnet1 -Resource $PublicSubnet1.SubnetId
Add-EC2NameTag -Name Trevor-PublicSubnet2 -Resource $PublicSubnet2.SubnetId
Add-EC2NameTag -Name Trevor-PrivateSubnet1 -Resource $PrivateSubnet1.SubnetId
Add-EC2NameTag -Name Trevor-PrivateSubnet2 -Resource $PrivateSubnet2.SubnetId
# Tag the private route table
Add-EC2NameTag -Name PrivateRouteTable -Resource $PrivateRouteTable.RouteTableId
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment