Я посетил и попробовал несколько примеров, но ошибка все та же. У меня есть группа AAD с именем Azure_SqlServer_Admins, назначенная SQL Server в разделе Entra в качестве администратора Microsoft Entra. У меня есть имя участника-службы DevEnvSP, привязанное к этой группе (внутри). DevEnvSP также используется в моих конвейерах Azure DevOps, а также для развертывания sql-сервера, сборки и т. д. Этот субъект службы имеет роль участника и может читать пользователей (чтение каталога). я сделал по инструкции
Цель: из конвейера в качестве субъекта-службы выполнить SQL-скрипт для базы данных. Я попробовал несколько разных кодов, например:
- task: SqlAzureDacpacDeployment@1
displayName: 'name'
inputs:
azureSubscription: ${{ variables.subscriptionName }}
AuthenticationType: 'servicePrincipal'
ServerName: ${{ variables.sqlServerName }}.database.windows.net
DatabaseName: ${{ parameters.sqlDbName }}
IpDetectionMethod: 'AutoDetect'
deployType: 'InlineSqlTask'
SqlInline: my sql code
Я получаю сообщение об ошибке «Не удалось войти в систему для пользователя» на этапе конвейера. Хорошо, я также попробовал другой случай из Microsoft Docs, я получил секрет, получил идентификатор клиента и прошел через accessToken:
- task: AzurePowerShell@5
displayName: Creating user for ${{ parameters.sqlDbName }}
inputs:
azureSubscription: ${{ variables.subscriptionName }}
azurePowerShellVersion: 'LatestVersion'
ScriptType: 'InlineScript'
FailOnStandardError: true
Inline: |
$token = (Get-AzAccessToken -ResourceUrl https://database.windows.net).Token
$CmdText = @"
My SQL query
"@
Invoke-SqlCmd -ServerInstance "${{ variables.sqlServerName }}.database.windows.net" `
-Database "DbTest" `
-AccessToken $token `
-Query $CmdText
-Verbose
-OutputSqlErrors $true
К сожалению, та же ошибка.
Я прочитал соответствующий и похожий ответ StackOverflow: https://stackoverflow.com/a/71510259/17239546 . Похоже, существуют некоторые ограничения, связанные с администратором, если он назначен группой AAD. Откуда: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-database-scoped-credential-transact-sql?view=sql-server-ver16#remarks
Учетные данные в области базы данных — это запись, содержащая данные аутентификации, необходимые для подключения к ресурсу за пределами SQL Server. Большинство учетных данных включают пользователя и пароль Windows.
Но я не нашел решения для этой проблемы или что-то упустил во всех примерах, все используют в качестве администратора одного пользователя/sp, а не группу, и это работает.
ПРИМЕЧАНИЕ:
DECLARE @UMIUser NVARCHAR(100) = 'SP name';
IF DATABASE_PRINCIPAL_ID(@UMIUser) IS NULL
BEGIN
CREATE USER [@UMIUser] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [@UMIUser];
ALTER ROLE db_datawriter ADD MEMBER [@UMIUser];
ALTER ROLE db_ddladmin ADD MEMBER [@UMIUser];
END
Буду признателен, если кто-нибудь поможет мне в этом...
$TenantId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$ApplicationId = "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"
$ClientSecret = "zzzzzz"
$azurePassword = ConvertTo-SecureString "$ClientSecret" -AsPlainText -Force
$pscredential = New-Object System.Management.Automation.PSCredential($ApplicationId , $azurePassword)
Connect-AzAccount -Credential $pscredential -TenantId $TenantId -ServicePrincipal
Вы также можете установить $DebugPreference = 'Continue'
, чтобы получать более подробные журналы в сеансе PowerShell при запуске команд AzurePowerShell.
Кроме того, по принципу субъекта-службы в группе AAD, это регистрация приложения или управляемое удостоверение?
Регистрация приложения @AlvinZhao-MSFT
Если приложение недавно добавлено в группу AAD, вступление в силу права на членство в группе может занять некоторое время.
@AlvinZhao-MSFT большое спасибо за ваши ответы, я успешно получил токен доступа, но не могу войти с ним в систему. Что касается второго вопроса, приложение не добавлено недавно, оно устарело :(
Привет! Последние результаты: поскольку команда AzurePowerShell также не удалась в локальном сценарии, я думаю, мы могли бы исключить причину в среде агента Azure Pipelines; и я подозреваю, что приложение, на которое ссылается ваш сценарий или задача конвейера, было добавлено в группу AAD в качестве администратора SQL-сервера. Существует вероятность того, что несколько регистраций приложений имели одно и то же имя. Не могли бы вы еще раз проверить, совпадает ли идентификатор приложения корпоративного приложения в группе AAD администратора SQL с идентификатором регистрации приложения, на которое ссылается соединение службы ARM в вашей задаче конвейера?
Основываясь на вашем описании, я создал базу данных SQL Azure с администратором, установленным в качестве группы AAD, и мне удалось получить доступ к базе данных через конвейер YAML ниже, чтобы выполнить простой запрос.
variables:
ARMSvcCnnName: ARMSvcCnnSubX
AzureSQLServerName: xxxazsqlserverxxx
AzureSQLDBName: xxxazsqldbxxx
system.debug: true
pool:
vmImage: 'windows-latest'
steps:
- task: SqlAzureDacpacDeployment@1
displayName: 'Run SQL query'
inputs:
azureSubscription: '$(ARMSvcCnnName)'
AuthenticationType: 'servicePrincipal'
ServerName: '$(AzureSQLServerName).database.windows.net'
DatabaseName: '$(AzureSQLDBName)'
deployType: 'InlineSqlTask'
SqlInline: 'SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES;'
IpDetectionMethod: 'AutoDetect'
DeleteFirewallRule: false
Поскольку задача SqlAzureDacpacDeployment@1
ссылалась на подключение службы Azure Resource Manager для аутентификации доступа к базе данных SQL Azure на основе ее базового субъекта-службы (регистрации приложения), который должен быть членом группы администраторов SQL-сервера, я бы также предложил установить переменную конвейера system.debug
как true
, чтобы информация об субъекте-службе была видна в журналах отладки, чтобы мы могли дважды проверить правильность выбранного нами подключения к службе ARM.
Кроме того, проверьте журналы входа в AAD, чтобы узнать, есть ли дополнительная информация о том, почему не удалось выполнить вход субъекта-службы.
Спасибо. Идентификатор субъекта-службы подключения Azure DevOps действительно отличался.
Рад узнать, что эта информация помогает проверить базовый субъект-службу. Ваше здоровье.
Чтобы определить причину проблемы, пытались ли вы пройти аутентификацию по принципу службы локально, а затем получить доступ
$token
для запускаInvoke-SqlCmd
? Вот сценарий, который вы можете протестировать для аутентификации доступа к Azure в самом начале.