Continuous Integration und Continuous Delivery in Azure Data FactoryContinuous integration and delivery in Azure Data Factory

GILT FÜR: Azure Data Factory Azure Synapse Analytics

ÜbersichtOverview

Bei Continuous Integration wird jede Änderung, die an Ihrer Codebasis vorgenommen wird, automatisch und so früh wie möglich getestet.Continuous integration is the practice of testing each change made to your codebase automatically and as early as possible.  Der Continuous Delivery-Prozess folgt auf das Testen während des Continuous Integration-Prozesses. Änderungen werden dabei in ein Staging- oder Produktionssystem gepusht.Continuous delivery follows the testing that happens during continuous integration and pushes changes to a staging or production system.

In Azure Data Factory bedeuten Continuous Integration und Continuous Delivery (CI/CD), dass Data Factory-Pipelines von einer Umgebung (Entwicklung, Test, Produktion) in eine andere verschoben werden.In Azure Data Factory, continuous integration and delivery (CI/CD) means moving Data Factory pipelines from one environment (development, test, production) to another. Azure Data Factory nutzt Azure Resource Manager-Vorlagen zum Speichern der Konfiguration ihrer verschiedenen ADF-Entitäten (Pipelines, Datasets, Datenflüsse usw.).Azure Data Factory utilizes Azure Resource Manager templates to store the configuration of your various ADF entities (pipelines, datasets, data flows, and so on). Es gibt zwei empfohlene Methoden zum Höherstufen einer Data Factory in eine andere Umgebung:There are two suggested methods to promote a data factory to another environment:

  • Automatisierte Bereitstellung über Integration von Data Factory in Azure PipelinesAutomated deployment using Data Factory's integration with Azure Pipelines
  • Manuelles Hochladen einer Resource Manager-Vorlage über Integration der Data Factory-Benutzeroberfläche in Azure Resource Manager.Manually upload a Resource Manager template using Data Factory UX integration with Azure Resource Manager.

Hinweis

Dieser Artikel wurde mit der Verwendung des Azure Az PowerShell-Moduls aktualisiert.This article has been updated to use the Azure Az PowerShell module. Das Azure Az PowerShell-Modul wird für die Interaktion mit Azure empfohlen.The Az PowerShell module is the recommended PowerShell module for interacting with Azure. Informationen zu den ersten Schritten mit dem Az PowerShell-Modul finden Sie unter Installieren von Azure PowerShell.To get started with the Az PowerShell module, see Install Azure PowerShell. Informationen zum Migrieren zum Az PowerShell-Modul finden Sie unter Migrieren von Azure PowerShell von AzureRM zum Az-Modul.To learn how to migrate to the Az PowerShell module, see Migrate Azure PowerShell from AzureRM to Az.

CI/CD-LebenszyklusCI/CD lifecycle

Unten ist eine Beispielübersicht des CI/CD-Lebenszyklus in einer Azure Data Factory-Instanz mit Konfiguration per Azure Repos Git angegeben.Below is a sample overview of the CI/CD lifecycle in an Azure data factory that's configured with Azure Repos Git. Weitere Informationen zum Konfigurieren eines Git-Repositorys finden Sie unter Quellcodeverwaltung in Azure Data Factory.For more information on how to configure a Git repository, see Source control in Azure Data Factory.

  1. Eine Data Factory-Entwicklungsinstanz wird erstellt und mit Azure Repos Git konfiguriert.A development data factory is created and configured with Azure Repos Git. Alle Entwickler sollten über die Berechtigung zum Erstellen von Data Factory-Ressourcen wie Pipelines und Datasets verfügen.All developers should have permission to author Data Factory resources like pipelines and datasets.

  2. Ein Entwickler erstellt einen Featurebranch, um eine Änderung vorzunehmen.A developer creates a feature branch to make a change. Er debuggt die Pipelineausführungen mit seinen neuesten Änderungen.They debug their pipeline runs with their most recent changes. Weitere Informationen zum Debuggen einer Pipelineausführung finden Sie unter Iteratives Entwickeln und Debuggen mit Azure Data Factory.For more information on how to debug a pipeline run, see Iterative development and debugging with Azure Data Factory.

  3. Wenn ein Entwickler mit den vorgenommenen Änderungen zufrieden ist, erstellt er einen Pull Request vom Featurebranch zum Main- oder Kollaborationsbranch, um seine Änderungen von anderen Entwicklern überprüfen zu lassen.After a developer is satisfied with their changes, they create a pull request from their feature branch to the main or collaboration branch to get their changes reviewed by peers.

  4. Nachdem ein Pull Request genehmigt wurde und Änderungen im Mainbranch zusammengeführt wurden, werden die Änderungen in der Entwicklungsfactory veröffentlicht.After a pull request is approved and changes are merged in the main branch, the changes get published to the development factory.

  5. Wenn das Team bereit ist für die Bereitstellung der Änderungen in einer Test- oder UAT-Factory (User Acceptance Tests, Benutzerakzeptanztests), wechselt es zu seinem Azure Pipelines-Release und stellt die gewünschte Version der Entwicklungsfactory für UAT bereit.When the team is ready to deploy the changes to a test or UAT (User Acceptance Testing) factory, the team goes to their Azure Pipelines release and deploys the desired version of the development factory to UAT. Diese Bereitstellung erfolgt im Rahmen einer Azure Pipelines-Aufgabe, und dabei kommen Resource Manager-Vorlagenparameter zum Einsatz, um die entsprechende Konfiguration anzuwenden.This deployment takes place as part of an Azure Pipelines task and uses Resource Manager template parameters to apply the appropriate configuration.

  6. Nachdem die Änderungen in der Testfactory überprüft wurden, stellen Sie sie mit der nächsten Aufgabe des Pipelines-Release in der Produktionsfactory bereit.After the changes have been verified in the test factory, deploy to the production factory by using the next task of the pipelines release.

Hinweis

Nur die Entwicklungsfactory wird einem Git-Repository zugeordnet.Only the development factory is associated with a git repository. Den Test- und Produktionsfactorys sollte kein Git-Repository zugeordnet sein, und sie sollten nur über eine Azure DevOps-Pipeline oder eine Resource Manager-Vorlage aktualisiert werden.The test and production factories shouldn't have a git repository associated with them and should only be updated via an Azure DevOps pipeline or via a Resource Management template.

In der nachstehenden Abbildung sind die verschiedenen Schritte dieses Lebenszyklus hervorgehoben.The below image highlights the different steps of this lifecycle.

Diagramm von Continuous Integration mit Azure Pipelines

Automatisieren von Continuous Integration mit Azure Pipelines-ReleasesAutomate continuous integration by using Azure Pipelines releases

Im Folgenden finden Sie eine Anleitung zum Einrichten eines Azure Pipelines-Release, mit dem die Bereitstellung einer Data Factory für mehrere Umgebungen automatisiert wird.The following is a guide for setting up an Azure Pipelines release that automates the deployment of a data factory to multiple environments.

Requirements (Anforderungen)Requirements

  • Ein Azure-Abonnement, das mit Visual Studio Team Foundation Server oder Azure Repos verknüpft ist und für das der Azure Resource Manager-Dienstendpunkt verwendet wirdAn Azure subscription linked to Visual Studio Team Foundation Server or Azure Repos that uses the Azure Resource Manager service endpoint.

  • Eine Data Factory-Instanz mit konfigurierter Azure Repos Git-IntegrationA data factory configured with Azure Repos Git integration.

  • Ein Azure-Schlüsseltresor mit den Geheimnissen für jede UmgebungAn Azure key vault that contains the secrets for each environment.

