Creating resources in multiple resource groups

Hi,

I have created a script that creates the resource groups, and then creates storage accounts in the resource groups.

Could you advise of a method of creating a Virtual Network in each resource group ? I am trying not to hardcode anything and use variables. I have tried a switch statement, although this doesn’t seem to be working. Is there a better way to do it? Also in my switch statement, I’ve hardcoded the values, therefore i’m not sure of the best way around this.

Basically If the resource group is RG01, it should create the VNET VNET01. RG02 = VNET02.

 

$resourcegroups = "RG01","RG02","RG03"
$location = 'West Europe'
$vnet1name = 'vnet1'
$VNET1AddressPrefix = "10.1.0.0/16"
$VNET1FESubnet = New-AzureRmVirtualNetworkSubnetConfig -name 'FrontEndSubnet' -AddressPrefix '10.1.1.0/24'
$VNET1BESubnet = New-AzureRmVirtualNetworkSubnetConfig -name 'BackEndSubnet' -AddressPrefix '10.1.2.0/24'
$vnet2name = 'vnet2'
$VNET2FESubnet = New-AzureRmVirtualNetworkSubnetConfig -name 'FrontEndSubnet' -AddressPrefix '10.2.1.0/24'
$VNET2BESubnet = New-AzureRmVirtualNetworkSubnetConfig -name 'BackEndSubnet' -AddressPrefix '10.2.2.0/24'


ForEach ($RG in $resourcegroups)

{

New-AzureRmResourceGroup -Name $RG -Location $Location

}

$resourcegroups = Get-AzureRmResourceGroup

ForEach ($RG in $resourcegroups)
{
$SAName = "$($rg.ResourceGroupName.ToLower())" + "lrs01"
$skuname = 'Standard_LRS'
New-AzureRmStorageAccount -ResourceGroupName $RG.resourcegroupname -SkuName $skuname -Location $location -Name $SAName

}

Switch ($resourcegroups)
{
'RG01' {
New-AzureRmVirtualNetwork -Name $vnet1name -ResourceGroupName $resourcegroups.resourcegroupname -Location $location -AddressPrefix $VNET1AddressPrefix -Subnet $VNET1FESubnet,$VNET1BESubnet

}
'RG02'
{
New-AzureRmVirtualNetwork -Name $vnet2name -ResourceGroupName $resourcegroups.resourcegroupname -Location $location -AddressPrefix $VNET1AddressPrefix -Subnet $VNET2FESubnet,$VNET2BESubnet

}
'default'

{
Write-Output "this didn't work"
}
}

Thanks in advance!

So firstly, a couple of suggestions. User PowerShell to create the empty resource groups then ARM templates to do the rest, that’s what they are for and would be easier to use in this instance. However, if you prefer using PowerShell, then I would do something like this. I’ve noticed that you don’t define VNET3 information in your code, but it shouldn’t be a problem to build on this example while using a combination of hashtables and arrays.

 

$resourcegroups = "RG01","RG02","RG03"
$location = 'West Europe'

$networks = @{}

$networks.RG01 = @()
$networks.RG01 += "VNET01"
$networks.RG01 += "10.1.0.0/16"
$networks.RG01 += New-AzureRmVirtualNetworkSubnetConfig -name 'FrontEndSubnet' -AddressPrefix '10.1.1.0/24'
$networks.RG01 += New-AzureRmVirtualNetworkSubnetConfig -name 'BackEndSubnet' -AddressPrefix '10.1.2.0/24'

$networks.RG02 = @()
$networks.RG01 += "VNET02"
$networks.RG02 += "10.1.0.0/16"
$networks.RG02 += New-AzureRmVirtualNetworkSubnetConfig -name 'FrontEndSubnet' -AddressPrefix '10.2.1.0/24'
$networks.RG02 += New-AzureRmVirtualNetworkSubnetConfig -name 'BackEndSubnet' -AddressPrefix '10.2.2.0/24'

ForEach ($RG in $resourcegroups)
{
$rgroup = New-AzureRmResourceGroup -Name $RG -Location $Location
$SAName = "$($rgroup.ResourceGroupName.ToLower())" + "lrs01"
$skuname = 'Standard_LRS'
New-AzureRmStorageAccount -ResourceGroupName $rgroup.resourcegroupname -SkuName $skuname -Location $location -Name $SAName
New-AzureRmVirtualNetwork -Name $networks.$RG[0] -ResourceGroupName $rgroup.resourcegroupname -Location $location -AddressPrefix $networks.$RG[1] -Subnet $networks.$RG[2],$networks.$RG[3]
}

