CIDR math? #3940
-
What's the idiomatic way to perform CIDR math in Bicep? How for example do I calculate the Xth IP in a subnet, or split a prefix into two smaller prefixes? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
I am not sure if there is a one size fits all solution here, however perhaps this may give you a few ideas. I always assign a networkid for any given Hub/Spoke deployment. I always assign a /20 address space, so that I can create either 8 * 512 (ip's) environments OR I can define 16 * 256 (ip's) Environments. I always assign 1 VNET per resource group. So I can essentially deploy 1 Hub, then 15 spokes OR 1 hub and 7 spokes, that all get peered from the Hub. I always assign the Hub as 0, then I can use lets say 1 to 7 OR 1 to 15 for the other resource groups. That number is what I call the deploymentID. For the example lets say we are using the 8 * 512 model. Globally I assign the /20 as below. .. I actually assign 1 of these in the primary region and a different one in the secondary/partner region, obviously this ensures no overlapping ip's. "networkId": [
"10.10.",
144
],
"DNSServers": [
"10.10.144.75",
"10.10.144.76"
], Then whenever I create a resource group (an Environment), which also has the VNET, I pass in the DeploymentID which is 0 up to 8... I use that to calculate the networkID that I actually assign on the VNET for the addressPrefix, then also use it to construct the subnet addresses as well. Below I carve up the 512 addresses (which is why it's a /23) into smaller subnets, however I actually show also dedicating a full 256 (of the 512) to MT02 (the mid tier 02 subnet). var networkId = '${Global.networkid[0]}${string((Global.networkid[1] - (2 * int(DeploymentID))))}'
var networkIdUpper = '${Global.networkid[0]}${string((1 + (Global.networkid[1] - (2 * int(DeploymentID)))))}'
var addressPrefixes = [
'${networkId}.0/23'
] then on my subnets, I simply define them as follows: "SubnetInfo": [
{
"name": "snMT01",
"prefix": "0/27",
"NSG": 1,
"FlowLogEnabled": true,
"FlowAnalyticsEnabled": true,
"delegations": "Microsoft.Web/serverfarms"
},
{
"name": "snFE01",
"prefix": "32/27",
"NSG": 1,
"FlowLogEnabled": true,
"FlowAnalyticsEnabled": true
},
{
"name": "snBE02",
"prefix": "64/28",
"NSG": 1,
"Route": 1,
"FlowLogEnabled": true,
"FlowAnalyticsEnabled": true,
"delegations": "Microsoft.ContainerInstance/containerGroups"
},
{
"name": "snBE01", // APIM Dedicated
"prefix": "80/28",
"NSG": 1,
"Route": 1,
"FlowLogEnabled": true,
"FlowAnalyticsEnabled": true
},
{
"name": "AzureBastionSubnet",
"prefix": "96/27",
"NSG": 1,
"FlowLogEnabled": true,
"FlowAnalyticsEnabled": true
},
{
"name": "snWAF01",
"prefix": "128/25",
"NSG": 1,
"Route": 0,
"FlowLogEnabled": true,
"FlowAnalyticsEnabled": true
},
{
"name": "snMT02",
"prefix": "0/24",
"NSG": 1,
"Route": 1,
"FlowLogEnabled": true,
"FlowAnalyticsEnabled": true
}
] Then when creating the VNET, you can see I just concatenate the networkid with the prefix from the subnets lookup. resource VNET 'Microsoft.Network/virtualNetworks@2021-02-01' = {
name: '${Deployment}-vn'
location: resourceGroup().location
properties: {
addressSpace: {
addressPrefixes: addressPrefixes
}
dhcpOptions: {
dnsServers: array(DNSServers)
}
subnets: [for sn in SubnetInfo: {
name: sn.name
properties: {
addressPrefix: '${((sn.name == 'snMT02') ? networkIdUpper : networkId)}.${sn.Prefix}'
networkSecurityGroup: ((contains(sn, 'NSG') && (sn.NSG == 1)) ? json('{"id":"${string(resourceId('Microsoft.Network/networkSecurityGroups', '${Deploymentnsg}-nsg${sn.name}'))}"}') : json('null'))
routeTable: ((contains(sn, 'Route') && (sn.Route == 1)) ? RouteTableGlobal : json('null'))
privateEndpointNetworkPolicies: 'Disabled'
delegations: (contains(sn, 'delegations') ? delegations[sn.delegations] : delegations.default)
}
}]
}
} So I know this may seem complicated, however it means that I know I can easily deploy 8 or 16 environments and the subnet and address space is always automatically generated (when doing hub/spoke). if I need to define a load balancer or vm with a static IP, I can just give it the single IP and it always calculates it to the environment that it is currently being deployed into. i.e. I just pass in the last octet IP and it then figures out the rest. So as an example below the load balancer front end ip is just 254. {
"LBName": "API",
"ASName": "API",
"Sku": "Standard",
"Type": "Private",
"BackEnd": [
"API"
],
"FrontEnd": [
{
"LBFEName": "API",
"SNName": "MT02",
"LBFEIP": "254" So hopefully this may give you some ideas and you can see that you can do inline math with + - * Etc. If this is not helpful, feel free to share some more specific ideas that you have or what kind of calculations that you want to perform Etc? |
Beta Was this translation helpful? Give feedback.
-
I'm playing with this idea, but I really dislike it for obvious reasons.
|
Beta Was this translation helpful? Give feedback.
-
This is now being tracked #3975 |
Beta Was this translation helpful? Give feedback.
@JohnDelisle
This is now being tracked #3975