@@ -205,24 +205,197 @@ param purviewAccountResourceId string = ''
205205@description ('Optional. Existing Purview collection name' )
206206param purviewCollectionName string = ''
207207
208+ // ========================================
209+ // PARAMETERS - POSTGRESQL FLEXIBLE SERVER
210+ // ========================================
211+
212+ @description ('Deploy PostgreSQL Flexible Server.' )
213+ param deployPostgreSql bool = false
214+
215+ @description ('PostgreSQL Flexible Server name.' )
216+ param postgreSqlServerName string = 'pg${resourceToken }'
217+
218+ @description ('Enable network isolation for PostgreSQL (private DNS + private endpoint).' )
219+ param postgreSqlNetworkIsolation bool = networkIsolation
220+
221+ @description ('Create and link the PostgreSQL private DNS zone to the VNet.' )
222+ param deployPostgreSqlPrivateDnsLink bool = true
223+
224+ @description ('Optional override for the PostgreSQL private DNS VNet link name.' )
225+ param postgreSqlPrivateDnsLinkNameOverride string = ''
226+
227+ @description ('PostgreSQL admin username.' )
228+ param postgreSqlAdminLogin string = 'pgadmin'
229+
230+ @description ('PostgreSQL admin password.' )
231+ @secure ()
232+ param postgreSqlAdminPassword string
233+
234+ @description ('Store PostgreSQL admin password in Key Vault.' )
235+ param enablePostgreSqlKeyVaultSecret bool = true
236+
237+ @description ('Key Vault secret name for PostgreSQL admin password.' )
238+ param postgreSqlAdminSecretName string = 'postgres-admin-password'
239+
240+ @description ('PostgreSQL role name for Fabric mirroring.' )
241+ param postgreSqlFabricUserName string = 'fabric_user'
242+
243+ @description ('Key Vault secret name for the Fabric mirroring PostgreSQL role password.' )
244+ param postgreSqlFabricUserSecretName string = 'postgres-fabric-user-password'
245+
246+ @description ('PostgreSQL SKU name (tier + family + cores).' )
247+ param postgreSqlSkuName string = 'Standard_D2s_v3'
248+
249+ @description ('PostgreSQL tier aligned with SKU.' )
250+ @allowed ([
251+ 'Burstable'
252+ 'GeneralPurpose'
253+ 'MemoryOptimized'
254+ ])
255+ param postgreSqlTier string = 'GeneralPurpose'
256+
257+ @description ('PostgreSQL availability zone. -1 means no zone preference.' )
258+ @allowed ([
259+ -1
260+ 1
261+ 2
262+ 3
263+ ])
264+ param postgreSqlAvailabilityZone int = -1
265+
266+ @description ('PostgreSQL high availability mode.' )
267+ @allowed ([
268+ 'Disabled'
269+ 'SameZone'
270+ 'ZoneRedundant'
271+ ])
272+ param postgreSqlHighAvailability string = 'Disabled'
273+
274+ @description ('PostgreSQL high availability standby zone. -1 means no zone preference.' )
275+ @allowed ([
276+ -1
277+ 1
278+ 2
279+ 3
280+ ])
281+ param postgreSqlHighAvailabilityZone int = -1
282+
283+ @description ('PostgreSQL version.' )
284+ @allowed ([
285+ '11'
286+ '12'
287+ '13'
288+ '14'
289+ '15'
290+ '16'
291+ '17'
292+ '18'
293+ ])
294+ param postgreSqlVersion string = '16'
295+
296+ @description ('PostgreSQL storage size in GB.' )
297+ param postgreSqlStorageSizeGB int = 32
298+
208299// ========================================
209300// FABRIC CAPACITY DEPLOYMENT
210301// ========================================
211302
212303var effectiveFabricCapacityMode = fabricCapacityMode
213304var effectiveFabricWorkspaceMode = fabricWorkspaceMode
305+ var effectiveLocation = !empty (location ) ? location : resourceGroup ().location
214306
215307var envSlugSanitized = replace (replace (replace (replace (replace (replace (replace (replace (toLower (environmentName ), ' ' , '' ), '-' , '' ), '_' , '' ), '.' , '' ), '/' , '' ), '\\ ' , '' ), ':' , '' ), ',' , '' )
216308
217309var envSlugTrimmed = substring (envSlugSanitized , 0 , min (40 , length (envSlugSanitized )))
218310var capacityNameBase = !empty (envSlugTrimmed ) ? 'fabric${envSlugTrimmed }' : 'fabric${baseName }'
219311var capacityName = substring (capacityNameBase , 0 , min (50 , length (capacityNameBase )))
220312
313+ var effectiveVnetResourceId = useExistingVNet && !empty (existingVnetResourceId )
314+ ? existingVnetResourceId
315+ : resourceId ('Microsoft.Network/virtualNetworks' , vnetName )
316+
317+ var postgreSqlPrivateDnsZoneName = 'privatelink.postgres.database.azure.com'
318+ var postgreSqlPrivateDnsLinkNameRaw = '${postgreSqlServerName }-vnetlink'
319+ var postgreSqlPrivateEndpointNameRaw = '${postgreSqlServerName }-pe'
320+ var postgreSqlPrivateDnsLinkName = substring (postgreSqlPrivateDnsLinkNameRaw , 0 , min (80 , length (postgreSqlPrivateDnsLinkNameRaw )))
321+ var effectivePostgreSqlPrivateDnsLinkName = !empty (postgreSqlPrivateDnsLinkNameOverride )
322+ ? postgreSqlPrivateDnsLinkNameOverride
323+ : postgreSqlPrivateDnsLinkName
324+ var postgreSqlPrivateEndpointName = substring (postgreSqlPrivateEndpointNameRaw , 0 , min (80 , length (postgreSqlPrivateEndpointNameRaw )))
325+
326+ var effectiveKeyVaultResourceId = !empty (keyVaultResourceId )
327+ ? keyVaultResourceId
328+ : resourceId ('Microsoft.KeyVault/vaults' , keyVaultName )
329+
330+ resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
331+ name : last (split (effectiveKeyVaultResourceId , '/' ))
332+ }
333+
334+ resource postgreSqlPrivateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' = if (deployPostgreSql && postgreSqlNetworkIsolation ) {
335+ name : postgreSqlPrivateDnsZoneName
336+ location : 'global'
337+ tags : deploymentTags
338+ }
339+
340+ resource postgreSqlPrivateDnsZoneVnetLink 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2020-06-01' = if (deployPostgreSql && postgreSqlNetworkIsolation && deployPostgreSqlPrivateDnsLink ) {
341+ name : '${postgreSqlPrivateDnsZone .name }/${effectivePostgreSqlPrivateDnsLinkName }'
342+ location : 'global'
343+ properties : {
344+ virtualNetwork : {
345+ id : effectiveVnetResourceId
346+ }
347+ registrationEnabled : false
348+ }
349+ }
350+
351+ var postgreSqlPrivateEndpoints = postgreSqlNetworkIsolation ? [
352+ {
353+ name : postgreSqlPrivateEndpointName
354+ subnetResourceId : '${effectiveVnetResourceId }/subnets/${peSubnetName }'
355+ privateDnsZoneGroup : {
356+ privateDnsZoneGroupConfigs : [
357+ {
358+ privateDnsZoneResourceId : postgreSqlPrivateDnsZone .id
359+ }
360+ ]
361+ }
362+ }
363+ ] : []
364+
365+ module postgreSqlFlexibleServer 'br/public:avm/res/db-for-postgre-sql/flexible-server:0.15.2' = if (deployPostgreSql ) {
366+ name : 'postgresql-flexible'
367+ params : {
368+ availabilityZone : postgreSqlAvailabilityZone
369+ highAvailability : postgreSqlHighAvailability
370+ highAvailabilityZone : postgreSqlHighAvailabilityZone
371+ name : postgreSqlServerName
372+ skuName : postgreSqlSkuName
373+ tier : postgreSqlTier
374+ administratorLogin : postgreSqlAdminLogin
375+ administratorLoginPassword : postgreSqlAdminPassword
376+ managedIdentities : {
377+ systemAssigned : true
378+ }
379+ publicNetworkAccess : postgreSqlNetworkIsolation ? 'Disabled' : 'Enabled'
380+ version : postgreSqlVersion
381+ storageSizeGB : postgreSqlStorageSizeGB
382+ privateEndpoints : postgreSqlPrivateEndpoints
383+ tags : deploymentTags
384+ }
385+ }
386+
387+ resource postgreSqlAdminSecret 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = if (deployPostgreSql && enablePostgreSqlKeyVaultSecret ) {
388+ name : '${keyVault .name }/${postgreSqlAdminSecretName }'
389+ properties : {
390+ value : postgreSqlAdminPassword
391+ }
392+ }
393+
221394module fabricCapacity 'modules/fabric-capacity.bicep' = if (effectiveFabricCapacityMode == 'create' ) {
222395 name : 'fabric-capacity'
223396 params : {
224397 capacityName : capacityName
225- location : location
398+ location : effectiveLocation
226399 sku : fabricCapacitySku
227400 adminMembers : fabricCapacityAdmins
228401 tags : deploymentTags
@@ -233,14 +406,6 @@ module fabricCapacity 'modules/fabric-capacity.bicep' = if (effectiveFabricCapac
233406// OUTPUTS - Pass through from AI Landing Zone
234407// ========================================
235408
236- var effectiveVnetResourceId = useExistingVNet && !empty (existingVnetResourceId )
237- ? existingVnetResourceId
238- : resourceId ('Microsoft.Network/virtualNetworks' , vnetName )
239-
240- var effectiveKeyVaultResourceId = !empty (keyVaultResourceId )
241- ? keyVaultResourceId
242- : resourceId ('Microsoft.KeyVault/vaults' , keyVaultName )
243-
244409var effectiveAiSearchResourceId = !empty (aiSearchResourceId )
245410 ? aiSearchResourceId
246411 : resourceId ('Microsoft.Search/searchServices' , searchServiceName )
@@ -276,6 +441,16 @@ output fabricCapacityResourceIdOut string = effectiveFabricCapacityResourceId
276441output fabricCapacityName string = effectiveFabricCapacityName
277442output fabricCapacityId string = effectiveFabricCapacityResourceId
278443
444+ // PostgreSQL outputs
445+ output postgreSqlServerNameOut string = deployPostgreSql ? postgreSqlFlexibleServer .outputs .name : ''
446+ output postgreSqlServerResourceId string = deployPostgreSql ? postgreSqlFlexibleServer .outputs .resourceId : ''
447+ output postgreSqlServerFqdn string = deployPostgreSql ? postgreSqlFlexibleServer .outputs .fqdn : ''
448+ output postgreSqlSystemAssignedPrincipalId string = deployPostgreSql ? postgreSqlFlexibleServer .outputs .systemAssignedMIPrincipalId : ''
449+ output postgreSqlAdminSecretName string = deployPostgreSql && enablePostgreSqlKeyVaultSecret ? postgreSqlAdminSecretName : ''
450+ output postgreSqlAdminLoginOut string = deployPostgreSql ? postgreSqlAdminLogin : ''
451+ output postgreSqlFabricUserNameOut string = deployPostgreSql ? postgreSqlFabricUserName : ''
452+ output postgreSqlFabricUserSecretNameOut string = deployPostgreSql && enablePostgreSqlKeyVaultSecret ? postgreSqlFabricUserSecretName : ''
453+
279454var effectiveFabricWorkspaceName = effectiveFabricWorkspaceMode == 'byo'
280455 ? (!empty (fabricWorkspaceName ) ? fabricWorkspaceName : (!empty (environmentName ) ? 'workspace-${environmentName }' : 'workspace-${baseName }' ))
281456 : (!empty (environmentName ) ? 'workspace-${environmentName }' : 'workspace-${baseName }' )
0 commit comments