Skip to content

Commit e5ac028

Browse files
committed
fix: filter out empty FQDNs for Traffic Manager endpoints using Bicep v0.20+ array filtering
1 parent a3c0cd5 commit e5ac028

File tree

12 files changed

+277
-185
lines changed

12 files changed

+277
-185
lines changed

AzureArchitecture/globalLayer.bicep

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ param enableGlobalCosmos bool = true
5353
@description('Array of regional endpoint FQDNs for Traffic Manager (e.g., Application Gateway FQDNs)')
5454
param regionalEndpoints array = []
5555

56+
57+
5658
@description('APIM Gateway URL for Front Door origin configuration')
5759
param apimGatewayUrl string = ''
5860

@@ -76,27 +78,29 @@ resource trafficManager 'Microsoft.Network/trafficManagerProfiles@2022-04-01' =
7678
profileStatus: 'Enabled'
7779
trafficRoutingMethod: 'Performance'
7880
dnsConfig: {
79-
// Traffic Manager requires a single-label relative name, not a FQDN.
80-
// Derive a label from the dnsZoneName by taking the first label before the dot.
81-
relativeName: split(toLower(dnsZoneName), '.')[0]
81+
// Traffic Manager requires a single-label relative name, not a FQDN.
82+
// Derive a label from the dnsZoneName by taking the first label before the dot.
83+
relativeName: split(toLower(dnsZoneName), '.')[0]
8284
ttl: 60
8385
}
8486
monitorConfig: {
8587
protocol: 'HTTPS'
8688
port: 443
8789
path: '/health'
8890
}
89-
endpoints: [for (endpoint, i) in regionalEndpoints: {
90-
name: 'regional-endpoint-${i + 1}'
91-
type: 'Microsoft.Network/trafficManagerProfiles/externalEndpoints'
92-
properties: {
93-
target: endpoint.fqdn
94-
endpointStatus: 'Enabled'
95-
endpointLocation: endpoint.location
96-
weight: 1
97-
priority: i + 1
91+
endpoints: [
92+
for (endpoint, i) in regionalEndpoints: if (!empty(endpoint.fqdn)) {
93+
name: 'regional-endpoint-${i + 1}'
94+
type: 'Microsoft.Network/trafficManagerProfiles/externalEndpoints'
95+
properties: {
96+
target: endpoint.fqdn
97+
endpointStatus: 'Enabled'
98+
endpointLocation: endpoint.location
99+
weight: 1
100+
priority: i + 1
101+
}
98102
}
99-
}]
103+
]
100104
}
101105
}
102106

@@ -181,7 +185,7 @@ resource apimRoute 'Microsoft.Cdn/profiles/afdEndpoints/routes@2023-05-01' = if
181185
}
182186

