Azure Deployment stack is the successor of Azure Blueprint. It lets you manage several resources as a block. It helps to manage the life cycle of what you deploy. See
It was designed to help the infrastructure team to deploy and manage necessary tooling for developer teams. What is the most current setup deployed by infrastructure teams? A Landing Zone.
To be short, An Azure Landing Zone is a best-practice architecture for setting up a secure and well-structured environment. Most of the time you need to customize a subscription by adding governance tools, configuring RBAC, adding resource groups, and configuring network connectivity (generally a spoke VNET peered to a HUB VNET). Let's try to do that using Azure Bicep and Azure deployment stacks.
Let’s try to make it simple, deploying only a resource group and a VNET and configuring a peering to a hub VNET.
It would be nice if we could do that by using a single multi-scope template. You can do that in Bicep by using the module. But it doesn't work as expected, If the deployment is valid and deploys resources with Bicep it throws an error if you try to use the same template with New-AzSubscriptionDeploymentStack.
We need to split the deployment into two parts, one for the subscription scope and the other for the resource group scope.
To create a resource group in Bicep we need to switch to the subscription scope by using targetScope
targetScope = 'subscription'
param resourceGroupName string = 'bicepstack'
param azureRegion string = 'westeurope'
resource myResourceGroup 'Microsoft.Resources/resourceGroups@2021-01-01' = {
name: resourceGroupName
location: azureRegion
}
But before deploying this stack we need to create one resource group that will host the deployment stack
And then we can use PowerShell to deploy the stack.
New-AzSubscriptionDeploymentStack -name rg01 -location westeurope -TemplateFile .\rg.bicep -DeploymentResourceGroupName 01-stack -DenySettingsMode none
Then we need to deploy our resources inside our new resource group. But we need to use some modules.
The first one is for the VNET (this one is optional as we could deploy from the main Bicep file).
param virtualNetworkName string
param virtualNetworkAddressPrefix string
param location string
param subnetName string
param subnetAddressPreffix string
resource virtualNetwork 'Microsoft.Network/virtualNetworks@2020-11-01' = {
name: virtualNetworkName
location: location
properties: {
addressSpace: {
addressPrefixes: [
virtualNetworkAddressPrefix
]
}
subnets: [
{
name: subnetName
properties: {
addressPrefix: subnetAddressPreffix
}
}
]
}
}
output vnetID string = virtualNetwork.id
We need to use output here to get access to the VNET ID
The second module is for peering. Here we need to be able to change the scope of the deployment. When you peer two VNETs you need to create an object inside each VNETs so we need to be able to change the scope to target the HUB VNET located in a separate subscription.
param peeringName string
param vnetName string
param localPrefix string
param remotePrefix string
param remoteVnetID string
var completePeeringName = '${vnetName}/${peeringName}'
resource peering 'Microsoft.Network/virtualNetworks/virtualNetworkPeerings@2023-04-01' = {
name: completePeeringName
properties: {
allowForwardedTraffic: true
allowVirtualNetworkAccess: true
remoteAddressSpace: {
addressPrefixes: [
localPrefix
]
}
remoteVirtualNetwork: {
id: remoteVnetID
}
remoteVirtualNetworkAddressSpace: {
addressPrefixes: [
remotePrefix
]
}
}
}
Now we can create the main.bicep template
module virtualNetwork 'vnet.bicep' = {
name: 'virtualNetwork'
params: {
virtualNetworkName: 'vnet1'
virtualNetworkAddressPrefix: '10.0.0.0/24'
location: 'westeurope'
subnetName: 'default'
subnetAddressPreffix: '10.0.0.0/24'
}
}
module peering01 'peering.bicep' = {
name: 'peering01'
params: {
peeringName: 'toHub'
vnetName: 'vnet1'
localPrefix: '10.0.0.0/24'
remotePrefix: '172.24.20.0/24'
remoteVnetID: '/subscriptions/xxx-xxx-xxx-xxxxx/resourceGroups/01-centralhubvnet/providers/Microsoft.Network/virtualNetworks/hubvnet'
}
}
module peering02 'peering.bicep' = {
name: 'peering0é'
scope: resourceGroup('xxx-xxx-xxx-xxx-xxx', '01-centralhubvnet')
params: {
peeringName: 'fromHUB'
vnetName: 'hubvnet'
localPrefix: '172.24.20.0/24'
remotePrefix: '10.0.0.0/24'
remoteVnetID: virtualNetwork.outputs.vnetID
}
}
We use the module to create the VNET and two modules for the peering. The first own create the peering on the newly created VNET. The second one with a different scope to deploy the peering in the HUB VNET localized in a different subscription. We use the resourceGroup function with the Subscription ID and the resource group name to change the scope.
Then we can use the New-AzResourceGroupDeploymentStack cmdlet to deploy the new stack.
New-AzResourceGroupDeploymentStack -name demo001 -ResourceGroupName stack -DenySettingsMode none -TemplateFile .\main.bicep
We, now, have in Azure a new stack with the VNET and the two peering objects. We can also apply different settings to protect these objects to be deleted and manage the life cycle of the stack.
Top comments (0)