|
| 1 | +--- |
| 2 | +title: Automate continuous integration with GitHub Actions |
| 3 | +description: Learn how to automate continuous integration in Azure Data Factory with GitHub Actions. |
| 4 | +ms.service: data-factory |
| 5 | +ms.subservice: ci-cd |
| 6 | +author: olmoloce |
| 7 | +ms.author: olmoloce |
| 8 | +ms.reviewer: kromerm |
| 9 | +ms.topic: conceptual |
| 10 | +ms.date: 08/29/2023 |
| 11 | +--- |
| 12 | + |
| 13 | +# Automate continuous integration and delivery using GitHub Actions |
| 14 | + |
| 15 | +[!INCLUDE[appliesto-adf-xxx-md](includes/appliesto-adf-xxx-md.md)] |
| 16 | + |
| 17 | +In this guide, we show how to do continuous integration and delivery in Azure Data Factory with GitHub Actions. This is done using workflows. A workflow is defined by a YAML file that contains the various steps and parameters that make up the workflow. |
| 18 | + |
| 19 | +The workflow leverages the [automated publishing capability](continuous-integration-delivery-improvements.md) of Azure Data Factory. And the [Azure Data Factory Deploy Action](https://github.com/marketplace/actions/data-factory-deploy) from the GitHub Marketplace that uses the [pre- and post-deployment script](continuous-integration-delivery-sample-script.md). |
| 20 | + |
| 21 | +## Requirements |
| 22 | + |
| 23 | +- Azure Subscription - if you don't have one, create a [free Azure account](https://azure.microsoft.com/free/) before you begin. |
| 24 | + |
| 25 | +- Azure Data Factory - you need two instances, one development instance that is the source of changes. And a second one where changes are propagated with the workflow. If you don't have an existing Data Factory instance, follow this [tutorial](quickstart-create-data-factory.md) to create one. |
| 26 | + |
| 27 | +- GitHub repository integration set up - if you don't have a GitHub repository connected to your development Data Factory, follow the [tutorial](source-control.md#github-settings) to connect it. |
| 28 | + |
| 29 | +## Create a user-assigned managed identity |
| 30 | + |
| 31 | +You need credentials that authenticate and authorize GitHub Actions to deploy your ARM template to the target Data Factory. We leverage a user-assigned managed identity (UAMI) with [workload identity federation](../active-directory/workload-identities/workload-identity-federation.md). Using workload identity federation allows you to access Azure Active Directory (Azure AD) protected resources without needing to manage secrets. In this scenario, GitHub Actions are able to access the Azure resource group and deploy the target Data Factory instance. |
| 32 | + |
| 33 | +Follow the tutorial to [create a user-assigned managed identity](../active-directory/managed-identities-azure-resources/how-manage-user-assigned-managed-identities.md#create-a-user-assigned-managed-identity). Once the UAMI is created, browse to the Overview page and take a note of the Subscription ID and Client ID. We need these values later. |
| 34 | + |
| 35 | +## Configure the workload identity federation |
| 36 | + |
| 37 | +1. Follow the tutorial to [configure a federated identity credential on a user-assigned managed identity](../active-directory/workload-identities/workload-identity-federation-create-trust-user-assigned-managed-identity.md#configure-a-federated-identity-credential-on-a-user-assigned-managed-identity). |
| 38 | + |
| 39 | + Here is an example of a federated identity configuration: |
| 40 | + |
| 41 | + :::image type="content" source="media/continuous-integration-delivery-github-actions/add-federated-credential.png" lightbox="media/continuous-integration-delivery-github-actions/add-federated-credential.png"alt-text="Screenshot of adding Federated Credential in Azure Portal."::: |
| 42 | + |
| 43 | +2. After creating the credential, navigate to Azure Active Directory Overview page and take a note of the tenant ID. We need this value later. |
| 44 | + |
| 45 | +3. Browse to the Resource Group containing the target Data Factory instance and assign the UAMI the [Data Factory Contributor role](concepts-roles-permissions.md#roles-and-requirements). |
| 46 | + |
| 47 | +> [!IMPORTANT] |
| 48 | +> In order to avoid authorization errors during deployment, be sure to assign the Data Factory Contributor role at the Resource Group level containing the target Data Factory instance. |
| 49 | +
|
| 50 | +## Configure the GitHub secrets |
| 51 | + |
| 52 | +You need to provide your application's Client ID, Tenant ID and Subscription ID to the login action. These values can be stored in GitHub secrets and referenced in your workflow. |
| 53 | +1. Open your GitHub repository and go to Settings. |
| 54 | + |
| 55 | + :::image type="content" source="media/continuous-integration-delivery-github-actions/github-settings.png" lightbox="media/continuous-integration-delivery-github-actions/github-settings.png" alt-text="Screenshot of navigating to GitHub Settings."::: |
| 56 | + |
| 57 | +2. Select Security -> Secrets and variables -> Actions. |
| 58 | + |
| 59 | + :::image type="content" source="media/continuous-integration-delivery-github-actions/github-secrets.png" lightbox="media/continuous-integration-delivery-github-actions/github-secrets.png" alt-text="Screenshot of navigating to GitHub Secrets."::: |
| 60 | + |
| 61 | +3. Create secrets for AZURE_CLIENT_ID, AZURE_TENANT_ID, and AZURE_SUBSCRIPTION_ID. Use these values from your Azure Active Directory application for your GitHub secrets: |
| 62 | + |
| 63 | + | GitHub Secret | Azure Active Directory Application | |
| 64 | + |---------------|----------------------------| |
| 65 | + | AZURE_CLIENT_ID | Application (client) ID | |
| 66 | + | AZURE_TENANT_ID | Directory (tenant) ID | |
| 67 | + | AZURE_SUBSCRIPTION_ID | Subscription ID | |
| 68 | + |
| 69 | +4. Save each secret by selecting Add secret. |
| 70 | + |
| 71 | +## Create the workflow that deploys the Data Factory ARM template |
| 72 | + |
| 73 | +At this point, you must have a Data Factory instance with git integration set up. If not, follow the links in the Requirements section. |
| 74 | + |
| 75 | +The workflow is composed of two jobs: |
| 76 | + |
| 77 | +- **A build job** which uses the npm package [@microsoft/azure-data-factory-utilities](https://www.npmjs.com/package/@microsoft/azure-data-factory-utilities) to (1) validate all the Data Factory resources in the repository. You get the same validation errors as when "Validate All" is selected in Data Factory Studio. And (2) export the ARM template that is later used to deploy to the QA or Staging environment. |
| 78 | +- **A release job** which takes the exported ARM template artifact and deploys it to the higher environment Data Factory instance. |
| 79 | + |
| 80 | +1. Navigate to the repository connected to your Data Factory, under your root folder (ADFroot in the below example) create a build folder where you store the package.json file: |
| 81 | + |
| 82 | + ```json |
| 83 | + { |
| 84 | + "scripts":{ |
| 85 | + "build":"node node_modules/@microsoft/azure-data-factory-utilities/lib/index" |
| 86 | + }, |
| 87 | + "dependencies":{ |
| 88 | + "@microsoft/azure-data-factory-utilities":"^1.0.0" |
| 89 | + } |
| 90 | + } |
| 91 | + ``` |
| 92 | + |
| 93 | + The setup should look like: |
| 94 | + |
| 95 | + :::image type="content" source="media/continuous-integration-delivery-github-actions/saving-package-json-file.png" lightbox="media/continuous-integration-delivery-github-actions/saving-package-json-file.png" alt-text="Screenshot of saving the package.json file in GitHub."::: |
| 96 | + |
| 97 | +2. Navigate to the Actions tab -> New workflow |
| 98 | + |
| 99 | + :::image type="content" source="media/continuous-integration-delivery-github-actions/new-workflow.png" lightbox="media/continuous-integration-delivery-github-actions/new-workflow.png" alt-text="Screenshot of creating a new workflow in GitHub."::: |
| 100 | + |
| 101 | +3. Paste the workflow YAML. |
| 102 | + |
| 103 | +```yml |
| 104 | +on: |
| 105 | + push: |
| 106 | + branches: |
| 107 | + - main |
| 108 | + |
| 109 | +permissions: |
| 110 | + id-token: write |
| 111 | + contents: read |
| 112 | + |
| 113 | +jobs: |
| 114 | + build: |
| 115 | + runs-on: ubuntu-latest |
| 116 | + steps: |
| 117 | + |
| 118 | + - uses: actions/checkout@v3 |
| 119 | +# Installs Node and the npm packages saved in your package.json file in the build |
| 120 | + - name: Setup Node.js environment |
| 121 | + |
| 122 | + with: |
| 123 | + node-version: 14.x |
| 124 | + |
| 125 | + - name: install ADF Utilities package |
| 126 | + run: npm install |
| 127 | + working-directory: ${{github.workspace}}/ADFroot/build # (1) provide the folder location of the package.json file |
| 128 | + |
| 129 | +# Validates all of the Data Factory resources in the repository. You'll get the same validation errors as when "Validate All" is selected. |
| 130 | + - name: Validate |
| 131 | + run: npm run build validate ${{github.workspace}}/ADFroot/ /subscriptions/<subscriptionID>/resourceGroups/<resourceGroupName>/providers/Microsoft.DataFactory/factories/<ADFname> # (2) The validate command needs the root folder location of your repository where all the objects are stored. And the 2nd parameter is the resourceID of the ADF instance |
| 132 | + working-directory: ${{github.workspace}}/ADFroot/build |
| 133 | + |
| 134 | + |
| 135 | + - name: Validate and Generate ARM template |
| 136 | + run: npm run build export ${{github.workspace}}/ADFroot/ /subscriptions/<subID>/resourceGroups/<resourceGroupName>/providers/Microsoft.DataFactory/factories/<ADFname> "ExportedArmTemplate" # (3) The build command, as validate, needs the root folder location of your repository where all the objects are stored. And the 2nd parameter is the resourceID of the ADF instance. The 3rd parameter is the exported ARM template artifact name |
| 137 | + working-directory: ${{github.workspace}}/ADFroot/build |
| 138 | + |
| 139 | +# In order to leverage the artifact in another job, we need to upload it with the upload action |
| 140 | + - name: upload artifact |
| 141 | + uses: actions/upload-artifact@v3 |
| 142 | + with: |
| 143 | + name: ExportedArmTemplate # (4) use the same artifact name you used in the previous export step |
| 144 | + path: ${{github.workspace}}/ADFroot/build/ExportedArmTemplate |
| 145 | + |
| 146 | + release: |
| 147 | + needs: build |
| 148 | + runs-on: ubuntu-latest |
| 149 | + steps: |
| 150 | + |
| 151 | + # we 1st download the previously uploaded artifact so we can leverage it later in the release job |
| 152 | + - name: Download a Build Artifact |
| 153 | + |
| 154 | + with: |
| 155 | + name: ExportedArmTemplate # (5) Artifact name |
| 156 | + |
| 157 | + |
| 158 | + - name: Login via Az module |
| 159 | + uses: azure/login@v1 |
| 160 | + with: |
| 161 | + client-id: ${{ secrets.AZURE_CLIENT_ID }} |
| 162 | + tenant-id: ${{ secrets.AZURE_TENANT_ID }} |
| 163 | + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} |
| 164 | + enable-AzPSSession: true |
| 165 | + |
| 166 | + - name: data-factory-deploy |
| 167 | + |
| 168 | + with: |
| 169 | + resourceGroupName: # (6) your target ADF resource group name |
| 170 | + dataFactoryName: # (7) your target ADF name |
| 171 | + armTemplateFile: # (8) ARM template file name ARMTemplateForFactory.json |
| 172 | + armTemplateParametersFile: # (9) ARM template parameters file name ARMTemplateParametersForFactory.json |
| 173 | + additionalParameters: # (10) Parameters which will be replaced in the ARM template. Expected format 'key1=value key2=value keyN=value'. At the minimum here you should provide the target ADF name parameter. Check the ARMTemplateParametersForFactory.json file for all the parameters that are expected in your scenario |
| 174 | +``` |
| 175 | + |
| 176 | +Let’s walk together through the workflow. It contains parameters that are numbered for your convenience and comments describe what each expects. |
| 177 | + |
| 178 | +For the build job, there are four parameters you need to provide. For more detailed information about these, check the npm package [Azure Data Factory utilities](https://www.npmjs.com/package/@microsoft/azure-data-factory-utilities) documentation. |
| 179 | + |
| 180 | +> [!TIP] |
| 181 | +> Use the same artifact name in the Export, Upload and Download actions. |
| 182 | +
|
| 183 | +In the Release job, there are the next six parameters you need to supply. For more details about these, please check the [Azure Data Factory Deploy Action GitHub Marketplace listing](https://github.com/marketplace/actions/data-factory-deploy). |
| 184 | + |
| 185 | +## Monitor the workflow execution |
| 186 | + |
| 187 | +Let’s test the setup by making some changes in the development Data Factory instance. Create a feature branch and make some changes. Then make a pull request to the main branch. This triggers the workflow to execute. |
| 188 | + |
| 189 | +1. To check it, browse to the repository -> Actions -> and identify your workflow. |
| 190 | + |
| 191 | + :::image type="content" source="media/continuous-integration-delivery-github-actions/monitoring-workflow.png" lightbox="media/continuous-integration-delivery-github-actions/monitoring-workflow.png" alt-text="Screenshot showing monitoring a workflow in GitHub."::: |
| 192 | + |
| 193 | +2. You can further drill down into each run, see the jobs composing it and their statuses and duration, as well as the Artifact created by the run. In our scenario, this is the ARM template created in the build job. |
| 194 | + |
| 195 | + :::image type="content" source="media/continuous-integration-delivery-github-actions/monitoring-jobs.png" lightbox="media/continuous-integration-delivery-github-actions/monitoring-jobs.png" alt-text="Screenshot showing monitoring jobs in GitHub."::: |
| 196 | + |
| 197 | +3. You can further drill down by navigating to a job and its steps. |
| 198 | + |
| 199 | + :::image type="content" source="media/continuous-integration-delivery-github-actions/monitoring-release-job.png" lightbox="media/continuous-integration-delivery-github-actions/monitoring-release-job.png" alt-text="Screenshot showing monitoring the release job in GitHub."::: |
| 200 | + |
| 201 | +4. You can also navigate to the target Data Factory instance to which you deployed changes to and make sure it reflects the latest changes. |
| 202 | + |
| 203 | +## Next steps |
| 204 | + |
| 205 | +- [Continuous integration and delivery overview](continuous-integration-delivery.md) |
| 206 | +- [Manually promote a Resource Manager template to each environment](continuous-integration-delivery-manual-promotion.md) |
| 207 | +- [Use custom parameters with a Resource Manager template](continuous-integration-delivery-resource-manager-custom-parameters.md) |
| 208 | +- [Linked Resource Manager templates](continuous-integration-delivery-linked-templates.md) |
| 209 | +- [Using a hotfix production environment](continuous-integration-delivery-hotfix-environment.md) |
| 210 | +- [Sample pre- and post-deployment script](continuous-integration-delivery-sample-script.md) |
0 commit comments