@@ -416,6 +416,19 @@ module userAssignedIdentity 'br/public:avm/res/managed-identity/user-assigned-id
416416 }
417417}
418418
419+ // ========== SQL Operations User Assigned Identity ========== //
420+ // Dedicated identity for backend SQL operations with limited permissions (db_datareader, db_datawriter)
421+ var sqlUserAssignedIdentityResourceName = 'id-sql-${solutionSuffix }'
422+ module sqlUserAssignedIdentity 'br/public:avm/res/managed-identity/user-assigned-identity:0.4.1' = {
423+ name : take ('avm.res.managed-identity.user-assigned-identity.${sqlUserAssignedIdentityResourceName }' , 64 )
424+ params : {
425+ name : sqlUserAssignedIdentityResourceName
426+ location : location
427+ tags : tags
428+ enableTelemetry : enableTelemetry
429+ }
430+ }
431+
419432// ========== AVM WAF ========== //
420433// ========== Key Vault Module ========== //
421434var keyVaultName = 'kv-${solutionSuffix }'
@@ -947,7 +960,7 @@ module storageAccount 'br/public:avm/res/storage/storage-account:0.20.0' = {
947960 accessTier : 'Hot'
948961 enableTelemetry : enableTelemetry
949962 tags : tags
950- enableHierarchicalNamespace : false
963+ enableHierarchicalNamespace : true
951964 roleAssignments : [
952965 {
953966 principalId : userAssignedIdentity .outputs .principalId
@@ -1271,6 +1284,49 @@ module createIndex 'br/public:avm/res/resources/deployment-script:0.5.1' = {
12711284 dependsOn :[sqlDBModule ,uploadFiles ]
12721285}
12731286
1287+ var databaseRoles = [
1288+ 'db_datareader'
1289+ 'db_datawriter'
1290+ ]
1291+ //========== Deployment script to create Sql User and Role ========== //
1292+ module createSqlUserAndRole 'br/public:avm/res/resources/deployment-script:0.5.1' = {
1293+ name : take ('avm.res.resources.deployment-script.createSqlUserAndRole' , 64 )
1294+ params : {
1295+ // Required parameters
1296+ kind : 'AzurePowerShell'
1297+ name : 'create_sql_user_and_role'
1298+ // Non-required parameters
1299+ azPowerShellVersion : '11.0'
1300+ location : enablePrivateNetworking ? location : secondaryLocation
1301+ managedIdentities : {
1302+ userAssignedResourceIds : [
1303+ userAssignedIdentity .outputs .resourceId
1304+ ]
1305+ }
1306+ runOnce : true
1307+ arguments : join (
1308+ [
1309+ '-SqlServerName \' ${sqlServerResourceName }\' '
1310+ '-SqlDatabaseName \' ${sqlDbModuleName }\' '
1311+ '-ClientId \' ${sqlUserAssignedIdentity .outputs .clientId }\' '
1312+ '-DisplayName \' ${sqlUserAssignedIdentity .outputs .name }\' '
1313+ '-DatabaseRoles \' ${join (databaseRoles , ',' )}\' '
1314+ ],
1315+ ' '
1316+ )
1317+ scriptContent : loadTextContent ('./scripts/add_user_scripts/create-sql-user-and-role.ps1' )
1318+ tags : tags
1319+ timeout : 'PT1H'
1320+ retentionInterval : 'PT1H'
1321+ cleanupPreference : 'OnSuccess'
1322+ storageAccountResourceId : storageAccount .outputs .resourceId
1323+ subnetResourceIds : enablePrivateNetworking ? [
1324+ network !.outputs .subnetDeploymentScriptsResourceId
1325+ ] : null
1326+ }
1327+ dependsOn :[sqlDBModule ]
1328+ }
1329+
12741330// ========== AVM WAF server farm ========== //
12751331// WAF best practices for Web Application Services: https://learn.microsoft.com/en-us/azure/well-architected/service-guides/app-service-web-apps
12761332// PSRule for Web Server Farm: https://azure.github.io/PSRule.Rules.Azure/en/rules/resource/#app-service
@@ -1395,7 +1451,7 @@ module webSiteBackend 'modules/web-sites.bicep' = {
13951451 AZURE_COSMOSDB_ENABLE_FEEDBACK : 'True'
13961452 SQLDB_DATABASE : 'sqldb-${solutionSuffix }'
13971453 SQLDB_SERVER : '${sqlDBModule .outputs .name }${environment ().suffixes .sqlServerHostname }'
1398- SQLDB_USER_MID : userAssignedIdentity .outputs .clientId
1454+ SQLDB_USER_MID : sqlUserAssignedIdentity .outputs .clientId
13991455 AZURE_AI_SEARCH_ENDPOINT : 'https://${aiSearchName }.search.windows.net'
14001456 AZURE_AI_SEARCH_INDEX : 'call_transcripts_index'
14011457 AZURE_AI_SEARCH_CONNECTION_NAME : aiSearchName
@@ -1541,7 +1597,7 @@ output SQLDB_DATABASE string = 'sqldb-${solutionSuffix}'
15411597output SQLDB_SERVER string = sqlDBModule .outputs .name
15421598
15431599@description ('Contains SQL database user managed identity client ID.' )
1544- output SQLDB_USER_MID string = userAssignedIdentity .outputs .clientId
1600+ output SQLDB_USER_MID string = sqlUserAssignedIdentity .outputs .clientId
15451601
15461602@description ('Contains AI project client usage setting.' )
15471603output USE_AI_PROJECT_CLIENT string = 'False'
0 commit comments