Azure SQL-Datenbank-Bereitstellung

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

Sie können Ihre Datenbankupdates nach jedem erfolgreichen Build automatisch in Azure SQL-Datenbank bereitstellen.

DACPAC

Die einfachste Möglichkeit zum Bereitstellen einer Datenbank besteht darin, ein Datenebenenpaket oder DACPAC zu erstellen. DACPACs können verwendet werden, um Schemaänderungen und Daten zu packen und bereitzustellen. Sie können eine DACPAC-Datei mithilfe des SQL-Datenbank-Projekts in Visual Studio erstellen.

Um eine DACPAC-Datei in einer Azure SQL-Datenbank-Instanz bereitzustellen, fügen Sie der Datei „azure-pipelines.yml“ den folgenden Codeschnipsel hinzu.

- 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>'

Weitere Informationen finden Sie unter Authentifizierungsinformationen beim Verwenden der Aufgabe „Azure SQL-Datenbank-Bereitstellung“.

SQL-Skripts

Anstelle einer DACPAC-Datei können Sie auch SQL-Skripts verwenden, um Ihre Datenbank bereitzustellen. Hier sehen Sie ein einfaches Beispiel für ein SQL-Skript, das eine leere Datenbank erstellt.

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

Um SQL-Skripts als Teil einer Pipeline auszuführen, benötigen Sie Azure PowerShell-Skripts, um Firewallregeln in Azure zu erstellen und zu entfernen. Ohne die Firewallregeln kann der Azure Pipelines-Agent nicht mit Azure SQL-Datenbank kommunizieren.

Das folgende PowerShell-Skript erstellt Firewallregeln. Sie können dieses Skript als SetAzureFirewallRule.ps1 in Ihr Repository einchecken.

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

Klassisch

[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
}

Das folgende PowerShell-Skript entfernt Firewallregeln. Sie können dieses Skript als RemoveAzureFirewallRule.ps1 in Ihr Repository einchecken.

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

Klassisch

[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
}

Fügen Sie Ihrer Datei „azure-pipelines.yml“ Folgendes hinzu, um ein SQL-Skript auszuführen.

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

Azure-Dienstverbindung

Die Aufgabe Azure SQL-Datenbank-Bereitstellung ist das primäre Verfahren zum Bereitstellen einer Datenbank in Azure. Für diese Aufgabe ist wie bei anderen integrierten Azure-Aufgaben eine Azure-Dienstverbindung als Eingabe erforderlich. Die Azure-Dienstverbindung speichert die Anmeldeinformationen für die Verbindung von Azure Pipelines mit Azure.

Am einfachsten beginnen Sie mit dieser Aufgabe, wenn Sie unter einem Benutzerkonto angemeldet sind, das sowohl die Azure DevOps-Organisation als auch das Azure-Abonnement besitzt. In diesem Fall müssen Sie die Dienstverbindung nicht manuell erstellen. Andernfalls finden Sie Informationen zum Erstellen einer Azure-Dienstverbindung unter Erstellen einer Azure-Dienstverbindung.

Weitere Informationen zum Erstellen einer Azure-Dienstverbindung finden Sie unter Erstellen einer Azure-Dienstverbindung.

Bedingtes Bereitstellen

Sie können nur bestimmte Builds in Ihrer Azure-Datenbank bereitstellen.

Um dies in YAML zu bewerkstelligen, können Sie eine der folgenden Methoden verwenden:

  • Isolieren der Bereitstellungsschritte in einen separaten Auftrag und Hinzufügen einer Bedingung zu diesem Auftrag.
  • Hinzufügen einer Bedingung zum Schritt.

Im folgenden Beispiel wird gezeigt, wie Schrittbedingungen verwendet werden, um nur Builds bereitzustellen, die aus dem Mainbranch stammen.

- 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>'

Weitere Informationen finden Sie unter Angeben von Bedingungen.

Weitere SQL-Aktionen

Die SQL Azure-DACPAC-Bereitstellung unterstützt möglicherweise nicht alle SQL Server-Aktionen, die Sie ausführen möchten. In diesen Fällen können Sie einfach PowerShell oder Befehlszeilenskripts verwenden, um die benötigten Befehle auszuführen. In diesem Abschnitt werden einige der gängigen Anwendungsfälle für den Aufruf des Tools SqlPackage.exe erläutert. Als Voraussetzung für die Ausführung dieses Tools müssen Sie einen selbstgehosteten Agent verwenden und das Tool auf Ihrem Agent installieren.

Hinweis

Wenn Sie SQLPackage aus dem Ordner ausführen, in dem es installiert ist, müssen Sie dem Pfad & als Präfix voranstellen und in doppelte Anführungszeichen einschließen.

Grundlegende Syntax

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

Abhängig von der Aktion, die Sie ausführen möchten, können Sie eines der folgenden SQL-Skripts verwenden.

Extrahieren

Erstellt eine Datenbankmomentaufnahme (DACPAC-Datei) von einer aktiven SQL Server- oder Microsoft Azure SQL-Datenbank-Instanz.

Befehlssyntax:

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

oder

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

Beispiel:

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

Hilfe:

sqlpackage.exe /Action:Extract /?

Veröffentlichen

Aktualisiert ein Datenbankschema inkrementell, sodass dieses dem Schema einer DACPAC-Quelldatei entspricht Wenn die Datenbank auf dem Server nicht vorhanden ist, wird sie durch den Veröffentlichungsvorgang erstellt. Andernfalls wird eine bestehende Datenbank aktualisiert.

Befehlssyntax:

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

Beispiel:

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

Hilfe:

sqlpackage.exe /Action:Publish /?

Exportieren

Exportiert eine Livedatenbank, einschließlich des Datenbankschemas und der Benutzerdaten, aus SQL Server oder Microsoft Azure SQL-Datenbank in ein BACPAC-Paket (BACPAC-Datei).

Befehlssyntax:

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

Beispiel:

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

Hilfe:

sqlpackage.exe /Action:Export /?

Importieren

Importiert das Schema und die Tabellendaten aus einem BACPAC-Paket in eine neue Benutzerdatenbank einer Instanz von SQL Server oder Microsoft Azure SQL-Datenbank.

Befehlssyntax:

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

Beispiel:

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

Hilfe:

sqlpackage.exe /Action:Import /?

DeployReport

Erstellt einen XML-Bericht der Änderungen, die durch eine Veröffentlichungsaktion vorgenommen würden

Befehlssyntax:

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>"

Beispiel:

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" 

Hilfe:

sqlpackage.exe /Action:DeployReport /?

DriftReport

Erstellt einen XML-Bericht der Änderungen, die seit der letzten Registrierung an einer registrierten Datenbank vorgenommen wurden.

Befehlssyntax:

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

Beispiel:

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

Hilfe:

sqlpackage.exe /Action:DriftReport /?

Skript

Erstellt ein inkrementelles Transact-SQL-Updateskript, durch das das Schema eines Ziels aktualisiert wird, sodass es dem Schema einer Quelle entspricht.

Befehlssyntax:

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>"

Beispiel:

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"

Hilfe:

sqlpackage.exe /Action:Script /?