Implementación de una base de datos de Azure SQL

Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019

Puede implementar automáticamente las actualizaciones de la base de datos en la base de datos de Azure SQL después de cada compilación correcta.

DACPAC

La manera más sencilla de implementar una base de datos es crear un paquete de capa de datos o DACPAC. Los DACPAC se pueden usar para empaquetar e implementar cambios y datos de esquema. Puede crear un DACPAC mediante el proyecto de base de datos SQL en Visual Studio.

Para implementar un DACPAC en una base de datos de Azure SQL, agregue el siguiente fragmento de código al archivo azure-pipelines.yml.

- task: SqlAzureDacpacDeployment@1
  displayName: Execute Azure SQL : DacpacTask
  inputs:
    azureSubscription: '<Azure service connection>'
    ServerName: '<Database server name>'
    DatabaseName: '<Database name>'
    SqlUsername: '<SQL user name>'
    SqlPassword: '<SQL user password>'
    DacpacFile: '<Location of Dacpac file in $(Build.SourcesDirectory) after compilation>'

Consulte también la información de autenticación al usar la tarea Implementación de Azure SQL Database.

Scripts de SQL

En lugar de usar un DACPAC, también puede usar scripts de SQL para implementar la base de datos. Este es un ejemplo sencillo de un script de SQL que crea una base de datos vacía.

  USE [main]
  GO
  IF NOT EXISTS (SELECT name FROM main.sys.databases WHERE name = N'DatabaseExample')
  CREATE DATABASE [DatabaseExample]
  GO

Para ejecutar scripts de SQL como parte de una canalización, necesitará scripts de Azure PowerShell para crear y quitar reglas de firewall en Azure. Sin las reglas de firewall, el agente de Azure Pipelines no puede comunicarse con Azure SQL Database.

El siguiente script de PowerShell crea reglas de firewall. Puede proteger este script como SetAzureFirewallRule.ps1 en el repositorio.

ARM

[CmdletBinding(DefaultParameterSetName = 'None')]
param
(
  [String] [Parameter(Mandatory = $true)] $ServerName,
  [String] [Parameter(Mandatory = $true)] $ResourceGroupName,
  [String] $FirewallRuleName = "AzureWebAppFirewall"
)
$agentIP = (New-Object net.webclient).downloadstring("https://api.ipify.org")
New-AzSqlServerFirewallRule -ResourceGroupName $ResourceGroupName -ServerName $ServerName -FirewallRuleName $FirewallRuleName -StartIPAddress $agentIp -EndIPAddress $agentIP

Clásico

[CmdletBinding(DefaultParameterSetName = 'None')]
param
(
  [String] [Parameter(Mandatory = $true)] $ServerName,
  [String] [Parameter(Mandatory = $true)] $ResourceGroupName,
  [String] $FirewallRuleName = "AzureWebAppFirewall"
)

$ErrorActionPreference = 'Stop'

function New-AzureSQLServerFirewallRule {
  $agentIP = (New-Object net.webclient).downloadstring("https://api.ipify.org")
  New-AzureSqlDatabaseServerFirewallRule -StartIPAddress $agentIp -EndIPAddress $agentIp -RuleName $FirewallRuleName -ServerName $ServerName
}

function Update-AzureSQLServerFirewallRule{
  $agentIP= (New-Object net.webclient).downloadstring("https://api.ipify.org")
  Set-AzureSqlDatabaseServerFirewallRule -StartIPAddress $agentIp -EndIPAddress $agentIp -RuleName $FirewallRuleName -ServerName $ServerName
}

if ((Get-AzureSqlDatabaseServerFirewallRule -ServerName $ServerName -RuleName $FirewallRuleName -ErrorAction SilentlyContinue) -eq $null)
{
  New-AzureSQLServerFirewallRule
}
else
{
  Update-AzureSQLServerFirewallRule
}

El siguiente script de PowerShell quita las reglas de firewall. Puede proteger este script como RemoveAzureFirewallRule.ps1 en el repositorio.