Einrichten eines Azure-Pipelines-ReleaseSet up an Azure Pipelines release

  1. Öffnen Sie in Azure DevOps das Projekt, das für Ihre Data Factory konfiguriert ist.In Azure DevOps, open the project that's configured with your data factory.

  2. Wählen Sie links auf der Seite die Option Pipelines und dann Releases aus.On the left side of the page, select Pipelines, and then select Releases.

    Auswählen von „Pipelines“ > „Releases“

  3. Wählen Sie Neue Pipeline oder – falls Pipelines vorhanden sind – die Option Neu und dann Neue Releasepipeline aus.Select New pipeline, or, if you have existing pipelines, select New and then New release pipeline.

  4. Wählen Sie die Vorlage Leere Stufe aus.Select the Empty job template.

    Auswählen von „Leere Stufe“

  5. Geben Sie im Feld Name der Stufe den Namen der Umgebung ein.In the Stage name box, enter the name of your environment.

  6. Wählen Sie Artefakt hinzufügen und dann das Git-Repository aus, das mit Ihrer Entwicklungs-Data Factory konfiguriert wurde.Select Add artifact, and then select the git repository configured with your development data factory. Wählen Sie den Branch für die Veröffentlichung des Repositorys für den Standardbranch aus.Select the publish branch of the repository for the Default branch. Dieser Branch für die Veröffentlichung lautet standardmäßig adf_publish.By default, this publish branch is adf_publish. Wählen Sie unter Standardversion die Option Letztes Element aus Standardbranch aus.For the Default version, select Latest from default branch.

    Hinzufügen eines Artefakts

  7. Fügen Sie eine Azure Resource Manager-Bereitstellungsaufgabe hinzu:Add an Azure Resource Manager Deployment task:

    a.a. Wählen Sie in der Stufenansicht die Option Stufenaufgaben anzeigen aus.In the stage view, select View stage tasks.

    Stufenansicht

    b.b. Erstellen Sie eine neue Aufgabe.Create a new task. Suchen Sie nach AMR-Vorlagenbereitstellung, und wählen Sie dann Hinzufügen aus.Search for ARM Template Deployment, and then select Add.

    c.c. Wählen Sie unter der Aufgabe „Bereitstellung“ das Abonnement, die Ressourcengruppe und den Speicherort für das Data Factory-Ziel aus.In the Deployment task, select the subscription, resource group, and location for the target data factory. Geben Sie die Anmeldeinformationen an, falls dies erforderlich ist.Provide credentials if necessary.

    d.d. Wählen Sie in der Liste Aktion den Eintrag Create or update resource group (Ressourcengruppe erstellen oder aktualisieren) aus.In the Action list, select Create or update resource group.

    e.e. Wählen Sie neben dem Feld Vorlage die Schaltfläche mit den Auslassungszeichen ( ) aus.Select the ellipsis button () next to the Template box. Suchen Sie nach der Azure Resource Manager-Vorlage, die in Ihrem Branch für die Veröffentlichung des konfigurierten Git-Repositorys generiert wird.Browse for the Azure Resource Manager template that is generated in your publish branch of the configured git repository. Suchen Sie im Ordner des Branches „adf_publish“ nach der Datei ARMTemplateForFactory.json.Look for the file ARMTemplateForFactory.json in the folder of the adf_publish branch.

    f.f. Wählen Sie Select neben dem Feld Vorlagenparameter aus, um die Parameterdatei auszuwählen.next to the Template parameters box to choose the parameters file. Suchen Sie im Ordner des Branches „adf_publish“ nach der Datei ARMTemplateParametersForFactory.json.Look for the file ARMTemplateParametersForFactory.json in the folder of the adf_publish branch.

    g.g. Wählen Sie Select neben dem Feld Vorlagenparameter überschreiben aus, und geben Sie die gewünschten Parameterwerte für das Ziel „Data Factory“ ein.next to the Override template parameters box, and enter the desired parameter values for the target data factory. Geben Sie für Anmeldeinformationen aus Azure Key Vault den Namen des Geheimnisses in doppelten Anführungszeichen ein.For credentials that come from Azure Key Vault, enter the secret's name between double quotation marks. Geben Sie als Wert hier beispielsweise Folgendes ein, wenn der Name des Geheimnisses „cred1“ lautet: "$(cred1)" .For example, if the secret's name is cred1, enter "$(cred1)" for this value.

    h.h. Wählen Sie unter Bereitstellungsmodus die Option Inkrementell aus.Select Incremental for the Deployment mode.

    Warnung

    Im vollständigen Bereitstellungsmodus werden Ressourcen, die in der Ressourcengruppe vorhanden, aber in der neuen Resource Manager-Vorlage nicht angegeben sind, gelöscht.In Complete deployment mode, resources that exist in the resource group but aren't specified in the new Resource Manager template will be deleted. Weitere Informationen finden Sie unter Azure Resource Manager-Bereitstellungsmodi.For more information, please refer to Azure Resource Manager Deployment Modes

    Data Factory-Bereitstellung in der Produktion

  8. Speichern Sie die Releasepipeline.Save the release pipeline.

  9. Wählen Sie zum Auslösen eines Release die Option Release erstellen aus.To trigger a release, select Create release. Informationen zum Automatisieren der Erstellung von Releases finden Sie unter Azure DevOps-Releasetrigger.To automate the creation of releases, see Azure DevOps release triggers

    Auswählen von „Release erstellen“

Wichtig

In CI/CD-Szenarien muss der Typ der Integration Runtime (IR) in unterschiedlichen Umgebungen identisch sein.In CI/CD scenarios, the integration runtime (IR) type in different environments must be the same. Wenn sich in Ihrer Entwicklungsumgebung beispielsweise eine selbstgehostete IR befindet, muss diese IR auch in anderen Umgebungen, z. B. Test- und Produktionsumgebungen, den Typ „Selbstgehostet“ aufweisen.For example, if you have a self-hosted IR in the development environment, the same IR must also be of type self-hosted in other environments, such as test and production. Wenn Sie Integration Runtimes in mehreren Stufen freigeben, müssen Sie die Integration Runtimes in allen Umgebungen, z. B. Entwicklungs-, Test- und Produktionsumgebungen, als „Verknüpft selbstgehostet“ konfigurieren.Similarly, if you're sharing integration runtimes across multiple stages, you have to configure the integration runtimes as linked self-hosted in all environments, such as development, test, and production.

Abrufen von Geheimnissen aus Azure Key VaultGet secrets from Azure Key Vault

Wenn Sie Geheimnisse in einer Azure Resource Manager-Vorlage übergeben möchten, empfehlen wir Ihnen die Verwendung von Azure Key Vault mit dem Azure Pipelines-Release.If you have secrets to pass in an Azure Resource Manager template, we recommend that you use Azure Key Vault with the Azure Pipelines release.

Es gibt zwei Möglichkeiten, um Geheimnisse zu verarbeiten:There are two ways to handle secrets:

  1. Fügen Sie die Geheimnisse der Parameterdatei hinzu.Add the secrets to parameters file. Weitere Informationen finden Sie unter Verwenden von Azure Key Vault zum Übergeben eines sicheren Parameterwerts während der Bereitstellung.For more info, see Use Azure Key Vault to pass secure parameter value during deployment.

    Erstellen Sie eine Kopie der Parameterdatei, die in den Branch für die Veröffentlichung hochgeladen wird.Create a copy of the parameters file that's uploaded to the publish branch. Legen Sie die Werte der Parameter, die Sie aus Key Vault abrufen möchten, in diesem Format fest:Set the values of the parameters that you want to get from Key Vault by using this format:

    {
        "parameters": {
            "azureSqlReportingDbPassword": {
                "reference": {
                    "keyVault": {
                        "id": "/subscriptions/<subId>/resourceGroups/<resourcegroupId> /providers/Microsoft.KeyVault/vaults/<vault-name> "
                    },
                    "secretName": " < secret - name > "
                }
            }
        }
    }
    

    Bei dieser Methode wird das Geheimnis per Pullvorgang automatisch aus dem Schlüsseltresor abgerufen.When you use this method, the secret is pulled from the key vault automatically.

    Die Parameterdatei muss sich auch im Branch für die Veröffentlichung befinden.The parameters file needs to be in the publish branch as well.

  2. Fügen Sie vor der im vorherigen Abschnitt beschriebenen Aufgabe für die Azure Resource Manager-Bereitstellung eine Azure Key Vault-Aufgabe hinzu:Add an Azure Key Vault task before the Azure Resource Manager Deployment task described in the previous section:

    1. Erstellen Sie auf der Registerkarte Tasks eine neue Aufgabe.On the Tasks tab, create a new task. Suchen Sie nach Azure Key Vault, und fügen Sie die Komponente hinzu.Search for Azure Key Vault and add it.

    2. Wählen Sie in der Key Vault-Aufgabe das Abonnement aus, unter dem Sie den Schlüsseltresor erstellt haben.In the Key Vault task, select the subscription in which you created the key vault. Geben Sie bei Bedarf Anmeldeinformationen an, und wählen Sie anschließend den Schlüsseltresor aus.Provide credentials if necessary, and then select the key vault.

    Hinzufügen einer Key Vault-Aufgabe

Gewähren von Berechtigungen für den Azure Pipelines-AgentGrant permissions to the Azure Pipelines agent

Unter Umständen tritt bei der Azure Key Vault-Aufgabe ein Fehler vom Typ „Zugriff verweigert“ auf, wenn nicht die richtigen Berechtigungen festgelegt wurden.The Azure Key Vault task might fail with an Access Denied error if the correct permissions aren't set. Laden Sie die Protokolle für das Release herunter, und suchen Sie nach der PS1-Datei, die den Befehl zum Erteilen von Berechtigungen für den Azure Pipelines-Agent enthält.Download the logs for the release, and locate the .ps1 file that contains the command to give permissions to the Azure Pipelines agent. Sie können den Befehl direkt ausführen.You can run the command directly. Alternativ können Sie die Prinzipal-ID aus der Datei kopieren und die Zugriffsrichtlinie manuell im Azure-Portal hinzufügen.Or you can copy the principal ID from the file and add the access policy manually in the Azure portal. Die Berechtigungen Get und List sind mindestens erforderlich.Get and List are the minimum permissions required.

Aktualisieren von aktiven TriggernUpdating active triggers

Für die Bereitstellung kann ein Fehler auftreten, wenn Sie versuchen, aktive Trigger zu aktualisieren.Deployment can fail if you try to update active triggers. Zum Aktualisieren von aktiven Triggern müssen Sie sie manuell beenden und nach der Bereitstellung wieder starten.To update active triggers, you need to manually stop them and then restart them after the deployment. Dies ist über eine Azure PowerShell-Aufgabe möglich:You can do this by using an Azure PowerShell task:

  1. Fügen Sie auf der Registerkarte Tasks des Release eine Azure PowerShell-Aufgabe hinzu.On the Tasks tab of the release, add an Azure PowerShell task. Wählen Sie die Aufgabenversion „4.*“ aus.Choose task version 4.*.

  2. Wählen Sie das Abonnement aus, in dem sich Ihre Factory befindet.Select the subscription your factory is in.

  3. Wählen Sie Pfad zur Skriptdatei als Skripttyp aus.Select Script File Path as the script type. Hierfür müssen Sie Ihr PowerShell-Skript in Ihrem Repository speichern.This requires you to save your PowerShell script in your repository. Das folgende PowerShell-Skript kann zum Beenden von Triggern verwendet werden:The following PowerShell script can be used to stop triggers:

    $triggersADF = Get-AzDataFactoryV2Trigger -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName
    
    $triggersADF | ForEach-Object { Stop-AzDataFactoryV2Trigger -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.name -Force }
    

Sie können ähnliche Schritte ausführen (mit der Funktion Start-AzDataFactoryV2Trigger), um die Trigger nach der Bereitstellung neu zu starten.You can complete similar steps (with the Start-AzDataFactoryV2Trigger function) to restart the triggers after deployment.

Das Data Factory-Team hat am Ende dieses Artikels ein Beispielskript für vor und nach der Bereitstellung hinzugefügt.The data factory team has provided a sample pre- and post-deployment script located at the bottom of this article.

