使用用户分配的托管标识创建 Azure SQL 托管实例
- 项目
适用于:Azure SQL 托管实例
本操作指南概述了使用来自 Microsoft Entra ID(以前称为 Azure Active Directory)的用户分配的托管标识创建 Azure SQL 托管实例的步骤。 有关在 Azure SQL 数据库中使用用户分配的托管标识作为服务器标识的好处的详细信息,请参阅 Microsoft Entra 中用于 Azure SQL 的用户分配的托管标识。
注意
Microsoft Entra ID 以前称为 Azure Active Directory (Azure AD)。
先决条件
- 若要使用用户分配的托管标识预配 SQL 托管实例,需要 SQL 托管实例参与者角色(或具有更高权限的角色)以及包含以下操作的 Azure RBAC 角色:
- Microsoft.ManagedIdentity/userAssignedIdentities/*/assign/action - 例如,托管标识操作员具有此操作。
- 创建用户分配的托管标识并为其分配必要的权限,使其成为服务器或托管实例标识。 有关详细信息,请参阅管理用户分配的托管标识和 Azure SQL 的用户分配的托管标识权限。
- 将 PowerShell 用于用户分配的托管标识时,需要 Az.Sql 模块 3.4 或更高版本。
- 需要 Azure CLI 2.26.0 或更高版本才能将 Azure CLI 与用户分配的托管标识一起使用。
- 有关使用用户分配的托管标识的限制和已知问题的列表,请参阅 Microsoft Entra 中用于 Azure SQL 的用户分配的托管标识
浏览到 Azure 门户中的选择 SQL 部署选项页。
如果你尚未登录到 Azure 门户,请按提示登录。
在“SQL 托管实例”下将“资源类型”设置保留为“单一实例”,然后选择“创建” 。
在“基本信息”选项卡的“项目详细信息”和“托管实例详细信息”中填写所需的必填信息。 这是预配 SQL 托管实例所需的最少量信息。
有关配置选项的详细信息,请参阅快速入门:创建 Azure SQL 托管实例。
在“身份验证”下,选择首选的身份验证模型。 如果要配置仅限 Microsoft Entra 身份验证,请参阅指南。
接下来,完成“网络”选项卡配置,或保留默认设置。
在“安全”选项卡的“标识”下,选择“配置标识”。
在“标识”窗格的“用户分配的托管标识”下,选择“添加”。 选择所需的订阅,然后在“用户分配的托管标识”下,从所选订阅中选择所需的用户分配的托管标识。 然后选择“选择”按钮。
在“主标识”下面,选择在上一步中选择的相同用户分配的托管标识。
注意
如果系统分配的托管标识是主标识,则“主标识”字段必须为空。
选择“应用”
可将其余设置保留为默认值。 有关其他选项卡和设置的详细信息,请按照快速入门:创建 Azure SQL 托管实例文章中的指南进行操作。
配置完设置后,选择“查看 + 创建”以继续。 选择“创建”,开始预配托管实例。
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>
:命名要创建的托管实例- 需要使用
<subscriptionId>
、<ResourceGroupName>
、<VNetName>
和<SubnetName>
更新subnet
参数。
# 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
- 需要使用
<subscriptionId>
、<ResourceGroupName>
、<VNetName>
和<SubnetName>
更新SubnetId
参数。
$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”- 需要使用
<ResourceGroupName>
、Subscription ID
、<VNetName>
和<SubnetName>
更新subnetId
参数
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 示例如 /subscriptions/<subscriptionId>/resourceGroups/<ResourceGroupName>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<managedIdentity>
所示。
{
"$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')]"
}
}
}
]
}