Loading Now

Create Azure vnet, subnet and Network security group with application policies with powershell

In a previous post I showed you how to create a resource group. The next thing I want to show you is how to create a vnet, subnet and a network security group with application security rules built in. This will result in a new network where we can place VMs or other objects. I am going to break down each section of this script and explain what is happening. At the end, I will put it all together so you can tweak it and use in your own environment.

Variables

This is the section you will change to fit your resource group, location and subnet preferences.

### Change these to your liking
$LocationName = "westus"
$ResourceGroupName = "Skylar-Testing"
$VnetAddressPrefix = "10.50.0.0/24"
$SubnetAddressPrefix = "10.50.0.0/24"

### Change these only if you don't like my naming convention
$NetworkName = "$ResourceGroupName-vnet"
$SubnetName = "$ResourceGroupName-subnet"

Create Application Security Groups

Application security groups are what you will use to define allow/deny rules based on ports for your VMs. In my example I make 3 groups;

Management-Linux
– I will use this group to attach a rule to allow SSH (Port 22) traffic.

Management-Windows
– I will use this group to attach a rule to allow RDP (Port 3389) traffic.

Web
– I will use this group to attach a rule to allow Web (Ports 80, 443) traffic.

### Create Application security Groups if they dont already exist
try {
    $asgLinux = get-AzApplicationSecurityGroup -Name "Management-Linux" -ResourceGroupName $ResourceGroupName -ErrorAction Stop
}
catch {
    $asgLinux = New-AzApplicationSecurityGroup -Name "Management-Linux" -Location $LocationName -ResourceGroupName $ResourceGroupName
}
try {
    $asgWindows = get-AzApplicationSecurityGroup -Name "Management-Windows" -ResourceGroupName $ResourceGroupName -ErrorAction Stop
}
catch {
    $asgWindows = New-AzApplicationSecurityGroup -Name "Management-Windows" -Location $LocationName -ResourceGroupName $ResourceGroupName  
}
try {
    $asgWeb = get-AzApplicationSecurityGroup -Name "Web" -ResourceGroupName $ResourceGroupName -ErrorAction Stop
}
catch {
    $asgWeb = New-AzApplicationSecurityGroup -Name "Web" -Location $LocationName -ResourceGroupName $ResourceGroupName
}

These are just the groups I am making, your needs may vary and in the next section you will see where the actual rules come into play.

Create Network Security Group (NSG) and apply rules

Here is where we create the actual nsg and apply rules to it. Your rules may vary but I think this is a good start. You might notice that the priority of each rule is set 10 apart. This allows us to add rules in between these few defaults. That way we can override one of these with a rule for a specific situation and put the priority lower than the more strict default rule. Another thing to note on the two management rules. In the code for this example I have the SourceAddresssPrefix set to Internet. This is not best practice for an actual production environment. Ideally you just use this for testing or better yet scope it down to your public IP. It would look something like 0.0.0.0/32 where the 0’s would be your public IP. You can get that easily here.

### Check to see if the NSG already exists and creates if not
try {
    $nsg = get-AzNetworkSecurityGroup -ResourceGroupName $ResourceGroupName -Name "$NetworkName-NSG" -ErrorAction Stop
}
catch {
    ### Security Group rules
    $RDP_Rule = New-AzNetworkSecurityRuleConfig -Name rdp-rule -Description "Allow RDP" `
    -Access Allow -Protocol Tcp -Direction Inbound -Priority 100 `
    -SourceAddressPrefix Internet -SourcePortRange * `
    -DestinationApplicationSecurityGroup $asgWindows -DestinationPortRange 3389

    $HTTP_Rule = New-AzNetworkSecurityRuleConfig -Name http-rule -Description "Allow HTTP" `
    -Access Allow -Protocol Tcp -Direction Inbound -Priority 110 `
    -SourceAddressPrefix Internet -SourcePortRange * `
    -DestinationApplicationSecurityGroup $asgWeb -DestinationPortRange 80

    $HTTPS_Rule = New-AzNetworkSecurityRuleConfig -Name https-rule -Description "Allow HTTPS" `
    -Access Allow -Protocol Tcp -Direction Inbound -Priority 120 `
    -SourceAddressPrefix Internet -SourcePortRange * `
    -DestinationApplicationSecurityGroup $asgWeb -DestinationPortRange 443

    $SSH_Rule = New-AzNetworkSecurityRuleConfig -Name ssh-rule -Description "Allow SSH" `
    -Access Allow -Protocol Tcp -Direction Inbound -Priority 130 `
    -SourceAddressPrefix Internet -SourcePortRange * `
    -DestinationApplicationSecurityGroup $asgLinux -DestinationPortRange 22 

    ### Create Network Security Group
    $nsg = New-AzNetworkSecurityGroup -ResourceGroupName $ResourceGroupName -Location $LocationName -Name "$NetworkName-NSG" -SecurityRules $RDP_Rule,$SSH_Rule,$HTTP_Rule,$HTTPS_Rule

}

Create vnet and subnet

Now that we have our asg’s and nsg we can create the vnet and associate it with what we created above. This is probably the shortest most straight forward section, but it couldn’t exist without the stuff we just did. Well it could, just wouldn’t have any security and we don’t want that! This section will check and make sure the vnet doesn’t already exist and then it uses all the info from above to create the vnet and the subnet inside. You shouldn’t have to edit this section.