Manuelles Höherstufen einer Resource Manager-Vorlage für jede UmgebungManually promote a Resource Manager template for each environment

  1. Wählen Sie in der Liste ARM-Vorlage den Eintrag Export ARM template (ARM-Vorlage exportieren) aus, um die Resource Manager-Vorlage für Ihre Data Factory in die Entwicklungsumgebung zu exportieren.In the ARM Template list, select Export ARM Template to export the Resource Manager template for your data factory in the development environment.

    Exportieren einer Resource Manager-Vorlage

  2. Wählen Sie in den Test- und Produktionsfactorys den Eintrag Import ARM template (ARM-Vorlage importieren) aus.In your test and production data factories, select Import ARM Template. Mit dieser Aktion gelangen Sie zum Azure-Portal, in dem sie die exportierte Vorlage importieren können.This action takes you to the Azure portal, where you can import the exported template. Wählen Sie Eigene Vorlage im Editor erstellen aus, um den Editor für Resource Manager-Vorlagen zu öffnen.Select Build your own template in the editor to open the Resource Manager template editor.

    Erstellen einer eigenen Vorlage

  3. Wählen Sie die Option Datei laden und anschließend die generierte Resource Manager-Vorlage aus.Select Load file, and then select the generated Resource Manager template. Dies ist die Datei arm_template.json in der ZIP-Datei, die Sie in Schritt 1 exportiert haben.This is the arm_template.json file located in the .zip file exported in step 1.

    Bearbeiten der Vorlage

  4. Geben Sie im Abschnitt mit den Einstellungen die Konfigurationswerte ein, z. B. die Anmeldeinformationen für verknüpfte Dienste.In the settings section, enter the configuration values, like linked service credentials. Wählen Sie anschließend die Option Kaufen aus, um die Resource Manager-Vorlage bereitzustellen.When you're done, select Purchase to deploy the Resource Manager template.

    Einstellungsabschnitt

Verwenden benutzerdefinierter Parameter mit der Resource Manager-VorlageUse custom parameters with the Resource Manager template

Wenn Ihre Entwicklungsfactory ein zugeordnetes Git-Repository hat, können Sie die standardmäßigen Parameter der Resource Manager-Vorlage überschreiben, die durch deren Veröffentlichung oder Export generiert wurden.If your development factory has an associated git repository, you can override the default Resource Manager template parameters of the Resource Manager template generated by publishing or exporting the template. Die Überschreibung der Standardparameterkonfiguration von Resource Manager kann beispielsweise in folgenden Szenarien erforderlich sein:You might want to override the default Resource Manager parameter configuration in these scenarios:

  • Sie verwenden automatisierte CI/CD und möchten einige Eigenschaften während der Resource Manager-Bereitstellung ändern, die Eigenschaften sind standardmäßig aber nicht parametrisiert.You use automated CI/CD and you want to change some properties during Resource Manager deployment, but the properties aren't parameterized by default.

  • Die Resource Manager-Standardvorlage ist aufgrund der Größe Ihrer Factory ungültig, da sie mehr als die maximal zulässige Parameteranzahl (256) enthält.Your factory is so large that the default Resource Manager template is invalid because it has more than the maximum allowed parameters (256).

    In Bezug auf das Limit von 256 für benutzerdefinierte Parameter gibt es drei Optionen:To handle custom parameter 256 limit, there are 3 options:

    • Verwenden Sie die benutzerdefinierte Parameterdatei, und entfernen Sie Eigenschaften, die keine Parametrisierung erfordern, d. h. Eigenschaften, die einen Standardwert beibehalten und somit die Parameteranzahl verringern können.Use the custom parameter file and remove properties that don't need parameterization, i.e., properties that can keep a default value and hence decrease the parameter count.
    • Gestalten Sie die Logik im Datenfluss zur Reduzierung von Parametern um. Wenn z. B. alle Pipelineparameter denselben Wert aufweisen, können Sie stattdessen globale Parameter verwenden.Refactor logic in the dataflow to reduce parameters, for example, pipeline parameters all have the same value, you can just use global parameters instead.
    • Teilen Sie eine Data Factory in mehrere Datenflüsse auf.Split one data factory into multiple data flows.

Um die Standardparameterkonfiguration von Resource Manager zu überschreiben, wechseln Sie zum Hub Verwalten, und wählen Sie im Abschnitt „Quellcodeverwaltung“ ARM-Vorlage aus.To override the default Resource Manager parameter configuration, go to the Manage hub and select ARM template in the "Source control" section. Klicken Sie im Abschnitt ARM-Parameterkonfiguration in „Parameterkonfiguration bearbeiten“ auf das Symbol Bearbeiten, um den Code-Editor für die Resource Manager-Parameterkonfiguration zu öffnen.Under ARM parameter configuration section, click Edit icon in "Edit parameter configuration" to open the Resource Manager parameter configuration code editor.

Verwalten von benutzerdefinierten Parametern

Hinweis

Die ARM-Parameterkonfiguration ist nur im Git-Modus aktiviert.ARM parameter configuration is only enabled in "GIT mode". Im Livemodus und Data Factory-Modus ist sie derzeit deaktiviert.Currently it is disabled in "live mode" or "Data Factory" mode.

Beim Erstellen einer benutzerdefinierten Resource Manager-Parameterkonfiguration wird im Stammordner Ihres Git-Branches eine Datei mit dem Namen arm-template-parameters-definition.json erstellt.Creating a custom Resource Manager parameter configuration creates a file named arm-template-parameters-definition.json in the root folder of your git branch. Sie müssen exakt diesen Dateinamen verwenden.You must use that exact file name.

Benutzerdefinierte Parameterdatei

Beim Veröffentlichen aus dem Kollaborationsbranch liest Data Factory diese Datei und verwendet deren Konfiguration zum Generieren der Eigenschaften, die parametrisiert werden sollen.When publishing from the collaboration branch, Data Factory will read this file and use its configuration to generate which properties get parameterized. Sollte keine Datei gefunden werden, wird die Standardvorlage verwendet.If no file is found, the default template is used.

Beim Exportieren einer Resource Manager-Vorlage liest Data Factory diese Datei aus dem Branch, an dem Sie gerade arbeiten, und nicht aus dem Kollaborationsbranch.When exporting a Resource Manager template, Data Factory reads this file from whichever branch you're currently working on, not the collaboration branch. Sie können die Datei in einem privaten Branch erstellen oder bearbeiten und Ihre Änderungen testen, indem Sie auf der Benutzeroberfläche die Option Export ARM Template (ARM-Vorlage exportieren) auswählen.You can create or edit the file from a private branch, where you can test your changes by selecting Export ARM Template in the UI. Anschließend können Sie die Datei mit dem Kollaborationsbranch zusammenführen.You can then merge the file into the collaboration branch.

Hinweis

Durch eine benutzerdefinierte Resource Manager-Parameterkonfiguration wird das ARM-Vorlagenparameterlimit von 256 nicht geändert.A custom Resource Manager parameter configuration doesn't change the ARM template parameter limit of 256. Sie können in ihr die parametrisierten Eigenschaften auswählen und ihre Anzahl verringern.It lets you choose and decrease the number of parameterized properties.

Benutzerdefinierte ParametersyntaxCustom parameter syntax

Nachstehend finden Sie einige Richtlinien, die beim Erstellen der benutzerdefinierten Parameterdatei, arm-template-parameters-definition.json, befolgt werden müssen.The following are some guidelines to follow when you create the custom parameters file, arm-template-parameters-definition.json. Die Datei enthält jeweils einen eigenen Abschnitt für die Entitätstypen „trigger“, „pipeline“, „linked service“, „dataset“, „integration runtime“ und „data flow“.The file consists of a section for each entity type: trigger, pipeline, linked service, dataset, integration runtime, and data flow.

  • Geben Sie den Eigenschaftenpfad unter dem relevanten Entitätstyp ein.Enter the property path under the relevant entity type.
  • Durch das Festlegen eines Eigenschaftennamens auf * geben Sie an, dass alle untergeordneten Eigenschaften parametrisiert werden sollen (nicht rekursiv, sondern nur bis zur ersten Ebene).Setting a property name to * indicates that you want to parameterize all properties under it (only down to the first level, not recursively). Sie können auch Ausnahmen für diese Konfiguration angeben.You can also provide exceptions to this configuration.
  • Wenn Sie den Wert einer Eigenschaft als Zeichenfolge festlegen, geben Sie damit an, dass die Eigenschaft parametrisiert werden soll.Setting the value of a property as a string indicates that you want to parameterize the property. Verwenden Sie das Format <action>:<name>:<stype>.Use the format <action>:<name>:<stype>.
    • <action> kann für eines dieser Zeichen durchgeführt werden:<action> can be one of these characters:
      • = bedeutet, dass der aktuelle Wert als Standardwert für den Parameter beibehalten werden soll.= means keep the current value as the default value for the parameter.
      • - bedeutet, dass der Standardwert für den Parameter nicht beibehalten werden soll.- means don't keep the default value for the parameter.
      • | ist ein Sonderfall für Geheimnisse aus Azure Key Vault für Verbindungszeichenfolgen oder Schlüssel.| is a special case for secrets from Azure Key Vault for connection strings or keys.
    • <name> ist der Name des Parameters.<name> is the name of the parameter. Wenn dieser Wert leer ist, wird der Name der Eigenschaft verwendet.If it's blank, it takes the name of the property. Beginnt der Wert mit dem Zeichen -, wird der Name gekürzt.If the value starts with a - character, the name is shortened. AzureStorage1_properties_typeProperties_connectionString wird beispielsweise in AzureStorage1_connectionString gekürzt.For example, AzureStorage1_properties_typeProperties_connectionString would be shortened to AzureStorage1_connectionString.
    • <stype> ist der Typ des Parameters.<stype> is the type of parameter. Wenn <stype> leer ist, wird standardmäßig der Typ string verwendet.If <stype> is blank, the default type is string. Unterstützte Werte: string, securestring, int, bool, object, secureobject und array.Supported values: string, securestring, int, bool, object, secureobject and array.
  • Wenn Sie ein Array in der Definitionsdatei angeben, bedeutet dies, dass die entsprechende Eigenschaft in der Vorlage ein Array ist.Specifying an array in the definition file indicates that the matching property in the template is an array. Data Factory durchläuft alle Objekte im Array anhand der Definition, die im Integration Runtime-Objekt des Arrays angegeben ist.Data Factory iterates through all the objects in the array by using the definition that's specified in the integration runtime object of the array. Das zweite Objekt (eine Zeichenfolge) wird zum Namen der Eigenschaft, der bei jeder Iteration als Name für den Parameter verwendet wird.The second object, a string, becomes the name of the property, which is used as the name for the parameter for each iteration.
  • Eine Definition kann nicht spezifisch für eine Ressourceninstanz sein.A definition can't be specific to a resource instance. Jede Definition gilt für alle Ressourcen dieses Typs.Any definition applies to all resources of that type.
  • Standardmäßig werden alle sicheren Zeichenfolgen parametrisiert, z. B. Key Vault-Geheimnisse, Verbindungszeichenfolgen, Schlüssel und Token.By default, all secure strings, like Key Vault secrets, and secure strings, like connection strings, keys, and tokens, are parameterized.

