-
2025-10-16
本操作指南概述了使用来自 Microsoft Entra ID(以前称为 Azure Active Directory)的用户分配的托管标识创建 Azure SQL 托管实例的步骤。 有关在 Azure SQL 数据库中为服务器标识使用用户分配的托管标识的好处的详细信息,请参阅 Azure SQL Microsoft Entra 中的托管标识。
注意
Microsoft Entra ID 以前称为 Azure Active Directory (Azure AD)。
先决条件
- 创建用户分配的托管标识并为其分配必要的权限,使其成为服务器或托管实例标识。 有关详细信息,请参阅管理用户分配的托管标识和 Azure SQL 的用户分配的托管标识权限。
- 一般情况下,托管标识需要在订阅范围内分配 SQL 托管实例参与者角色。 此外,它还需要在订阅范围内具有 Azure RBAC 角色以及权限 Microsoft.ManagedIdentity/userAssignedIdentities/*/assign/action(例如托管标识操作员)。
- 如果在已委托给Azure SQL 托管实例的子网中预配,托管标识只需要在订阅范围分配的 Microsoft.Sql/managedInstances/write 权限。
- 将 PowerShell 用于用户分配的托管标识时,需要 Az.Sql 模块 3.4 或更高版本。
- 需要 Azure CLI 2.26.0 或更高版本才能将 Azure CLI 与用户分配的托管标识一起使用。
- 有关使用用户分配的托管标识的限制和已知问题的列表,请参阅 Microsoft Entra 中用于 Azure SQL 的用户分配的托管标识
转到 Azure SQL 中心。
在 Azure SQL 托管实例的窗格中,选择“ 显示”选项。
在 Azure SQL 托管实例选项 窗口中,选择“ 创建 SQL 托管实例”。
在“基本信息”选项卡的“项目详细信息”和“托管实例详细信息”中填写所需的必填信息。 这是预配 SQL 托管实例所需的最少量信息。
有关配置选项的详细信息,请参阅 快速入门:创建 Azure SQL 托管实例。
在“身份验证”下,选择首选的身份验证模型。 如果要配置仅限 Microsoft Entra 身份验证,请参阅指南。
接下来,完成“网络”选项卡配置,或保留默认设置。
在“安全”选项卡的“标识”下,选择“配置标识”。
在“标识”窗格的“用户分配的托管标识”下,选择“添加”。 选择所需的订阅,然后在“用户分配的托管标识”下,从所选订阅中选择所需的用户分配的托管标识。 然后选择“选择”按钮。
在“主标识”下面,选择在上一步中选择的相同用户分配的托管标识。
注意
如果系统分配的托管标识是主标识,则“主标识”字段必须为空。
选择“应用”
可将其余设置保留为默认值。 有关其他选项卡和设置的详细信息,请按照 快速入门:创建 Azure SQL 托管实例一文中的指南进行作。
在“ 其他设置 ”选项卡上,考虑使用 Azure 标记。 例如,用于标识谁创建了资源的“所有者”或“CreatedBy”标记,以及用于标识此资源是否在生产、开发等环境中的环境标记。有关详细信息,请参阅 开发 Azure 资源的命名和标记策略。
配置完设置后,选择“查看 + 创建”以继续。 选择“创建”,开始预配托管实例。
Azure CLI 命令 az sql mi create
用于预配新的 Azure SQL 托管实例。 以下命令将预配一个具有用户分配托管身份的托管实例,并启用 仅限 Microsoft Entra 的身份验证。
注意
作为先决条件,该脚本要求创建虚拟网络和子网。
托管实例 SQL 管理员登录名将自动创建,密码将设置为随机密码。 由于在预配过程中禁用了 SQL 身份验证连接,因此不会使用 SQL 管理员登录名。
Microsoft Entra 管理员是为 <AzureADAccount>
设置的帐户,可用于在预配完成时管理实例。
替换示例中的以下值:
-
<subscriptionId>
:可以在 Azure 门户中找到订阅 ID -
<ResourceGroupName>
:托管实例的资源组的名称。 资源组还应包括创建的虚拟网络和子网 -
<managedIdentity>
:用户分配的托管标识。 还可以用作主标识。 -
<primaryIdentity>
:你要用作实例标识的主标识 -
<AzureADAccount>
:可以是 Microsoft Entra 用户或组。 例如:DummyLogin
-
<AzureADAccountSID>
:用户的 Microsoft Entra 对象 ID -
<managedinstancename>
:命名要创建的托管实例 - 需要使用
subnet
、<subscriptionId>
、<ResourceGroupName>
和<VNetName>
更新<SubnetName>
参数。
# Define variables for resources
subscriptionId="<subscriptionId>"
resourceGroupName="<ResourceGroupName>"
managedIdentity="<managedIdentity>"
primaryIdentity="<primaryIdentity>"
AzureADAccount="<AzureADAccount>"
AzureADAccountSID="<AzureADAccountSID>"
VNetName="<VNetName>"
SubnetName="<SubnetName>"
managedinstancename="<managedinstancename>"
# Create a managed instance with a user-assigned managed identity
az sql mi create \
--assign-identity \
--identity-type UserAssigned \
--user-assigned-identity-id "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$managedIdentity" \
--primary-user-assigned-identity-id "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$primaryIdentity" \
--enable-ad-only-auth \
--external-admin-principal-type User \
--external-admin-name $AzureADAccount \
--external-admin-sid $AzureADAccountSID \
-g $resourceGroupName \
-n $managedinstancename \
--subnet "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Network/virtualNetworks/$VNetName/subnets/$SubnetName"
有关详细信息,请参阅 az sql mi create。
注意
上面的示例为托管实例仅预配了一个由用户分配的托管标识。 如果希望在实例中创建两种类型的托管标识,可以将 --identity-type
设置为 UserAssigned,SystemAssigned
。
PowerShell 命令 New-AzSqlInstance
用于预配新的 Azure SQL 托管实例。 以下命令将使用用户分配的托管标识预配托管实例,并启用仅限 Microsoft Entra 身份验证。
注意
作为先决条件,该脚本要求创建虚拟网络和子网。
托管实例 SQL 管理员登录名将自动创建,密码将设置为随机密码。 由于在预配过程中禁用了 SQL 身份验证连接,因此不会使用 SQL 管理员登录名。
Microsoft Entra 管理员是为 <AzureADAccount>
设置的帐户,可用于在预配完成时管理实例。
替换示例中的以下值:
-
<managedinstancename>
:命名要创建的托管实例 -
<ResourceGroupName>
:托管实例的资源组的名称。 资源组还应包括创建的虚拟网络和子网 -
<subscriptionId>
:可以在 Azure 门户中找到订阅 ID -
<managedIdentity>
:用户分配的托管标识。 还可以用作主标识。 -
<primaryIdentity>
:你要用作实例标识的主标识 -
<Location>
:托管实例的位置,例如,China East 2
或China North 2
-
<AzureADAccount>
:可以是 Microsoft Entra 用户或组。 例如:DummyLogin
- 需要使用
SubnetId
、<subscriptionId>
、<ResourceGroupName>
和<VNetName>
更新<SubnetName>
参数。
$instanceName = @{
Name = "<managedinstancename>"
ResourceGroupName = "<ResourceGroupName>"
AssignIdentity = $true
IdentityType = "UserAssigned"
UserAssignedIdentityId = "/subscriptions/<subscriptionId>/resourceGroups/<ResourceGroupName>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<managedIdentity>"
PrimaryUserAssignedIdentityId = "/subscriptions/<subscriptionId>/resourceGroups/<ResourceGroupName>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<primaryIdentity>"
ExternalAdminName = "<AzureADAccount>"
EnableActiveDirectoryOnlyAuthentication = $true
Location = "<Location>"
SubnetId = "/subscriptions/<subscriptionId>/resourceGroups/<ResourceGroupName>/providers/Microsoft.Network/virtualNetworks/<VNetName>/subnets/<SubnetName>"
LicenseType = "LicenseIncluded"
StorageSizeInGB = 1024
VCore = 16
Edition = "GeneralPurpose"
ComputeGeneration = "Gen5"
}
New-AzSqlInstance @instanceName
有关详细信息,请参阅 New-AzSqlInstance。
注意
上面的示例为托管实例仅预配了一个由用户分配的托管标识。 如果希望在实例中创建两种类型的托管标识,可以将 -IdentityType
设置为 "UserAssigned,SystemAssigned"
。
SQL 托管实例 - 创建或更新 REST API 可用来通过用户分配的托管标识来创建一个托管实例。
注意
作为先决条件,该脚本要求创建虚拟网络和子网。
以下脚本将使用用户分配的托管标识预配托管实例,将 Microsoft Entra 管理员设置为 <AzureADAccount>
,并启用仅限 Microsoft Entra 的身份验证。 实例 SQL 管理员登录名也将自动创建,而且密码将设置为随机密码。 由于在预配过程中禁用了 SQL 身份验证连接,因此不会使用 SQL 管理员登录。
Microsoft Entra 管理员 <AzureADAccount>
可用于在预配完成时管理实例。
替换示例中的以下值:
-
<tenantId>
:可通过转到 Azure 门户并进入 Microsoft Entra ID 资源找到。 在“概述”窗格中,应会看到“租户 ID” -
<subscriptionId>
:可以在 Azure 门户中找到订阅 ID -
<instanceName>
:使用唯一的托管实例名称 -
<ResourceGroupName>
:逻辑服务器的资源组名称 -
<AzureADAccount>
:可以是 Microsoft Entra 用户或组。 例如:DummyLogin
-
<Location>
:服务器的位置,例如chinaeast2
或chinanorth2
-
<objectId>
:可通过转到 Azure 门户并进入 Microsoft Entra ID 资源找到。 在“用户”窗格中,搜索 Microsoft Entra 用户并查找其“对象 ID” - 需要使用
subnetId
、<ResourceGroupName>
、Subscription ID
和<VNetName>
更新<SubnetName>
参数
Import-Module Azure
Import-Module MSAL.PS
$tenantId = '<tenantId>'
$clientId = '1950a258-227b-4e31-a9cf-717495945fc2' # Static Microsoft client ID used for getting a token
$subscriptionId = '<subscriptionId>'
$uri = "urn:ietf:wg:oauth:2.0:oob"
$instanceName = "<instanceName>"
$resourceGroupName = "<ResourceGroupName>"
$scopes ="https://management.core.chinacloudapi.cn/.default"
Login-AzAccount -tenantId $tenantId -Environment AzureChinaCloud
# Login as an Azure AD user with permission to provision a managed instance
$result = Get-MsalToken -RedirectUri $uri -ClientId $clientId -TenantId $tenantId -Scopes $scopes
$authHeader = @{
'Content-Type'='application\json; '
'Authorization'=$result.CreateAuthorizationHeader()
}
$body = '{
"name": "<instanceName>", "type": "Microsoft.Sql/managedInstances", "identity": {"type" : "UserAssigned", "UserAssignedIdentities" : {"/subscriptions/<subscriptionId>/resourceGroups/<ResourceGroupName>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<managedIdentity>" : {}}},"location": "<Location>", "sku": {"name": "GP_Gen5", "tier": "GeneralPurpose", "family":"Gen5","capacity": 8},
"properties": { "PrimaryUserAssignedIdentityId":"/subscriptions/<subscriptionId>/resourceGroups/<ResourceGroupName>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<primaryIdentity>","administrators":{ "login":"<AzureADAccount>", "sid":"<objectId>", "tenantId":"<tenantId>", "principalType":"User", "azureADOnlyAuthentication":true },
"subnetId": "/subscriptions/<subscriptionId>/resourceGroups/<ResourceGroupName>/providers/Microsoft.Network/virtualNetworks/<VNetName>/subnets/<SubnetName>",
"licenseType": "LicenseIncluded", "vCores": 8, "storageSizeInGB": 2048, "collation": "SQL_Latin1_General_CP1_CI_AS", "proxyOverride": "Proxy", "timezoneId": "UTC", "privateEndpointConnections": [], "storageAccountType": "GRS", "zoneRedundant": false
}
}'
# To provision the instance, execute the `PUT` command
Invoke-RestMethod -Uri https://management.chinacloudapi.cn/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Sql/managedInstances/$instanceName/?api-version=2020-11-01-preview -Method PUT -Headers $authHeader -Body $body -ContentType "application/json"
要检查结果,请执行 GET
命令:
Invoke-RestMethod -Uri https://management.chinacloudapi.cn/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Sql/managedInstances/$instanceName/?api-version=2020-11-01-preview -Method GET -Headers $authHeader | Format-List
若要预配使用 Microsoft Entra 管理员、用户分配的托管标识和仅限 Microsoft Entra 身份验证配置的新虚拟网络、子网和新托管实例,请使用以下模板。
使用 Azure 门户中的自定义部署,在编辑器中生成自己的模板。 接下来,粘贴到示例中后保存配置。
若要获取用户分配的托管标识资源 ID,请在 Azure 门户中搜索托管标识。 找到你的托管标识,然后转到“属性”。 你的 UMI 资源 ID 示例如 所示。
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.1",
"parameters": {
"managedInstanceName": {
"type": "String",
"metadata": {
"description": "Enter managed instance name."
}
},
"aad_admin_name": {
"type": "String",
"metadata": {
"description": "The name of the Azure AD admin for the SQL managed instance."
}
},
"aad_admin_objectid": {
"type": "String",
"metadata": {
"description": "The Object ID of the Azure AD admin."
}
},
"aad_admin_tenantid": {
"type": "String",
"defaultValue": "[subscription().tenantId]",
"metadata": {
"description": "The Tenant ID of the Azure Active Directory"
}
},
"aad_admin_type": {
"defaultValue": "User",
"allowedValues": [
"User",
"Group",
"Application"
],
"type": "String"
},
"aad_only_auth": {
"defaultValue": true,
"type": "Bool"
},
"user_identity_resource_id": {
"defaultValue": "",
"type": "String",
"metadata": {
"description": "The Resource ID of the user-assigned managed identity, in the form of /subscriptions/<subscriptionId>/resourceGroups/<ResourceGroupName>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<managedIdentity>."
}
},
"location": {
"defaultValue": "[resourceGroup().location]",
"type": "String",
"metadata": {
"description": "Enter location. If you leave this field blank resource group location would be used."
}
},
"virtualNetworkName": {
"type": "String",
"defaultValue": "SQLMI-VNET",
"metadata": {
"description": "Enter virtual network name. If you leave this field blank name will be created by the template."
}
},
"addressPrefix": {
"defaultValue": "10.0.0.0/16",
"type": "String",
"metadata": {
"description": "Enter virtual network address prefix."
}
},
"subnetName": {
"type": "String",
"defaultValue": "ManagedInstances",
"metadata": {
"description": "Enter subnet name. If you leave this field blank name will be created by the template."
}
},
"subnetPrefix": {
"defaultValue": "10.0.0.0/24",
"type": "String",
"metadata": {
"description": "Enter subnet address prefix."
}
},
"skuName": {
"defaultValue": "GP_Gen5",
"allowedValues": [
"GP_Gen5",
"BC_Gen5"
],
"type": "String",
"metadata": {
"description": "Enter sku name."
}
},
"vCores": {
"defaultValue": 16,
"allowedValues": [
8,
16,
24,
32,
40,
64,
80
],
"type": "Int",
"metadata": {
"description": "Enter number of vCores."
}
},
"storageSizeInGB": {
"defaultValue": 256,
"minValue": 32,
"maxValue": 8192,
"type": "Int",
"metadata": {
"description": "Enter storage size."
}
},
"licenseType": {
"defaultValue": "LicenseIncluded",
"allowedValues": [
"BasePrice",
"LicenseIncluded"
],
"type": "String",
"metadata": {
"description": "Enter license type."
}
}
},
"variables": {
"networkSecurityGroupName": "[concat('SQLMI-', parameters('managedInstanceName'), '-NSG')]",
"routeTableName": "[concat('SQLMI-', parameters('managedInstanceName'), '-Route-Table')]"
},
"resources": [
{
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2020-06-01",
"name": "[variables('networkSecurityGroupName')]",
"location": "[parameters('location')]",
"properties": {
"securityRules": [
{
"name": "allow_tds_inbound",
"properties": {
"description": "Allow access to data",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "1433",
"sourceAddressPrefix": "VirtualNetwork",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 1000,
"direction": "Inbound"
}
},
{
"name": "allow_redirect_inbound",
"properties": {
"description": "Allow inbound redirect traffic to Managed Instance inside the virtual network",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "11000-11999",
"sourceAddressPrefix": "VirtualNetwork",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 1100,
"direction": "Inbound"
}
},
{
"name": "deny_all_inbound",
"properties": {
"description": "Deny all other inbound traffic",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "*",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Deny",
"priority": 4096,
"direction": "Inbound"
}
},
{
"name": "deny_all_outbound",
"properties": {
"description": "Deny all other outbound traffic",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "*",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Deny",
"priority": 4096,
"direction": "Outbound"
}
}
]
}
},
{
"type": "Microsoft.Network/routeTables",
"apiVersion": "2020-06-01",
"name": "[variables('routeTableName')]",
"location": "[parameters('location')]",
"properties": {
"disableBgpRoutePropagation": false
}
},
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2020-06-01",
"name": "[parameters('virtualNetworkName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[variables('routeTableName')]",
"[variables('networkSecurityGroupName')]"
],
"properties": {
"addressSpace": {
"addressPrefixes": [
"[parameters('addressPrefix')]"
]
},
"subnets": [
{
"name": "[parameters('subnetName')]",
"properties": {
"addressPrefix": "[parameters('subnetPrefix')]",
"routeTable": {
"id": "[resourceId('Microsoft.Network/routeTables', variables('routeTableName'))]"
},
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
},
"delegations": [
{
"name": "miDelegation",
"properties": {
"serviceName": "Microsoft.Sql/managedInstances"
}
}
]
}
}
]
}
},
{
"type": "Microsoft.Sql/managedInstances",
"apiVersion": "2020-11-01-preview",
"name": "[parameters('managedInstanceName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[parameters('virtualNetworkName')]"
],
"sku": {
"name": "[parameters('skuName')]"
},
"identity": {
"type": "UserAssigned",
"UserAssignedIdentities": {
"[parameters('user_identity_resource_id')]": {}
}
},
"properties": {
"subnetId": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName'))]",
"storageSizeInGB": "[parameters('storageSizeInGB')]",
"vCores": "[parameters('vCores')]",
"licenseType": "[parameters('licenseType')]",
"PrimaryUserAssignedIdentityId": "[parameters('user_identity_resource_id')]",
"administrators": {
"login": "[parameters('aad_admin_name')]",
"sid": "[parameters('aad_admin_objectid')]",
"tenantId": "[parameters('aad_admin_tenantid')]",
"principalType": "[parameters('aad_admin_type')]",
"azureADOnlyAuthentication": "[parameters('aad_only_auth')]"
}
}
}
]
}