├── CODE_OF_CONDUCT.md ├── LICENSE ├── PrePostDeploymentScript.ps1 ├── README.md ├── SECURITY.md ├── SUPPORT.md ├── action.yml └── images └── architecture-design.png /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /PrePostDeploymentScript.ps1: -------------------------------------------------------------------------------- 1 | param 2 | ( 3 | [parameter(Mandatory = $false)] [String] $armTemplate, 4 | [parameter(Mandatory = $false)] [String] $ResourceGroupName, 5 | [parameter(Mandatory = $false)] [String] $DataFactoryName, 6 | [parameter(Mandatory = $false)] [Bool] $predeployment=$true, 7 | [parameter(Mandatory = $false)] [Bool] $deleteDeployment=$false 8 | ) 9 | 10 | function getPipelineDependencies { 11 | param([System.Object] $activity) 12 | if ($activity.Pipeline) { 13 | return @($activity.Pipeline.ReferenceName) 14 | } elseif ($activity.Activities) { 15 | $result = @() 16 | $activity.Activities | ForEach-Object{ $result += getPipelineDependencies -activity $_ } 17 | return $result 18 | } elseif ($activity.ifFalseActivities -or $activity.ifTrueActivities) { 19 | $result = @() 20 | $activity.ifFalseActivities | Where-Object {$_ -ne $null} | ForEach-Object{ $result += getPipelineDependencies -activity $_ } 21 | $activity.ifTrueActivities | Where-Object {$_ -ne $null} | ForEach-Object{ $result += getPipelineDependencies -activity $_ } 22 | return $result 23 | } elseif ($activity.defaultActivities) { 24 | $result = @() 25 | $activity.defaultActivities | ForEach-Object{ $result += getPipelineDependencies -activity $_ } 26 | if ($activity.cases) { 27 | $activity.cases | ForEach-Object{ $_.activities } | ForEach-Object{$result += getPipelineDependencies -activity $_ } 28 | } 29 | return $result 30 | } else { 31 | return @() 32 | } 33 | } 34 | 35 | function pipelineSortUtil { 36 | param([Microsoft.Azure.Commands.DataFactoryV2.Models.PSPipeline]$pipeline, 37 | [Hashtable] $pipelineNameResourceDict, 38 | [Hashtable] $visited, 39 | [System.Collections.Stack] $sortedList) 40 | if ($visited[$pipeline.Name] -eq $true) { 41 | return; 42 | } 43 | $visited[$pipeline.Name] = $true; 44 | $pipeline.Activities | ForEach-Object{ getPipelineDependencies -activity $_ -pipelineNameResourceDict $pipelineNameResourceDict} | ForEach-Object{ 45 | pipelineSortUtil -pipeline $pipelineNameResourceDict[$_] -pipelineNameResourceDict $pipelineNameResourceDict -visited $visited -sortedList $sortedList 46 | } 47 | $sortedList.Push($pipeline) 48 | 49 | } 50 | 51 | function Get-SortedPipelines { 52 | param( 53 | [string] $DataFactoryName, 54 | [string] $ResourceGroupName 55 | ) 56 | $pipelines = Get-AzDataFactoryV2Pipeline -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName 57 | $ppDict = @{} 58 | $visited = @{} 59 | $stack = new-object System.Collections.Stack 60 | $pipelines | ForEach-Object{ $ppDict[$_.Name] = $_ } 61 | $pipelines | ForEach-Object{ pipelineSortUtil -pipeline $_ -pipelineNameResourceDict $ppDict -visited $visited -sortedList $stack } 62 | $sortedList = new-object Collections.Generic.List[Microsoft.Azure.Commands.DataFactoryV2.Models.PSPipeline] 63 | 64 | while ($stack.Count -gt 0) { 65 | $sortedList.Add($stack.Pop()) 66 | } 67 | $sortedList 68 | } 69 | 70 | function triggerSortUtil { 71 | param([Microsoft.Azure.Commands.DataFactoryV2.Models.PSTrigger]$trigger, 72 | [Hashtable] $triggerNameResourceDict, 73 | [Hashtable] $visited, 74 | [System.Collections.Stack] $sortedList) 75 | if ($visited[$trigger.Name] -eq $true) { 76 | return; 77 | } 78 | $visited[$trigger.Name] = $true; 79 | if ($trigger.Properties.DependsOn) { 80 | $trigger.Properties.DependsOn | Where-Object {$_ -and $_.ReferenceTrigger} | ForEach-Object{ 81 | triggerSortUtil -trigger $triggerNameResourceDict[$_.ReferenceTrigger.ReferenceName] -triggerNameResourceDict $triggerNameResourceDict -visited $visited -sortedList $sortedList 82 | } 83 | } 84 | $sortedList.Push($trigger) 85 | } 86 | 87 | function Get-SortedTriggers { 88 | param( 89 | [string] $DataFactoryName, 90 | [string] $ResourceGroupName 91 | ) 92 | $triggers = Get-AzDataFactoryV2Trigger -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName 93 | $triggerDict = @{} 94 | $visited = @{} 95 | $stack = new-object System.Collections.Stack 96 | $triggers | ForEach-Object{ $triggerDict[$_.Name] = $_ } 97 | $triggers | ForEach-Object{ triggerSortUtil -trigger $_ -triggerNameResourceDict $triggerDict -visited $visited -sortedList $stack } 98 | $sortedList = new-object Collections.Generic.List[Microsoft.Azure.Commands.DataFactoryV2.Models.PSTrigger] 99 | 100 | while ($stack.Count -gt 0) { 101 | $sortedList.Add($stack.Pop()) 102 | } 103 | $sortedList 104 | } 105 | 106 | function Get-SortedLinkedServices { 107 | param( 108 | [string] $DataFactoryName, 109 | [string] $ResourceGroupName 110 | ) 111 | $linkedServices = Get-AzDataFactoryV2LinkedService -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName 112 | $LinkedServiceHasDependencies = @('HDInsightLinkedService', 'HDInsightOnDemandLinkedService', 'AzureBatchLinkedService') 113 | $Akv = 'AzureKeyVaultLinkedService' 114 | $HighOrderList = New-Object Collections.Generic.List[Microsoft.Azure.Commands.DataFactoryV2.Models.PSLinkedService] 115 | $RegularList = New-Object Collections.Generic.List[Microsoft.Azure.Commands.DataFactoryV2.Models.PSLinkedService] 116 | $AkvList = New-Object Collections.Generic.List[Microsoft.Azure.Commands.DataFactoryV2.Models.PSLinkedService] 117 | 118 | $linkedServices | ForEach-Object { 119 | if ($_.Properties.GetType().Name -in $LinkedServiceHasDependencies) { 120 | $HighOrderList.Add($_) 121 | } 122 | elseif ($_.Properties.GetType().Name -eq $Akv) { 123 | $AkvList.Add($_) 124 | } 125 | else { 126 | $RegularList.Add($_) 127 | } 128 | } 129 | 130 | $SortedList = New-Object Collections.Generic.List[Microsoft.Azure.Commands.DataFactoryV2.Models.PSLinkedService]($HighOrderList.Count + $RegularList.Count + $AkvList.Count) 131 | $SortedList.AddRange($HighOrderList) 132 | $SortedList.AddRange($RegularList) 133 | $SortedList.AddRange($AkvList) 134 | $SortedList 135 | } 136 | 137 | $templateJson = Get-Content $armTemplate | ConvertFrom-Json 138 | $resources = $templateJson.resources 139 | 140 | #Triggers 141 | Write-Host "Getting triggers" 142 | $triggersInTemplate = $resources | Where-Object { $_.type -eq "Microsoft.DataFactory/factories/triggers" } 143 | $triggerNamesInTemplate = $triggersInTemplate | ForEach-Object {$_.name.Substring(37, $_.name.Length-40)} 144 | 145 | $triggersDeployed = Get-SortedTriggers -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName 146 | 147 | $triggersToStop = $triggersDeployed | Where-Object { $triggerNamesInTemplate -contains $_.Name } | ForEach-Object { 148 | New-Object PSObject -Property @{ 149 | Name = $_.Name 150 | TriggerType = $_.Properties.GetType().Name 151 | } 152 | } 153 | $triggersToDelete = $triggersDeployed | Where-Object { $triggerNamesInTemplate -notcontains $_.Name } | ForEach-Object { 154 | New-Object PSObject -Property @{ 155 | Name = $_.Name 156 | TriggerType = $_.Properties.GetType().Name 157 | } 158 | } 159 | $triggersToStart = $triggersInTemplate | Where-Object { $_.properties.runtimeState -eq "Started" -and ($_.properties.pipelines.Count -gt 0 -or $_.properties.pipeline.pipelineReference -ne $null)} | ForEach-Object { 160 | New-Object PSObject -Property @{ 161 | Name = $_.name.Substring(37, $_.name.Length-40) 162 | TriggerType = $_.Properties.type 163 | } 164 | } 165 | 166 | if ($predeployment -eq $true) { 167 | #Stop all triggers 168 | Write-Host "Stopping deployed triggers`n" 169 | $triggersToStop | ForEach-Object { 170 | if ($_.TriggerType -eq "BlobEventsTrigger" -or $_.TriggerType -eq "CustomEventsTrigger") { 171 | Write-Host "Unsubscribing" $_.Name "from events" 172 | $status = Remove-AzDataFactoryV2TriggerSubscription -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name 173 | while ($status.Status -ne "Disabled"){ 174 | Start-Sleep -s 15 175 | $status = Get-AzDataFactoryV2TriggerSubscriptionStatus -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name 176 | } 177 | } 178 | Write-Host "Stopping trigger" $_.Name 179 | Stop-AzDataFactoryV2Trigger -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name -Force 180 | } 181 | } 182 | else { 183 | #Deleted resources 184 | #pipelines 185 | Write-Host "Getting pipelines" 186 | $pipelinesADF = Get-SortedPipelines -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName 187 | $pipelinesTemplate = $resources | Where-Object { $_.type -eq "Microsoft.DataFactory/factories/pipelines" } 188 | $pipelinesNames = $pipelinesTemplate | ForEach-Object {$_.name.Substring(37, $_.name.Length-40)} 189 | $deletedpipelines = $pipelinesADF | Where-Object { $pipelinesNames -notcontains $_.Name } 190 | #dataflows 191 | $dataflowsADF = Get-AzDataFactoryV2DataFlow -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName 192 | $dataflowsTemplate = $resources | Where-Object { $_.type -eq "Microsoft.DataFactory/factories/dataflows" } 193 | $dataflowsNames = $dataflowsTemplate | ForEach-Object {$_.name.Substring(37, $_.name.Length-40) } 194 | $deleteddataflow = $dataflowsADF | Where-Object { $dataflowsNames -notcontains $_.Name } 195 | #datasets 196 | Write-Host "Getting datasets" 197 | $datasetsADF = Get-AzDataFactoryV2Dataset -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName 198 | $datasetsTemplate = $resources | Where-Object { $_.type -eq "Microsoft.DataFactory/factories/datasets" } 199 | $datasetsNames = $datasetsTemplate | ForEach-Object {$_.name.Substring(37, $_.name.Length-40) } 200 | $deleteddataset = $datasetsADF | Where-Object { $datasetsNames -notcontains $_.Name } 201 | #linkedservices 202 | Write-Host "Getting linked services" 203 | $linkedservicesADF = Get-SortedLinkedServices -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName 204 | $linkedservicesTemplate = $resources | Where-Object { $_.type -eq "Microsoft.DataFactory/factories/linkedservices" } 205 | $linkedservicesNames = $linkedservicesTemplate | ForEach-Object {$_.name.Substring(37, $_.name.Length-40)} 206 | $deletedlinkedservices = $linkedservicesADF | Where-Object { $linkedservicesNames -notcontains $_.Name } 207 | #Integrationruntimes 208 | Write-Host "Getting integration runtimes" 209 | $integrationruntimesADF = Get-AzDataFactoryV2IntegrationRuntime -DataFactoryName $DataFactoryName -ResourceGroupName $ResourceGroupName 210 | $integrationruntimesTemplate = $resources | Where-Object { $_.type -eq "Microsoft.DataFactory/factories/integrationruntimes" } 211 | $integrationruntimesNames = $integrationruntimesTemplate | ForEach-Object {$_.name.Substring(37, $_.name.Length-40)} 212 | $deletedintegrationruntimes = $integrationruntimesADF | Where-Object { $integrationruntimesNames -notcontains $_.Name } 213 | 214 | #Delete resources 215 | Write-Host "Deleting triggers" 216 | $triggersToDelete | ForEach-Object { 217 | Write-Host "Deleting trigger " $_.Name 218 | $trig = Get-AzDataFactoryV2Trigger -name $_.Name -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName 219 | if ($trig.RuntimeState -eq "Started") { 220 | if ($_.TriggerType -eq "BlobEventsTrigger" -or $_.TriggerType -eq "CustomEventsTrigger") { 221 | Write-Host "Unsubscribing trigger" $_.Name "from events" 222 | $status = Remove-AzDataFactoryV2TriggerSubscription -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name 223 | while ($status.Status -ne "Disabled"){ 224 | Start-Sleep -s 15 225 | $status = Get-AzDataFactoryV2TriggerSubscriptionStatus -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name 226 | } 227 | } 228 | Stop-AzDataFactoryV2Trigger -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name -Force 229 | } 230 | Remove-AzDataFactoryV2Trigger -Name $_.Name -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Force 231 | } 232 | Write-Host "Deleting pipelines" 233 | $deletedpipelines | ForEach-Object { 234 | Write-Host "Deleting pipeline " $_.Name 235 | Remove-AzDataFactoryV2Pipeline -Name $_.Name -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Force 236 | } 237 | Write-Host "Deleting dataflows" 238 | $deleteddataflow | ForEach-Object { 239 | Write-Host "Deleting dataflow " $_.Name 240 | Remove-AzDataFactoryV2DataFlow -Name $_.Name -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Force 241 | } 242 | Write-Host "Deleting datasets" 243 | $deleteddataset | ForEach-Object { 244 | Write-Host "Deleting dataset " $_.Name 245 | Remove-AzDataFactoryV2Dataset -Name $_.Name -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Force 246 | } 247 | Write-Host "Deleting linked services" 248 | $deletedlinkedservices | ForEach-Object { 249 | Write-Host "Deleting Linked Service " $_.Name 250 | Remove-AzDataFactoryV2LinkedService -Name $_.Name -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Force 251 | } 252 | Write-Host "Deleting integration runtimes" 253 | $deletedintegrationruntimes | ForEach-Object { 254 | Write-Host "Deleting integration runtime " $_.Name 255 | Remove-AzDataFactoryV2IntegrationRuntime -Name $_.Name -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Force 256 | } 257 | 258 | if ($deleteDeployment -eq $true) { 259 | Write-Host "Deleting ARM deployment ... under resource group: " $ResourceGroupName 260 | $deployments = Get-AzResourceGroupDeployment -ResourceGroupName $ResourceGroupName 261 | $deploymentsToConsider = $deployments | Where { $_.DeploymentName -like "ArmTemplate_master*" -or $_.DeploymentName -like "ArmTemplateForFactory*" } | Sort-Object -Property Timestamp -Descending 262 | $deploymentName = $deploymentsToConsider[0].DeploymentName 263 | 264 | Write-Host "Deployment to be deleted: " $deploymentName 265 | $deploymentOperations = Get-AzResourceGroupDeploymentOperation -DeploymentName $deploymentName -ResourceGroupName $ResourceGroupName 266 | $deploymentsToDelete = $deploymentOperations | Where { $_.properties.targetResource.id -like "*Microsoft.Resources/deployments*" } 267 | 268 | $deploymentsToDelete | ForEach-Object { 269 | Write-host "Deleting inner deployment: " $_.properties.targetResource.id 270 | Remove-AzResourceGroupDeployment -Id $_.properties.targetResource.id 271 | } 272 | Write-Host "Deleting deployment: " $deploymentName 273 | Remove-AzResourceGroupDeployment -ResourceGroupName $ResourceGroupName -Name $deploymentName 274 | } 275 | 276 | #Start active triggers - after cleanup efforts 277 | Write-Host "Starting active triggers" 278 | $triggersToStart | ForEach-Object { 279 | if ($_.TriggerType -eq "BlobEventsTrigger" -or $_.TriggerType -eq "CustomEventsTrigger") { 280 | Write-Host "Subscribing" $_.Name "to events" 281 | $status = Add-AzDataFactoryV2TriggerSubscription -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name 282 | while ($status.Status -ne "Enabled"){ 283 | Start-Sleep -s 15 284 | $status = Get-AzDataFactoryV2TriggerSubscriptionStatus -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name 285 | } 286 | } 287 | Write-Host "Starting trigger" $_.Name 288 | Start-AzDataFactoryV2Trigger -ResourceGroupName $ResourceGroupName -DataFactoryName $DataFactoryName -Name $_.Name -Force 289 | } 290 | } 291 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Azure Data Factory Deploy Action 2 | 3 | GitHub Action that performs a side-effect free deployment of Azure Data Factory entities in a Data Factory instance. 4 | 5 | ## How it works 6 | 7 | The GitHub Action uses [pre and post-deployment scripts](https://docs.microsoft.com/en-us/azure/data-factory/continuous-integration-deployment#script) to prevent the deployment from potential side effects, such as: 8 | 9 | * Execution of active triggers during the deployment process that could corrupt resources relationships or have pipelines in undesired states. 10 | * Availability of unused resources that could bring confusion to data engineers and reduce maintainability. 11 | 12 | ![Architecture Design](./images/architecture-design.png) 13 | 14 | It is designed to run the following steps sequentially: 15 | 16 | 1. A pre-deployment task checks for all active triggers and stop them. 17 | 2. An ARM template deployment task is executed. 18 | 3. A post-deployment task deletes all resources that have been removed from the ARM template (triggers, pipelines, dataflows, datasets, linked services, Integration Runtimes) and restarts the active triggers. 19 | 20 | ## When to use 21 | 22 | The action is useful on Continuous Deployment (CD) scenarios, where a step can be added in a workflow to deploy the Data Factory resources. 23 | 24 | ## Getting Started 25 | 26 | ### Prerequisites 27 | 28 | * A GitHub repository integrated with an existing Azure Data Factory. For more info, see [Source control in Azure Data Factory](https://docs.microsoft.com/en-us/azure/data-factory/source-control). 29 | * An Azure service principal with `Contributor` role added as a secret on your GitHub repository. For more info, see [Create a service principal and add it to GitHub secret](https://docs.microsoft.com/azure/developer/github/connect-from-azure#create-a-service-principal-and-add-it-to-github-secret). 30 | 31 | If your GitHub Actions workflows are running on a [self-hosted runner](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners), ensure you have installed: 32 | 33 | * [PowerShell 7.1](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell?view=powershell-7.1) with [Azure Az PowerShell module](https://docs.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-6.4.0) 34 | * [GitHub Actions Runner](https://github.com/actions/runner) `v2.280.3` or later. 35 | 36 | ### Example Usage 37 | 38 | ```yml 39 | steps: 40 | - name: Login via Az module 41 | uses: azure/login@v1 42 | with: 43 | creds: ${{ secrets.AZURE_CREDENTIALS }} 44 | enable-AzPSSession: true 45 | 46 | - name: Deploy resources 47 | uses: Azure/data-factory-deploy-action@v1.2.0 48 | with: 49 | resourceGroupName: myResourceGroup 50 | dataFactoryName: myDataFactory 51 | armTemplateFile: myArmTemplate.json 52 | # armTemplateParametersFile: myArmTemplateParameters.json [optional] 53 | # additionalParameters: 'key1=value key2=value keyN=value' [optional] 54 | # skipAzModuleInstallation: true [optional] 55 | ``` 56 | 57 | ### Inputs 58 | 59 | | Name | Description | Required | Default value | 60 | | --- | --- | --- | --- | 61 | | `resourceGroupName` | Data Factory resource group name | true | | 62 | | `dataFactoryName` | Data Factory name | true | | 63 | | `armTemplateFile` | Data Factory ARM template file | false | `ARMTemplateForFactory.json` | 64 | | `armTemplateParametersFile` | Data Factory ARM template parameters file | false | `ARMTemplateParametersForFactory.json` | 65 | | `additionalParameters` | Data Factory custom parameters. Key-values must be splitted by space. | false | 66 | | `skipAzModuleInstallation` | Skip `Az` powershell module installation. | false | false | 67 | 68 | ## Contributing 69 | 70 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 71 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 72 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 73 | 74 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 75 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 76 | provided by the bot. You will only need to do this once across all repos using our CLA. 77 | 78 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 79 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 80 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 81 | 82 | ## Trademarks 83 | 84 | This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft 85 | trademarks or logos is subject to and must follow 86 | [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). 87 | Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. 88 | Any use of third-party trademarks or logos are subject to those third-party's policies. 89 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). 40 | 41 | -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | ## How to file issues and get help 4 | 5 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing 6 | issues before filing new issues to avoid duplicates. For new issues, file your bug or 7 | feature request as a new Issue. 8 | 9 | For help and questions about using this project, please **REPO MAINTAINER: INSERT INSTRUCTIONS HERE 10 | FOR HOW TO ENGAGE REPO OWNERS OR COMMUNITY FOR HELP. COULD BE A STACK OVERFLOW TAG OR OTHER 11 | CHANNEL. WHERE WILL YOU HELP PEOPLE?**. 12 | 13 | ## Microsoft Support Policy 14 | 15 | Support for this **PROJECT or PRODUCT** is limited to the resources listed above. 16 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: data-factory-deploy 2 | description: Deploy Azure Data Factory resources 3 | 4 | inputs: 5 | resourceGroupName: 6 | description: 'Data Factory resource group name' 7 | required: true 8 | dataFactoryName: 9 | description: 'Data factory name' 10 | required: true 11 | armTemplateFile: 12 | description: 'ARM template file name' 13 | required: false 14 | default: 'ARMTemplateForFactory.json' 15 | armTemplateParametersFile: 16 | description: 'ARM template parameters file name' 17 | required: false 18 | default: 'ARMTemplateParametersForFactory.json' 19 | additionalParameters: 20 | description: 'Parameters which will be replaced in the ARM template' 21 | required: false 22 | default: '' 23 | skipAzModuleInstallation: 24 | description: 'Parameters which skip the Az module installation' 25 | required: false 26 | default: 'false' 27 | 28 | runs: 29 | using: 'composite' 30 | steps: 31 | - name: Install Az PowerShell module 32 | run: if('${{ inputs.skipAzModuleInstallation }}' -ne 'true') { Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force } 33 | shell: pwsh 34 | 35 | - name: Run Pre-deployment script 36 | run: | 37 | ${{ github.action_path }}/PrePostDeploymentScript.ps1 ` 38 | -armTemplate "${{ inputs.armTemplateFile }}" ` 39 | -ResourceGroupName "${{ inputs.resourceGroupName }}" ` 40 | -DataFactoryName "${{ inputs.dataFactoryName }}" ` 41 | -predeployment $true ` 42 | -deleteDeployment $false 43 | shell: pwsh 44 | 45 | - name: Run ARM deploy 46 | uses: azure/arm-deploy@v1 47 | with: 48 | resourceGroupName: ${{ inputs.resourceGroupName }} 49 | template: ${{ inputs.armTemplateFile }} 50 | parameters: ${{ inputs.armTemplateParametersFile }} factoryName=${{ inputs.dataFactoryName }} ${{ inputs.additionalParameters }} 51 | 52 | - name: Run Post-deployment script 53 | run: | 54 | ${{ github.action_path }}/PrePostDeploymentScript.ps1 ` 55 | -armTemplate "${{ inputs.armTemplateFile }}" ` 56 | -ResourceGroupName "${{ inputs.resourceGroupName }}" ` 57 | -DataFactoryName '${{ inputs.dataFactoryName }}' ` 58 | -predeployment $false ` 59 | -deleteDeployment $true 60 | shell: pwsh 61 | -------------------------------------------------------------------------------- /images/architecture-design.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Azure/data-factory-deploy-action/f4cc0700879395c7a021d8cc26272e2d4e56fba8/images/architecture-design.png --------------------------------------------------------------------------------