Exemplarische ParametrisierungsvorlageSample parameterization template

Im folgenden Beispiel wird gezeigt, wie eine Resource Manager-Parameterkonfiguration aussehen kann:Here's an example of what an Resource Manager parameter configuration might look like:

{
    "Microsoft.DataFactory/factories/pipelines": {
        "properties": {
            "activities": [{
                "typeProperties": {
                    "waitTimeInSeconds": "-::int",
                    "headers": "=::object"
                }
            }]
        }
    },
    "Microsoft.DataFactory/factories/integrationRuntimes": {
        "properties": {
            "typeProperties": {
                "*": "="
            }
        }
    },
    "Microsoft.DataFactory/factories/triggers": {
        "properties": {
            "typeProperties": {
                "recurrence": {
                    "*": "=",
                    "interval": "=:triggerSuffix:int",
                    "frequency": "=:-freq"
                },
                "maxConcurrency": "="
            }
        }
    },
    "Microsoft.DataFactory/factories/linkedServices": {
        "*": {
            "properties": {
                "typeProperties": {
                    "accountName": "=",
                    "username": "=",
                    "connectionString": "|:-connectionString:secureString",
                    "secretAccessKey": "|"
                }
            }
        },
        "AzureDataLakeStore": {
            "properties": {
                "typeProperties": {
                    "dataLakeStoreUri": "="
                }
            }
        }
    },
    "Microsoft.DataFactory/factories/datasets": {
        "properties": {
            "typeProperties": {
                "*": "="
            }
        }
    }
}

Im Folgenden wird das Erstellen der obigen Vorlage mit einer Aufschlüsselung nach Ressourcentypen beschrieben.Here's an explanation of how the preceding template is constructed, broken down by resource type.

PipelinesPipelines

  • Jede Eigenschaft im Pfad activities/typeProperties/waitTimeInSeconds wird parametrisiert.Any property in the path activities/typeProperties/waitTimeInSeconds is parameterized. Jede Aktivität in einer Pipeline, die eine Eigenschaft auf Codeebene mit dem Namen waitTimeInSeconds enthält (z. B. die Aktivität Wait), wird als Zahl mit einem Standardnamen parametrisiert.Any activity in a pipeline that has a code-level property named waitTimeInSeconds (for example, the Wait activity) is parameterized as a number, with a default name. Die Aktivität verfügt jedoch nicht über einen Standardwert in der Resource Manager-Vorlage.But it won't have a default value in the Resource Manager template. Hierbei handelt es sich um eine erforderliche Eingabe bei der Resource Manager-Bereitstellung.It will be a mandatory input during the Resource Manager deployment.
  • Analog dazu wird eine Eigenschaft namens headers (etwa in einer Aktivität vom Typ Web) mit dem Typ object (JObject) parametrisiert.Similarly, a property called headers (for example, in a Web activity) is parameterized with type object (JObject). Sie verfügt über einen Standardwert (gleicher Wert wie für die Quellfactory).It has a default value, which is the same value as that of the source factory.

IntegrationRuntimesIntegrationRuntimes

  • Alle Eigenschaften unter dem Pfad typeProperties werden mit ihren jeweiligen Standardwerten parametrisiert.All properties under the path typeProperties are parameterized with their respective default values. Beispielsweise sind unter Eigenschaften vom Typ IntegrationRuntimes zwei Eigenschaften vorhanden: computeProperties und ssisProperties.For example, there are two properties under IntegrationRuntimes type properties: computeProperties and ssisProperties. Beide Eigenschaftentypen werden mit ihren jeweiligen Standardwerten und -typen (Objekt) erstellt.Both property types are created with their respective default values and types (Object).

TriggerTriggers

  • Unter typeProperties werden zwei Eigenschaften parametrisiert.Under typeProperties, two properties are parameterized. Die erste ist maxConcurrency. Diese Eigenschaft besitzt einen Standardwert und ist vom Typ string.The first one is maxConcurrency, which is specified to have a default value and is of typestring. Der Standardparametername lautet <entityName>_properties_typeProperties_maxConcurrency.It has the default parameter name <entityName>_properties_typeProperties_maxConcurrency.
  • Die Eigenschaft recurrence wird ebenfalls parametrisiert.The recurrence property also is parameterized. Darunter werden alle Eigenschaften auf dieser Ebene gemäß Angabe als Zeichenfolgen mit Standardwerten und Parameternamen parametrisiert.Under it, all properties at that level are specified to be parameterized as strings, with default values and parameter names. Eine Ausnahme ist die interval-Eigenschaft, für die beim Parametrisieren der Typ int verwendet wird.An exception is the interval property, which is parameterized as type int. An den Parameternamen ist das Suffix <entityName>_properties_typeProperties_recurrence_triggerSuffix angehängt.The parameter name is suffixed with <entityName>_properties_typeProperties_recurrence_triggerSuffix. Analog dazu ist die Eigenschaft freq eine Zeichenfolge und wird als Zeichenfolge parametrisiert.Similarly, the freq property is a string and is parameterized as a string. Die Eigenschaft freq wird jedoch ohne Standardwert parametrisiert.However, the freq property is parameterized without a default value. Der Name wird verkürzt und mit einem Suffix versehen.The name is shortened and suffixed. Beispiel: <entityName>_freq.For example, <entityName>_freq.

LinkedServicesLinkedServices

  • Verknüpfte Dienste sind ein Sonderfall.Linked services are unique. Da verknüpfte Dienste und Datasets eine breite Palette von Typen umfassen, können Sie eine typspezifische Anpassung vornehmen.Because linked services and datasets have a wide range of types, you can provide type-specific customization. In diesem Beispiel wird für alle verknüpften Dienste vom Typ AzureDataLakeStore eine bestimmte Vorlage angewendet.In this example, for all linked services of type AzureDataLakeStore, a specific template will be applied. Für alle anderen Dienste wird eine andere Vorlage angewendet (per *).For all others (via *), a different template will be applied.
  • Die connectionString-Eigenschaft wird als securestring-Wert parametrisiert.The connectionString property will be parameterized as a securestring value. Sie hat keinen Standardwert.It won't have a default value. Sie weist einen verkürzten Parameternamen auf, an den das Suffix connectionString angehängt ist.It will have a shortened parameter name that's suffixed with connectionString.
  • Die secretAccessKey-Eigenschaft ist eine Eigenschaft vom Typ AzureKeyVaultSecret (beispielsweise in einem verknüpften Amazon S3-Dienst).The property secretAccessKey happens to be an AzureKeyVaultSecret (for example, in an Amazon S3 linked service). Sie wird automatisch als Azure Key Vault-Geheimnis parametrisiert und aus dem konfigurierten Schlüsseltresor abgerufen.It's automatically parameterized as an Azure Key Vault secret and fetched from the configured key vault. Auch der Schlüsseltresor kann parametrisiert werden.You can also parameterize the key vault itself.

DatasetsDatasets

  • Für Datasets steht zwar eine typspezifische Anpassung zur Verfügung, aber Sie können die Konfiguration durchführen, ohne dass eine explizite Konfiguration auf der Ebene * vorhanden sein muss.Although type-specific customization is available for datasets, you can provide configuration without explicitly having a *-level configuration. Im vorherigen Beispiel werden alle Dataseteigenschaften unter typeProperties parametrisiert.In the preceding example, all dataset properties under typeProperties are parameterized.

Standardvorlage für die ParametrisierungDefault parameterization template

Nachfolgend ist die aktuelle Standardvorlage für die Parametrisierung dargestellt.Below is the current default parameterization template. Falls Sie nur wenige Parameter hinzufügen müssen, ist die direkte Bearbeitung dieser Vorlage ggf. eine gute Idee, weil die vorhandene Parametrisierungsstruktur nicht verloren geht.If you need to add only a few parameters, editing this template directly might be a good idea because you won't lose the existing parameterization structure.