ARM

[CmdletBinding(DefaultParameterSetName = 'None')]
param
(
  [String] [Parameter(Mandatory = $true)] $ServerName,
  [String] [Parameter(Mandatory = $true)] $ResourceGroupName,
  [String] $FirewallRuleName = "AzureWebAppFirewall"
)
Remove-AzSqlServerFirewallRule -ServerName $ServerName -FirewallRuleName $FirewallRuleName -ResourceGroupName $ResourceGroupName

Clásico

[CmdletBinding(DefaultParameterSetName = 'None')]
param
(
  [String] [Parameter(Mandatory = $true)] $ServerName,
  [String] [Parameter(Mandatory = $true)] $ResourceGroupName,
  [String] $FirewallRuleName = "AzureWebAppFirewall"
)

$ErrorActionPreference = 'Stop'

if ((Get-AzureSqlDatabaseServerFirewallRule -ServerName $ServerName -RuleName $FirewallRuleName -ErrorAction SilentlyContinue))
{
  Remove-AzureSqlDatabaseServerFirewallRule -RuleName $FirewallRuleName -ServerName $ServerName
}

Agregue lo siguiente al archivo azure-pipelines.yml para ejecutar un script de SQL.

variables:
  AzureSubscription: '<SERVICE_CONNECTION_NAME>'
  ResourceGroupName: '<RESOURCE_GROUP_NAME>'
  ServerName: '<DATABASE_SERVER_NAME>'
  ServerFqdn: '<DATABASE_FQDN>'
  DatabaseName: '<DATABASE_NAME>'
  AdminUser: '<DATABASE_USERNAME>'
  AdminPassword: '<DATABASE_PASSWORD>'
  SQLFile: '<LOCATION_OF_SQL_FILE_IN_$(Build.SourcesDirectory)>'

steps:
- task: AzurePowerShell@5
  displayName: 'Azure PowerShell script'
  inputs:
    azureSubscription: '$(AzureSubscription)'
    ScriptType: filePath
    ScriptPath: '$(Build.SourcesDirectory)\scripts\SetAzureFirewallRule.ps1'
    ScriptArguments: '-ServerName $(ServerName) -ResourceGroupName $(ResourceGroupName)'
    azurePowerShellVersion: LatestVersion

- task: CmdLine@2
  displayName: Run Sqlcmd
  inputs:
    filename: sqlcmd
    arguments: '-S $(ServerFqdn) -U $(AdminUser) -P $(AdminPassword) -d $(DatabaseName) -i $(SQLFile)'

- task: AzurePowerShell@5
  displayName: 'Azure PowerShell script'
  inputs:
    azureSubscription: '$(AzureSubscription)'
    ScriptType: filePath
    ScriptPath: '$(Build.SourcesDirectory)\scripts\RemoveAzureFirewallRule.ps1'
    ScriptArguments: '-ServerName $(ServerName) -ResourceGroupName $(ResourceGroupName)'
    azurePowerShellVersion: LatestVersion

Conexión del servicio de Azure

La tarea Implementación de Azure SQL Database es el mecanismo principal para implementar una base de datos en Azure. Esta tarea, al igual que con otras tareas integradas de Azure, requiere una conexión de servicio de Azure como entrada. La conexión de servicio de Azure almacena las credenciales para conectarse de Azure Pipelines a Azure.

La manera más fácil de empezar a trabajar con esta tarea es iniciar sesión como usuario propietario de la organización Azure DevOps y la suscripción de Azure. En este caso, no tendrá que crear manualmente la conexión de servicio. Por otro lado, para aprender a crear una conexión de servicio de Azure, consulte Creación de una conexión de servicio de Azure.

Para aprender a crear una conexión de servicio de Azure, consulte Creación de una conexión de servicio de Azure.

Implementación condicional

Puede optar por implementar solo determinadas compilaciones en la base de datos de Azure.