#Check for Network and create if it does not exist
try {
    Get-AzResourceGroup $ResourceGroupName | Get-AzVirtualnetwork -Name $NetworkName -ErrorAction Stop
    Write-Host "Network exists!" -ForegroundColor DarkGreen
}
catch {
    Write-Host "Network does not exist.  It will now be created." -ForegroundColor DarkRed
    ### Create vnet and subnet
    $SingleSubnet = New-AzVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix $SubnetAddressPrefix -NetworkSecurityGroup $nsg -ErrorAction Stop
    $Vnet = New-AzVirtualNetwork -Name $NetworkName -ResourceGroupName $ResourceGroupName -Location $LocationName -AddressPrefix $VnetAddressPrefix -Subnet $SingleSubnet -ErrorAction Stop
    Write-Host "Completed!" -ForegroundColor DarkGreen    
}

Put it all together

Here is the script in its entirety. Hopefully the explanation helped. This was kind of weird the first few times I did it.

$LocationName = "westus"
$ResourceGroupName = "Testing42"
$NetworkName = "$ResourceGroupName-vnet"
$VnetAddressPrefix = "10.50.0.0/24"
$SubnetName = "$ResourceGroupName-subnet"
$SubnetAddressPrefix = "10.50.0.0/24"


### Create Application security Groups if they dont already exist
try {
    $asgLinux = get-AzApplicationSecurityGroup -Name "Management-Linux" -ResourceGroupName $ResourceGroupName -ErrorAction Stop
}
catch {
    $asgLinux = New-AzApplicationSecurityGroup -Name "Management-Linux" -Location $LocationName -ResourceGroupName $ResourceGroupName
}
try {
    $asgWindows = get-AzApplicationSecurityGroup -Name "Management-Windows" -ResourceGroupName $ResourceGroupName -ErrorAction Stop
}
catch {
    $asgWindows = New-AzApplicationSecurityGroup -Name "Management-Windows" -Location $LocationName -ResourceGroupName $ResourceGroupName  
}
try {
    $asgWeb = get-AzApplicationSecurityGroup -Name "Web" -ResourceGroupName $ResourceGroupName -ErrorAction Stop
}
catch {
    $asgWeb = New-AzApplicationSecurityGroup -Name "Web" -Location $LocationName -ResourceGroupName $ResourceGroupName
}


### Check to see if the NSG already exists and creates if not
try {
    $nsg = get-AzNetworkSecurityGroup -ResourceGroupName $ResourceGroupName -Name "$NetworkName-NSG" -ErrorAction Stop
}
catch {
    ### Security Group rules
    $RDP_Rule = New-AzNetworkSecurityRuleConfig -Name rdp-rule -Description "Allow RDP" `
    -Access Allow -Protocol Tcp -Direction Inbound -Priority 100 `
    -SourceAddressPrefix Internet -SourcePortRange * `
    -DestinationApplicationSecurityGroup $asgWindows -DestinationPortRange 3389

    $HTTP_Rule = New-AzNetworkSecurityRuleConfig -Name http-rule -Description "Allow HTTP" `
    -Access Allow -Protocol Tcp -Direction Inbound -Priority 110 `
    -SourceAddressPrefix Internet -SourcePortRange * `
    -DestinationApplicationSecurityGroup $asgWeb -DestinationPortRange 80

    $HTTPS_Rule = New-AzNetworkSecurityRuleConfig -Name https-rule -Description "Allow HTTPS" `
    -Access Allow -Protocol Tcp -Direction Inbound -Priority 120 `
    -SourceAddressPrefix Internet -SourcePortRange * `
    -DestinationApplicationSecurityGroup $asgWeb -DestinationPortRange 443

    $SSH_Rule = New-AzNetworkSecurityRuleConfig -Name ssh-rule -Description "Allow SSH" `
    -Access Allow -Protocol Tcp -Direction Inbound -Priority 130 `
    -SourceAddressPrefix Internet -SourcePortRange * `
    -DestinationApplicationSecurityGroup $asgLinux -DestinationPortRange 22 

    ### Create Network Security Group
    $nsg = New-AzNetworkSecurityGroup -ResourceGroupName $ResourceGroupName -Location $LocationName -Name "$NetworkName-NSG" -SecurityRules $RDP_Rule,$SSH_Rule,$HTTP_Rule,$HTTPS_Rule

}

#Check for Network and create if it does not exist
try {
    Get-AzResourceGroup $ResourceGroupName | Get-AzVirtualnetwork -Name $NetworkName -ErrorAction Stop
    Write-Host "Network exists!" -ForegroundColor DarkGreen
}
catch {
    Write-Host "Network does not exist.  It will now be created." -ForegroundColor DarkRed
    ### Create vnet and subnet
    $SingleSubnet = New-AzVirtualNetworkSubnetConfig -Name $SubnetName -AddressPrefix $SubnetAddressPrefix -NetworkSecurityGroup $nsg -ErrorAction Stop
    $Vnet = New-AzVirtualNetwork -Name $NetworkName -ResourceGroupName $ResourceGroupName -Location $LocationName -AddressPrefix $VnetAddressPrefix -Subnet $SingleSubnet -ErrorAction Stop
    Write-Host "Completed!" -ForegroundColor DarkGreen    
}

My name is Skylar Pearce, I have been working as a System Administror since 2013 as well some side consulting work. During my career I have worked with everything from Active Directory and vCenter to configuring routers and switches and phone systems, documenting and scripting my way through the whole thing. I have a Security+ certification and am currently working on my PenTest+. Throughout my career I have gained almost all of my knowledge from blogs like this. It is now time for me to pay it back. Over time I have gathered scripts and tricks over the years that I will share on this site. A lot of the posts here will be mainly reference posts, some will be full on how to’s. I am happy to go into more depth on any other topics I go over here, just make a comment on a post. I will do my best to post once a day on weekdays but as I run out of ideas it may slow down. My WordPress skills are still growing so the site will likely get better over time as I learn. You can reach me at contact@allthesystems.com or on LinkedIn