{
    "Microsoft.DataFactory/factories": {
        "properties": {
            "globalParameters": {
                "*": {
                    "value": "="
                }
            }
        },
        "location": "="
    },
    "Microsoft.DataFactory/factories/pipelines": {
    },
    "Microsoft.DataFactory/factories/dataflows": {
    },
    "Microsoft.DataFactory/factories/integrationRuntimes":{
        "properties": {
            "typeProperties": {
                "ssisProperties": {
                    "catalogInfo": {
                        "catalogServerEndpoint": "=",
                        "catalogAdminUserName": "=",
                        "catalogAdminPassword": {
                            "value": "-::secureString"
                        }
                    },
                    "customSetupScriptProperties": {
                        "sasToken": {
                            "value": "-::secureString"
                        }
                    }
                },
                "linkedInfo": {
                    "key": {
                        "value": "-::secureString"
                    },
                    "resourceId": "="
                },
                "computeProperties": {
                    "dataFlowProperties": {
                        "externalComputeInfo": [{
                                "accessToken": "-::secureString"
                            }
                        ]
                    }
                }
            }
        }
    },
    "Microsoft.DataFactory/factories/triggers": {
        "properties": {
            "pipelines": [{
                    "parameters": {
                        "*": "="
                    }
                },  
                "pipelineReference.referenceName"
            ],
            "pipeline": {
                "parameters": {
                    "*": "="
                }
            },
            "typeProperties": {
                "scope": "="
            }
        }
    },
    "Microsoft.DataFactory/factories/linkedServices": {
        "*": {
            "properties": {
                "typeProperties": {
                    "accountName": "=",
                    "username": "=",
                    "userName": "=",
                    "accessKeyId": "=",
                    "servicePrincipalId": "=",
                    "userId": "=",
                    "host": "=",
                    "clientId": "=",
                    "clusterUserName": "=",
                    "clusterSshUserName": "=",
                    "hostSubscriptionId": "=",
                    "clusterResourceGroup": "=",
                    "subscriptionId": "=",
                    "resourceGroupName": "=",
                    "tenant": "=",
                    "dataLakeStoreUri": "=",
                    "baseUrl": "=",
                    "database": "=",
                    "serviceEndpoint": "=",
                    "batchUri": "=",
                    "poolName": "=",
                    "databaseName": "=",
                    "systemNumber": "=",
                    "server": "=",
                    "url":"=",
                    "functionAppUrl":"=",
                    "environmentUrl": "=",
                    "aadResourceId": "=",
                    "sasUri": "|:-sasUri:secureString",
                    "sasToken": "|",
                    "connectionString": "|:-connectionString:secureString",
                    "hostKeyFingerprint": "="
                }
            }
        },
        "Odbc": {
            "properties": {
                "typeProperties": {
                    "userName": "=",
                    "connectionString": {
                        "secretName": "="
                    }
                }
            }
        }
    },
    "Microsoft.DataFactory/factories/datasets": {
        "*": {
            "properties": {
                "typeProperties": {
                    "folderPath": "=",
                    "fileName": "="
                }
            }
        }
    },
    "Microsoft.DataFactory/factories/managedVirtualNetworks/managedPrivateEndpoints": {
        "properties": {
            "*": "="
        }
    }
}

Beispiel: Parametrisieren der ID eines vorhandenen interaktiven Azure Databricks-ClustersExample: parameterizing an existing Azure Databricks interactive cluster ID

Im folgenden Beispiel wird das Hinzufügen eines einzelnen Werts zur Standardvorlage für die Parametrisierung veranschaulicht.The following example shows how to add a single value to the default parameterization template. Der Parameterdatei soll lediglich die ID eines vorhandenen interaktiven Azure Databricks-Clusters für einen verknüpften Databricks-Dienst hinzugefügt werden.We only want to add an existing Azure Databricks interactive cluster ID for a Databricks linked service to the parameters file. Beachten Sie, dass diese Datei mit der vorherigen Datei nahezu identisch ist. Die einzige Ausnahme ist, dass unter dem Eigenschaftenfeld von Microsoft.DataFactory/factories/linkedServices das existingClusterId-Element hinzugefügt wurde.Note that this file is the same as the previous file except for the addition of existingClusterId under the properties field of Microsoft.DataFactory/factories/linkedServices.

{
    "Microsoft.DataFactory/factories": {
        "properties": {
            "globalParameters": {
                "*": {
                    "value": "="
                }
            }
        },
        "location": "="
    },
    "Microsoft.DataFactory/factories/pipelines": {
    },
    "Microsoft.DataFactory/factories/dataflows": {
    },
    "Microsoft.DataFactory/factories/integrationRuntimes":{
        "properties": {
            "typeProperties": {
                "ssisProperties": {
                    "catalogInfo": {
                        "catalogServerEndpoint": "=",
                        "catalogAdminUserName": "=",
                        "catalogAdminPassword": {
                            "value": "-::secureString"
                        }
                    },
                    "customSetupScriptProperties": {
                        "sasToken": {
                            "value": "-::secureString"
                        }
                    }
                },
                "linkedInfo": {
                    "key": {
                        "value": "-::secureString"
                    },
                    "resourceId": "="
                }
            }
        }
    },
    "Microsoft.DataFactory/factories/triggers": {
        "properties": {
            "pipelines": [{
                    "parameters": {
                        "*": "="
                    }
                },  
                "pipelineReference.referenceName"
            ],
            "pipeline": {
                "parameters": {
                    "*": "="
                }
            },
            "typeProperties": {
                "scope": "="
            }
 
        }
    },
    "Microsoft.DataFactory/factories/linkedServices": {
        "*": {
            "properties": {
                "typeProperties": {
                    "accountName": "=",
                    "username": "=",
                    "userName": "=",
                    "accessKeyId": "=",
                    "servicePrincipalId": "=",
                    "userId": "=",
                    "clientId": "=",
                    "clusterUserName": "=",
                    "clusterSshUserName": "=",
                    "hostSubscriptionId": "=",
                    "clusterResourceGroup": "=",
                    "subscriptionId": "=",
                    "resourceGroupName": "=",
                    "tenant": "=",
                    "dataLakeStoreUri": "=",
                    "baseUrl": "=",
                    "database": "=",
                    "serviceEndpoint": "=",
                    "batchUri": "=",
                    "poolName": "=",
                    "databaseName": "=",
                    "systemNumber": "=",
                    "server": "=",
                    "url":"=",
                    "aadResourceId": "=",
                    "connectionString": "|:-connectionString:secureString",
                    "existingClusterId": "-"
                }
            }
        },
        "Odbc": {
            "properties": {
                "typeProperties": {
                    "userName": "=",
                    "connectionString": {
                        "secretName": "="
                    }
                }
            }
        }
    },
    "Microsoft.DataFactory/factories/datasets": {
        "*": {
            "properties": {
                "typeProperties": {
                    "folderPath": "=",
                    "fileName": "="
                }
            }
        }}
}

Verknüpfte Resource Manager-VorlagenLinked Resource Manager templates

Wenn Sie CI/CD für Ihre Data Factorys eingerichtet haben, werden ggf. die Grenzwerte für Azure Resource Manager-Vorlagen überschritten, wenn die Größe Ihrer Factory zunimmt.If you've set up CI/CD for your data factories, you might exceed the Azure Resource Manager template limits as your factory grows bigger. Ein Beispiel für eine Beschränkung ist die maximale Anzahl von Ressourcen in einer Resource Manager-Vorlage.For example, one limit is the maximum number of resources in a Resource Manager template. Um die Verwendung umfangreicher Factorys zu ermöglichen, während die vollständige Resource Manager-Vorlage für eine Factory generiert wird, werden von Data Factory jetzt verknüpfte Resource Manager-Vorlagen generiert.To accommodate large factories while generating the full Resource Manager template for a factory, Data Factory now generates linked Resource Manager templates. Mit dieser Funktion wird die gesamte Nutzlast einer Factory auf mehrere Dateien aufgeteilt, damit für Sie keine Einschränkungen aufgrund von Grenzwerten bestehen.With this feature, the entire factory payload is broken down into several files so that you aren't constrained by the limits.

Wenn Sie Git konfiguriert haben, werden die verknüpften Vorlagen zusammen mit den vollständigen Resource Manager-Vorlagen im Branch „adf_publish“ in einem neuen Ordner mit dem Namen „linkedTemplates“ generiert und gespeichert:If you've configured Git, the linked templates are generated and saved alongside the full Resource Manager templates in the adf_publish branch in a new folder called linkedTemplates:

Ordner für verknüpfte Resource Manager-Vorlagen

Verknüpfte Resource Manager-Vorlagen verfügen normalerweise über eine Mastervorlage und eine Reihe von untergeordneten Vorlagen, die mit der Mastervorlage verknüpft sind.The linked Resource Manager templates usually consist of a master template and a set of child templates that are linked to the master. Die übergeordnete Vorlage hat den Namen „ArmTemplate_master.json“, und für untergeordnete Vorlagen werden Namen nach dem Muster „ArmTemplate_0.json“, „ArmTemplate_1.json“ usw. verwendet.The parent template is called ArmTemplate_master.json, and child templates are named with the pattern ArmTemplate_0.json, ArmTemplate_1.json, and so on.

Um anstelle der vollständigen Resource Manager-Vorlage verknüpfte Vorlagen zu verwenden, sollten Sie den CI/CD-Task so aktualisieren, dass dieser nicht auf „ArmTemplateForFactory.json“ (vollständige Resource Manager-Vorlage), sondern auf „ArmTemplate_master.json“ verweist.To use linked templates instead of the full Resource Manager template, update your CI/CD task to point to ArmTemplate_master.json instead of ArmTemplateForFactory.json (the full Resource Manager template). Für Resource Manager ist es auch erforderlich, dass Sie die verknüpften Vorlagen in ein Speicherkonto hochladen, damit von Azure während der Bereitstellung darauf zugegriffen werden kann.Resource Manager also requires that you upload the linked templates into a storage account so Azure can access them during deployment. Weitere Informationen finden Sie unter Bereitstellen von verknüpften Resource Manager-Vorlagen per VSTS.For more info, see Deploying linked Resource Manager templates with VSTS.

Denken Sie daran, die Data Factory-Skripts vor und nach dem Bereitstellungstask zu Ihrer CI/CD-Pipeline hinzuzufügen.Remember to add the Data Factory scripts in your CI/CD pipeline before and after the deployment task.

