Aplica-se a:
SQL Server 2022 (16.x)
Observação
Esse recurso está disponível no SQL Server 2022 (16.x) ou em versões posteriores e só tem suporte no SQL Server local para hosts Windows e Linux e SQL Server 2022 em VMs do Windows Azure.
Neste artigo, veremos como configurar o administrador do Microsoft Entra para permitir autenticação com o Microsoft Entra ID (anteriormente Azure Active Directory) para SQL Server usando o portal do Azure e APIs como:
- PowerShell
- A CLI do Azure
- Modelo do ARM
Também analisaremos a funcionalidade atualizada para configurar um administrador do Microsoft Entra para SQL Server no portal do Azure que permitiria a criação automatizada de certificados e o registro de aplicativo. Antes, configurar a autenticação do Microsoft Entra para o SQL Server exigia a configuração manual do administrador do Microsoft Entra com um certificado do Azure e um registro de aplicativo.
Observação
Embora o Microsoft Entra ID seja o novo nome do Azure Active Directory (Azure AD), para evitar a interrupção de ambientes existentes, o Azure AD ainda permanecerá em alguns elementos codificados, como campos de interface do usuário, provedores de conexão, códigos de erro e cmdlets. Neste artigo, os dois nomes são intercambiáveis.
Pré-requisitos
Preparação antes de definir o administrador do Microsoft Entra
As permissões a seguir são necessárias para configurar o administrador do Microsoft Entra nos recursos SQL Server – Azure Arc e cofre de chaves.
Siga o guia para verificar se o SQL Server está conectado ao Azure Arc. O usuário que configura o administrador do Microsoft Entra para o recurso SQL Server – Azure Arc deve ter a função Colaborador para o servidor.
- Vá para o Portal do Azure
- Selecione SQL Server – Azure Arc e escolha a instância do host do SQL Server.
- Selecione IAM (Controle de acesso) .
- Selecione Adicionar>Adicionar atribuição de função para adicionar a função Colaborador ao usuário que configura o administrador do Microsoft Entra.
Crie um Azure Key Vault, se ainda não tiver um. O usuário que está configurando o administrador do Microsoft Entra deve ter a função Colaborador no Azure Key Vault. Para adicionar uma função a um usuário no Azure Key Vault:
- Vá para o Portal do Azure
- Acesse o recurso do cofre de chaves.
- Escolha Controle de acesso (IAM).
- Selecione Adicionar>Adicionar atribuição de função para adicionar a função Colaborador ao usuário que configura o administrador do Microsoft Entra.
Configurar políticas de acesso para o host do SQL Server
No portal do Azure, navegue até a instância do Azure Key Vault e selecione Políticas de acesso.
Selecione Adicionar Política de Acesso.
Para Permissões de chave, use Assinar.
Para Permissões de segredo, selecione Obter e Listar.
Em Permissões de certificado, escolha Obter e Listar.
Selecione Avançar.
Na página Principal, pesquise o nome da sua Máquina - instância do Azure Arc, que é o nome do host do SQL Server.
Ignore a páginaAplicativo (opcional) selecionando duas vezes Avançar ou selecionando Analisar + criar.
Verifique se a "ID de objeto" do Principal corresponde à ID de principal da identidade gerenciada atribuída à instância.
Para confirmar, vá para a página de recursos e selecione Exibição JSON no canto superior direito da caixa Essenciais na página de Visão geral. Em identidade, você encontrará o principalId.
Selecione Criar.
Você deve selecionar Criar para garantir que as permissões sejam aplicadas. Para garantir que as permissões tenham sido armazenadas, atualize a janela do navegador e verifique se a linha da instância do Azure Arc ainda está presente.
Definir políticas de acesso para usuários do Microsoft Entra
- No portal do Azure, navegue até a instância do Azure Key Vault e selecione Políticas de acesso.
- Selecione Adicionar Política de Acesso.
- Em Permissões de chave, escolha Obter, Listar e Criar.
- Selecione Permissões de segredo e escolha Obter, Listar e Definir.
- Em Permissões de certificado, escolha Obter, Listar e Criar.
- Em Selecionar principal, adicione o usuário do Microsoft Entra que você quer usar para se conectar ao SQL Server.
- Selecione Adicionar e, em seguida, Salvar.
Configurando o administrador do Microsoft Entra para SQL Server
Com as novas APIs e a funcionalidade do portal, os usuários podem configurar um administrador do Microsoft Entra para SQL Server sem criar um certificado do Azure e um aplicativo do Microsoft Entra separadamente. Selecione uma guia para saber como configurar um administrador do Microsoft Entra para seu SQL Server conectado ao Azure Arc com criação automática de certificados e aplicativos.
Use o portal do Azure para configurar um administrador do Microsoft Entra, crie um certificado do Azure Key Vault e um aplicativo do Microsoft Entra no mesmo processo. Isso é necessário para usar a autenticação do Microsoft Entra com o SQL Server.
Configurando o administrador do Microsoft Entra usando o portal do Azure
Acesse o portal do Azure, escolha SQL Server – Azure Arc. Escolha a instância do host do SQL Server.
Verifique o status do seu recurso SQL Server – Azure Arc e veja se ele está conectado, acessando o menu Propriedades. Para obter mais informações, confira Validar os recursos do SQL Server habilitados para Arc.
Selecione Microsoft Entra ID e Purview no menu Configurações do menu de recursos.
Selecione Definir Administrador para abrir o painel do Microsoft Entra ID e escolha uma conta que será adicionada como logon de administrador ao SQL Server.
Selecione Certificado de gerenciamento de Serviços.
Selecione Alterar cofre de chaves e selecione seu recurso do Azure Key Vault existente.
Escolha Registro de aplicativo gerenciado pelo serviço.
Selecione Salvar. Isso envia uma solicitação ao agente do servidor do Arc que configura a autenticação Microsoft Entra para essa instância do SQL Server. A operação pode levar vários minutos para ser concluída; aguarde até que o processo de salvamento seja confirmado com Saved successfully
antes de tentar fazer logon no Microsoft Entra.
O registro de aplicativo gerenciado pelo serviço faz o seguinte para você:
- Cria um certificado no cofre de chaves com um nome na forma
<hostname>-<instanceName><uniqueNumber>
.
- Cria um aplicativo do Microsoft Entra com um nome como
<hostname>-<instanceName><uniqueNumber>
e atribui as permissões necessárias ao aplicativo. Veja mais informações em Conceder permissões de aplicativo
- Atribui o novo certificado do Azure Key Vault ao aplicativo.
- Salve as configurações no Azure Arc.
O script da CLI do Azure abaixo configura um administrador do Microsoft Entra e cria um certificado do Azure Key Vault e um aplicativo do Microsoft Entra. Há outra seção que fornece um script de exemplo para configurar um administrador do Microsoft Entra quando o certificado e o aplicativo já existem.
Observação
Os certificados criados para a configuração do Microsoft Entra não são renovados automaticamente.
- A CLI do Azure, versão 2.37.0 ou superior é obrigatória
- Az.ConnectedMachine 0.5.1 ou posterior é obrigatório
Para instalar o módulo Az.ConnectedMachine
, use az extension add --name ConnectedMachine
. Para verificar a versão da CLI do Azure instalada, use az version
.
Os seguintes parâmetros de entrada são usados no script da CLI do Azure:
<applicationName>
: nome do aplicativo que será criado
<certSubjectName>
: nome do certificado que será criado
<keyVaultName>
– O nome do cofre de chaves. Esse cofre de chaves deve ser criado antes da execução do script
<machineName>
: nome do computador do host do SQL Server
<resourceGroupName>
: nome do grupo de recursos que contém a instância SQL Server – Azure Arc
<adminAccountName>
: conta do administrador do Microsoft Entra que você quer definir para o SQL Server
<instanceName>
: parâmetro opcional para instâncias nomeadas do SQL Server. Use esse parâmetro quando tiver uma instância nomeada. Se ele for omitido, será usado nome padrão MSSQLSERVER
<tenantId>
: parâmetro opcional para ID do locatário. Você pode encontrar a ID do locatário acessando o portal do Azure e o recurso Microsoft Entra ID. No painel de Visão geral, você deveria ver seu Tenant ID. Se omitida, será usada a ID do locatário padrão como parâmetro
<subscriptionId>
: parâmetro opcional para ID da assinatura. Sua ID da assinatura pode ser encontrada no portal do Azure. Se omitida, será usada a ID da assinatura padrão
Para usar o script da CLI do Azure abaixo, salve o script como arquivo .ps1
e execute este comando:
./aadAzCliSetup.ps1 -applicationName "<applicationName>" -certSubjectName "<certSubjectName>" -keyVaultName "<keyVaultName>" -machineName "<machineName>" -resourceGroupName "<resourceGroupName>" -adminAccountName "<adminAccountName>" -instanceName "<instanceName>" -tenantId "<tenantId>" -subscriptionId "<subscriptionId>"
O script da CLI do Azure
Observação
Para o SQL Server em computadores host do Linux, substitua WindowsAgent.SqlServer
por LinuxAgent.SqlServer
no script.
# AZ CLI and AZ CLI's connected machine extension must be installed before running this script
param (
[Parameter(mandatory=$true)] $applicationName,
[Parameter(mandatory=$true)] $certSubjectName,
[Parameter(mandatory=$true)] $keyVaultName,
[Parameter(mandatory=$true)] $machineName,
[Parameter(mandatory=$true)] $resourceGroupName,
[Parameter(mandatory=$true)] $adminAccountName,
$instanceName,
$tenantId,
$subscriptionId
)
# Constants
#
$NUMRETRIES = 60
# Helper functions
#
function ConvertFrom-StringArray {
param (
[string[]] $stringArray
)
if (!$stringArray)
{
return $null
}
else
{
return ConvertFrom-JSON ($stringArray -join "`n")
}
}
# Check parameters
#
if ([string]::IsNullOrEmpty($instanceName))
{
Write-Host "Warning: SQL Instance name (-instanceName) not provided. Default of MSSQLSERVER will be used"
$instanceName = "MSSQLSERVER"
}
$tenantIdArgument = ""
if ([string]::IsNullOrEmpty($tenantId))
{
Write-Host "Warning: Tenant ID (-tenantId) not supplied to the script, so default tenant is being used"
}
else
{
$tenantIdArgument = "-TenantId '" + $tenantId + "'"
}
$subscriptionIdArgument = ""
if ([string]::IsNullOrEmpty($subscriptionId))
{
Write-Host "Warning: Subscription ID (-subscriptionId) not supplied to the script, so default subscription is being used"
}
else
{
$subscriptionIdArgument = "-SubscriptionId '" + $subscriptionId + "'"
}
# Login and select subscription
#
$login = az login --tenant $tenantId --use-device-code
if (!$login)
{
Write-Error "Login to Azure AD failed. Exiting."
exit 1
}
if ($subscriptionId)
{
az account set -s $subscriptionId
}
$accountInfo = ConvertFrom-StringArray (az account show)
if (!$accountInfo)
{
Write-Error "Cannot query logged in Azure AD account. Check that 'az login' and 'az account set' succeeded"
exit 1
}
if ($subscriptionId)
{
if ($subscriptionId.ToLower() -ne $accountInfo.id.ToLower())
{
Write-Error "Could not select the desired subscription"
exit 1
}
}
else
{
$subscriptionId = $accountInfo.id
}
# Check AKV path exists
#
$keyVault = ConvertFrom-StringArray (az keyvault show --name $keyVaultName)
if (!$keyVault)
{
Write-Error "Azure key vault '$keyVaultName' does not exist"
exit 1
}
# Check certificate doesn't exist
#
$cert = ConvertFrom-StringArray (az keyvault certificate show --name $certSubjectName --vault-name $keyVaultName 2>$null)
if ($cert)
{
Write-Error "Certificate '$certSubjectName' already exists in key vault '$keyVaultName'"
exit 1
}
# Check app registration doesn't exist
#
$applications = ConvertFrom-StringArray (az ad app list --display-name $applicationName --only-show-errors)
if ($applications.length -gt 0)
{
Write-Error "App registration with name '$applicationName' already exists"
exit 1
}
# Check Arc SQL instance is valid
#
$extension = ConvertFrom-StringArray (az connectedmachine extension show --machine-name $machineName --name "WindowsAgent.SqlServer" --resource-group $resourceGroupName)
if (!$extension)
{
Write-Error "SQL Server Arc Server not found for machine '$machineName' in resource group '$resourceGroupName'"
exit 1
}
$arcServicePrincipals = ConvertFrom-StringArray(az ad sp list --display-name $machineName --only-show-errors)
if (!$arcServicePrincipals -or $arcServicePrincipals.length -eq 0)
{
Write-Error "Could not find a service principal account with the name '$machineName'"
exit 1
}
else
{
$principalFound = $false
for ($i = 0; $i -lt $arcServicePrincipals.length; $i++)
{
if ($arcServicePrincipals[$i].displayName.toLower() -eq $machineName.toLower()) {
if ($principalFound) {
Write-Error "Could not find exactly one service principal account with the name '$machineName'"
exit 1
}
$arcServicePrincipal = $arcServicePrincipals[$i]
$principalFound = $true
}
}
if (!$principalFound) {
Write-Error "Could not find a service principal account with the name '$machineName'"
exit 1
}
}
# Check if admin account exists
#
$adminAccount = ConvertFrom-StringArray (az ad user show --id $adminAccountName --only-show-errors 2>$null)
$adminAccountType = 0
if (!$adminAccount)
{
$adminAccounts = ConvertFrom-StringArray (az ad user list --filter "mail eq '$adminAccountName'" --only-show-errors 2>$null)
if ($adminAccounts -and $adminAccounts.length -gt 0)
{
if ($adminAccounts.length -eq 1)
{
$adminAccount = $adminAccounts[0]
}
else
{
Write-Error "Multiple Azure AD accounts found with identifier '$adminAccountName'"
exit 1
}
}
else
{
$adminAccount = ConvertFrom-StringArray (az ad group show --group $adminAccountName --only-show-errors 2>$null)
if (!$adminAccount)
{
$adminAccounts = ConvertFrom-StringArray (az ad app list --display-name $adminAccountName --only-show-errors 2>$null)
if ($adminAccounts -and $adminAccounts.length -gt 0)
{
if ($adminAccounts.length -eq 1)
{
$adminAccount = $adminAccounts[0]
}
else
{
Write-Error "Multiple Azure AD applications found with identifier '$adminAccountName'"
exit 1
}
}
else
{
Write-Error "Admin account not found"
exit 1
}
}
else
{
$adminAccountType = 1
}
}
}
if ($adminAccount)
{
$adminAccountSid = $adminAccount.id
}
else
{
Write-Error "Admin account not found"
exit 1
}
# Create certificate in AKV
#
$keyVaultPolicy = ConvertFrom-StringArray (az keyvault certificate get-default-policy)
if (!$keyVaultPolicy)
{
Write-Error "Could not get default key vault policy"
exit 1
}
$keyVaultPolicy.x509CertificateProperties.subject = "CN=" + $certSubjectName
$policyString = (ConvertTo-JSON -Depth 8 $keyVaultPolicy).replace("`r`n", "")
$escapedPolicyString = $policyString.replace("`"", "\`"")
$cert = ConvertFrom-StringArray (az keyvault certificate create --vault-name $keyVaultName --name $certSubjectName --policy $escapedPolicyString)
if (!$cert)
{
Write-Error "Failed to create certificate '$certSubjectName'"
exit 1
}
# Wait until cert is created?
#
$cert = ConvertFrom-StringArray (az keyvault certificate show --vault-name $keyVaultName --name $certSubjectName)
for (($i = 0); $i -lt $NUMRETRIES -and (!$cert -or !$cert.attributes.enabled); $i++)
{
$cert = ConvertFrom-StringArray (az keyvault certificate show --vault-name $keyVaultName --name $certSubjectName)
if (!$cert -or !$cert.attributes.enabled)
{
Start-Sleep -Seconds 5
}
}
# Allow Arc to access AKV
#
$newPerms = ConvertFrom-StringArray (az keyvault set-policy --name $keyVaultName --secret-permissions get list --certificate-permissions get list --object-id $arcServicePrincipal.id)
if (!$newPerms)
{
Write-Host "Warning: Unable to add permissions to key vault '$keyVaultName' for Arc's service principal's identity '$($arcServicePrincipal.id)'. Arc may not be able to configure Azure AD authentication"
}
# Create an Azure AD application
#
$application = ConvertFrom-StringArray (az ad app create --display-name $applicationName --only-show-errors)
if (!$application)
{
Write-Error "Unable to create the app registration '$applicationName'"
exit 1
}
# Set perms on app registration
#
az ad app permission add --id $application.id --api 00000003-0000-0000-c000-000000000000 --api-permissions c79f8feb-a9db-4090-85f9-90d820caa0eb=Scope --only-show-errors # Delegated Application.Read.All
az ad app permission add --id $application.id --api 00000003-0000-0000-c000-000000000000 --api-permissions 0e263e50-5827-48a4-b97c-d940288653c7=Scope --only-show-errors # Delegated Directory.AccessAsUser.All
az ad app permission add --id $application.id --api 00000003-0000-0000-c000-000000000000 --api-permissions 7ab1d382-f21e-4acd-a863-ba3e13f7da61=Role --only-show-errors # Application Directory.Read.All
az ad app permission add --id $application.id --api 00000003-0000-0000-c000-000000000000 --api-permissions 5f8c59db-677d-491f-a6b8-5f174b11ec1d=Scope --only-show-errors # Delegated Group.Read.All
az ad app permission add --id $application.id --api 00000003-0000-0000-c000-000000000000 --api-permissions a154be20-db9c-4678-8ab7-66f6cc099a59=Scope --only-show-errors # Delegated User.Read.All
# Upload cert to Azure AD
#
$certUploadRes = ConvertFrom-StringArray (az ad app credential reset --id $application.id --cert $certSubjectName --keyvault $keyVaultName --append --only-show-errors)
if (!$certUploadRes)
{
Write-Error "Failed to set certificate '$certSubjectName' as a credential for app registration '$applicationName'"
exit 1
}
# Remove the version from the secret ID if present
#
$secretId = $cert.sid
if ($secretId -Match "(https:\/\/[^\/]+\/secrets\/[^\/]+)(\/.*){0,1}$") {
if ($Matches[1]) {
$secretId = $Matches[1]
}
}
# Create the settings object to write to the Azure extension for SQL Server
#
$instanceSettings = @{
instanceName = $instanceName
adminLoginName = $adminAccountName
adminLoginSid = $adminAccountSid
azureCertSecretId = $secretId
azureCertUri = $cert.id
azureKeyVaultResourceUID = $keyVault.id
managedCertSetting = "CUSTOMER MANAGED CERT"
managedAppSetting = "CUSTOMER MANAGED APP"
appRegistrationName = $application.displayName
appRegistrationSid = $application.appId
tenantId = $tenantId
aadCertSubjectName = $certSubjectName
adminLoginType = $adminAccountType
}
$extension = ConvertFrom-StringArray (az connectedmachine extension show --machine-name $machineName --name "WindowsAgent.SqlServer" --resource-group $resourceGroupName)
if ($extension.properties.Settings.AzureAD)
{
$aadSettings = $extension.properties.Settings.AzureAD
$instanceFound = $false
$instanceNameLower = $instanceName.ToLower()
$instanceIndex = 0
for (($i = 0); $i -lt $aadSettings.Length; $i++)
{
if ($aadSettings[$i].instanceName.ToLower() -eq $instanceNameLower)
{
$instanceIndex = $i
$instanceFound = $true
break
}
}
if ($instanceFound)
{
$aadSettings[$instanceIndex] = $instanceSettings
}
else
{
$aadSettings += $instanceSettings
}
$extension.properties.Settings.AzureAD = $aadSettings
}
else
{
$aadSettings = , $instanceSettings
$extension.properties.Settings | Add-Member -Name 'AzureAD' -Value $aadSettings -MemberType NoteProperty
}
$settingsString = (ConvertTo-Json $extension.properties.Settings).replace("`"", "\`"").replace("`r`n", "")
# Push settings to Arc
#
Write-Host "Writing Azure AD setting to Azure extension for SQL Server. This may take several minutes..."
$updateRes = az connectedmachine extension update --machine-name $machineName --name "WindowsAgent.SqlServer" --resource-group $resourceGroupName --settings $settingsString
if (!$updateRes)
{
Write-Error "Failed to update Azure extension for SQL Server with Azure AD settings"
exit 1
}
Write-Output "Success"
A execução do script pode levar vários minutos para ser concluída. Quando o processo é concluído, exibe-se uma mensagem como esta:
Name Location ProvisioningState
---- -------- -----------------
WindowsAgent.SqlServer westus2 Succeeded
Success
Configurando um administrador do Microsoft Entra com certificado e aplicativo já criados usando a CLI do Azure
Se você já tiver um certificado do Azure Key Vault e um aplicativo Azure que deseja usar para configurar o administrador do Microsoft Entra, poderá usar este script da CLI:
# Set up Microsoft Entra admin for user's existing key vault, certificate, and application
# Requires input parameters indicated below
# Connect statement
AZ Login
#Input parameters
$subscriptionId="<subscriptionId>"
$tenantId="<tenantId>"
$machineName="<machineName>" # hostname
$instanceName="<instanceName>" # SQL Server is define as `machine_name\instance_name`
$resourceGroupName="<resourceGroupName>"
$keyVaultName="<keyVaultName>"
$certSubjectName="<certSubjectName>" # Your existing certificate name
$applicationName="<applicationName>" # Your existing application name
$adminAccountName="<adminAccountName>"
$adminAccountSid="<adminID>" # Use object ID for the Azure AD user and group, or client ID for the Azure AD application
$adminAccountType= 0 # 0 – for Azure AD user and application, 1 for Azure AD group
# Helper function
#
function ConvertFrom-StringArray {
param (
[string[]] $stringArray
)
if (!$stringArray)
{
return $null
}
else
{
return ConvertFrom-JSON ($stringArray -join "`n")
}
}
$keyVault = ConvertFrom-StringArray (az keyvault show --name $keyVaultName)
if (!$keyVault)
{
Write-Error "Azure key vault '$keyVaultName' does not exist"
exit 1
}
$cert = ConvertFrom-StringArray (az keyvault certificate show --name $certSubjectName --vault-name $keyVaultName 2>$null)
if (!$cert)
{
Write-Error "Supplied certificate $certSubjectName was not found for this key vault. Please specify an existing certificate"
exit 1
}
$secretId = $cert.sid
if ($secretId -Match "(https:\/\/[^\/]+\/secrets\/[^\/]+)(\/.*){0,1}$") {
if ($Matches[1]) {
$secretId = $Matches[1]
}
}
$application = ConvertFrom-StringArray (az ad app list --display-name $applicationName --only-show-errors)
if (!$application)
{
Write-Error "Supplied application was not found in the subscription. Please specify an existing application"
exit 1
}
# Create the settings object to write to the Arc extension
#
$instanceSettings = @{
instanceName = $instanceName
adminLoginName = $adminAccountName
adminLoginSid = $adminAccountSid
azureCertSecretId = $secretId
azureCertUri = $cert.id
azureKeyVaultResourceUID = $keyVault.id
managedCertSetting = "CUSTOMER MANAGED CERT"
managedAppSetting = "CUSTOMER MANAGED APP"
appRegistrationName = $application.displayName
appRegistrationSid = $application.appId
tenantId = $tenantId
aadCertSubjectName = $certSubjectName
adminLoginType = $adminAccountType
}
$extension = ConvertFrom-StringArray (az connectedmachine extension show --machine-name $machineName --name "WindowsAgent.SqlServer" --resource-group $resourceGroupName)
if ($extension.properties.Settings.AzureAD)
{
$aadSettings = $extension.properties.Settings.AzureAD
$instanceFound = $false
$instanceNameLower = $instanceName.ToLower()
$instanceIndex = 0
for (($i = 0); $i -lt $aadSettings.Length; $i++)
{
if ($aadSettings[$i].instanceName.ToLower() -eq $instanceNameLower)
{
$instanceIndex = $i
$instanceFound = $true
break
}
}
if ($instanceFound)
{
$aadSettings[$instanceIndex] = $instanceSettings
}
else
{
$aadSettings += $instanceSettings
}
$extension.properties.Settings.AzureAD = $aadSettings
}
else
{
$aadSettings = , $instanceSettings
$extension.properties.Settings | Add-Member -Name 'AzureAD' -Value $aadSettings -MemberType NoteProperty
}
$settingsString = (ConvertTo-Json $extension.properties.Settings).replace("`"", "\`"").replace("`r`n", "")
# Push settings to Arc
#
Write-Host "Writing Azure AD setting to SQL Server Arc Extension. This may take several minutes..."
$updateRes = az connectedmachine extension update --machine-name $machineName --name "WindowsAgent.SqlServer" --resource-group $resourceGroupName --settings $settingsString
if (!$updateRes)
{
Write-Error "Failed to update SQL Arc Extension with Azure AD settings"
exit 1
}
Write-Output "Success"
O script da CLI do PowerShell abaixo configura um administrador do Microsoft Entra e cria um certificado do Azure Key Vault e um aplicativo do Microsoft Entra. Há outra seção que fornece um script de exemplo para configurar um administrador do Microsoft Entra quando o certificado e o aplicativo já existem.
Observação
Os certificados criados para a instalação do Microsoft Entra não são girados automaticamente.
Para acompanhar este tutorial, você precisará dos módulos a seguir. Instale as últimas versões dos módulos ou posteriores à versão indicada abaixo:
- Az.Accounts 3.37.0
- Az.ConnectedMachine 0.5.0
- Az.KeyVault 4.5.0
- Az.Resources 6.0.0
Estes parâmetros de entrada são usados para o script do PowerShell:
<applicationName>
: nome do aplicativo que será criado
<certSubjectName>
: nome do certificado que será criado
<keyVaultName>
- O nome do cofre de chaves. Esse cofre de chaves deve ser criado antes da execução do script
<machineName>
: nome do computador do host do SQL Server
<resourceGroupName>
: nome do grupo de recursos que contém a instância SQL Server – Azure Arc
<adminAccountName>
: conta do administrador do Microsoft Entra que você quer definir para o SQL Server
<instanceName>
: parâmetro opcional para instâncias nomeadas do SQL Server. Use esse parâmetro quando tiver uma instância nomeada. Se ele for omitido, será usado nome padrão MSSQLSERVER
<tenantId>
: parâmetro opcional para ID do locatário. Você pode encontrar a ID do locatário acessando o portal do Azure e o recurso Microsoft Entra ID. No painel de Visão geral, você deveria ver seu Tenant ID. Se omitida, será usada a ID do locatário padrão como parâmetro
<subscriptionId>
: parâmetro opcional para ID da assinatura. Sua ID da assinatura pode ser encontrada no portal do Azure. Se omitida, será usada a ID da assinatura padrão
Para usar o script da CLI do PowerShell abaixo, salve o script como arquivo .ps1
e execute este comando:
./aadPowerShellsetup.ps1 -applicationName "<applicationName>" -certSubjectName "<certSubjectName>" -keyVaultName "<keyVaultName>" -machineName "<machineName>" -resourceGroupName "<resourceGroupName>" -adminAccountName "<adminAccountName>" -instanceName "<instanceName>" -tenantId "<tenantId>" -subscriptionId "<subscriptionId>"
O script do PowerShell
Para o SQL Server em computadores host do Linux, substitua WindowsAgent.SqlServer
por LinuxAgent.SqlServer
no script.
param (
[Parameter(mandatory=$true)] $applicationName,
[Parameter(mandatory=$true)] $certSubjectName,
[Parameter(mandatory=$true)] $keyVaultName,
[Parameter(mandatory=$true)] $machineName,
[Parameter(mandatory=$true)] $resourceGroupName,
[Parameter(mandatory=$true)] $adminAccountName,
$instanceName,
$tenantId,
$subscriptionId
)
Import-Module Az.Accounts
Import-Module Az.ConnectedMachine
Import-Module Az.KeyVault
Import-Module Az.Resources
# Constants
#
$NUMRETRIES = 60
# Check parameters
#
if ([string]::IsNullOrEmpty($instanceName))
{
Write-Host "Warning: SQL Instance name (-instanceName) not provided. Default of MSSQLSERVER will be used"
$instanceName = "MSSQLSERVER"
}
$tenantIdArgument = ""
if ([string]::IsNullOrEmpty($tenantId))
{
Write-Host "Warning: Tenant ID (-tenantId) not supplied to the script, so default tenant is being used"
}
else
{
$tenantIdArgument = "-TenantId '" + $tenantId + "'"
}
$subscriptionIdArgument = ""
if ([string]::IsNullOrEmpty($subscriptionId))
{
Write-Host "Warning: Subscription ID (-subscriptionId) not supplied to the script, so default subscription is being used"
}
else
{
$subscriptionIdArgument = "-SubscriptionId '" + $subscriptionId + "'"
}
# Login
#
try
{
$loginRes = Invoke-Expression -Command ("Connect-AzAccount " + $tenantIdArgument + " " + $subscriptionIdArgument + " -ErrorAction stop -UseDeviceAuthentication")
}
catch
{
Write-Error $_
Write-Error "Failed to login to Azure. Script can not continue"
exit 1
}
# Get subscription ID
#
if ([string]::IsNullOrEmpty($subscriptionId))
{
$context = Get-AzContext
if ($context)
{
if ($context.Name -Match "[^(]+\(([^)]{36})\)")
{
if ($Matches[1])
{
$subscriptionId = $Matches[1]
}
}
}
}
if ([string]::IsNullOrEmpty($subscriptionId))
{
Write-Error "Failed to find default subscription"
exit 1
}
# Check AKV path exists
#
$keyVault = Get-AzKeyVault -VaultName $keyVaultName
if (!$keyVault)
{
Write-Error "Supplied key vault was not found in the subscription. Please specify an existing key vault"
exit 1
}
# Check certificate doesn't exist
#
$cert = Get-AzKeyVaultCertificate -VaultName $keyVaultName -Name $certSubjectName
if ($cert)
{
Write-Error "Certificate $certSubjectName already exists"
exit 1
}
# Check app registration doesn't exist
#
$application = Get-AzADApplication -DisplayName $applicationName
if ($application)
{
Write-Error "Application $applicationName already exists"
exit 1
}
# Check Arc SQL instance is valid
#
$arcInstance = Get-AzConnectedMachineExtension -SubscriptionId $subscriptionId -MachineName $machineName -ResourceGroupName $resourceGroupName -Name "WindowsAgent.SqlServer"
if (!$arcInstance)
{
Write-Error "Could not find a SQL Server Arc instance in subscription '$subscriptionId' and resource group '$resourceGroupName' with name '$machineName'"
exit 1
}
# Check if admin account exists
#
$adminAccount = Get-AzADUser -UserPrincipalName $adminAccountName
$adminAccountType = 0
if (!$adminAccount)
{
# Check for guest user
#
$adminAccount = Get-AzADUser -Mail $adminAccountName
if (!$adminAccount)
{
$adminAccount = Get-AzADGroup -DisplayName $adminAccountName
if (!$adminAccount)
{
$adminAccount = Get-AzADServicePrincipal -DisplayName $adminAccountName
}
else
{
$adminAccountType = 1
}
}
}
if ($adminAccount)
{
if ($adminAccount.Length -gt 1)
{
Write-Error "Multiple accounts with found with name $adminAccountName"
exit 1
}
$adminAccountSid = $adminAccount.Id
}
else
{
Write-Error "Could not find an account with name $adminAccountName"
exit 1
}
# Create certificate in AKV
#
$Policy = New-AzKeyVaultCertificatePolicy -SecretContentType "application/x-pkcs12" -SubjectName "CN=$certSubjectName" -IssuerName "Self" -ValidityInMonths 12 -ReuseKeyOnRenewal
try
{
$addCertRes = Add-AzKeyVaultCertificate -VaultName $keyVaultName -Name $certSubjectName -CertificatePolicy $Policy -ErrorAction stop
}
catch
{
Write-Error $_
Write-Error "Certificate $certSubjectName could not be created"
exit 1
}
for (($i = 0); $i -lt $NUMRETRIES -and (!$cert -or !$cert.enabled); $i++)
{
$cert = Get-AzKeyVaultCertificate -VaultName $keyVaultName -Name $certSubjectName
if (!$cert -or !$cert.enabled)
{
Start-Sleep -Seconds 5
}
}
if (!$cert)
{
Write-Error "Certificate $certSubjectName could not be created"
exit 1
}
# Allow Arc to access AKV
#
$arcServicePrincipal = Get-AzADServicePrincipal -DisplayName $machineName
if ($arcServicePrincipal -and ![string]::IsNullOrEmpty($arcServicePrincipal.Id))
{
try
{
Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -ObjectId $arcServicePrincipal.Id -PermissionsToSecrets Get,List -PermissionsToCertificates Get,List
}
catch
{
Write-Error $_
Write-Host "Warning: Could not find the identity of the Azure extension for SQL Server and thus, could not add permissions for the Arc process to read from AKV. Ensure the Arc identity has the required permissions to read from AKV."
}
}
else
{
Write-Host "Warning: Could not find the identity of the Azure extension for SQL Server and thus, could not add permissions for the Arc process to read from AKV. Ensure the Arc identity has the required permissions to read from AKV."
}
# Create an Azure AD application
#
$application = New-AzADApplication -DisplayName $applicationName
if (!$application)
{
Write-Error "Application could not be created"
exit 1
}
# Set perms on app registration
#
Add-AzADAppPermission -ObjectId $application.Id -ApiId 00000003-0000-0000-c000-000000000000 -PermissionId c79f8feb-a9db-4090-85f9-90d820caa0eb # Delegated Application.Read.All
Add-AzADAppPermission -ObjectId $application.Id -ApiId 00000003-0000-0000-c000-000000000000 -PermissionId 0e263e50-5827-48a4-b97c-d940288653c7 # Delegated Directory.AccessAsUser.All
Add-AzADAppPermission -ObjectId $application.Id -ApiId 00000003-0000-0000-c000-000000000000 -PermissionId 7ab1d382-f21e-4acd-a863-ba3e13f7da61 -Type Role # Application Directory.Read.All
Add-AzADAppPermission -ObjectId $application.Id -ApiId 00000003-0000-0000-c000-000000000000 -PermissionId 5f8c59db-677d-491f-a6b8-5f174b11ec1d # Delegated Group.Read.All
Add-AzADAppPermission -ObjectId $application.Id -ApiId 00000003-0000-0000-c000-000000000000 -PermissionId a154be20-db9c-4678-8ab7-66f6cc099a59 # Delegated User.Read.All
# Upload cert to Azure AD
#
try
{
$base64Cert = [System.Convert]::ToBase64String($cert.Certificate.GetRawCertData())
New-AzADAppCredential -ApplicationObject $application -CertValue $base64Cert -EndDate $cert.Certificate.NotAfter -StartDate $cert.Certificate.NotBefore -ErrorAction stop
}
catch
{
Write-Error $_
Write-Error "Failed to add certificate to app registration"
exit 1
}
# Remove the version from the secret ID if present
#
$secretId = $cert.SecretId
if ($secretId -Match "(https:\/\/[^\/]+\/secrets\/[^\/]+)(\/.*){0,1}$") {
if ($Matches[1]) {
$secretId = $Matches[1]
}
}
# Create the settings object to write to the Azure extension for SQL Server
#
$instanceSettings = @{
instanceName = $instanceName
adminLoginName = $adminAccountName
adminLoginSid = $adminAccountSid
azureCertSecretId = $secretId.replace(":443", "")
azureCertUri = $cert.Id.replace(":443", "")
azureKeyVaultResourceUID = $keyVault.ResourceId
managedCertSetting = "CUSTOMER MANAGED CERT"
managedAppSetting = "CUSTOMER MANAGED APP"
appRegistrationName = $application.DisplayName
appRegistrationSid = $application.AppId
tenantId = $tenantId
aadCertSubjectName = $certSubjectName
adminLoginType = $adminAccountType
}
$arcInstance = Get-AzConnectedMachineExtension -SubscriptionId $subscriptionId -MachineName $machineName -ResourceGroupName $resourceGroupName -Name "WindowsAgent.SqlServer"
if ($arcInstance.Setting.AdditionalProperties.AzureAD)
{
$aadSettings = $arcInstance.Setting.AdditionalProperties.AzureAD
$instanceFound = $false
$instanceNameLower = $instanceName.ToLower()
$instanceIndex = 0
for (($i = 0); $i -lt $aadSettings.Length; $i++)
{
if ($aadSettings[$i].instanceName.ToLower() -eq $instanceNameLower)
{
$instanceIndex = $i
$instanceFound = $true
break
}
}
if ($instanceFound)
{
$aadSettings[$instanceIndex] = $instanceSettings
}
else
{
$aadSettings += $instanceSettings
}
}
else
{
$aadSettings = , $instanceSettings
}
Write-Host "Writing Microsoft Entra setting to SQL Server Arc Extension. This may take several minutes..."
# Push settings to Arc
#
try
{
#set the Entra ID / AzureAD setting in the hash table
$SettingsToConfigure = @{
AzureAD = $aadSettings
}
#add any non-AzureAD key value pairs back to the hashtable
$keys = $arcInstance.Setting.Keys | where-object {$_ -notin ("AzureAD")}
foreach ($key in $keys) {
$SettingsToConfigure.$key = $arcInstance.Setting["$key"]
}
#Issue the update of the updated settings
Update-AzConnectedMachineExtension `
-MachineName $machineName `
-Name "WindowsAgent.SqlServer" `
-ResourceGroupName $resourceGroupName `
-Setting $SettingsToConfigure
}
catch
{
Write-Error $_
Write-Error "Failed to write settings to Arc host"
exit 1
}
Write-Output "Success"
Configurando um administrador do Microsoft Entra com certificado e aplicativo já criados usando a CLI do PowerShell
Se você já tiver um certificado do Azure Key Vault e um aplicativo Azure que deseja usar para configurar o administrador do Microsoft Entra, poderá usar este script do PowerShell:
# Connect statement
Connect-AzAccount
#Input parameters
$subscriptionId="<subscriptionId>"
$tenantId="<tenantId>"
$machineName="<machineName>" # hostname
$instanceName="<instanceName>" # SQL Server is define as `machine_name\instance_name`
$resourceGroupName="<resourceGroupName>"
$keyVaultName="<keyVaultName>"
$certSubjectName="<certSubjectName>" # Your existing certificate name
$applicationName="<applicationName>" # Your existing application name
$adminAccountName="<adminAccountName>"
$adminAccountSid="<adminID>" # Use object ID for the Microsoft Entra user and group, or client ID for the Microsoft Entra application
$adminAccountType= 0 # 0 – for Microsoft Entra user and application, 1 for Microsoft Entra group
$keyVault = Get-AzKeyVault -VaultName $keyVaultName
if (!$keyVault)
{
Write-Error "Supplied key vault was not found in the subscription. Please specify an existing key vault"
exit 1
}
$cert = Get-AzKeyVaultCertificate -VaultName $keyVaultName -Name $certSubjectName
if (!$cert)
{
Write-Error "Supplied certificate $certSubjectName was not found for this key vault. Please specify an existing certificate"
exit 1
}
$secretId = $cert.SecretId
if ($secretId -Match "(https:\/\/[^\/]+\/secrets\/[^\/]+)(\/.*){0,1}$") {
if ($Matches[1]) {
$secretId = $Matches[1]
}
}
$application = Get-AzADApplication -DisplayName $applicationName
if (!$application)
{
Write-Error "Supplied application was not found in the subscription. Please specify an existing application"
exit 1
}
# Create the settings object to write to the Arc extension
#
$instanceSettings = @{
instanceName = $instanceName
adminLoginName = $adminAccountName
adminLoginSid = $adminAccountSid
azureCertSecretId = $secretId.replace(":443", "")
azureCertUri = $cert.Id.replace(":443", "")
azureKeyVaultResourceUID = $keyVault.ResourceId
managedCertSetting = "CUSTOMER MANAGED CERT"
managedAppSetting = "CUSTOMER MANAGED APP"
appRegistrationName = $application.DisplayName
appRegistrationSid = $application.AppId
tenantId = $tenantId
aadCertSubjectName = $certSubjectName
adminLoginType = $adminAccountType
}
$arcInstance = Get-AzConnectedMachineExtension -SubscriptionId $subscriptionId -MachineName $machineName -ResourceGroupName $resourceGroupName -Name "WindowsAgent.SqlServer"
if ($arcInstance.Setting.AdditionalProperties.AzureAD)
{
$aadSettings = $arcInstance.Setting.AdditionalProperties.AzureAD
$instanceFound = $false
$instanceNameLower = $instanceName.ToLower()
$instanceIndex = 0
for (($i = 0); $i -lt $aadSettings.Length; $i++)
{
if ($aadSettings[$i].instanceName.ToLower() -eq $instanceNameLower)
{
$instanceIndex = $i
$instanceFound = $true
break
}
}
if ($instanceFound)
{
$aadSettings[$instanceIndex] = $instanceSettings
}
else
{
$aadSettings += $instanceSettings
}
}
else
{
$aadSettings = , $instanceSettings
}
Write-Host "Writing Microsoft Entra setting to SQL Server Arc Extension. This may take several minutes..."
# Push settings to Arc
#
try
{
#set the Entra ID / AzureAD setting in the hash table
$SettingsToConfigure = @{
AzureAD = $aadSettings
}
#add any non-AzureAD key value pairs back to the hashtable
$keys = $arcInstance.Setting.Keys | where-object {$_ -notin ("AzureAD")}
foreach ($key in $keys) {
$SettingsToConfigure.$key = $arcInstance.Setting["$key"]
}
#Issue the update of the updated settings
Update-AzConnectedMachineExtension `
-MachineName $machineName `
-Name "WindowsAgent.SqlServer" `
-ResourceGroupName $resourceGroupName `
-Setting $SettingsToConfigure
}
catch
{
Write-Error $_
Write-Error "Failed to write settings to Arc host"
exit 1
}
Write-Output "Success"
O modelo do ARM a seguir configura um administrador do Microsoft Entra usando um certificado do Azure Key Vault e um aplicativo Microsoft Entra já criados.
Utilizam-se estes parâmetros de entrada com o modelo ARM:
<machineName>
: nome do computador do host do SQL Server
<Location>
: localização do grupo de recursos do SQL Server – Azure Arc, como West US
ou Central US
<tenantId>
: o ID do locatário pode ser encontrado acessando o portal do Azure e acessando o recurso Microsoft Entra ID. No painel Visão geral, você verá seu ID de Locatário
<instanceName>
: o nome da instância do SQL Server O nome da instância padrão do SQL Server é MSSQLSERVER
<certSubjectName>
: nome do certificado que você criou
<subscriptionId>
: ID da assinatura. Sua ID da assinatura pode ser encontrada no portal do Azure
<resourceGroupName>
- Nome do grupo de recursos que contém o cofre de chaves. Encontre o valor completo de azureKeyVaultResourceUID acessando o recurso Cofre de chaves, selecionando Propriedades e copiando a ID do recurso
<keyVaultName>
– Seu nome do cofre de chaves
<certIdentifier>
: o identificador de certificado do certificado do Azure Key Vault. Para obter o identificador de certificado, vá para o recurso Cofre de chaves e selecione Certificados em Configurações. Selecione a versão atual do certificado que você criou e copie o valor do identificador de certificado. Para obter mais informações, confira Adicionar um certificado ao Key Vault
<certSecret>
: o identificador secreto do certificado, e pode ser encontrado no mesmo menu que o identificador do certificado
<applicationName>
- o nome do aplicativo Microsoft Entra que você criou
<appID>
- A ID do Aplicativo (cliente) do seu aplicativo Microsoft Entra pode ser encontrada no menu Visão geral do aplicativo
<adminAccountName>
: conta do administrador do Microsoft Entra que você quer definir para o SQL Server
<adminID>
: a ID de objeto do usuário ou grupo do Microsoft Entra ou a ID do aplicativo (cliente) do aplicativo, se você estiver usando outro aplicativo como conta do administrador do Microsoft Entra. Veja mais informações no Tutorial: criar e gerenciar usuários do Microsoft Entra usando aplicativos do Microsoft Entra
<adminType>
: usar 0
para usuários e aplicativos do Microsoft Entra e 1
para grupos do Microsoft Entra
Use uma implantação personalizada no portal do Azure e crie um modelo próprio no editor. Em seguida, salve a configuração depois de colá-la no exemplo.
Observação
Para o SQL Server em computadores host do Linux, substitua WindowsAgent.SqlServer
por LinuxAgent.SqlServer
no script.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"resources": [
{
"type": "Microsoft.HybridCompute/machines/extensions",
"apiVersion": "2022-03-10",
"name": "<machineName>/WindowsAgent.SqlServer",
"location": "<Location>",
"properties": {
"publisher": "Microsoft.AzureData",
"type": "WindowsAgent.SqlServer",
"settings": {
"AzureAD": [
{
"tenantId": "<tenantId>",
"instanceName": "<instanceName>",
"managedCertSetting": "CUSTOMER MANAGED CERT",
"aadCertSubjectName": "<certSubjectName>",
"azureKeyVaultResourceUID": "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.KeyVault/vaults/<keyVaultName>",
"azureCertUri": "<certIdentifier>",
"azureCertSecretId": "<certSecret>",
"managedAppSetting": "CUSTOMER MANAGED APP",
"appRegistrationName": "<applicationName>",
"appRegistrationSid": "<appID>",
"adminLoginName": "<adminAccountName>",
"adminLoginSid" : "<adminID>",
"adminLoginType": 0
}
]
}
}
}
]
}
Dar consentimento do administrador para o aplicativo
Quando o administrador do Microsoft Entra estiver configurado, você poderá se conectar ao SQL Server usando as credenciais de administrador do Microsoft Entra. Porém, outras atividades de banco de dados que envolvam a criação de novos logons e usuários do Microsoft Entra falharão até que o consentimento do administrador seja concedido ao aplicativo do Microsoft Entra.
Observação
Para conceder consentimento do administrador para o aplicativo, a conta que concede o consentimento precisa ter a função Administrador de funções com privilégios do Microsoft Entra ID. Essas funções são necessárias para conceder consentimento do administrador ao aplicativo, mas não para configurar o administrador do Microsoft Entra.
No portal do Azure, selecione Microsoft Entra ID>Registros de aplicativo e selecione o aplicativo recém-criado. O aplicativo deve ter um nome como <hostname>-<instanceName><uniqueNumber>
.
Escolha o menu Permissões da API.
Selecione Conceder consentimento do administrador.
Sem conceder consentimento do administrador ao aplicativo, criar um logon ou usuário do Microsoft Entra no SQL Server resultará no seguinte erro:
Msg 37455, Level 16, State 1, Line 2
Server identity does not have permissions to access MS Graph.
Usando a autenticação do Microsoft Entra para conectar-se ao SQL Server
A autenticação do Microsoft Entra agora está configurada para o SQL Server conectado ao Azure Arc. Siga as seções após configurar o administrador do Microsoft Entra no artigo Tutorial: configurar a autenticação do Microsoft Entra para o SQL Server e se conecte ao SQL Server usando a autenticação do Microsoft Entra.
Confira também