Para hacer esto en YAML, puede usar una de estas técnicas:

  • Aísle los pasos de implementación en un trabajo independiente y agregue una condición a ese trabajo.
  • Agregue una condición al paso.

En el siguiente ejemplo se muestra cómo usar condiciones de paso para implementar solo las compilaciones que se originan en la rama principal.

- task: SqlAzureDacpacDeployment@1
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
  inputs:
    azureSubscription: '<Azure service connection>'
    ServerName: '<Database server name>'
    DatabaseName: '<Database name>'
    SqlUsername: '<SQL user name>'
    SqlPassword: '<SQL user password>'
    DacpacFile: '<Location of Dacpac file in $(Build.SourcesDirectory) after compilation>'

Para más información sobre condiciones, consulte Especificación de condiciones.

Más acciones de SQL

Es posible que la implementación de SQL Azure Dacpac no admita todas las acciones de SQL Server que quiera realizar. En estos casos, puede usar simplemente scripts de PowerShell o de línea de comandos para ejecutar los comandos que necesita. En esta sección se muestran algunos de los casos de uso comunes para invocar la herramienta SqlPackage.exe. Como requisito previo para ejecutar esta herramienta, debe usar un agente autohospedado y tener instalada la herramienta en el agente.

Nota:

Si ejecuta SQLPackage desde la carpeta donde está instalado, debe prefijar el trazado con & y encapsularla entre comillas dobles.

Sintaxis básica

<Path of SQLPackage.exe> <Arguments to SQLPackage.exe>

Puede usar cualquiera de los siguientes scripts de SQL en función de la acción que desee realizar

Extracción

Crea un archivo de instantáneas de base de datos (.dacpac) a partir de un servidor SQL activo o Microsoft Azure SQL Database.

Sintaxis de comandos:

SqlPackage.exe /TargetFile:"<Target location of dacpac file>" /Action:Extract
/SourceServerName:"<ServerName>.database.windows.net"
/SourceDatabaseName:"<DatabaseName>" /SourceUser:"<Username>" /SourcePassword:"<Password>"

o bien

SqlPackage.exe /action:Extract /tf:"<Target location of dacpac file>"
/SourceConnectionString:"Data Source=ServerName;Initial Catalog=DatabaseName;Integrated Security=SSPI;Persist Security Info=False;"

Ejemplo:

SqlPackage.exe /TargetFile:"C:\temp\test.dacpac" /Action:Extract /SourceServerName:"DemoSqlServer.database.windows.net"
 /SourceDatabaseName:"Testdb" /SourceUser:"ajay" /SourcePassword:"SQLPassword"

Ayuda:

sqlpackage.exe /Action:Extract /?

Publicar

actualiza de forma incremental un esquema de la base de datos para coincidir con el esquema de un archivo .dacpac de origen. Si la base de datos no existe en el servidor, la operación de publicación la creará. De lo contrario, se actualizará una base de datos existente.

Sintaxis de comandos:

SqlPackage.exe /SourceFile:"<Dacpac file location>" /Action:Publish /TargetServerName:"<ServerName>.database.windows.net"
/TargetDatabaseName:"<DatabaseName>" /TargetUser:"<Username>" /TargetPassword:"<Password> "

Ejemplo:

SqlPackage.exe /SourceFile:"E:\dacpac\ajyadb.dacpac" /Action:Publish /TargetServerName:"DemoSqlServer.database.windows.net"
/TargetDatabaseName:"Testdb4" /TargetUser:"ajay" /TargetPassword:"SQLPassword"

Ayuda:

sqlpackage.exe /Action:Publish /?

Exportación

Exporta una base de datos activa, incluidos los datos de usuario y el esquema de base de datos, desde SQL Server o Microsoft Azure SQL Database a un paquete BACPAC (archivo.bacpac).

Sintaxis de comandos:

SqlPackage.exe /TargetFile:"<Target location for bacpac file>" /Action:Export /SourceServerName:"<ServerName>.database.windows.net"
/SourceDatabaseName:"<DatabaseName>" /SourceUser:"<Username>" /SourcePassword:"<Password>"

