11// /******************************************************************************************************************/
2- // This is an example test program to create private networking resources independently with sample inputs
3- //
2+ // This is an example test program to create private networking resources independently with sample network design.
3+ // It is an illustration of how to use the main.bicep in the infra/modules/network folder, with your own parameters.
4+ // You can independently deploy this module to create a network with subnets, NSGs, Azure Bastion Host, and Jumpbox VM.
5+ // Test them with this test program. Then integrate your design into the modules/network.bicep which is intended for
6+ // a specific network design.
7+ //
8+ // All things in infra/modules/network are designed to be reusable and composable without the need to modify
9+ // any code in the network folder.
10+ //
411// Please review below modules to understand how things are wired together:
5- // infra/main.bicep
6- // infra/modules/network.bicep
7- // infra/moddules/network/main.bicep
12+ // infra/main.bicep
13+ // infra/modules/network.bicep
14+ // infra/moddules/network/main.bicep
815//
916// /******************************************************************************************************************/
1017
1118@minLength (6 )
1219@maxLength (25 )
13- @description ('Default name used for all resources.' )
14- param resourcesName string = 'testNetwork '
20+ @description ('Name used for naming all network resources.' )
21+ param resourcesName string = 'nettest '
1522
1623@minLength (3 )
1724@description ('Azure region for all services.' )
18- param location string = 'eastus'
25+ param location string = resourceGroup ().location
26+
27+ @description ('Optional. Enable/Disable usage telemetry for module.' )
28+ param enableTelemetry bool = true
1929
2030@description ('Optional. Tags to be applied to the resources.' )
2131param tags object = {}
2232
23- var vnetName = 'vnet-${resourcesName }'
24- @description ('Networking address prefix for the VNET only' )
25- param addressPrefixes array = ['10.0.0.0/20' ] // 4096 addresses (enough for 8 /23 subnets or 16 /24 subnets)
33+ import { bastionHostConfigurationType } from '../modules/network/bastionHost.bicep'
34+ @description ('Optional. Configuration for the Azure Bastion Host. Leave null to omit Bastion creation.' )
35+ param bastionConfiguration bastionHostConfigurationType = {
36+ name : 'bastion-${resourcesName }'
37+ subnetAddressPrefixes : ['10.0.10.0/23' ] // /23 (10.0.10.0 - 10.0.11.255), 512 addresses
38+ }
2639
27- param enableBastionHost bool = true
28- var bastionHostName = 'bastionHost-${resourcesName }'
40+ import { jumpBoxConfigurationType } from '../modules/network/jumpbox.bicep'
41+ @description ('Optional. Configuration for the Jumpbox VM. Leave null to omit Jumpbox creation.' )
42+ param jumpboxConfiguration jumpBoxConfigurationType = {
43+ name : 'vm-jumpbox-${resourcesName }'
44+ size : 'Standard_D2s_v3' // Default size, can be overridden
45+ username : 'JumpboxAdminUser'
46+ password : 'JumpboxAdminP@ssw0rd1234!'
47+ subnet : {
48+ name : 'jumpbox-subnet'
49+ addressPrefixes : ['10.0.12.0/23' ] // /23 (10.0.12.0 - 10.0.13.255), 512 addresses
50+ networkSecurityGroup : {
51+ name : 'jumpbox-nsg'
52+ securityRules : [
53+ {
54+ name : 'AllowJumpboxInbound'
55+ properties : {
56+ access : 'Allow'
57+ direction : 'Inbound'
58+ priority : 100
59+ protocol : 'Tcp'
60+ sourcePortRange : '*'
61+ destinationPortRange : '22'
62+ sourceAddressPrefixes : [
63+ '10.0.10.0/23' // Azure Bastion subnet as an example here. You can adjust this as needed by adding more
64+ ]
65+ destinationAddressPrefixes : ['10.0.12.0/23' ]
66+ }
67+ }
68+ ]
69+ }
70+ }
71+ }
2972
30- param jumpboxVM bool = true
31- param jumpboxAdminUser string = 'JumpboxAdminUser'
32- @secure ()
33- param jumpboxAdminPassword string = 'JumpboxAdminP@ssw0rd1234!'
34- param jumpboxVmSize string = 'Standard_D2s_v3'
35- var jumpboxVmName = 'jumpboxVM-${resourcesName }'
73+ // ====================================================================================================================
74+ // Below paremeters define default the VNET and subnets. You can customize them as needed.
75+ // ====================================================================================================================
76+ @description ('Networking address prefix for the VNET.' )
77+ param addressPrefixes array = ['10.0.0.0/20' ] // 4096 addresses (enough for 8 /23 subnets or 16 /24 subnets)
3678
79+ import { subnetType } from '../modules/network/virtualNetwork.bicep'
3780@description ('Array of subnets to be created within the VNET.' )
38- param subnets array = [
39- // Only one delegation per subnet is supported by the AVM module as of June 2025.
40- // For subnets that do not require delegation, leave the array empty.
81+ param subnets subnetType [] = [
4182 {
42- name : 'web '
83+ name : 'peps '
4384 addressPrefixes : ['10.0.0.0/23' ] // /23 (10.0.0.0 - 10.0.1.255), 512 addresses
85+ privateEndpointNetworkPolicies : 'Disabled'
86+ privateLinkServiceNetworkPolicies : 'Disabled'
87+ networkSecurityGroup : {
88+ name : 'peps-nsg'
89+ securityRules : []
90+ }
91+ }
92+ {
93+ name : 'web'
94+ addressPrefixes : ['10.0.2.0/23' ] // /23 (10.0.2.0 - 10.0.3.255), 512 addresses
95+ privateEndpointNetworkPolicies : 'Disabled'
96+ privateLinkServiceNetworkPolicies : 'Disabled'
4497 networkSecurityGroup : {
4598 name : 'web-nsg'
4699 securityRules : [
@@ -54,7 +107,7 @@ param subnets array = [
54107 sourcePortRange : '*'
55108 destinationPortRange : '443'
56109 sourceAddressPrefixes : ['0.0.0.0/0' ]
57- destinationAddressPrefixes : ['10.0.0 .0/23' ]
110+ destinationAddressPrefixes : ['10.0.2 .0/23' ]
58111 }
59112 }
60113 ]
@@ -68,7 +121,9 @@ param subnets array = [
68121 }
69122 {
70123 name : 'app'
71- addressPrefixes : ['10.0.2.0/23' ] // /23 (10.0.2.0 - 10.0.3.255), 512 addresses
124+ addressPrefixes : ['10.0.4.0/23' ] // /23 (10.0.4.0 - 10.0.5.255), 512 addresses
125+ privateEndpointNetworkPolicies : 'Disabled'
126+ privateLinkServiceNetworkPolicies : 'Disabled'
72127 networkSecurityGroup : {
73128 name : 'app-nsg'
74129 securityRules : [
@@ -81,8 +136,8 @@ param subnets array = [
81136 protocol : 'Tcp'
82137 sourcePortRange : '*'
83138 destinationPortRange : '*'
84- sourceAddressPrefixes : ['10.0.0 .0/23' ] // web subnet
85- destinationAddressPrefixes : ['10.0.2 .0/23' ]
139+ sourceAddressPrefixes : ['10.0.2 .0/23' ] // web subnet
140+ destinationAddressPrefixes : ['10.0.4 .0/23' ]
86141 }
87142 }
88143 ]
@@ -96,7 +151,9 @@ param subnets array = [
96151 }
97152 {
98153 name : 'ai'
99- addressPrefixes : ['10.0.4.0/23' ] // /23 (10.0.4.0 - 10.0.5.255), 512 addresses
154+ addressPrefixes : ['10.0.6.0/23' ] // /23 (10.0.6.0 - 10.0.7.255), 512 addresses
155+ privateEndpointNetworkPolicies : 'Disabled'
156+ privateLinkServiceNetworkPolicies : 'Disabled'
100157 networkSecurityGroup : {
101158 name : 'ai-nsg'
102159 securityRules : [
@@ -110,10 +167,10 @@ param subnets array = [
110167 sourcePortRange : '*'
111168 destinationPortRange : '*'
112169 sourceAddressPrefixes : [
113- '10.0.0 .0/23' // web subnet
114- '10.0.2 .0/23' // app subnet
170+ '10.0.2 .0/23' // web subnet
171+ '10.0.4 .0/23' // app subnet
115172 ]
116- destinationAddressPrefixes : ['10.0.4 .0/23' ]
173+ destinationAddressPrefixes : ['10.0.6 .0/23' ]
117174 }
118175 }
119176 ]
@@ -122,7 +179,9 @@ param subnets array = [
122179 }
123180 {
124181 name : 'data'
125- addressPrefixes : ['10.0.6.0/23' ] // /23 (10.0.6.0 - 10.0.7.255)
182+ addressPrefixes : ['10.0.8.0/23' ] // /23 (10.0.8.0 - 10.0.9.255), 512 addresses
183+ privateEndpointNetworkPolicies : 'Disabled'
184+ privateLinkServiceNetworkPolicies : 'Disabled'
126185 networkSecurityGroup : {
127186 name : 'data-nsg'
128187 securityRules : [
@@ -136,36 +195,9 @@ param subnets array = [
136195 sourcePortRange : '*'
137196 destinationPortRange : '*'
138197 sourceAddressPrefixes : [
139- '10.0.0.0/23' // web subnet
140- '10.0.2.0/23' // app subnet
141- '10.0.4.0/23' // ai subnet
142- ]
143- destinationAddressPrefixes : ['10.0.6.0/23' ]
144- }
145- }
146- ]
147- }
148- delegations : [] // No delegation required for this subnet.
149- }
150- {
151- name : 'services'
152- addressPrefixes : ['10.0.8.0/23' ] // /23 (10.0.8.0 - 10.0.9.255), 512 addresses
153- networkSecurityGroup : {
154- name : 'services-nsg'
155- securityRules : [
156- {
157- name : 'AllowWebAppAiToServices'
158- properties : {
159- access : 'Allow'
160- direction : 'Inbound'
161- priority : 100
162- protocol : 'Tcp'
163- sourcePortRange : '*'
164- destinationPortRange : '*'
165- sourceAddressPrefixes : [
166- '10.0.0.0/23' // web subnet
167- '10.0.2.0/23' // app subnet
168- '10.0.4.0/23' // ai subnet
198+ '10.0.2.0/23' // web subnet
199+ '10.0.4.0/23' // app subnet
200+ '10.0.6.0/23' // ai subnet
169201 ]
170202 destinationAddressPrefixes : ['10.0.8.0/23' ]
171203 }
@@ -176,39 +208,6 @@ param subnets array = [
176208 }
177209]
178210
179- // jumpbox parameters
180- param jumpboxSubnet object = {
181- name : 'jumpbox'
182- addressPrefixes : ['10.0.12.0/23' ] // /23 (10.0.12.0 - 10.0.13.255), 512 addresses
183- networkSecurityGroup : {
184- name : 'jumpbox-nsg'
185- securityRules : [
186- {
187- name : 'AllowJumpboxInbound'
188- properties : {
189- access : 'Allow'
190- direction : 'Inbound'
191- priority : 100
192- protocol : 'Tcp'
193- sourcePortRange : '*'
194- destinationPortRange : '22'
195- sourceAddressPrefixes : [
196- '10.0.7.0/24' // Azure Bastion subnet as an example here. You can adjust this as needed by adding more
197- ]
198- destinationAddressPrefixes : ['10.0.12.0/23' ]
199- }
200- }
201- ]
202- }
203- }
204-
205- // Azure Bastion Host parameters
206- param bastionSubnet object = {
207- addressPrefixes : ['10.0.10.0/23' ] // /23 (10.0.10.0 - 10.0.11.255), 512 addresses
208- networkSecurityGroup : null // Azure Bastion subnet must NOT have custom NSG as it is managed by Azure
209- }
210-
211-
212211// /******************************************************************************************************************/
213212// Create Log Analytics Workspace for monitoring and diagnostics
214213// /******************************************************************************************************************/
@@ -224,65 +223,21 @@ module logAnalyticsWorkspace 'br/public:avm/res/operational-insights/workspace:0
224223 }
225224}
226225
226+ // /******************************************************************************************************************/
227+ // Networking - NSGs, VNET and Subnets. Each subnet has its own NSG
227228// /******************************************************************************************************************/
228- // Networking - NSGs, VNET and Subnets. Each subnet has its own NSG
229- // /******************************************************************************************************************/
230- module virtualNetwork 'virtualNetwork.bicep' = {
231- name : '${resourcesName }-virtualNetwork'
232- params : {
233- name : vnetName
234- addressPrefixes : addressPrefixes
235- subnets : subnets
236- location : location
237- tags : tags
238- logAnalyticsWorkspaceId : logAnalyticsWorkspace .outputs .resourceId
239- }
240- }
241229
242- // /******************************************************************************************************************/
243- // // Create Azure Bastion Subnet and Azure Bastion Host
244- // /******************************************************************************************************************/
245- module bastionHost 'bastionHost.bicep' = if (enableBastionHost && !empty (bastionSubnet )) {
246- name : '${resourcesName }-bastionHost'
230+ module network '../modules/network/main.bicep' = {
231+ name : take ('network-${resourcesName }-create' , 64 )
247232 params : {
248- subnet : bastionSubnet
233+ resourcesName : resourcesName
249234 location : location
250- vnetName : virtualNetwork .outputs .name
251- vnetId : virtualNetwork .outputs .resourceId
252- name : bastionHostName
253- logAnalyticsWorkspaceId : logAnalyticsWorkspace .outputs .resourceId
235+ logAnalyticsWorkSpaceResourceId : logAnalyticsWorkspace .outputs .resourceId
254236 tags : tags
237+ addressPrefixes : addressPrefixes
238+ subnets : subnets
239+ bastionConfiguration : bastionConfiguration
240+ jumpboxConfiguration : jumpboxConfiguration
241+ enableTelemetry : enableTelemetry
255242 }
256243}
257-
258- // /******************************************************************************************************************/
259- // // create Jumpbox NSG and Jumpbox Subnet, then create Jumpbox VM
260- // /******************************************************************************************************************/
261- module jumpbox 'jumpbox.bicep' = if (jumpboxVM && !empty (jumpboxSubnet )) {
262- name : '${resourcesName }-jumpbox'
263- params : {
264- vmName : jumpboxVmName
265- location : location
266- vnetName : virtualNetwork .outputs .name
267- jumpboxVmSize : jumpboxVmSize
268- jumpboxSubnet : jumpboxSubnet
269- jumpboxAdminUser : jumpboxAdminUser
270- jumpboxAdminPassword : jumpboxAdminPassword
271- tags : tags
272- logAnalyticsWorkspaceId : logAnalyticsWorkspace .outputs .resourceId
273- }
274- }
275-
276- output vnetName string = virtualNetwork .outputs .name
277- output vnetResourceId string = virtualNetwork .outputs .resourceId
278- output subnets array = virtualNetwork .outputs .subnets // This one holds critical info for subnets, including NSGs
279-
280- output bastionSubnetId string = bastionHost .outputs .subnetId
281- output bastionSubnetName string = bastionHost .outputs .subnetName
282- output bastionHostId string = bastionHost .outputs .resourceId
283- output bastionHostName string = bastionHost .outputs .name
284-
285- output jumpboxSubnetName string = jumpbox .outputs .subnetId
286- output jumpboxSubnetId string = jumpbox .outputs .subnetId
287- output jumpboxVmName string = jumpbox .outputs .vmName
288- output jumpboxVmId string = jumpbox .outputs .vmId
0 commit comments