P.S. you will need to do the same for storage, I’ve just given you an example with the networks side of things.

Hi Edgar, firstly thank you for your reply.

This is a much better way of doing it.

I understand ARM templates are a better way of doing it, I’ve built an environment using ARM templates and now you can create RG’s with ARM templates it’s a lot easier to do that I agree with you. Although i’m trying to improve PowerShell skills so I guess learning it in PowerShell can’t harm :slight_smile:

Although I don’t understand how the foreach loop will work when it comes to creating the second VNET?

 

New-AzureRmVirtualNetwork -Name $networks.$RG[0] -ResourceGroupName $rgroup.resourcegroupname -Location $location -AddressPrefix $networks.$RG[1] -Subnet $networks.$RG[2],$networks.$RG[3]

 

This will create the first VNET (Which it did), although when it loops back round to do the next RG it will just create the same again because it’s the same VNET name in the $networks.$rg[1].

Therefore I thought about adding another new-azurermvirtualnetwork line in the foreach loop, although then it will just create 2 VNET’S in each resource group which I don’t want.

New-AzureRmVirtualNetwork -Name $networks.$RG01[0] -ResourceGroupName $rgroup.resourcegroupname -Location $location -AddressPrefix $networks.$RG01[1] -Subnet $networks.$RG01[2],$networks.$RG01[3]
New-AzureRmVirtualNetwork -Name $networks.$RG02[0] -ResourceGroupName $rgroup.resourcegroupname -Location $location -AddressPrefix $networks.$RG02[1] -Subnet $networks.$RG02[2],$networks.$RG02[3]

I like the array idea though! any ideas how I can fix it so it will do $rg01 first, and then $rg02 afterwards? would it need 2 foreach loops?

Thanks for the help!

Matt

Can I suggest you use a custom object to specify each component you want. In my opinion it makes it easier to read and easier to maintain, especially if somebody else inherits it:

$resources = @()
$resources += [PSCustomObject]@{
    resourceGroup = "RG01"
    location = "westeurope"
    vnet = "VNET01"
    vnetAdressPrefix = "10.1.0.0/16"
    feSubnetName = 'FrontEndSubnet'
    frontEndSubnet = '10.1.1.0/24'
    beSubnetName = 'BackEndSubnet'
    backEndSubnet = '10.1.2.0/24'
    skuName = 'Standard_LRS'
    saName = 'rg01lrs01'
}

You can then loop over the custom objects in the array:

foreach ($resource in $resources) {
    $vnetFeSubnet = New-AzureRmVirtualNetworkSubnetConfig -name $resource.feSubnetName -AddressPrefix $resource.frontEndSubnet
    $vnetBeSubnet = New-AzureRmVirtualNetworkSubnetConfig -name $resource.beSubnetName -AddressPrefix $resource.backEndSubnet
    $resourceGroup = New-AzureRmResourceGroup -Name $resource.resourceGroup -Location $resource.Location
    $storage = New-AzureRmStorageAccount -ResourceGroupName $resource. -SkuName $resource.skuname -Location $resource.location -Name $resource.saName
    $vnet = New-AzureRmVirtualNetwork -Name $resource.vnet -ResourceGroupName $resource.resourceGroup -Location $resource.location -AddressPrefix $resource.vnetAdressPrefix -Subnet $vnetFeSubnet,$vnetBeSubnet
}

This may be a little more work up front but will be worth it in the long run.

In the foreach loop you go through $resourcegroups which are:

$resourcegroups = "RG01","RG02","RG03"

The temporary variable you use for the duration of the loop is $RG.

Then you query the hashtable with a particular key inside the loop:

$networks.$RG

The first time it goes through foreach loop $RG = “RG01”, so $networks.RG01 will be accessed which will return networks information for $RG01

$networks.RG01 += "VNET01"
$networks.RG01 += "10.1.0.0/16"
$networks.RG01 += New-AzureRmVirtualNetworkSubnetConfig -name 'FrontEndSubnet' -AddressPrefix '10.1.1.0/24'
$networks.RG01 += New-AzureRmVirtualNetworkSubnetConfig -name 'BackEndSubnet' -AddressPrefix '10.1.2.0/24'

And so on. You just need to create the same logic for the storage too.

Thanks Edgar.

I understand.

 

 

 

Hi Bunzab, thanks for your comment.

 

If I use this method, i’d need to create another set of custom objects for the next loop right? as the objects are for the first VNET only.

 

Thanks,

Matt

Yes, like I said more work up front, but keeps it easy to read and maintain. You might question why use this instead of an ARM template though :).