10.06.2016

Automatisiertes Deployment einer BI Solution – Teil 2 SSIS Environment

Technical Value

In Teil 1 dieser Serie (Automatisiertes Deployment einer BI Lösung - SSIS Pakete) habe ich gezeigt, wie SSIS-Pakete über Power Shell in den SQL Server deployed werden können. In diesem Teil zeige ich, wie ein Environment erstellt und mit den deployten Projekten verknüpft werden kann. Seit SSIS 2012 werden SSIS Pakete über ein Environment parametrisiert. Das Environment löst somit (zumindest zum Teil) die SSIS Configurations Tabelle aus früheren Versionen ab.

Der offizielle Weg zum Erstellen eines Environments ist leider vollständig manuell, ebenso wie die Verknüpfung eines SSIS Projektes mit diesem Environment: Create and Map a Server Environment

Hat man nun ein BI-Projekt mit mehreren SSIS Projekten, so muss nach dem initialen Deployment jedes einzelne Projekt mit dem Environment und den darin enthaltenen Variablen verknüpft werden. Bei einem Projekt mit 3 SSIS Projekten und sechs Environment Variablen sind dies bereits 21 Konfigurationen, die manuell vorgenommen werden müssen (3x Verknüpfung des Environment und 3x sechs Variablen mappen).

Spätestens wenn das Projekt noch weiter wächst, ist dieser Weg nicht mehr praktikabel. Daher haben wir uns dazu entschieden, das Environment aus den Project-Parametern der einzelnen SSIS-Solutions automatisch aufzubauen und direkt beim Deployment zu verknüpfen. Hierzu habe ich das folgende PowerShell Script geschrieben und in das in Teil 1 bereits demonstrierte Script integriert.

Funktionsweise

Das im Folgenden gezeigte Script erstellt bei Bedarf ein neues Environment aus den Project Parametern, oder ergänzt ein bestehendes Environment mit evtl. neuen Project Parametern. Auf diese Weise sind die Variablen in den SSIS-Projekten immer identisch mit den Variablen des Environments. Die Environment Variablen werden additiv erstellt. D.h. am Ende entsteht ein Environment mit allen “distincten” Variablen der einzelnen SSIS Projekte. Neu angelegte Environment Variablen werden standardmäßig mit dem Wert der Project Variable gefüllt.

Ein weiterer Vorteil dieser Vorgehensweise ist, dass jeder Entwickler seine eigene Project Configuration haben kann und auch das Deployment in die Entwicklungsumgebung so erleichtert wird. Es muss nur noch die Project Configuration gepflegt werden.

Gleichzeitig wird verhindert, dass in der Entwicklung neue Environment Variablen erstellt werden und vergessen wird, diese auf die Produktion zu übertragen. Das Fehlen der Variable fällt spätestens bei der Abnahme auf.

Parameter

Zusätzlich zu den bereits definierten Parametern wird noch der folgende benötigt, um den Namen des Environment zu definieren:

  1. [string]$environmentName = $(Read-Host "Environment Name")

Erstellung des Environments

Es wird zunächst geprüft, ob ein Environment mit dem gegebenen Namen existiert. Existiert dies noch nicht, wird es neu angelegt. Wenn das Environment bereits existiert könnte dies überschrieben werden. Wir haben uns jedoch dazu entschieden das Environment nicht zu überschreiben und in diesem Fall nur neue Variablen hinzuzufügen.

  1. if(!$ssisFolder.Environments[$environmentName])
  2.   {
  3.     Write-Host "Creating new Environment..."
  4.     $environment = New-Object "$ssisNamespace.EnvironmentInfo" ($ssisFolder, $environmentName, $environmentDescription)
  5.     $environment.Create();
  6.   }
  7.   else
  8.   {
  9.     $environment = $ssisFolder.Environments[$environmentName]
  10.   }

Erstellung neuer Environment Variablen

Wie bereits erwähnt erstelle ich die Environment Variablen direkt aus den Project Parametern. Hierzu wird über jedes SSIS Projekt iteriert, welches auch im Deployment verwendet wird. Selbstverständlich könnte an dieser Stelle auch auf andere Konfigurationen zurückgegriffen und die Variablen z.B. aus einer Tabelle erstellt werden. Auch werden die Variablen nur dann erstellt, wenn diese noch nicht vorhanden sind. Genau wie beim Environment könnten die existierenden Variablen an dieser Stelle auch einfach überschrieben werden.

  1. Write-Host "Configuring Environment..."
  2.   foreach($param in $ssisProject.Parameters)
  3.   {
  4.     if(!$environment.Variables.Contains($param.Name))
  5.     {
  6.       $environment.Variables.Add($param.Name, $param.DataType, $param.DesignDefaultValue, $param.Sensitive, $param.Description)
  7.       $environment.Alter()
  8.     }
  9.   }

Verknüpfung des Projektes und des Environments

Zur Verknüpfung des SSIS Projektes mit dem Environment ist lediglich eine Referenz erforderlich. Wichtig ist nach jeder Änderung explizit die Methode “Alter()” aufzurufen. Diese speichert die durchgeführten Änderungen.

  1. Write-Host "Connecting Project and Environment..."
  2. $ssisProject.References.Add($environmentName, $ssisFolderName)
  3. $ssisProject.Alter()

Verknüpfung der Projekt Parameter mit Environment Variablen