Wenn Sie Git nicht konfiguriert haben, können Sie über die Option Export ARM Template (ARM-Vorlage exportieren) in der Liste ARM-Vorlage auf die verknüpften Vorlagen zugreifen.If you don't have Git configured, you can access the linked templates via Export ARM Template in the ARM Template list.

Hotfix für ProduktionsumgebungHotfix production environment

Wenn Sie eine Factory in der Produktionsumgebung bereitstellen und ein sofort zu behebender Fehler vorhanden ist, Sie den aktuellen Kollaborationsbranch aber nicht bereitstellen können, müssen Sie unter Umständen einen Hotfix verwenden.If you deploy a factory to production and realize there's a bug that needs to be fixed right away, but you can't deploy the current collaboration branch, you might need to deploy a hotfix. Dieser Ansatz wird als Quick Fix Engineering oder QFE bezeichnet.This approach is as known as quick-fix engineering or QFE.

  1. Navigieren Sie in Azure DevOps zu dem Release, das für die Produktion bereitgestellt wurde.In Azure DevOps, go to the release that was deployed to production. Suchen Sie nach dem letzten bereitgestellten Commit.Find the last commit that was deployed.

  2. Rufen Sie aus der Commitmeldung die Commit-ID des Kollaborationsbranch ab.From the commit message, get the commit ID of the collaboration branch.

  3. Erstellen Sie aus diesem Commit einen neuen Hotfixbranch.Create a new hotfix branch from that commit.

  4. Navigieren Sie zur Azure Data Factory-Benutzeroberfläche und dort zum neuen Hotfixbranch.Go to the Azure Data Factory UX and switch to the hotfix branch.

  5. Beheben Sie den Fehler auf der Azure Data Factory-Benutzeroberfläche.By using the Azure Data Factory UX, fix the bug. Testen Sie die Änderungen.Test your changes.

  6. Wählen Sie nach der Verifizierung der Fehlerbehebung die Option Export ARM Template (ARM-Vorlage exportieren) aus, um die Resource Manager-Vorlage für den Hotfix abzurufen.After the fix is verified, select Export ARM Template to get the hotfix Resource Manager template.

  7. Checken Sie diesen Build manuell im Branch „adf_publish“ ein.Manually check this build into the adf_publish branch.

  8. Wenn Sie die Releasepipeline so konfiguriert haben, dass sie bei Check-Ins in „adf_publish“ automatisch ausgelöst wird, wird automatisch ein neues Release gestartet.If you've configured your release pipeline to automatically trigger based on adf_publish check-ins, a new release will start automatically. Reihen Sie andernfalls manuell ein Release in die Warteschlange ein.Otherwise, manually queue a release.

  9. Stellen Sie das Hotfixrelease für die Test- und Produktionsfactorys bereit.Deploy the hotfix release to the test and production factories. Dieses Release enthält die vorherige Nutzlast der Produktionsumgebung sowie die Korrektur, die Sie in Schritt 5 vorgenommen haben.This release contains the previous production payload plus the fix that you made in step 5.

  10. Fügen Sie dem Entwicklungsbranch die Änderungen aus dem Hotfix hinzu, damit spätere Releases nicht den gleichen Fehler enthalten.Add the changes from the hotfix to the development branch so that later releases won't include the same bug.

Das folgende Video ist ein ausführliches Videotutorial, in dem Sie erfahren, wie Sie ein Hotfix in Ihren Umgebungen anwenden.See the video below an in-depth video tutorial on how to hot-fix your environments.

Anzeigesteuerungs- und FeatureflagsExposure control and feature flags

Wenn Sie in einem Team arbeiten, gibt es Instanzen, für die Sie Änderungen zusammenführen können, aber nicht möchten, dass sie in Umgebungen mit erhöhten Rechten wie PROD und QA ausgeführt werden.When working on a team, there are instances where you may merge changes, but don't want them to be ran in elevated environments such as PROD and QA. Für dieses Szenario empfiehlt das ADF-Team das DevOps-Konzept der Verwendung von Featureflags.To handle this scenario, the ADF team recommends the DevOps concept of using feature flags. In ADF können Sie globale Parameter und die Aktivität „IfCondition“ kombinieren, um Logiksätze auf der Grundlage dieser Umgebungsflags auszublenden.In ADF, you can combine global parameters and the if condition activity to hide sets of logic based upon these environment flags.

Informationen zum Einrichten eines Featureflags finden Sie im folgenden Videotutorial:To learn how to set up a feature flag, see the below video tutorial:

Bewährte Methoden für CI/CDBest practices for CI/CD

Wenn Sie die Git-Integration mit Ihrer Data Factory verwenden und über eine CI/CD-Pipeline verfügen, die Ihre Änderungen aus der Entwicklungs- in die Test- und dann in die Produktionsumgebung verschiebt, empfehlen wir Ihnen diese bewährten Methoden:If you're using Git integration with your data factory and have a CI/CD pipeline that moves your changes from development into test and then to production, we recommend these best practices:

  • Git-Integration.Git integration. Konfigurieren Sie nur Ihre Entwicklungs-Data Factory mit Git-Integration.Configure only your development data factory with Git integration. Änderungen an den Test- und Produktionsumgebungen werden über CI/CD bereitgestellt, und eine Git-Integration wird hierfür nicht benötigt.Changes to test and production are deployed via CI/CD and don't need Git integration.

  • Skript für vor und nach der Bereitstellung.Pre- and post-deployment script. Bevor Sie den Schritt für die Resource Manager-Bereitstellung für CI/CD ausführen, müssen Sie bestimmte Aufgaben erledigen, z. B. das Beenden und erneute Starten von Triggern und das Durchführen einer Bereinigung.Before the Resource Manager deployment step in CI/CD, you need to complete certain tasks, like stopping and restarting triggers and performing cleanup. Wir empfehlen Ihnen, vor und nach der Bereitstellungsaufgabe PowerShell-Skripts zu verwenden.We recommend that you use PowerShell scripts before and after the deployment task. Weitere Informationen finden Sie unter Aktualisieren von aktiven Triggern.For more information, see Update active triggers. Das Data Factory Team hat am Ende dieser Seite ein Skript hinzugefügt, das Sie nutzen können.The data factory team has provided a script to use located at the bottom of this page.

  • Integration Runtimes und Freigaben.Integration runtimes and sharing. Integration Runtimes werden nicht sehr häufig geändert und sind in allen Stufen von CI/CD ähnlich.Integration runtimes don't change often and are similar across all stages in your CI/CD. Daher erwartet Data Factory, dass diese in allen Stufen von CI/CD den gleichen Integration Runtime-Namen bzw. -Typ aufweisen.So Data Factory expects you to have the same name and type of integration runtime across all stages of CI/CD. Wenn Sie Integration Runtimes über alle Stufen hinweg freigeben möchten, können Sie eine ternäre Factory verwenden, die nur die freigegebenen Integration Runtimes enthält.If you want to share integration runtimes across all stages, consider using a ternary factory just to contain the shared integration runtimes. Diese freigegebene Factory können Sie in allen Umgebungen als verknüpften Integration Runtime-Typ verwenden.You can use this shared factory in all of your environments as a linked integration runtime type.

  • Bereitstellung eines verwalteten privaten Endpunkts.Managed private endpoint deployment. Wenn bereits ein privater Endpunkt in einer Factory vorhanden ist und Sie versuchen, eine ARM-Vorlage bereitzustellen, die einen privaten Endpunkt mit demselben Namen, jedoch mit geänderten Eigenschaften enthält, tritt bei der Bereitstellung ein Fehler auf.If a private endpoint already exists in a factory and you try to deploy an ARM template that contains a private endpoint with the same name but with modified properties, the deployment will fail. Das bedeutet, dass Sie einen privaten Endpunkt erfolgreich bereitstellen können, sofern dieser dieselben Eigenschaften wie der Endpunkt aufweist, der bereits in der Factory vorhanden ist.In other words, you can successfully deploy a private endpoint as long as it has the same properties as the one that already exists in the factory. Wenn eine Eigenschaft in den Umgebungen unterschiedlich ist, können Sie diese überschreiben, indem Sie die Eigenschaft parametrisieren und den entsprechenden Wert während der Bereitstellung angeben.If any property is different between environments, you can override it by parameterizing that property and providing the respective value during deployment.

  • Key Vault.Key Vault. Wenn Sie verknüpfte Dienste verwenden, deren Verbindungsinformationen in Azure Key Vault gespeichert sind, wird empfohlen, separate Schlüsseltresore für verschiedene Umgebungen beizubehalten.When you use linked services whose connection information is stored in Azure Key Vault, it is recommended to keep separate key vaults for different environments. Sie können auch separate Berechtigungsstufen für jeden Schlüsseltresor konfigurieren.You can also configure separate permission levels for each key vault. Es kann beispielsweise sein, dass Teammitglieder nicht über Berechtigungen für Produktionsgeheimnisse verfügen sollen.For example, you might not want your team members to have permissions to production secrets. Bei diesem Ansatz empfehlen wir Ihnen, in allen Stufen die gleichen Geheimnisnamen beizubehalten.If you follow this approach, we recommend that you to keep the same secret names across all stages. Wenn Sie die gleichen Geheimnisnamen beibehalten, müssen Sie nicht jede einzelne Verbindungszeichenfolge für alle CI/CD-Umgebungen parametrisieren, weil sich lediglich der Name des Schlüsseltresors ändert, und der ist ein separater Parameter.If you keep the same secret names, you don't need to parameterize each connection string across CI/CD environments because the only thing that changes is the key vault name, which is a separate parameter.

  • Benennen von Ressourcen. Aufgrund von Einschränkungen bei Resource Manager-Vorlagen können bei der Bereitstellung Probleme auftreten, wenn die Namen Ihrer Ressourcen Leerzeichen enthalten.Resource naming Due to ARM template constraints, issues in deployment may arise if your resources contain spaces in the name. Daher empfiehlt das Azure Data Factory-Team bei Ressourcennamen die Verwendung der Zeichen „“ bzw. „-“ anstelle von Leerzeichen.The Azure Data Factory team recommends using '' or '-' characters instead of spaces for resources. Verwenden Sie beispielsweise „Pipeline_1“ anstelle von „Pipeline 1“.For example, 'Pipeline_1' would be a preferable name over 'Pipeline 1'.

