zoukankan      html  css  js  c++  java
  • Azure Data Factory(三)集成 Azure Devops 实现CI/CD

    一,引言

      由于上一节文章内容过长,无法分享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

    4,Azure Data Factory(四)集成 Logic App 的邮件通知提醒

    5,Azure Data Factory(五)Blob Storage 密钥管理问题

    二,正文

    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 }
    adf_ci_cd.sh

    我们将当前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 

    版权:转载请在文章明显位置注明作者及出处。如发现错误,欢迎批评指正。

  • 相关阅读:
    nginx下配置WebSocket连接错误Error:Unexpected response code 404
    qqzone/tx云登录所用g_tk/x-csrfcode获取
    自动化工具Ansible的使用操作
    Docker可视化图形工具Portainer
    centos下.Netcore的docker容器部署出现“The type initializer for 'Gdip' threw an exception.”
    苹果开发者公司账号申请全流程以及出现的问题(2021更新)
    Certbot配置Let's Encrypt的https_ssl证书以及过程中出现的问题(2021更新)
    开源的一小步----开源类库传至Maven中央仓库
    使用微软的Office Online实现Office,word文档的在线浏览,编辑 ,以及不能正常查看文档问题
    Linux安装Mysql5.6
  • 原文地址:https://www.cnblogs.com/AllenMaster/p/13922858.html
Copyright © 2011-2022 走看看