Zum Schluss werden noch die einzelnen Project Variablen mit den neu erstellten Environment Variablen verknüpft. Dies erfolgt ebenfalls in der oben genannten For-Each-Schleife.

  1. $ssisProject.Parameters[$param.IdentityKey].Set("Referenced", $param.Name)

Damit ist das gesamte SSIS Deployment bereits abgeschlossen. Im nächsten Teil demonstriere ich das Deployment einer SSDT Solution. Für alle, die das Script direkt ausprobieren möchten, hier noch die vollständige Version.

  1. # declare parameter
  2. param (
  3.   # required Parameter
  4.   [string]$ssisServerName = $(Read-Host "SSIS Server Name"),
  5.   [string]$ispacPath = $(Read-Host "Ordner mit ISPAC Datei(en)"),
  6.   [string]$ssisFolderName = $(Read-Host "SSIS Folder Name"),
  7.   [string]$environmentName = $(Read-Host "Environment Name"),
  8.  
  9.   # parameter with suitable default values
  10.   [string]$ssisDbName = "SSISDB",
  11.   $overwriteEnvironment = $FALSE,
  12. )
  13.  
  14. $ErrorActionPreference = "Stop"
  15.  
  16. # loading Assemblies
  17. [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Management.IntegrationServices")
  18. [void][System.Reflection.Assembly]::LoadWithPartialName("System.IO")
  19.  
  20. # connecting to target SSIS Server
  21. Write-Host "Connection to target server..."
  22. $ssisNamespace = "Microsoft.SqlServer.Management.IntegrationServices"
  23. $ioNamespace = "System.IO"
  24.  
  25. $sqlConnectionString = "Data Source=" + $ssisServerName + ";Initial Catalog=master;Integrated Security=SSPI;"
  26. $sqlConnection = New-Object System.Data.SqlClient.SqlConnection $sqlConnectionString
  27.  
  28. $ssisService = New-Object "$ssisNamespace.IntegrationServices" $sqlConnection
  29. $ssisdb = $ssisService.Catalogs[$ssisDbName]
  30.  
  31. # get SSIS Folder, or create a new one if none exists
  32. $ssisFolder = $ssisdb.Folders[$ssisFolderName]
  33.  
  34. if(!$ssisFolder)
  35. {
  36.   Write-Host "Creating Folder" $ssisFolderName "..."
  37.   $ssisFolder = New-Object "$ssisNamespace.CatalogFolder" $ssisdb, $ssisFolderName
  38.   $ssisFolder.Create()
  39.   $ssisFolder = $ssisdb.Folders[$ssisFolderName]
  40. }
  41.  
  42. $files = Get-ChildItem $ispacPath -Filter *.ispac
  43. foreach($file in $files)
  44. {
  45.   $ispacName = $file.Name.Split(".")[0]  
  46.   $ispacPath = $file.FullName
  47.  
  48.   Write-Host "Deploying Project" $ispacName
  49.   $ssisFolder.DeployProject($ispacName, [System.IO.File]::ReadAllBytes($ispacPath)) | Out-Null
  50.   $ssisProject = $ssisFolder.Projects[$ispacName]
  51.  
  52.   if($overwriteEnvironment)
  53.   {
  54.     if($ssisFolder.Environments[$environmentName])
  55.     {
  56.       Write-Host "Deleting old Environment..."
  57.       $ssisFolder.Environments.Remove($ssisFolder.Environments[$environmentName]) | Out-Null
  58.       $ssisFolder.Alter()
  59.     }
  60.   }
  61.  
  62.   if(!$ssisFolder.Environments[$environmentName])
  63.   {
  64.     Write-Host "Creating new Environment..."
  65.     $environment = New-Object "$ssisNamespace.EnvironmentInfo" ($ssisFolder, $environmentName, "")
  66.     $environment.Create();
  67.   }
  68.   else
  69.   {
  70.     $environment = $ssisFolder.Environments[$environmentName]
  71.   }
  72.  
  73.   Write-Host "Configuring Environment..."
  74.   foreach($param in $ssisProject.Parameters)
  75.   {  
  76.     if($environment.Variables.Contains($param.Name) -And $overwriteEnvironment)
  77.     {
  78.       $environment.Variables.Remove($param.Name)
  79.       $environment.Alter()
  80.     }
  81.     
  82.     if(!$environment.Variables.Contains($param.Name))
  83.     {
  84.       $environment.Variables.Add($param.Name, $param.DataType, $param.DesignDefaultValue, $param.Sensitive, $param.Description)
  85.       $environment.Alter()
  86.     }
  87.  
  88.     $ssisProject.Parameters[$param.IdentityKey].Set("Referenced", $param.Name)
  89.   }
  90.  
  91.   Write-Host "Connecting Project and Environment..."
  92.   if($ssisProject.References.Contains($environmentName, $ssisFolderName))
  93.   {
  94.     $ssisProject.References.Remove($environmentName, $ssisFolderName)
  95.   }
  96.  
  97.   $ssisProject.References.Add($environmentName, $ssisFolderName)
  98.  
  99.   $ssisProject.Alter()
  100. }
Teilen auf

Newsletter Anmeldung

Abonnieren Sie unseren Newsletter!
Lassen Sie sich regelmäßig über alle Neuigkeiten rundum ORAYLIS und die BI- & Big-Data-Branche informieren.

Jetzt anmelden