Azure Local | Bicep – Logical Networks
When you deploy an Azure environment inside a complex enterprise landscape, the last thing you want is a build process that depends on manual steps, tribal knowledge, and someone remembering which portal blade contained the “one important checkbox.” In these scenarios, consistency is not a nice-to-have; it’s a prerequisite for reliability. Infrastructure as Code (IaC) solves that by turning your platform configuration into a repeatable, testable, and reviewable artifact. Instead of rebuilding clusters, networks, identities, and policies by hand every time, you define them once and redeploy them with confidence across development, staging, and production—without configuration drift creeping in between environments.
This is also why an organizational policy of “IaC first” (or even more strictly, “IaC only” for production changes) is a strong governance stance. It establishes that infrastructure changes should be traceable, peer-reviewed, and controlled through the same engineering discipline you apply to application code. It improves auditability because every change is recorded in version control, and it reduces operational risk because deployments become predictable and reproducible. Most importantly, it accelerates delivery: once the baseline is codified, teams spend less time redoing platform work and more time improving it.
Azure Bicep is an ideal way to implement this approach in Azure because it is declarative, readable, and compiles directly to ARM templates, which makes it a first-class citizen in the Azure deployment ecosystem. You can modularize common building blocks—naming standards, tagging, RBAC assignments, monitoring integrations, and networking patterns—so platform teams can publish approved modules while application teams consume them safely and consistently.
A practical example of where this shines is hybrid and edge deployments: you can standardize the creation of networking constructs such as logical networks for an Azure Local cluster, ensuring Arc-managed workloads consistently land in the correct segments. In complex network environments, you don’t want to click this all together.
Bicep
I’ve been developing a reusable Bicep template to streamline deployments that require multiple logical networks, reducing manual effort and improving consistency across environments. To keep the implementation aligned with Microsoft’s recommended patterns, I’m leveraging Azure Verified Modules, which provides standardized, tested building blocks. This approach means future maintenance is minimal: in most cases, you only need to update the module API versions as Azure Local evolves over time, at scale.
https://github.com/GetToThe-Cloud/Website/tree/main/AzureBicep-AzureLocal-LogicalNetworks
Features
- ✅ Deploys multiple logical networks from a single template
- ✅ Supports VLAN segmentation
- ✅ Configurable IP address pools with static or dynamic allocation
- ✅ DNS server configuration
- ✅ Default gateway routing
- ✅ Custom resource tagging
- ✅ Uses Azure Verified Modules (AVM) for Azure Stack HCI logical networks
Main Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
subscriptionId | string | Yes | Azure subscription ID where resources will be deployed |
paramsNetworks | array | Yes | Array of network configuration objects |
Network Configuration Object
Each network object in the paramsNetworks array contains:
| Parameter | Type | Required | Description |
|---|---|---|---|
parName | string | Yes | Name of the logical network |
parResourceGroupName | string | Yes | Resource group containing the custom location |
parLocation | string | Yes | Azure region (e.g., ‘westeurope’) |
parSubscriptionId | string | Yes | Azure subscription ID |
parExtendedLocationName | string | Yes | Name of the custom location (Azure Stack HCI cluster) |
parVSwitchName | string | Yes | Name of the virtual switch on the cluster |
parAddressPrefix | string | Yes | IP address prefix in CIDR notation (e.g., ‘172.16.1.0/24’) |
parVlan | integer | Yes | VLAN ID for network segmentation (use 0 for untagged) |
parIpAllocationMethod | string | Yes | IP allocation method (‘Static’ or ‘Dynamic’) |
parDnsServers | array | Yes | Array of DNS server IP addresses |
parDefaultGateway | string | Yes | Default gateway IP address |
parIpPools | array | Yes | Array of IP pool objects with ‘start’ and ‘end’ properties |
parTags | object | No | Resource tags as key-value pairs |