Ejemplo:

SqlPackage.exe /TargetFile:"C:\temp\test.bacpac" /Action:Export /SourceServerName:"DemoSqlServer.database.windows.net"
/SourceDatabaseName:"Testdb" /SourceUser:"ajay" /SourcePassword:"SQLPassword"

Ayuda:

sqlpackage.exe /Action:Export /?

Importar

importa los datos de esquema y tabla de un paquete BACPAC en una nueva base de datos de usuario en una instancia de SQL Server o Microsoft Azure SQL Database.

Sintaxis de comandos:

SqlPackage.exe /SourceFile:"<Bacpac file location>" /Action:Import /TargetServerName:"<ServerName>.database.windows.net"
/TargetDatabaseName:"<DatabaseName>" /TargetUser:"<Username>" /TargetPassword:"<Password>"

Ejemplo:

SqlPackage.exe /SourceFile:"C:\temp\test.bacpac" /Action:Import /TargetServerName:"DemoSqlServer.database.windows.net"
/TargetDatabaseName:"Testdb" /TargetUser:"ajay" /TargetPassword:"SQLPassword"

Ayuda:

sqlpackage.exe /Action:Import /?

DeployReport

crea un informe XML de los cambios que realizaría una acción de publicación.

Sintaxis de comandos:

SqlPackage.exe /SourceFile:"<Dacpac file location>" /Action:DeployReport /TargetServerName:"<ServerName>.database.windows.net"
/TargetDatabaseName:"<DatabaseName>" /TargetUser:"<Username>" /TargetPassword:"<Password>" /OutputPath:"<Output XML file path for deploy report>"

Ejemplo:

SqlPackage.exe /SourceFile:"E: \dacpac\ajyadb.dacpac" /Action:DeployReport /TargetServerName:"DemoSqlServer.database.windows.net"
/TargetDatabaseName:"Testdb" /TargetUser:"ajay" /TargetPassword:"SQLPassword" /OutputPath:"C:\temp\deployReport.xml" 

Ayuda:

sqlpackage.exe /Action:DeployReport /?

DriftReport

crea un informe XML de los cambios que se han realizado en una base de datos registrada desde que se registró por última vez.

Sintaxis de comandos:

SqlPackage.exe /Action:DriftReport /TargetServerName:"<ServerName>.database.windows.net" /TargetDatabaseName:"<DatabaseName>"
/TargetUser:"<Username>" /TargetPassword:"<Password>" /OutputPath:"<Output XML file path for drift report>"

Ejemplo:

SqlPackage.exe /Action:DriftReport /TargetServerName:"DemoSqlServer.database.windows.net" /TargetDatabaseName:"Testdb"
/TargetUser:"ajay" /TargetPassword:"SQLPassword" /OutputPath:"C:\temp\driftReport.xml"

Ayuda:

sqlpackage.exe /Action:DriftReport /?

Script

crea un script de actualización incremental de Transact-SQL que actualiza el esquema de un destino para que coincida con el esquema de un origen.

Sintaxis de comandos:

SqlPackage.exe /SourceFile:"<Dacpac file location>" /Action:Script /TargetServerName:"<ServerName>.database.windows.net"
/TargetDatabaseName:"<DatabaseName>" /TargetUser:"<Username>" /TargetPassword:"<Password>" /OutputPath:"<Output SQL script file path>"

Ejemplo:

SqlPackage.exe /Action:Script /SourceFile:"E:\dacpac\ajyadb.dacpac" /TargetServerName:"DemoSqlServer.database.windows.net"
/TargetDatabaseName:"Testdb" /TargetUser:"ajay" /TargetPassword:"SQLPassword" /OutputPath:"C:\temp\test.sql"
/Variables:StagingDatabase="Staging DB Variable value"

Ayuda:

sqlpackage.exe /Action:Script /?