The example is doing this as a nested template because the resource group that the virtual network is in, is in a different resource group to the virtual network its self. If yor NSG and vNet are in the same resource group then there is no need for this. All you need to do is add the subnet part to your main template, with a dependency on your NSG.
"name": "[concat(parameters('virtualNetworkName'), '/', parameters('subnetName'))]",
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', 'new-nsg')]"
If your NSG and vNet are in different resource groups then the only way to do this is with a nested template. This is one of the downsides or ARM compared to something like Terraform. That said there are still a couple of options you could look at:
- You could use an inline nested template. These are a bit limited but wouldn’t require you to reference an external file
- You could run it as two separate deployments, passing the NSG resource group between the two