Nicht unterstützte FunktionenUnsupported features

  • Standardmäßig ist für Data Factory ein Cherrypicking von Commits oder die selektive Veröffentlichung von Ressourcen nicht zulässig.By design, Data Factory doesn't allow cherry-picking of commits or selective publishing of resources. Veröffentlichungen umfassen alle in der Data Factory vorgenommenen Änderungen.Publishes will include all changes made in the data factory.

    • Data Factory-Entitäten sind voneinander abhängig.Data factory entities depend on each other. Beispielsweise hängen Trigger von Pipelines ab, während Pipelines von Datasets und anderen Pipelines abhängig sind.For example, triggers depend on pipelines, and pipelines depend on datasets and other pipelines. Die selektive Veröffentlichung einer Teilmenge von Ressourcen kann ggf. zu unerwartetem Verhalten und Fehlern führen.Selective publishing of a subset of resources could lead to unexpected behaviors and errors.
    • In den seltenen Fällen, in denen Sie eine selektive Veröffentlichung durchführen müssen, können Sie die Verwendung eines Hotfix erwägen.On rare occasions when you need selective publishing, consider using a hotfix. Weitere Informationen finden Sie unter Hotfix für Produktionsumgebung.For more information, see Hotfix production environment.
  • Das Azure Data Factory-Team rät davon ab, Azure RBAC-Steuerelemente einzelnen Entitäten (Pipelines, Datasets usw.) in einer Data Factory zuzuweisen.The Azure Data Factory team doesn’t recommend assigning Azure RBAC controls to individual entities (pipelines, datasets, etc.) in a data factory. Wenn ein Entwickler beispielsweise Zugriff auf eine Pipeline oder ein Dataset hat, sollte er in der Lage sein, auf alle Pipelines oder Datasets in der Data Factory zuzugreifen.For example, if a developer has access to a pipeline or a dataset, they should be able to access all pipelines or datasets in the data factory. Wenn Sie der Ansicht sind, dass Sie viele Azure-Rollen innerhalb einer Data Factory implementieren müssen, ziehen Sie die Bereitstellung einer zweiten Data Factory in Betracht.If you feel that you need to implement many Azure roles within a data factory, look at deploying a second data factory.

  • Sie können nicht aus privaten Branches veröffentlichen.You can't publish from private branches.

  • Es ist derzeit nicht möglich, Projekte in Bitbucket zu hosten.You can't currently host projects on Bitbucket.

Beispielskript für vor und nach der BereitstellungSample pre- and post-deployment script

Das folgende Beispielskript kann verwendet werden, um Trigger vor der Bereitstellung zu beenden und anschließend neu starten.The following sample script can be used to stop triggers before deployment and restart them afterward. Außerdem enthält das Skript den Code zum Löschen von Ressourcen, die entfernt wurden.The script also includes code to delete resources that have been removed. Speichern Sie das Skript in einem Azure DevOps-Git-Repository, und verweisen Sie es über eine Azure PowerShell Aufgabe unter Verwendung von „Version 4.*“.Save the script in an Azure DevOps git repository and reference it via an Azure PowerShell task using version 4.*.

Wenn Sie ein Skript vor der Bereitstellung ausführen, müssen Sie im Feld Skriptargumente eine Variation der folgenden Parameter angeben.When running a pre-deployment script, you will need to specify a variation of the following parameters in the Script Arguments field.

-armTemplate "$(System.DefaultWorkingDirectory)/<your-arm-template-location>" -ResourceGroupName <your-resource-group-name> -DataFactoryName <your-data-factory-name> -predeployment $true -deleteDeployment $false

Wenn Sie ein Skript nach der Bereitstellung ausführen, müssen Sie im Feld Skriptargumente eine Variation der folgenden Parameter angeben.When running a post-deployment script, you will need to specify a variation of the following parameters in the Script Arguments field.

-armTemplate "$(System.DefaultWorkingDirectory)/<your-arm-template-location>" -ResourceGroupName <your-resource-group-name> -DataFactoryName <your-data-factory-name> -predeployment $false -deleteDeployment $true

Azure PowerShell-Aufgabe

Hier ist das Skript, das für vor und nach der Bereitstellung verwendet werden kann.Here is the script that can be used for pre- and post-deployment. Es berücksichtigt gelöschte Ressourcen und Ressourcenverweise.It accounts for deleted resources and resource references.

param
(
    [parameter(Mandatory = $false)] [String] $armTemplate,
    [parameter(Mandatory = $false)] [String] $ResourceGroupName,
    [parameter(Mandatory = $false)] [String] $DataFactoryName,
    [parameter(Mandatory = $false)] [Bool] $predeployment=$true,
    [parameter(Mandatory = $false)] [Bool] $deleteDeployment=$false
)

function getPipelineDependencies {
    param([System.Object] $activity)
    if ($activity.Pipeline) {
        return @($activity.Pipeline.ReferenceName)
    } elseif ($activity.Activities) {
        $result = @()
        $activity.Activities | ForEach-Object{ $result += getPipelineDependencies -activity $_ }
        return $result
    } elseif ($activity.ifFalseActivities -or $activity.ifTrueActivities) {
        $result = @()
        $activity.ifFalseActivities | Where-Object {$_ -ne $null} | ForEach-Object{ $result += getPipelineDependencies -activity $_ }
        $activity.ifTrueActivities | Where-Object {$_ -ne $null} | ForEach-Object{ $result += getPipelineDependencies -activity $_ }
        return $result
    } elseif ($activity.defaultActivities) {
        $result = @()
        $activity.defaultActivities | ForEach-Object{ $result += getPipelineDependencies -activity $_ }
        if ($activity.cases) {
            $activity.cases | ForEach-Object{ $_.activities } | ForEach-Object{$result += getPipelineDependencies -activity $_ }
        }
        return $result
    } else {
        return @()
    }
}

function pipelineSortUtil {
    param([Microsoft.Azure.Commands.DataFactoryV2.Models.PSPipeline]$pipeline,
    [Hashtable] $pipelineNameResourceDict,
    [Hashtable] $visited,
    [System.Collections.Stack] $sortedList)
    if ($visited[$pipeline.Name] -eq $true) {
        return;
    }
    $visited[$pipeline.Name] = $true;
    $pipeline.Activities | ForEach-Object{ getPipelineDependencies -activity $_ -pipelineNameResourceDict $pipelineNameResourceDict}  | ForEach-Object{
        pipelineSortUtil -pipeline $pipelineNameResourceDict[$_] -pipelineNameResourceDict $pipelineNameResourceDict -visited $visited -sortedList $sortedList
    }
    $sortedList.Push($pipeline)

}

function Get-SortedPipelines {
    param(
        [string] $DataFactoryName,
        [string] $ResourceGroupName
    )
    $pipelines = Get-AzDataFactoryV2Pipeline -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName
    $ppDict = @{}
    $visited = @{}
    $stack = new-object System.Collections.Stack
    $pipelines | ForEach-Object{ $ppDict[$_.Name] = $_ }
    $pipelines | ForEach-Object{ pipelineSortUtil -pipeline $_ -pipelineNameResourceDict $ppDict -visited $visited -sortedList $stack }
    $sortedList = new-object Collections.Generic.List[Microsoft.Azure.Commands.DataFactoryV2.Models.PSPipeline]
    
    while ($stack.Count -gt 0) {
        $sortedList.Add($stack.Pop())
    }
    $sortedList
}

function triggerSortUtil {
    param([Microsoft.Azure.Commands.DataFactoryV2.Models.PSTrigger]$trigger,
    [Hashtable] $triggerNameResourceDict,
    [Hashtable] $visited,
    [System.Collections.Stack] $sortedList)
    if ($visited[$trigger.Name] -eq $true) {
        return;
    }
    $visited[$trigger.Name] = $true;
    if ($trigger.Properties.DependsOn) {
        $trigger.Properties.DependsOn | Where-Object {$_ -and $_.ReferenceTrigger} | ForEach-Object{
            triggerSortUtil -trigger $triggerNameResourceDict[$_.ReferenceTrigger.ReferenceName] -triggerNameResourceDict $triggerNameResourceDict -visited $visited -sortedList $sortedList
        }
    }
    $sortedList.Push($trigger)
}

function Get-SortedTriggers {
    param(
        [string] $DataFactoryName,
        [string] $ResourceGroupName
    )
    $triggers = Get-AzDataFactoryV2Trigger -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName
    $triggerDict = @{}
    $visited = @{}
    $stack = new-object System.Collections.Stack
    $triggers | ForEach-Object{ $triggerDict[$_.Name] = $_ }
    $triggers | ForEach-Object{ triggerSortUtil -trigger $_ -triggerNameResourceDict $triggerDict -visited $visited -sortedList $stack }
    $sortedList = new-object Collections.Generic.List[Microsoft.Azure.Commands.DataFactoryV2.Models.PSTrigger]
    
    while ($stack.Count -gt 0) {
        $sortedList.Add($stack.Pop())
    }
    $sortedList
}

