Я создаю сервер и базу данных Azure SQL с помощью задачи терраформирования в конвейере Azure Devops с использованием размещенных агентов.
Ресурсы создаются без проблем.
Однако следующее задание на моем этапе пытается запустить сценарий db_init.sql для вновь созданной базы данных с помощью Задача развертывания базы данных SQL Azure. Эта задача периодически завершается ошибкой со следующей ошибкой:
Invoke-Sqlcmd -ServerInstance [отредактировано] .database.windows.net -Database [отредактировано] -Имя пользователя [отредактировано] -Пароль *** *** -Inputfile C: \ Users \ VssAdministrator \ AppData \ Local \ Temp \ tmp6F48.tmp -ConnectionTimeout 120
## [error] System.Management.Automation.RuntimeException: ресурс с именем serverName [отредактировано], serverType Microsoft.Sql / серверов в подписке [отредактировано] не найден. Укажите правильный serverName / serverType и повторите попытку. Узнайте, как устранять неполадки, на странице https://aka.ms/sqlazuredeployreadme#troubleshooting-
Ссылка для устранения неполадок, приведенная выше, не пригодилась. Я также нашел этот вопрос по SO, но ответ там не применимо.
Устройство трубопровода выглядит следующим образом:
stages:
- stage: rg
displayName: Create Resource Group
...
- stage: db
dependsOn:
- rg
displayName: Create DB Stage
jobs:
- job: createDB
displayName: 'Create Database'
steps:
...
- task: TerraformTaskV1@0
name: terraformApply
displayName: Terraform Apply
inputs: ...
- task: PowerShell@2
displayName: Read terraform outputs
name: terraformOutput
inputs:
pwsh: true
targetType: 'inline'
script: |
$terraformOutput = Get-Content "$(terraformApply.jsonOutputVariablesPath)" | ConvertFrom-Json
$terraformOutput | Get-Member -MemberType NoteProperty | % { $o = $terraformOutput.($_.Name); Write-Host "##vso[task.setvariable variable=$($_.Name);isoutput=true;issecret=$($o.sensitive)]$($o.value)" }
failOnStderr: true
showWarnings: true
- job:
displayName: Initialise DB
dependsOn: createDB
variables:
serverFQDN: $[ dependencies.createDB.outputs['terraformOutput.sql_server_fqdn'] ]
dbName: $[ dependencies.createDB.outputs['terraformOutput.sql_db_name'] ]
serverName: $[ dependencies.createDB.outputs['terraformOutput.server_name'] ]
pool:
vmImage: 'windows-latest'
steps:
- task: SqlAzureDacpacDeployment@1
displayName: Initialise DB
inputs:
azureSubscription: '[azure subscription id]'
AuthenticationType: 'server'
ServerName: '$(serverFQDN)'
DatabaseName: '$(dbName)'
SqlUsername: '[sql admin username]'
SqlPassword: '[sql admin password]'
deployType: 'SqlTask'
SqlFile: '$(System.DefaultWorkingDirectory)/[path-to]/db_init.sql'
IpDetectionMethod: 'AutoDetect'
Проблема возникает нечасто, и конвейер часто завершается успешно после повторной попытки неудачного шага. Тем не менее, я иногда видел, как шаг «Инициализация БД» терпит неудачу 3 или 4 попытки подряд в течение нескольких минут.
Я также протестировал использование задачи Azure CLI, чтобы дождаться сервера db (проверяя оба флага --created и --exists) перед попыткой инициализации, но это, похоже, не помогает.
- task: AzureCLI@2
displayName: 'Wait for DB to be ready'
inputs:
azureSubscription: '$(azure-subscription-id)'
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
# wait up to 5 minutes for the db server to be available. check every 10 seconds
az sql server wait --exists --interval 10 --timeout 300 --resource-group [rg name] --name $(serverName)
failOnStderr: true
ИЗМЕНИТЬ 2021-03-05: при более глубоком исследовании эта проблема, похоже, вызвана проблемой с вызовом API Azure, используемым задачей конвейера. Чтобы установить правило брандмауэра, задача пытается получить идентификатор целевого сервера Azure Sql. Для этого он вызывает GET https://management.azure.com//subscriptions/[subscription id]/resources?api-version=2014-04-01
и просматривает ответ, чтобы найти ресурс сервера Sql с совпадающим именем. В некоторых случаях я видел, как это действие завершается ошибкой ›через 30 минут после создания сервера базы данных, в то время как я мог запросить его на портале Azure.