Моя задача заключается в полной автоматизации процессов с помощью агента сборки AzureDevOps в конфигурации по умолчанию.
Я пытаюсь использовать управляемую идентификацию службы приложений (https://docs.microsoft.com/en-us/azure/app-service/overview-managed-identity) для доступа к базе данных SQL.
Вся группа ресурсов создается агентом сборки AzureDevOps во время одного развертывания.
Упрощенная версия моих развертываний:
New-AzResourceGroup `
-Name $Env:RESOURCEGROUP_NAME `
-Location $Env:AZURE_REGION_COMMON `
-Force
#Create the functionapp
New-AzResource `
-ResourceGroupName $Env:RESOURCEGROUP_NAME `
-location $Env:AZURE_REGION_COMMON `
-ResourceName $Env:APPFUNCTIONS_NAME_SAFE `
-Kind 'functionapp' `
-ResourceType 'Microsoft.Web/Sites' `
-Properties @{} `
-Force
#Apply the Managed Service Identity
Set-AzWebApp `
-ResourceGroupName $Env:RESOURCEGROUP_NAME `
-Name $Env:APPFUNCTIONS_NAME_SAFE `
-AssignIdentity $true
# Create Sql Server
New-AzSqlServer `
-ResourceGroupName $Env:RESOURCEGROUP_NAME `
-location $Env:AZURE_REGION_COMMON `
-ServerName $Env:SQLSERVER_NAME_SAFE `
-ServerVersion $Env:SQLSERVER_VERSION `
-SqlAdministratorCredentials (New-Object `
-TypeName System.Management.Automation.PSCredential `
-ArgumentList $Env:SQLSERVER_ADMIN_USERNAME, (ConvertTo-SecureString -String $Env:SQLSERVER_ADMIN_PASSWORD -AsPlainText -Force)) `
-AssignIdentity
#Update Sql Server Firewall Rules for Azure
New-AzSqlServerFirewallRule `
-ResourceGroupName $Env:RESOURCEGROUP_NAME `
-ServerName $Env:SQLSERVER_NAME_SAFE `
-AllowAllAzureIPs
#Update Sql Server Firewall Rules for non-Azure build machine
$ip = Invoke-RestMethod http://ipinfo.io/json | Select -exp ip
New-AzSqlServerFirewallRule `
-ResourceGroupName $Env:RESOURCEGROUP_NAME `
-ServerName $Env:SQLSERVER_NAME_SAFE `
-FirewallRuleName "BuildMachine" `
-StartIpAddress $ip `
-EndIpAddress $ip
#Create Sql Database
New-AzSqlDatabase `
-ResourceGroupName $Env:RESOURCEGROUP_NAME `
-ServerName $Env:SQLSERVER_NAME_SAFE `
-DatabaseName $Env:SQLSERVER_DATABASE_NAME
На данный момент; Я не нахожу ни одного PowerShell, который может запустить агент сборки, чтобы предоставить полномочия базы данных для удостоверения.
Я нахожу ссылки, которые предлагают запустить что-то подобное в базе данных
CREATE USER [$Env:APPFUNCTIONS_NAME_SAFE] FROM EXTERNAL PROVIDER
ALTER ROLE db_datareader ADD MEMBER [$Env:APPFUNCTIONS_NAME_SAFE]
ALTER ROLE db_datawriter ADD MEMBER [$Env:APPFUNCTIONS_NAME_SAFE]
Именно здесь я безуспешно сосредоточил свои усилия.
Когда я вхожу в базу данных как администратор БД (см. SqlAdministratorCredentials
выше), тогда я получаю следующее исключение
Exception calling "ExecuteNonQuery" with "0" argument(s): "Principal '<value of Env:$APPFUNCTIONS_NAME_SAFE>' could not be created. Only connections established with Active Directory accounts can create other Active Directory users.
Чтобы обойти это, я вручную добавил группу AAD, подключение службы Azure Devops к этой группе. Это позволяет агенту сборки проходить аутентификацию через AAD на сервере Sql.
Повторное развертывание, я получаю System.Management.Automation.MethodInvocationException: Exception calling "Open" with "0" argument(s): "One or more errors occurred." ---> System.AggregateException: One or more errors occurred. ---> System.AggregateException: One or more errors occurred. ---> AdalException: No mapping between account names and security IDs was done.
Что подводит меня к - Как автоматизировать аутентификацию удостоверения AppService в базе данных Sql?
Ссылки
Вот как я выполняю SQL в качестве агента сборки
function Get-SqlServer{
Get-AzSqlServer `
-ResourceGroupName $Env:RESOURCEGROUP_NAME `
-ServerName $Env:SQLSERVER_NAME_SAFE `
-ErrorAction Ignore
}
function Add-User-Sql($database, $sql){
$server = "tcp:$((Get-SqlServer).FullyQualifiedDomainName),1433"
$adminName = $Env:SQLSERVER_ADMIN_USERNAME
$adminPassword = $Env:SQLSERVER_ADMIN_PASSWORD
$connectionString = "Server=$server;Database=$database;User ID=$adminName;Password=$adminPassword;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
#$connectionString = "Data Source=$server; Authentication=Active Directory Integrated; Initial Catalog=$database;";
$connection = New-Object -TypeName System.Data.SqlClient.SqlConnection($connectionString)
$command = New-Object -TypeName System.Data.SqlClient.SqlCommand($sql, $connection)
Write-Host "Add User [database=$database] on SqlServer [$Env:SQLSERVER_NAME_SAFE]"
Write-Host $sql
$connection.Open()
$command.ExecuteNonQuery()
$connection.Close()
}
Сценарий очистки
Remove-AzResourceGroup `
-Name $Env:RESOURCEGROUP_NAME `
-Force