function Get-SortedLinkedServices {
    param(
        [string] $DataFactoryName,
        [string] $ResourceGroupName
    )
    $linkedServices = Get-AzDataFactoryV2LinkedService -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName
    $LinkedServiceHasDependencies = @('HDInsightLinkedService', 'HDInsightOnDemandLinkedService', 'AzureBatchLinkedService')
    $Akv = 'AzureKeyVaultLinkedService'
    $HighOrderList = New-Object Collections.Generic.List[Microsoft.Azure.Commands.DataFactoryV2.Models.PSLinkedService]
    $RegularList = New-Object Collections.Generic.List[Microsoft.Azure.Commands.DataFactoryV2.Models.PSLinkedService]
    $AkvList = New-Object Collections.Generic.List[Microsoft.Azure.Commands.DataFactoryV2.Models.PSLinkedService]

    $linkedServices | ForEach-Object {
        if ($_.Properties.GetType().Name -in $LinkedServiceHasDependencies) {
            $HighOrderList.Add($_)
        }
        elseif ($_.Properties.GetType().Name -eq $Akv) {
            $AkvList.Add($_)
        }
        else {
            $RegularList.Add($_)
        }
    }

    $SortedList = New-Object Collections.Generic.List[Microsoft.Azure.Commands.DataFactoryV2.Models.PSLinkedService]($HighOrderList.Count + $RegularList.Count + $AkvList.Count)
    $SortedList.AddRange($HighOrderList)
    $SortedList.AddRange($RegularList)
    $SortedList.AddRange($AkvList)
    $SortedList
}

$templateJson = Get-Content $armTemplate | ConvertFrom-Json
$resources = $templateJson.resources

#Triggers 
Write-Host "Getting triggers"
$triggersInTemplate = $resources | Where-Object { $_.type -eq "Microsoft.DataFactory/factories/triggers" }
$triggerNamesInTemplate = $triggersInTemplate | ForEach-Object {$_.name.Substring(37, $_.name.Length-40)}

$triggersDeployed = Get-SortedTriggers -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName

$triggersToStop = $triggersDeployed | Where-Object { $triggerNamesInTemplate -contains $_.Name } | ForEach-Object { 
    New-Object PSObject -Property @{
        Name = $_.Name
        TriggerType = $_.Properties.GetType().Name 
    }
}
$triggersToDelete = $triggersDeployed | Where-Object { $triggerNamesInTemplate -notcontains $_.Name } | ForEach-Object { 
    New-Object PSObject -Property @{
        Name = $_.Name
        TriggerType = $_.Properties.GetType().Name 
    }
}
$triggersToStart = $triggersInTemplate | Where-Object { $_.properties.runtimeState -eq "Started" -and ($_.properties.pipelines.Count -gt 0 -or $_.properties.pipeline.pipelineReference -ne $null)} | ForEach-Object { 
    New-Object PSObject -Property @{
        Name = $_.name.Substring(37, $_.name.Length-40)
        TriggerType = $_.Properties.type
    }
}

if ($predeployment -eq $true) {
    #Stop all triggers
    Write-Host "Stopping deployed triggers`n"
    $triggersToStop | ForEach-Object {
        if ($_.TriggerType -eq "BlobEventsTrigger") {
            Write-Host "Unsubscribing" $_.Name "from events"
            $status = Remove-AzDataFactoryV2TriggerSubscription -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name
            while ($status.Status -ne "Disabled"){
                Start-Sleep -s 15
                $status = Get-AzDataFactoryV2TriggerSubscriptionStatus -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name
            }
        }
        Write-Host "Stopping trigger" $_.Name
        Stop-AzDataFactoryV2Trigger -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name -Force
    }
}
else {
    #Deleted resources
    #pipelines
    Write-Host "Getting pipelines"
    $pipelinesADF = Get-SortedPipelines -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName
    $pipelinesTemplate = $resources | Where-Object { $_.type -eq "Microsoft.DataFactory/factories/pipelines" }
    $pipelinesNames = $pipelinesTemplate | ForEach-Object {$_.name.Substring(37, $_.name.Length-40)}
    $deletedpipelines = $pipelinesADF | Where-Object { $pipelinesNames -notcontains $_.Name }
    #dataflows
    $dataflowsADF = Get-AzDataFactoryV2DataFlow -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName
    $dataflowsTemplate = $resources | Where-Object { $_.type -eq "Microsoft.DataFactory/factories/dataflows" }
    $dataflowsNames = $dataflowsTemplate | ForEach-Object {$_.name.Substring(37, $_.name.Length-40) }
    $deleteddataflow = $dataflowsADF | Where-Object { $dataflowsNames -notcontains $_.Name }
    #datasets
    Write-Host "Getting datasets"
    $datasetsADF = Get-AzDataFactoryV2Dataset -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName
    $datasetsTemplate = $resources | Where-Object { $_.type -eq "Microsoft.DataFactory/factories/datasets" }
    $datasetsNames = $datasetsTemplate | ForEach-Object {$_.name.Substring(37, $_.name.Length-40) }
    $deleteddataset = $datasetsADF | Where-Object { $datasetsNames -notcontains $_.Name }
    #linkedservices
    Write-Host "Getting linked services"
    $linkedservicesADF = Get-SortedLinkedServices -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName
    $linkedservicesTemplate = $resources | Where-Object { $_.type -eq "Microsoft.DataFactory/factories/linkedservices" }
    $linkedservicesNames = $linkedservicesTemplate | ForEach-Object {$_.name.Substring(37, $_.name.Length-40)}
    $deletedlinkedservices = $linkedservicesADF | Where-Object { $linkedservicesNames -notcontains $_.Name }
    #Integrationruntimes
    Write-Host "Getting integration runtimes"
    $integrationruntimesADF = Get-AzDataFactoryV2IntegrationRuntime -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName
    $integrationruntimesTemplate = $resources | Where-Object { $_.type -eq "Microsoft.DataFactory/factories/integrationruntimes" }
    $integrationruntimesNames = $integrationruntimesTemplate | ForEach-Object {$_.name.Substring(37, $_.name.Length-40)}
    $deletedintegrationruntimes = $integrationruntimesADF | Where-Object { $integrationruntimesNames -notcontains $_.Name }

    #Delete resources
    Write-Host "Deleting triggers"
    $triggersToDelete | ForEach-Object { 
        Write-Host "Deleting trigger "  $_.Name
        $trig = Get-AzDataFactoryV2Trigger -name $_.Name -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName
        if ($trig.RuntimeState -eq "Started") {
            if ($_.TriggerType -eq "BlobEventsTrigger") {
                Write-Host "Unsubscribing trigger" $_.Name "from events"
                $status = Remove-AzDataFactoryV2TriggerSubscription -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name
                while ($status.Status -ne "Disabled"){
                    Start-Sleep -s 15
                    $status = Get-AzDataFactoryV2TriggerSubscriptionStatus -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name
                }
            }
            Stop-AzDataFactoryV2Trigger -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name -Force 
        }
        Remove-AzDataFactoryV2Trigger -Name $_.Name -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Force 
    }
    Write-Host "Deleting pipelines"
    $deletedpipelines | ForEach-Object { 
        Write-Host "Deleting pipeline " $_.Name
        Remove-AzDataFactoryV2Pipeline -Name $_.Name -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Force 
    }
    Write-Host "Deleting dataflows"
    $deleteddataflow | ForEach-Object { 
        Write-Host "Deleting dataflow " $_.Name
        Remove-AzDataFactoryV2DataFlow -Name $_.Name -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Force 
    }
    Write-Host "Deleting datasets"
    $deleteddataset | ForEach-Object { 
        Write-Host "Deleting dataset " $_.Name
        Remove-AzDataFactoryV2Dataset -Name $_.Name -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Force 
    }
    Write-Host "Deleting linked services"
    $deletedlinkedservices | ForEach-Object { 
        Write-Host "Deleting Linked Service " $_.Name
        Remove-AzDataFactoryV2LinkedService -Name $_.Name -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Force 
    }
    Write-Host "Deleting integration runtimes"
    $deletedintegrationruntimes | ForEach-Object { 
        Write-Host "Deleting integration runtime " $_.Name
        Remove-AzDataFactoryV2IntegrationRuntime -Name $_.Name -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Force 
    }

    if ($deleteDeployment -eq $true) {
        Write-Host "Deleting ARM deployment ... under resource group: " $ResourceGroupName
        $deployments = Get-AzResourceGroupDeployment -ResourceGroupName $ResourceGroupName
        $deploymentsToConsider = $deployments | Where { $_.DeploymentName -like "ArmTemplate_master*" -or $_.DeploymentName -like "ArmTemplateForFactory*" } | Sort-Object -Property Timestamp -Descending
        $deploymentName = $deploymentsToConsider[0].DeploymentName

       Write-Host "Deployment to be deleted: " $deploymentName
        $deploymentOperations = Get-AzResourceGroupDeploymentOperation -DeploymentName $deploymentName -ResourceGroupName $ResourceGroupName
        $deploymentsToDelete = $deploymentOperations | Where { $_.properties.targetResource.id -like "*Microsoft.Resources/deployments*" }

        $deploymentsToDelete | ForEach-Object { 
            Write-host "Deleting inner deployment: " $_.properties.targetResource.id
            Remove-AzResourceGroupDeployment -Id $_.properties.targetResource.id
        }
        Write-Host "Deleting deployment: " $deploymentName
        Remove-AzResourceGroupDeployment -ResourceGroupName $ResourceGroupName -Name $deploymentName
    }

    #Start active triggers - after cleanup efforts
    Write-Host "Starting active triggers"
    $triggersToStart | ForEach-Object { 
        if ($_.TriggerType -eq "BlobEventsTrigger") {
            Write-Host "Subscribing" $_.Name "to events"
            $status = Add-AzDataFactoryV2TriggerSubscription -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name
            while ($status.Status -ne "Enabled"){
                Start-Sleep -s 15
                $status = Get-AzDataFactoryV2TriggerSubscriptionStatus -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name
            }
        }
        Write-Host "Starting trigger" $_.Name
        Start-AzDataFactoryV2Trigger -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name -Force
    }
}