Aplica-se a:
SQL Server 2022 (16.x)
Observação
Esse recurso está disponível no SQL Server 2022 (16.x) ou versões posteriores e só tem suporte para SQL Server local, para hosts Windows e Linux e SQL Server 2022 em VMs do Windows Azure.
Neste artigo, explicaremos como configurar o administrador do Microsoft Entra para permitir a autenticação com a ID do Microsoft Entra (anteriormente Azure Ative Directory) para SQL Server usando o portal do Azure e APIs como:
- PowerShell
- A Interface de Linha de Comando do Azure
- Modelo ARM
Também abordaremos 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 aplicativos. Anteriormente, a configuração da autenticação do Microsoft Entra para o SQL Server exigia a configuração manual de um administrador do Microsoft Entra com um certificado do Azure e um registo de aplicação.
Observação
Embora o Microsoft Entra ID seja o novo nome para o Azure Active Directory (Azure AD), para evitar a interrupção de ambientes existentes, o Azure AD ainda permanece 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 as instruções do guia para garantir que o seu SQL Server esteja conectado ao Azure Arc. O utilizador que está a configurar o administrador do Microsoft Entra para o recurso SQL Server – Azure Arc deve ter a função de Colaborador no servidor.
- Vá para o portal do Azure
- Selecione SQL Server – Azure Arce selecione a instância para seu host do SQL Server.
- Selecione Controle de acesso (IAM).
- Selecione Adicionar>Atribuir função para adicionar a função Colaborador ao utilizador que está a configurar o administrador do Microsoft Entra.
Crie um Cofre de Chaves do Azure se ainda não tiver um. O utilizador que configura o administrador do Microsoft Entra deve ter a função Colaborador no seu Cofre de Chaves do Azure. Para adicionar uma função a um usuário no Cofre da Chave do Azure:
- Vá para o portal do Azure
- Aceda ao recurso do cofre de chaves .
- Selecione o Controle de acesso (IAM).
- Selecione Adicionar>Atribuir função para adicionar a função Colaborador ao utilizador que está a configurar o administrador do Microsoft Entra.
Definir políticas de acesso para o host do SQL Server
No portal do Azure, navegue até a sua 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 secretas, selecione Obter e Listar.
Para permissões de Certificado, selecione Obter e Listar.
Selecione Avançar.
Na página Principal, procure o nome da sua instância Machine - Azure Arc, que é o nome do host do SQL Server.
Salte a página Aplicativo (opcional) ao selecionar Avançar duas vezes ou ao selecionar Revisão e criação.
Verifique se o "ID do Objeto" do Principal corresponde ao ID do principal da identidade gerida atribuída à instância.
Para confirmar, vá para a página de recursos e selecione Visualização JSON no canto superior direito da caixa Essentials na página de Visão Geral. Sob a identidade , irá encontrar o principalId.
Selecione Criar.
Você deve selecionar Criar para garantir que as permissões sejam aplicadas. Para garantir que as permissões foram armazenadas, atualize a janela do navegador e verifique se a linha da sua 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 sua instância do Azure Key Vault e selecione políticas de acesso.
- Selecione Adicionar Política de Acesso.
- Para permissões de chave, selecione Obter, Listare Criar.
- Para permissões secretas, selecione Obter, Listae Definir.
- Para permissões de Certificado, selecione Obter, Listare Criar.
- Para Selecionar principal, adicione o usuário do Microsoft Entra que você deseja usar para se conectar ao SQL Server.
- Selecione Adicionar e, em seguida, selecione Guardar.
Configurando o administrador do Microsoft Entra para SQL Server
As novas APIs e funcionalidades do portal permitem que os usuários configurem um administrador do Microsoft Entra para SQL Server sem precisar criar separadamente um certificado do Azure e um aplicativo Microsoft Entra. Selecione uma guia para saber como configurar um administrador do Microsoft Entra para seu SQL Server conectado ao Azure Arc com certificado automático e criação de aplicativos.
Use o portal do Azure para configurar um administrador do Microsoft Entra, criar um certificado do Azure Key Vault e um aplicativo 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
Vá para o portal do Azuree selecione SQL Server – Azure Arc. Selecione a instância para seu host do SQL Server.
Verifique o estado do seu recurso SQL Server - Azure Arc e veja se está conectado acedendo ao menu Propriedades . Para obter mais informações, consulte Validar os seus recursos do SQL Server habilitados com Arc.
Selecione Microsoft Entra ID e Purview em Configurações no menu de recursos.
Selecione Configurar Administração para abrir o painel Microsoft Entra ID e escolha uma conta que será adicionada como nome de utilizador de administrador no SQL Server.
Selecione certificado gerenciado por serviço.
Selecione Mudar cofre de chaves e selecione o seu recurso existente do Cofre de Chaves do Azure.
Selecione registo de aplicação gerida por serviço.
Selecione Salvar. Isso envia uma solicitação para o agente do servidor Arc, que configura a autenticação do 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 um login do Microsoft Entra.
O registro do aplicativo gerenciado pelo serviço faz o seguinte para você:
- Cria um certificado no cofre de chaves com um nome no formato
<hostname>-<instanceName><uniqueNumber>.
- Cria um aplicativo Microsoft Entra com um nome como
<hostname>-<instanceName><uniqueNumber>e atribui as permissões necessárias a esse aplicativo. Para obter mais informações, consulte Conceder permissões de aplicativo
- Atribui o novo certificado no Cofre da Chave do Azure ao aplicativo.
- Salva essas configurações no Azure Arc.
O script da CLI do Azure abaixo configura um administrador do Microsoft Entra, cria um certificado do Azure Key Vault e cria um aplicativo Microsoft Entra. Há uma seção adicional que fornece um script de exemplo para configurar um administrador do Microsoft Entra quando um certificado e um aplicativo já existem.
Observação
Os certificados criados para a instalação do Microsoft Entra não são girados automaticamente.
-
A CLI do Azure versão 2.37.0 ou superior é necessária
- Az.ConnectedMachine 0.5.1 ou superior é necessário
Para instalar o módulo Az.ConnectedMachine, use az extension add --name ConnectedMachine. Para verificar qual versão da CLI do Azure está instalada, use az version.
Os seguintes parâmetros de entrada são usados para o 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 de executar o script
-
<machineName> - Nome da máquina do host do SQL Server
-
<resourceGroupName> - Nome do grupo de recursos que contém sua instância SQL Server – Azure Arc
-
<adminAccountName> - Conta de administrador do Microsoft Entra que você deseja 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 for omitido, o nome padrão do MSSQLSERVER é usado
-
<tenantId> - Parâmetro opcional para ID do locatário. O ID do locatário pode ser encontrado ao aceder ao portal do Azure, e depois ir para o recurso do Microsoft Entra ID. No painel Painel de Visão Geral, deve ver o seu ID do Tenant. Se omitido, o ID do locatário padrão é usado como parâmetro
-
<subscriptionId> - Parâmetro opcional para ID de assinatura. Sua ID de assinatura pode ser encontrada no portal do Azure. Se omitido, o ID de assinatura padrão será usado
Para usar o script da CLI do Azure abaixo, salve o script como um arquivo de .ps1 e execute o seguinte 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 SQL Server em máquinas host 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 estiver concluído, aparecerá uma mensagem semelhante à seguinte:
Name Location ProvisioningState
---- -------- -----------------
WindowsAgent.SqlServer westus2 Succeeded
Success
Configurando um administrador do Microsoft Entra com certificado e aplicativo existentes usando a CLI do Azure
Se você já tiver um certificado existente do Azure Key Vault e um aplicativo do Azure que deseja usar para configurar um administrador do Microsoft Entra, poderá usar o seguinte 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 do PowerShell abaixo configura um administrador do Microsoft Entra, cria um certificado do Azure Key Vault e cria um aplicativo Microsoft Entra. Há uma seção adicional que fornece um script de exemplo para configurar um administrador do Microsoft Entra quando um certificado e um aplicativo já existem.
Observação
Os certificados criados para a instalação do Microsoft Entra não são girados automaticamente.
Os módulos a seguir são necessários para este tutorial. Instale as versões mais recentes dos módulos ou superiores à versão indicada abaixo:
- Az.Contas 3.37.0
- Az.ConnectedMachine 0.5.0
- Az.KeyVault 4.5.0
- Az.Recursos 6.0.0
Os seguintes 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 de executar o script
-
<machineName> - Nome da máquina do host do SQL Server
-
<resourceGroupName> - Nome do grupo de recursos que contém sua instância SQL Server – Azure Arc
-
<adminAccountName> - Conta de administrador do Microsoft Entra que você deseja 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 for omitido, o nome padrão do MSSQLSERVER é usado
-
<tenantId> - Parâmetro opcional para ID do locatário. O ID do locatário pode ser encontrado ao aceder ao portal do Azure, e depois ir para o recurso do Microsoft Entra ID. No painel Painel de Visão Geral, deve ver o seu ID do Tenant. Se omitido, o ID do locatário padrão é usado como parâmetro
-
<subscriptionId> - Parâmetro opcional para ID de assinatura. Sua ID de assinatura pode ser encontrada no portal do Azure. Se omitido, o ID de assinatura padrão será usado
Para usar o script do PowerShell abaixo, salve o script como um arquivo de .ps1 e execute o seguinte 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 SQL Server em máquinas host 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 existentes usando o PowerShell
Se você já tiver um certificado existente do Azure Key Vault e um aplicativo do Azure que deseja usar para configurar um administrador do Microsoft Entra, poderá usar o seguinte 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 ARM a seguir configura um administrador do Microsoft Entra usando um certificado existente do Azure Key Vault e um aplicativo Microsoft Entra.
Os seguintes parâmetros de entrada são usados para o modelo ARM:
-
<machineName> - Nome da máquina do host do SQL Server
-
<Location> - Localização do seu SQL Server – Azure Arc grupo de recursos, como West USou Central US
-
<tenantId> - O ID do locatário pode ser encontrado acedendo ao portal do Azure e ao seu recurso Microsoft Entra ID. No painel Visão Geral, deverá ver o seu ID de Inquilino
-
<instanceName> - 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 subscrição. Sua ID de assinatura pode ser encontrada no portal do Azure
-
<resourceGroupName> - Nome do grupo de recursos que contém o cofre de chaves. O valor completo azureKeyVaultResourceUID pode ser encontrado acedendo ao recurso do cofre de chaves , selecionando Propriedades e copiando ID do Recurso
-
<keyVaultName> - O nome do seu cofre de chaves
-
<certIdentifier> - O Identificador de Certificado para o seu certificado do Cofre de Chaves do Azure. Para obter o Identificador de Certificado , vá para o seu recurso de Cofre de Chaves e selecione Certificados em Configurações . Selecione a versão atual do certificado que crioue copie o valor de Identificador de Certificado . Para obter mais informações, consulte Adicionar um certificado ao Cofre de Chaves
-
<certSecret> - O Identificador Secreto do seu certificado pode ser encontrado no mesmo menu que o Identificador de Certificado
-
<applicationName> - O nome da sua aplicação Microsoft Entra criada
-
<appID> - O ID do Aplicativo (cliente) do seu aplicativo Microsoft Entra pode ser encontrado no menu Visão Geral do aplicativo
-
<adminAccountName> - Conta de administrador do Microsoft Entra que você deseja definir para o SQL Server
-
<adminID> - O ID de Objeto do utilizador ou grupo do Microsoft Entra, ou o ID do Aplicativo (cliente) do aplicativo, se estiver a usar outra aplicação como conta de administrador do Microsoft Entra. Para obter mais informações, consulte Tutorial: Criar usuários do Microsoft Entra usando aplicativos do Microsoft Entra
-
<adminType> - Use o 0 para usuários e aplicativos do Microsoft Entra e 1 para grupos do Microsoft Entra
Use uma implantação personalizada no portal do Azuree construa o seu próprio modelo no editor. Em seguida, Guarde a configuração depois de colar o exemplo.
Observação
Para SQL Server em máquinas host 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
}
]
}
}
}
]
}
Conceder consentimento de administrador para o aplicativo
Depois que o administrador do Microsoft Entra tiver sido configurado, o uso das credenciais de administrador do Microsoft Entra permitirá que você se conecte ao SQL Server. No entanto, quaisquer outras atividades de banco de dados que envolvam a criação de novos logins e usuários do Microsoft Entra falharão até que o consentimento do administrador seja concedido ao aplicativo Microsoft Entra.
Observação
Para conceder consentimento de administrador para o aplicativo, a conta que concede o consentimento requer a função de Administrador de Função Privilegiada do Microsoft Entra ID. Essas funções são necessárias para conceder consentimento de administrador para o aplicativo, mas não é necessário para configurar o administrador do Microsoft Entra.
No portal Azure, selecione Microsoft Entra ID>Registos de aplicações, e selecione a aplicação recém-criada. O aplicativo deve ter um nome como <hostname>-<instanceName><uniqueNumber>.
Selecione o menu permissões da API.
Selecione Conceder consentimento de administrador.
Sem conceder consentimento de administrador para o aplicativo, a criação de 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 se conectar ao SQL Server
A autenticação do Microsoft Entra já está configurada para o seu SQL Server conectado ao Azure Arc. Após configurar o administrador Microsoft Entra, siga as seções do artigo Tutorial: Configurar a autenticação do Microsoft Entra para SQL Server para estabelecer a conexão ao SQL Server utilizando a autenticação do Microsoft Entra.
Ver também