Cloud can be tricky sometimes. Find out what scenarios we've ran into that are worth being mentioned and explained.
When working with Azure Bicep, clarity and structure are just as important as functionality. A well-organized template simplifies troubleshooting, enhances collaboration, and makes future modifications easier.
Bicep
param name string
param addressPrefix string
var location = 'westeurope'
resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-05-01' = {
name: name
location: location
properties: {
addressSpace: {
addressPrefixes: [addressPrefix]
}
}
}
output vnet object = virtualNetwork
In this template, the purpose of name and addressPrefix isn't immediately clear. Without a naming pattern, it’s difficult to distinguish whether name refers to a resource name, parameter, or variable. In the next section, I’ll show how a structured naming approach improves clarity.
Bicep
param parVnetName string
param parAddressPrefix string
var varLocation = 'westeurope'
resource resVirtualNetwork 'Microsoft.Network/virtualNetworks@2023-05-01' = {
name: parVnetName
location: varLocation
properties: {
addressSpace: {
addressPrefixes: [parAddressPrefix]
}
}
}
output outVnet object = resVirtualNetwork
Here, the prefixes make it obvious that:
# | Component | Prefix |
---|---|---|
1 | Module | mod |
2 | Resource | res |
3 | Variable | var |
4 | Parameter | par |
5 | Output | out |
6 | Function | func |
7 | Type | type |
This is just one approach to organizing Bicep templates. If you or your team already follow a different naming convention that ensures clarity and consistency, there’s no need to change it. The key is to maintain a structured format that makes templates easy to read and maintain over time.
Bicep
param parSubnets array
resource resVirtualNetwork 'Microsoft.Network/virtualNetworks@2024-01-01' = {
name: 'vnet-example'
location: 'westeurope'
properties: {
addressSpace: {
addressPrefixes: [
'10.0.0.0/16'
]
}
subnets: parSubnets
}
}
Because parSubnets is defined as a generic array, there are no restrictions on its content. This makes the template harder to validate and troubleshoot, especially in large deployments. In the next section, we’ll explore how defining a proper type can improve both clarity and reliability.
Bicep
param parSubnets subnetType
resource resVirtualNetwork 'Microsoft.Network/virtualNetworks@2024-01-01' = {
name: 'vnet-example'
location: 'westeurope'
properties: {
addressSpace: {
addressPrefixes: [
'10.0.0.0/16'
]
}
subnets: parSubnets
}
}
type subnetType = {
name: string
properties: {
addressPrefix: string
delegation: string?
}
}[]
Benefits of Using a Typed Array
Bicep
// vnetModule.bicep
param parVnetName string
param parAddressPrefixes array
resource resVirtualNetwork 'Microsoft.Network/virtualNetworks@2024-01-01' = {
name: parVnetName
location: resourceGroup().location
properties: {
addressSpace: {
addressPrefixes: parAddressPrefixes
}
}
}
output outVnetId string = resVirtualNetwork.id
Bicep
module modVnet './vnetModule.bicep' = {
name: 'deployVnet'
params: {
parVnetName: 'vnet-example'
parAddressPrefixes: ['10.0.0.0/16']
}
}
Conclusion