183187
// Secondary Origin Group for regional Application Gateways (fallback/direct routing)
184-
resource regionalOriginGroup 'Microsoft.Cdn/profiles/originGroups@2023-05-01' = if (length(regionalEndpoints) > 0) {
188+
resource regionalOriginGroup 'Microsoft.Cdn/profiles/originGroups@2023-05-01' = if (length([for endpoint in regionalEndpoints: if (!empty(endpoint.fqdn)) endpoint]) > 0) {
185189
name: 'regional-agw-origins'
186190
parent: frontDoor
187191
properties: {
@@ -200,7 +204,7 @@ resource regionalOriginGroup 'Microsoft.Cdn/profiles/originGroups@2023-05-01' =
200204
}
201205

202206
// Origins for each regional Application Gateway (fallback routing)
203-
resource regionalOrigins 'Microsoft.Cdn/profiles/originGroups/origins@2023-05-01' = [for (endpoint, i) in regionalEndpoints: if (length(regionalEndpoints) > 0) {
207+
resource regionalOrigins 'Microsoft.Cdn/profiles/originGroups/origins@2023-05-01' = [for (endpoint, i) in regionalEndpoints: if (!empty(endpoint.fqdn)) {
204208
name: 'agw-${endpoint.location}-origin'
205209
parent: regionalOriginGroup
206210
properties: {
@@ -216,7 +220,7 @@ resource regionalOrigins 'Microsoft.Cdn/profiles/originGroups/origins@2023-05-01
216220
}]
217221

218222
// Fallback Route for direct regional access (bypassing APIM)
219-
resource regionalRoute 'Microsoft.Cdn/profiles/afdEndpoints/routes@2023-05-01' = if (length(regionalEndpoints) > 0) {
223+
resource regionalRoute 'Microsoft.Cdn/profiles/afdEndpoints/routes@2023-05-01' = if (length([for endpoint in regionalEndpoints: if (!empty(endpoint.fqdn)) endpoint]) > 0) {
220224
name: 'regional-fallback-route'
221225
parent: frontDoorEndpoint
222226
properties: {

AzureArchitecture/host-main.bicep

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,14 @@ var regionShortNames = {
6868
westus: 'wus'
6969
westus2: 'wus2'
7070
westus3: 'wus3'
71+
centralus: 'cus'
7172
northeurope: 'neu'
7273
westeurope: 'weu'
7374
}
7475

7576
// Short names for geographies, used in resource naming.
7677
var geoShortNames = {
77-
northamerica: 'us'
78+
northamerica: 'na'
7879
europe: 'eu'
7980
asia: 'apac'
8081
}
@@ -106,15 +107,15 @@ resource globalResourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
106107
// Create a resource group for each region
107108
// Each region gets its own RG for isolation and quota management.
108109
resource regionResourceGroups 'Microsoft.Resources/resourceGroups@2021-04-01' = [for region in regions: {
109-
name: 'rg-stamps-region-${region.geoName}-${region.regionName}-${envShort}'
110+
name: 'rg-stamps-region-${(geoShortNames[?region.geoName] ?? substring(region.geoName, 0, 2))}-${region.regionName}-${envShort}'
110111
location: region.regionName
111112
tags: union(tags, { geo: region.geoName, region: region.regionName, scope: 'region' })
112113
}]
113114

114115
// Create a resource group for each CELL
115116
// CELLs are the core isolation boundary for tenants; each gets its own RG.
116117
resource cellResourceGroups 'Microsoft.Resources/resourceGroups@2021-04-01' = [for cell in cells: {
117-
name: 'rg-stamps-cell-${cell.geoName}-${cell.regionName}-${cell.cellName}-${envShort}'
118+
name: 'rg-stamps-cell-${(geoShortNames[?cell.geoName] ?? substring(cell.geoName, 0, 2))}-${cell.regionName}-${cell.cellName}-${envShort}'
118119
location: cell.regionName
119120
tags: union(tags, {
120121
geo: cell.geoName
@@ -135,8 +136,8 @@ resource cellResourceGroups 'Microsoft.Resources/resourceGroups@2021-04-01' = [f
135136

136137
// Deploy regional modules into their region RGs
137138
module regionalNetworks './regionalNetwork.bicep' = [for (region, idx) in regions: {
138-
name: 'regionalNetwork-${region.geoName}-${region.regionName}'
139-
scope: resourceGroup('rg-stamps-region-${region.geoName}-${region.regionName}-${envShort}')
139+
name: 'regionalNetwork-${(geoShortNames[?region.geoName] ?? substring(region.geoName, 0, 2))}-${region.regionName}'
140+
scope: resourceGroup('rg-stamps-region-${(geoShortNames[?region.geoName] ?? substring(region.geoName, 0, 2))}-${region.regionName}-${envShort}')
140141
params: {
141142
location: region.regionName
142143
geoName: region.geoName
@@ -151,8 +152,8 @@ module regionalNetworks './regionalNetwork.bicep' = [for (region, idx) in region
151152

152153
// Deploy monitoring and regional layers into their region RGs
153154
module monitoringLayers './monitoringLayer.bicep' = [for (region, idx) in regions: {
154-
name: 'monitoring-${region.geoName}-${region.regionName}'
155-
scope: resourceGroup('rg-region-${region.geoName}-${region.regionName}')
155+
name: 'monitoring-${(geoShortNames[?region.geoName] ?? substring(region.geoName, 0, 2))}-${region.regionName}'
156+
scope: resourceGroup('rg-stamps-region-${(geoShortNames[?region.geoName] ?? substring(region.geoName, 0, 2))}-${region.regionName}-${envShort}')
156157
params: {
157158
location: region.regionName
158159
logAnalyticsWorkspaceName: 'law-stamps-${(regionShortNames[?region.regionName] ?? substring(region.regionName, 0, 3))}-${envShort}'
@@ -162,8 +163,8 @@ module monitoringLayers './monitoringLayer.bicep' = [for (region, idx) in region
162163
}]
163164

164165
module regionalLayers './regionalLayer.bicep' = [for (region, idx) in regions: {
165-
name: 'regional-${region.geoName}-${region.regionName}'
166-
scope: resourceGroup('rg-region-${region.geoName}-${region.regionName}')
166+
name: 'regional-${(geoShortNames[?region.geoName] ?? substring(region.geoName, 0, 2))}-${region.regionName}'
167+
scope: resourceGroup('rg-stamps-region-${(geoShortNames[?region.geoName] ?? substring(region.geoName, 0, 2))}-${region.regionName}-${envShort}')
167168
params: {
168169
location: region.regionName
169170
appGatewayName: 'agw-${(geoShortNames[?region.geoName] ?? substring(region.geoName, 0, 2))}-${(regionShortNames[?region.regionName] ?? substring(region.regionName, 0, 3))}-${envShort}'
@@ -183,17 +184,17 @@ module regionalLayers './regionalLayer.bicep' = [for (region, idx) in regions: {
183184

184185
// Deploy the CELL module into each dedicated RG
185186
module deploymentStampLayers './deploymentStampLayer.bicep' = [for (cell, idx) in cells: {
186-
name: 'cell-${cell.geoName}-${cell.regionName}-${cell.cellName}'
187-
scope: resourceGroup('rg-stamps-cell-${cell.geoName}-${cell.regionName}-${cell.cellName}-${envShort}')
187+
name: 'cell-${(geoShortNames[?cell.geoName] ?? substring(cell.geoName, 0, 2))}-${cell.regionName}-${cell.cellName}'
188+
scope: resourceGroup('rg-stamps-cell-${(geoShortNames[?cell.geoName] ?? substring(cell.geoName, 0, 2))}-${cell.regionName}-${cell.cellName}-${envShort}')
188189
params: {
189190
location: cell.regionName
190-
sqlServerName: toLower('sql-${(geoShortNames[?cell.geoName] ?? substring(cell.geoName, 0, 2))}-${(regionShortNames[?cell.regionName] ?? substring(cell.regionName, 0, 3))}-cell${(substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 0, 2) == '00' ? substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 2, 1) : (substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 0, 1) == '0' ? substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 1, 2) : substring(cell.cellName, length(cell.cellName) - 3, 3)))}-${envShort}')
191+
sqlServerName: toLower('sql-${(geoShortNames[?cell.geoName] ?? substring(cell.geoName, 0, 2))}-${(regionShortNames[?cell.regionName] ?? substring(cell.regionName, 0, 3))}-cell${substring(cell.cellName, length(cell.cellName) - 2, 2)}-${envShort}')
191192
sqlAdminUsername: sqlAdminUsername
192193
sqlAdminPassword: sqlAdminPassword
193-
sqlDbName: toLower('sqldb-cell${(substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 0, 2) == '00' ? substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 2, 1) : (substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 0, 1) == '0' ? substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 1, 2) : substring(cell.cellName, length(cell.cellName) - 3, 3)))}-z${string(length(cell.availabilityZones))}-${(regionShortNames[?cell.regionName] ?? substring(cell.regionName, 0, 3))}-${envShort}')
194-
storageAccountName: toLower('st${(geoShortNames[?cell.geoName] ?? substring(cell.geoName, 0, 2))}${(regionShortNames[?cell.regionName] ?? substring(cell.regionName, 0, 3))}cell${(substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 0, 2) == '00' ? substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 2, 1) : (substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 0, 1) == '0' ? substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 1, 2) : substring(cell.cellName, length(cell.cellName) - 3, 3)))}z${string(length(cell.availabilityZones))}${envShort}${substring(uniqueString(subscription().id, cell.regionName, cell.cellName, deployment().name), 0, 2)}')
195-
keyVaultName: toLower('kv-${(geoShortNames[?cell.geoName] ?? substring(cell.geoName, 0, 2))}-${(regionShortNames[?cell.regionName] ?? substring(cell.regionName, 0, 3))}-cell${(substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 0, 2) == '00' ? substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 2, 1) : (substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 0, 1) == '0' ? substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 1, 2) : substring(cell.cellName, length(cell.cellName) - 3, 3)))}-${envShort}-${substring(uniqueString(subscription().id, cell.regionName, cell.cellName), 0, 2)}')
196-
cosmosDbStampName: toLower('cosmos${(geoShortNames[?cell.geoName] ?? substring(cell.geoName, 0, 2))}${(regionShortNames[?cell.regionName] ?? substring(cell.regionName, 0, 3))}cell${(substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 0, 2) == '00' ? substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 2, 1) : (substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 0, 1) == '0' ? substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 1, 2) : substring(cell.cellName, length(cell.cellName) - 3, 3)))}z${string(length(cell.availabilityZones))}${envShort}${substring(uniqueString(subscription().id, cell.regionName, cell.cellName, deployment().name), 0, 6)}')
194+
sqlDbName: toLower('sqldb-cell${substring(cell.cellName, length(cell.cellName) - 2, 2)}-z${string(length(cell.availabilityZones))}-${(regionShortNames[?cell.regionName] ?? substring(cell.regionName, 0, 3))}-${envShort}')
195+
storageAccountName: toLower('st${(geoShortNames[?cell.geoName] ?? substring(cell.geoName, 0, 2))}${(regionShortNames[?cell.regionName] ?? substring(cell.regionName, 0, 3))}cell${substring(cell.cellName, length(cell.cellName) - 2, 2)}z${string(length(cell.availabilityZones))}${envShort}${substring(uniqueString(subscription().id, cell.regionName, cell.cellName, deployment().name), 0, 2)}')
196+
keyVaultName: toLower('kv-${(geoShortNames[?cell.geoName] ?? substring(cell.geoName, 0, 2))}-${(regionShortNames[?cell.regionName] ?? substring(cell.regionName, 0, 3))}-cell${substring(cell.cellName, length(cell.cellName) - 2, 2)}-${envShort}-${substring(uniqueString(subscription().id, cell.regionName, cell.cellName), 0, 2)}')
197+
cosmosDbStampName: toLower('cosmos${(geoShortNames[?cell.geoName] ?? substring(cell.geoName, 0, 2))}${(regionShortNames[?cell.regionName] ?? substring(cell.regionName, 0, 3))}cell${substring(cell.cellName, length(cell.cellName) - 2, 2)}z${string(length(cell.availabilityZones))}${envShort}${substring(uniqueString(subscription().id, cell.regionName, cell.cellName, deployment().name), 0, 6)}')
197198
tags: union(tags, {
198199
geo: cell.geoName
199200
region: cell.regionName
@@ -204,7 +205,7 @@ module deploymentStampLayers './deploymentStampLayer.bicep' = [for (cell, idx) i
204205
})
205206
containerRegistryName: toLower('acr${(geoShortNames[?cell.geoName] ?? substring(cell.geoName, 0, 2))}${(regionShortNames[?cell.regionName] ?? substring(cell.regionName, 0, 3))}${envShort}')
206207
enableContainerRegistry: false
207-
containerAppName: toLower('ca-cell${(substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 0, 2) == '00' ? substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 2, 1) : (substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 0, 1) == '0' ? substring(substring(cell.cellName, length(cell.cellName) - 3, 3), 1, 2) : substring(cell.cellName, length(cell.cellName) - 3, 3)))}-z${string(length(cell.availabilityZones))}-${(regionShortNames[?cell.regionName] ?? substring(cell.regionName, 0, 3))}-${envShort}')
208+
containerAppName: toLower('ca-cell${substring(cell.cellName, length(cell.cellName) - 2, 2)}-z${string(length(cell.availabilityZones))}-${(regionShortNames[?cell.regionName] ?? substring(cell.regionName, 0, 3))}-${envShort}')
208209
baseDomain: cell.baseDomain
209210
globalLogAnalyticsWorkspaceId: globalLogAnalyticsWorkspaceId
210211
cosmosAdditionalLocations: cell.?cosmosAdditionalLocations ?? []

AzureArchitecture/host-main.parameters.json

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,38 @@
66
"managementClientTenantId": { "value": "30dd575a-bca7-491b-adf6-41d5f39275d4" },
77
"tags": { "value": { "environment": "tst", "project": "StampsPattern" } },
88
"sqlAdminUsername": { "value": "sqladmin" },
9-
"sqlAdminPassword": { "value": "REPLACE_WITH_SECURE_PASSWORD" },
10-
"globalLogAnalyticsWorkspaceId": { "value": "REPLACE_WITH_HUB_LAW_ID" },
11-
"smoke": { "value": false },
9+
"sqlAdminPassword": { "value": "G7!rT9p#xQ2z@LmS" },
10+
"globalLogAnalyticsWorkspaceId": { "value": "/subscriptions/2fb123ca-e419-4838-9b44-c2eb71a21769/resourceGroups/rg-stamps-global-tst/providers/Microsoft.OperationalInsights/workspaces/law-stamps-na-wus3" },
11+
"smoke": { "value": true },
1212
"regions": {
1313
"value": [
14-
{
15-
"geoName": "northamerica",
16-
"regionName": "westus2",
17-
"cells": ["cell-01", "cell-02", "cell-03"],
18-
"baseDomain": "westus2.stamps.sdp-saas.com",
19-
"keyVaultName": "kv-stamps-na-wus2",
20-
"logAnalyticsWorkspaceName": "law-stamps-na-wus2"
21-
},
2214
{
2315
"geoName": "northamerica",
2416
"regionName": "westus3",
2517
"cells": ["cell-01", "cell-02", "cell-03"],
2618
"baseDomain": "westus3.stamps.sdp-saas.com",
2719
"keyVaultName": "kv-stamps-na-wus3",
2820
"logAnalyticsWorkspaceName": "law-stamps-na-wus3"
21+
},
22+
{
23+
"geoName": "northamerica",
24+
"regionName": "centralus",
25+
"cells": ["cell-01", "cell-02", "cell-03"],
26+
"baseDomain": "centralus.stamps.sdp-saas.com",
27+
"keyVaultName": "kv-stamps-na-cus",
28+
"logAnalyticsWorkspaceName": "law-stamps-na-cus"
2929
}
3030
]
3131
},
3232
"cells": {
3333
"value": [
34-
{ "geoName": "northamerica", "regionName": "westus2", "cellName": "CELL-001", "cellType": "Shared", "availabilityZones": [], "maxTenantCount": 100, "baseDomain": "westus2.stamps.sdp-saas.com" },
35-
{ "geoName": "northamerica", "regionName": "westus2", "cellName": "CELL-002", "cellType": "Shared", "availabilityZones": ["1", "2"], "maxTenantCount": 100, "baseDomain": "westus2.stamps.sdp-saas.com" },
36-
{ "geoName": "northamerica", "regionName": "westus2", "cellName": "CELL-003", "cellType": "Dedicated", "availabilityZones": ["1", "2", "3"], "maxTenantCount": 1, "baseDomain": "westus2.stamps.sdp-saas.com" },
34+
{ "geoName": "northamerica", "regionName": "westus3", "cellName": "CELL-01", "cellType": "Shared", "availabilityZones": [], "maxTenantCount": 100, "baseDomain": "westus3.stamps.sdp-saas.com" },
35+
{ "geoName": "northamerica", "regionName": "westus3", "cellName": "CELL-02", "cellType": "Shared", "availabilityZones": [], "maxTenantCount": 100, "baseDomain": "westus3.stamps.sdp-saas.com" },
36+
{ "geoName": "northamerica", "regionName": "westus3", "cellName": "CELL-03", "cellType": "Dedicated", "availabilityZones": [], "maxTenantCount": 1, "baseDomain": "westus3.stamps.sdp-saas.com" },
3737

38-
{ "geoName": "northamerica", "regionName": "westus3", "cellName": "CELL-001", "cellType": "Dedicated", "availabilityZones": [], "maxTenantCount": 1, "baseDomain": "westus3.stamps.sdp-saas.com" },
39-
{ "geoName": "northamerica", "regionName": "westus3", "cellName": "CELL-002", "cellType": "Shared", "availabilityZones": ["1", "2"], "maxTenantCount": 100, "baseDomain": "westus3.stamps.sdp-saas.com" },
40-
{ "geoName": "northamerica", "regionName": "westus3", "cellName": "CELL-003", "cellType": "Dedicated", "availabilityZones": ["1", "2", "3"], "maxTenantCount": 1, "baseDomain": "westus3.stamps.sdp-saas.com" }
38+
{ "geoName": "northamerica", "regionName": "centralus", "cellName": "CELL-01", "cellType": "Dedicated", "availabilityZones": [], "maxTenantCount": 1, "baseDomain": "centralus.stamps.sdp-saas.com" },
39+
{ "geoName": "northamerica", "regionName": "centralus", "cellName": "CELL-02", "cellType": "Shared", "availabilityZones": [], "maxTenantCount": 100, "baseDomain": "centralus.stamps.sdp-saas.com" },
40+
{ "geoName": "northamerica", "regionName": "centralus", "cellName": "CELL-03", "cellType": "Dedicated", "availabilityZones": [], "maxTenantCount": 1, "baseDomain": "centralus.stamps.sdp-saas.com" }
4141
]
4242
}
4343
}

0 commit comments

Comments
 (0)