当前位置:网站首页>Azure Data Factory(三)整合 Azure Devops 實現CI/CD
Azure Data Factory(三)整合 Azure Devops 實現CI/CD
2020-11-06 01:28:00 【itread01】
一,引言
由於上一節文章內容過長,無法分享Azure Data Factory 的持續整合,持續釋出。今天將著重介紹一下在使用 Azure DevOps Pipeline 釋出,自動進行持續整合,並且已自動化釋出,將Azure Data Factory 部署到多個環境中。
其實大家也不必驚訝,這裡的部署其實也沒有多麼神祕的,我們在ADF中的 master 分支釋出之後,其實會將ADF中所有的配置資訊打包,編譯到adf_master 分支下面,如果大家仔細看過釋出之後的程式碼,就很很容易發現,都是一些 ARM 模板資源。以當前我建立的demo為例
這是就有人在問了,什麼是ARM模板?這裡就先見到你的概規一下:
針對於Azure上一些基礎設施資源的部署,可以通過運用基礎架構即程式碼,可是實現部署自動化,在程式碼中定義需要部署的基礎架構資源。將這些基礎架構資原始碼變成專案的一部分,與應用程式程式碼一樣。通過程式碼管理工具,管理起來,方便部署,通過程式碼的方式建立、刪除資源。而ARM模板就是基礎架構即程式碼的一種形式(另外一種是 Terraform),該模板是一個定義專案基礎結構和配置的 JavaScript 物件表示法 (JSON) 檔案。 該模板使用宣告性語法,使你可以指明要部署的內容,而不需要編寫一系列程式設計命令來建立內容。 在該模板中,指定要部署的資源以及這些資源的屬性。
說人話,就是ARM模板中描述了我們需要部署的雲資源以及其資源所需要的引數,比如說通過使用ARM不是一臺VM,那麼ARM模板中就描述了VM資源以及其建立VM所需要的必要的引數。
回到ADF中,也就是說我們最終通過master分支釋出到 adf_master 分支的程式碼,其實就是一堆描述ADF資源以及ADF配置的屬性及引數。我們今天的內容也就是通過ARM去實現ADF的 UAT,PRO 環境的部署。
--------------------我是分割線--------------------
1,Azure Data Factory(一)入門簡介
2,Azure Data Factory(二)複製資料
3,Azure Data Factory(三)整合 Azure Devops 實現CI/CD
二,正文
1,建立ADF的 UAT 環境
我們通過資源名+UAT的方式來模擬測試環境,如下新建立了一個叫 "ADF-CnBateBlogWeb-UAT" 的 Azure Data Factory 和 兩個UAT 環境的 Blob Storage
”cnbateblogwebaccount1dev“ 作為UAT 環境的資料來源,我們也為UAT環境建立叫 “resformfolder” 的容器
“cnbateblogwebaccount2dev” 作為UAT 環境的目標源,我們也為UAT環境建立叫 “restofolder” 的容器
2,初始化部署前後指令碼
實際中,我們在部署ADF 甚至其他專案程式碼時,都是需要將AFD的觸發器停止,等到部署完成後,我們就得重啟ADF中配置的觸發器。微軟有幫助我們提供了部署前後可以使用的指令碼
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") { 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") { 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") { 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 }
我們將當前powershell 指令碼新增到程式碼中。檔案命名為 “adf_ci_cd.sh”
將,上面的指令碼檔案的內容貼進去,點選 “Commit”,並且提交儲存到 “master” 分支中
3,配置Azure DevOps Pipeline 環境
回到Azure DevOps 中,選擇 “Pipelines=》Releases”,點選 “New pipeline”
此時需要我們選擇模板,我們先點選 “Empty job” 建立一個空的 job
修改補助名稱為 “UAT”
接下來選擇新增 “artifact”,先新增一個afd_master 釋出產品源
Source Type 選擇:”Azure Repos Git“
Project 選擇:”CnBateBlogWeb_Proj“
Source(reposity)選擇:”CnBateBlogWeb_Proj“
Default branch:”adf_publish“
Source alias(源別名):”_CnBateBlogWeb_Proj_Publish“
點選 ”Add“ 進行新增操作。
再新增 “artifact”,先新增一個ADF的 ”master“ 分佈作為產品釋出源,大家注意裡面的引數
Default branch:”master“
Source alias:”_CnBateBlogWeb_Proj_Master“
點選 ”OK“ 進行新增操作。
最後,讓我們給 ”UAT“ stages 新增 task,點選圖中圈起來的部分
點選 ”+“,進行新增 ”Azure PowerShell“ Task,同時PowerShell 指令碼去停止目前所有正在執行的 Triggers
對於當前停止Trigger的 Task,有些需要我們留意的屬性配置
1,Display name 可以改為 ”Stop Triggers“(表面當前Task具體幹了什麼事)
2,選擇 ”UAT“ 環境所在的Azure 訂閱
3,Script Path(指令碼路徑)
4,Script Arguments(指令碼引數)
上面提到的指令碼檔案說明一下,就是我們剛剛在 ”master“ 分支提交的 adf_ci_cd.sh 這個檔案,我們可以進行選擇
部署前,需要停止所有Trigger,關於指令碼引數(停止Trigger)
-armTemplate "$(System.DefaultWorkingDirectory)/<your-arm-template-location>" -ResourceGroupName <your-resource-group-name> -DataFactoryName <your-data-factory-name> -predeployment $true -deleteDeployment $false
部署完成後,需要啟動所有Trigger,關於指令碼引數(啟動Trigger)
-armTemplate "$(System.DefaultWorkingDirectory)/<your-arm-template-location>" -ResourceGroupName <your-resource-group-name> -DataFactoryName <your-data-factory-name> -predeployment $false -deleteDeployment $true
大家將上面對應的的指令碼引數貼上自己的實際的UAT環境所在的資源組,資源名稱,以及模板所在路徑
以下是我當前的模板引數;大家可以作為參考:
-armTemplate "$(System.DefaultWorkingDirectory)/_CnBateBlogWeb_Proj_Publish/ADF-CnBateBlogWeb-Dev/ARMTemplateForFactory.json" -ResourceGroupName "Web_Test_DF_RG_UAT" -DataFactoryName "ADF-CnBateBlogWeb-AUT" -predeployment $true -deleteDeployment $false
接下來就是新增 ARM 模板部署了,搜尋 ”ARM template deployment“,找到 ARM 模板部署,點選 ”Add“ 進行新增
修改當前Task屬性
Display name:”ARM Template deployment:ADF Deploy“
Subscription 選擇:當前需要UAT環境所在的訂閱
Resource group 選擇:”Web_Test_DF_RG_UAT“(也就是當前UAT環境 ADF所在的資源組)
Loaction 選擇:”East Asia“
Template 以及 Template parameters 分別選擇 ”_CnBateBlog_Proj_Publish“ 下的 ”ARMTemplateForFactory.json“,"ARMTemplateParametersForFactory.json"
而 Override template parameters(替換模板引數)則指我們需要把模板引數檔案中的一些引數替換掉,如需要部署的ADF的名稱,資料來源、目標源的blob Storage 的連結字串
如下,我演示的覆蓋模板引數例項(大家需要將UAT環境的ADF 名稱換成自己建立命名的,以及兩個連結字元引數名稱需要在模板引數檔案中找到自己對應的名稱,連結字串複製貼上自己UAT環境的兩個Blob Storage的連結字串):
-factoryName "ADF-CnBateBlogWeb-AUT" -CnBateBlogFromBlobStorage_connectionString "DefaultEndpointsProtocol=https;AccountName=cnbateblogwebaccount1uat;AccountKey=XF7XkFsnEdIGZT8CCUJs7At1E/Ni9k/XJBtwWaKvwAuBnp3cCN6e2CYiV2uzsq2iI0vI2eZVHS8Kh9CvcuoNcg==;EndpointSuffix=core.windows.net" -CnBateBlobToBlobStorage_connectionString "DefaultEndpointsProtocol=https;AccountName=cnbateblogwebaccount2uat;AccountKey=E5z+q7XL7+8xTlqHsyaIGr0Eje/0DhT9+/E+oro4D57tsSuEchmnjLiK8zftTtyvQKLQUvTGJEsAOFCBGdioHw==;EndpointSuffix=core.windows.net"
最近就是新增重啟所有 Trigger 的 PowerShell 的 Task,具體引數如下圖
Script Path 選擇 :”_CnBateBlogWeb_Proj_Master“ 檔案下的 “adf_ci_cd.sh” 檔案
Script Path (需要清理資源、重啟所有Trigger的指令碼引數):
-armTemplate "$(System.DefaultWorkingDirectory)/<your-arm-template-location>" -ResourceGroupName <your-resource-group-name> -DataFactoryName <your-data-factory-name> -predeployment $false -deleteDeployment $true
大家將上面對應的的指令碼引數貼上自己的實際的UAT環境所在的資源組,資源名稱,以及模板所在路徑
以下是我當前的模板引數;大家可以作為參考:
-armTemplate "$(System.DefaultWorkingDirectory)/_CnBateBlogWeb_Proj_Publish/ADF-CnBateBlogWeb-Dev/ARMTemplateForFactory.json" -ResourceGroupName "Web_Test_DF_RG_UAT" -DataFactoryName "ADF-CnBateBlogWeb-AUT" -predeployment $true -deleteDeployment $true
修改當前pipeline 的名稱,點選 "Save” 進行儲存。
接下來,就是設定 pipeline 的觸發條件
開啟持續部署觸發,每次在所選儲存庫中發生Git推送時觸發pipeline,接下來新增分支篩選條件
Type:Include,Branch:“adf_master”,也就是說每當 “adf_publish” 發生git 推送的時候,觸發此 pipeline
設定完畢後,點選 “Save” 進行儲存
我們可以手動 “建立Release”,測試 pipeline 狀態顯示正常,成功
回到Azure UAT 環境中,我們可以發現 UAT 環境的ADF的 pipeline dataset 等也已經部署配置成功
4,測試ADF 自動化部署
我們回到ADF的 Dev 環境,我們嘗試在ADF Dev 環境建立一個的新的 “Feature Branch” 嘗試更改 pipeline 中複製資料的名稱
我們將上圖中的Copy Data 的名稱由 “Copy data1” 改為 “Copy data2”,並且進行儲存,驗證操作。
驗證沒有問題後,我們就可以將當前 “allen/Feature_1” 分支上的更改合併到 “master” 分支上
通過提交 “Create pull request”
接下來我就不再演示了,有什麼的不懂的,大家可以去看上一篇文章。等待合併完成後,我們回到Dev 環境的ADF 中就可以在 “master” 分支進行釋出了。當釋出完成後,就會將最新更改推送到 "adf_master" 分支上的 ARM 模板以及引數等。這個時候就會觸發之前設定好的Azure DevOps pipeline 了,就可以自動就這些更改自動部署到UA環境了。
三,結尾
今天的內容著重介紹了一下Azure Data Factory 與Azure Pipeline 的整合和自動化部署,但是同樣的也遺留了一個問題,就是在部署ARM 模板的時候,我們時直接將Blob Storage 的連結字串直接貼上到覆蓋模板引數一欄中,如果ADF 中新增很多資料來源的化,使用直接這種方式也是不合適的,這個問題怎麼解決,下一節我們繼續。**,°*:.*( ̄▽ ̄)/$:*.°** 。
作者:Allen
版權:轉載請在文章明顯位置註明作者及出處。如發現錯誤,歡迎批評指正。
版权声明
本文为[itread01]所创,转载请带上原文链接,感谢
https://www.itread01.com/content/1604511362.html
边栏推荐
猜你喜欢
随机推荐
看完这篇就看懂了很多webpack脚手架
TensorFlow2.0 问世,Pytorch还能否撼动老大哥地位?
刷了LeetCode的链表专题,我发现了一个秘密!
天天说要做性能优化,到底在优化什么?
PPT画成这样,述职答辩还能过吗?
对pandas 数据进行数据打乱并选取训练机与测试机集
mac 下常用快捷键,mac启动ftp
6.7 theme resolver theme style parser (in-depth analysis of SSM and project practice)
8.2.2 inject bean (interceptor and filter) into filter through delegatingfilterproxy
JVM Metaspace内存溢出排查与总结
面经手册 · 第14篇《volatile 怎么实现的内存可见?没有 volatile 一定不可见吗?》
How to select the evaluation index of classification model
Gradient understanding decline
PMP考试心得
JVM内存区域与垃圾回收
给萌新HTML5 入门指南(二)
Python machine learning algorithm: linear regression
用git2consul从Git同步配置到Consul
滴滴 Elasticsearch 集群跨版本升级与平台重构之路
【jmeter】實現介面關聯的兩種方式:正則表示式提取器和json提取器