|
5 | 5 | "_generator": { |
6 | 6 | "name": "bicep", |
7 | 7 | "version": "0.36.177.2456", |
8 | | - "templateHash": "15970509425891056575" |
| 8 | + "templateHash": "8960822814596420700" |
9 | 9 | } |
10 | 10 | }, |
11 | 11 | "parameters": { |
|
2677 | 2677 | } |
2678 | 2678 | }, |
2679 | 2679 | "variables": { |
2680 | | - "$fxv#0": "#Requires -Version 7.2\r\n\r\n<#\r\n.SYNOPSIS\r\n Creates a SQL user and assigns the user account to one or more roles.\r\n\r\n.DESCRIPTION\r\n During an application deployment, the managed identity (and potentially the developer identity)\r\n must be added to the SQL database as a user and assigned to one or more roles. This script\r\n accomplishes this task using the owner-managed identity for authentication.\r\n\r\n.PARAMETER SqlServerName\r\n The name of the Azure SQL Server resource.\r\n\r\n.PARAMETER SqlDatabaseName\r\n The name of the Azure SQL Database where the user will be created.\r\n\r\n.PARAMETER ClientId\r\n The Client (Principal) ID (GUID) of the identity to be added.\r\n\r\n.PARAMETER DisplayName\r\n The Object (Principal) display name of the identity to be added.\r\n\r\n.PARAMETER DatabaseRoles\r\n A comma-separated string of database roles to assign (e.g., 'db_datareader,db_datawriter')\r\n#>\r\n\r\nParam(\r\n [string] $SqlServerName,\r\n [string] $SqlDatabaseName,\r\n [string] $ClientId,\r\n [string] $DisplayName,\r\n [string] $DatabaseRoles\r\n)\r\n\r\n# Using specific version of SqlServer module to avoid issues with newer versions\r\n$SqlServerModuleVersion = \"22.3.0\"\r\n\r\nfunction Resolve-Module($moduleName) {\r\n # If module is imported; say that and do nothing\r\n if (Get-Module | Where-Object { $_.Name -eq $moduleName }) {\r\n Write-Debug \"Module $moduleName is already imported\"\r\n } elseif (Get-Module -ListAvailable | Where-Object { $_.Name -eq $moduleName }) {\r\n Import-Module $moduleName\r\n } elseif (Find-Module -Name $moduleName | Where-Object { $_.Name -eq $moduleName }) {\r\n # Use specific version for SqlServer\r\n if ($ModuleName -eq \"SqlServer\") {\r\n Install-Module -Name $ModuleName -RequiredVersion $SqlServerModuleVersion -Force -Scope CurrentUser\r\n } else {\r\n Install-Module -Name $ModuleName -Force\r\n }\r\n Import-Module $moduleName\r\n } else {\r\n Write-Error \"Module $moduleName not found\"\r\n [Environment]::exit(1)\r\n }\r\n}\r\n\r\n###\r\n### MAIN SCRIPT\r\n###\r\nResolve-Module -moduleName Az.Resources\r\nResolve-Module -moduleName SqlServer\r\n\r\n# Split comma-separated roles into an array\r\n$roleArray = $DatabaseRoles -split ','\r\n\r\n$roleSql = \"\"\r\nforeach ($role in $roleArray) {\r\n $trimmedRole = $role.Trim()\r\n $roleSql += \"EXEC sp_addrolemember N'$trimmedRole', N'$DisplayName';`n\"\r\n}\r\n\r\n$sql = @\"\r\nDECLARE @username nvarchar(max) = N'$($DisplayName)';\r\nDECLARE @clientId uniqueidentifier = '$($ClientId)';\r\nDECLARE @sid NVARCHAR(max) = CONVERT(VARCHAR(max), CONVERT(VARBINARY(16), @clientId), 1);\r\nDECLARE @cmd NVARCHAR(max) = N'CREATE USER [' + @username + '] WITH SID = ' + @sid + ', TYPE = E;';\r\nIF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = @username)\r\nBEGIN\r\n EXEC(@cmd)\r\nEND\r\n$($roleSql)\r\n\"@\r\n\r\nWrite-Output \"`nSQL:`n$($sql)`n`n\"\r\n\r\n$token = (Get-AzAccessToken -AsSecureString -ResourceUrl https://database.windows.net/).Token\r\n$ssPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($token)\r\ntry {\r\n $serverInstance = if ($SqlServerName -like \"*.database.windows.net\") { \r\n $SqlServerName \r\n } else { \r\n \"$SqlServerName.database.windows.net\" \r\n }\r\n $plaintext = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ssPtr)\r\n Invoke-Sqlcmd -ServerInstance $serverInstance -Database $SqlDatabaseName -AccessToken $plaintext -Query $sql -ErrorAction 'Stop'\r\n} finally {\r\n # The following line ensures that sensitive data is not left in memory.\r\n $plainText = [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ssPtr)\r\n}" |
| 2680 | + "$fxv#0": "#Requires -Version 7.2\r\n\r\n<#\r\n.SYNOPSIS\r\n Creates a SQL user and assigns the user account to one or more roles.\r\n\r\n.DESCRIPTION\r\n During an application deployment, the managed identity (and potentially the developer identity)\r\n must be added to the SQL database as a user and assigned to one or more roles. This script\r\n accomplishes this task using the owner-managed identity for authentication.\r\n\r\n.PARAMETER SqlServerName\r\n The name of the Azure SQL Server resource.\r\n\r\n.PARAMETER SqlDatabaseName\r\n The name of the Azure SQL Database where the user will be created.\r\n\r\n.PARAMETER ClientId\r\n The Client (Principal) ID (GUID) of the identity to be added.\r\n\r\n.PARAMETER DisplayName\r\n The Object (Principal) display name of the identity to be added.\r\n\r\n.PARAMETER DatabaseRoles\r\n A comma-separated string of database roles to assign (e.g., 'db_datareader,db_datawriter')\r\n#>\r\n\r\nParam(\r\n [string] $SqlServerName,\r\n [string] $SqlDatabaseName,\r\n [string] $ClientId,\r\n [string] $DisplayName,\r\n [string] $DatabaseRoles\r\n)\r\n\r\n# Using specific version of SqlServer module to avoid issues with newer versions\r\n$SqlServerModuleVersion = \"22.3.0\"\r\n\r\nfunction Resolve-Module($moduleName) {\r\n # If module is imported; say that and do nothing\r\n if (Get-Module | Where-Object { $_.Name -eq $moduleName }) {\r\n Write-Debug \"Module $moduleName is already imported\"\r\n } elseif (Get-Module -ListAvailable | Where-Object { $_.Name -eq $moduleName }) {\r\n Import-Module $moduleName\r\n } elseif (Find-Module -Name $moduleName | Where-Object { $_.Name -eq $moduleName }) {\r\n # Use specific version for SqlServer\r\n if ($moduleName -eq \"SqlServer\") {\r\n Install-Module -Name $moduleName -RequiredVersion $SqlServerModuleVersion -Force -Scope CurrentUser\r\n } else {\r\n Install-Module -Name $moduleName -Force\r\n }\r\n Import-Module $moduleName\r\n } else {\r\n Write-Error \"Module $moduleName not found\"\r\n [Environment]::exit(1)\r\n }\r\n}\r\n\r\n###\r\n### MAIN SCRIPT\r\n###\r\nResolve-Module -moduleName Az.Resources\r\nResolve-Module -moduleName SqlServer\r\n\r\n# Split comma-separated roles into an array\r\n$roleArray = $DatabaseRoles -split ','\r\n\r\n$roleSql = \"\"\r\nforeach ($role in $roleArray) {\r\n $trimmedRole = $role.Trim()\r\n $roleSql += \"EXEC sp_addrolemember N'$trimmedRole', N'$DisplayName';`n\"\r\n}\r\n\r\n$sql = @\"\r\nDECLARE @username nvarchar(max) = N'$($DisplayName)';\r\nDECLARE @clientId uniqueidentifier = '$($ClientId)';\r\nDECLARE @sid NVARCHAR(max) = CONVERT(VARCHAR(max), CONVERT(VARBINARY(16), @clientId), 1);\r\nDECLARE @cmd NVARCHAR(max) = N'CREATE USER [' + @username + '] WITH SID = ' + @sid + ', TYPE = E;';\r\nIF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = @username)\r\nBEGIN\r\n EXEC(@cmd)\r\nEND\r\n$($roleSql)\r\n\"@\r\n\r\nWrite-Output \"`nSQL:`n$($sql)`n`n\"\r\n\r\n$token = (Get-AzAccessToken -AsSecureString -ResourceUrl https://database.windows.net/).Token\r\n$ssPtr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($token)\r\ntry {\r\n $serverInstance = if ($SqlServerName -like \"*.database.windows.net\") { \r\n $SqlServerName \r\n } else { \r\n \"$SqlServerName.database.windows.net\" \r\n }\r\n $plaintext = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ssPtr)\r\n Invoke-Sqlcmd -ServerInstance $serverInstance -Database $SqlDatabaseName -AccessToken $plaintext -Query $sql -ErrorAction 'Stop'\r\n} finally {\r\n # The following line ensures that sensitive data is not left in memory.\r\n $plainText = [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ssPtr)\r\n}" |
2681 | 2681 | }, |
2682 | 2682 | "resources": { |
2683 | 2683 | "managedIdentity": { |
|
2756 | 2756 | "containerName": { |
2757 | 2757 | "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, resourceGroup().name), 'Microsoft.Resources/deployments', 'deploy_storage_account'), '2022-09-01').outputs.storageContainer.value]" |
2758 | 2758 | }, |
2759 | | - "managedIdentityObjectId": { |
| 2759 | + "managedIdentityResourceId": { |
2760 | 2760 | "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, resourceGroup().name), 'Microsoft.Resources/deployments', 'deploy_managed_identity'), '2022-09-01').outputs.managedIdentityOutput.value.id]" |
| 2761 | + }, |
| 2762 | + "managedIdentityClientId": { |
| 2763 | + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, resourceGroup().name), 'Microsoft.Resources/deployments', 'deploy_managed_identity'), '2022-09-01').outputs.managedIdentityOutput.value.clientId]" |
2761 | 2764 | } |
2762 | 2765 | }, |
2763 | 2766 | "template": { |
|
2767 | 2770 | "_generator": { |
2768 | 2771 | "name": "bicep", |
2769 | 2772 | "version": "0.36.177.2456", |
2770 | | - "templateHash": "13543451525678147122" |
| 2773 | + "templateHash": "11731675131496313545" |
2771 | 2774 | } |
2772 | 2775 | }, |
2773 | 2776 | "parameters": { |
|
2780 | 2783 | "baseUrl": { |
2781 | 2784 | "type": "string" |
2782 | 2785 | }, |
2783 | | - "managedIdentityObjectId": { |
| 2786 | + "managedIdentityResourceId": { |
| 2787 | + "type": "string" |
| 2788 | + }, |
| 2789 | + "managedIdentityClientId": { |
2784 | 2790 | "type": "string" |
2785 | 2791 | }, |
2786 | 2792 | "storageAccountName": { |
|
2800 | 2806 | "identity": { |
2801 | 2807 | "type": "UserAssigned", |
2802 | 2808 | "userAssignedIdentities": { |
2803 | | - "[format('{0}', parameters('managedIdentityObjectId'))]": {} |
| 2809 | + "[format('{0}', parameters('managedIdentityResourceId'))]": {} |
2804 | 2810 | } |
2805 | 2811 | }, |
2806 | 2812 | "properties": { |
2807 | 2813 | "azCliVersion": "2.52.0", |
2808 | 2814 | "primaryScriptUri": "[format('{0}infra/scripts/copy_kb_files.sh', parameters('baseUrl'))]", |
2809 | | - "arguments": "[format('{0} {1} {2} {3}', parameters('storageAccountName'), parameters('containerName'), parameters('baseUrl'), parameters('managedIdentityObjectId'))]", |
| 2815 | + "arguments": "[format('{0} {1} {2} {3}', parameters('storageAccountName'), parameters('containerName'), parameters('baseUrl'), parameters('managedIdentityClientId'))]", |
2810 | 2816 | "timeout": "PT1H", |
2811 | 2817 | "retentionInterval": "PT1H", |
2812 | 2818 | "cleanupPreference": "OnSuccess" |
|
2833 | 2839 | "solutionLocation": { |
2834 | 2840 | "value": "[parameters('secondaryLocation')]" |
2835 | 2841 | }, |
2836 | | - "managedIdentityObjectId": { |
| 2842 | + "managedIdentityResourceId": { |
2837 | 2843 | "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, resourceGroup().name), 'Microsoft.Resources/deployments', 'deploy_managed_identity'), '2022-09-01').outputs.managedIdentityOutput.value.id]" |
2838 | 2844 | }, |
2839 | 2845 | "managedIdentityClientId": { |
|
2853 | 2859 | "_generator": { |
2854 | 2860 | "name": "bicep", |
2855 | 2861 | "version": "0.36.177.2456", |
2856 | | - "templateHash": "11062122159171182625" |
| 2862 | + "templateHash": "13172962234134518300" |
2857 | 2863 | } |
2858 | 2864 | }, |
2859 | 2865 | "parameters": { |
|
2869 | 2875 | "keyVaultName": { |
2870 | 2876 | "type": "string" |
2871 | 2877 | }, |
2872 | | - "managedIdentityObjectId": { |
| 2878 | + "managedIdentityResourceId": { |
2873 | 2879 | "type": "string" |
2874 | 2880 | }, |
2875 | 2881 | "managedIdentityClientId": { |
|
2886 | 2892 | "identity": { |
2887 | 2893 | "type": "UserAssigned", |
2888 | 2894 | "userAssignedIdentities": { |
2889 | | - "[format('{0}', parameters('managedIdentityObjectId'))]": {} |
| 2895 | + "[format('{0}', parameters('managedIdentityResourceId'))]": {} |
2890 | 2896 | } |
2891 | 2897 | }, |
2892 | 2898 | "properties": { |
|
0 commit comments