如何将 Azure 管道变量传递给 AzureResourceManagerTemplateDeployment@3 任务使用的 ARM 模板?

Posted

技术标签:

【中文标题】如何将 Azure 管道变量传递给 AzureResourceManagerTemplateDeployment@3 任务使用的 ARM 模板?【英文标题】:How to pass an Azure pipeline variable to an ARM template used by AzureResourceManagerTemplateDeployment@3 task? 【发布时间】:2020-09-13 18:15:12 【问题描述】:

我正在尝试在每天晚上安排的 Azure 管道中执行以下 2 个步骤:

    将自签名证书放入密钥库 通过 ARM 模板部署 Service Fabric 集群并使用证书指纹和机密 ID 作为参数。

在密钥库中创建证书的第一步对我来说很有效:

# import the self-signed certificate ccg-self-signed-cert into the Keyvault
- task: AzurePowerShell@5
  inputs:
    azureSubscription: '$ parameters.ArmConnection '
    ScriptType: 'InlineScript'
    azurePowerShellVersion: '3.1.0'
    Inline: |
      $Pwd = ConvertTo-SecureString -String 'MyPassword' -Force -AsPlainText
      $Base64 = 'MIIKqQ____3000_CHARS_HERE______1ICAgfQ=='
      $Cert = Import-AzKeyVaultCertificate -VaultName $(KeyVaultName) -Name my-self-signed-cert -CertificateString $Base64 -Password $Pwd
      echo "##vso[task.setvariable variable=Thumbprint;isOutput=true]$Cert.Thumbprint"

我想我通过echo 行设置了管道变量(不太确定,如何验证...)

但是如何在下一个管道任务中将保存证书指纹值的管道变量传递给 ARM 模板?

# deploy SF cluster by ARM template and use the SF Cluster certificate thumbsprint as admin cert
- task: AzureResourceManagerTemplateDeployment@3
  inputs:
    deploymentScope: 'Resource Group'
    azureResourceManagerConnection: '$ parameters.ArmConnection '
    subscriptionId: 'XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'
    action: 'Create Or Update Resource Group'
    resourceGroupName: '$ parameters.resourceGroupName '
    location: 'West Europe'
    templateLocation: 'Linked artifact'
    csmFile: '$(Build.SourcesDirectory)/pipelines/templates/sfcluster.json'
    csmParametersFile: '$(Build.SourcesDirectory)/pipelines/templates/sfcluster-params.json'
    deploymentMode: 'Incremental'

我正在使用azure-quickstart-template 创建一个 SF 集群。

如果您查看它,它需要证书指纹作为参数:

"certificateThumbprint": 
  "type": "string",
  "metadata": 
    "description": "Certificate Thumbprint"
  
,

"certificateUrlValue": 
  "type": "string",
  "metadata": 
    "description": "Refers to the location URL in your key vault where the certificate was uploaded, it is should be in the format of https://<name of the vault>.vault.azure.net:443/secrets/<exact location>"
  
,

如何将 AzurePowerShell@5 任务中的值传递给后续 AzureResourceManagerTemplateDeployment@3 任务使用的 ARM 模板?

更新:

我已尝试遵循 Nilay 的建议,并将 3 个变量放入我的 sfcluster.json ARM 模板中:


    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": 
        "clusterName": 
            "type": "string",
            "defaultValue": "ccg-sfcluster",
            "minLength": 5,
            "metadata": 
                "description": "Name of the SF cluster"
            
        ,
        "certificateThumbprint": 
            "type": "string",
            "defaultValue": "[$env:THUMBPRINT]",
            "metadata": 
                "description": "Certificate Thumbprint"
            
        ,
        "sourceVaultResourceId": 
            "type": "string",
            "defaultValue": "[$env:KEYVAULTID]",
            "metadata": 
                "description": "Resource Id of the key vault, is should be in the format of /subscriptions/<Sub ID>/resourceGroups/<Resource group name>/providers/Microsoft.KeyVault/vaults/<vault name>"
            
        ,
        "certificateUrlValue": 
            "type": "string",
            "defaultValue": "[$env:SECRETID]",
            "metadata": 
                "description": "Refers to the location URL in your key vault where the certificate was uploaded, it is should be in the format of https://<name of the vault>.vault.azure.net:443/secrets/<exact location>"
            
        
    ,
    "variables": 

但是我得到了语法错误:

2020-05-27T12:31:54.1327314Z There were errors in your deployment. Error code: InvalidTemplate.
2020-05-27T12:31:54.1354742Z ##[error]Deployment template language expression evaluation failed: 'The language expression '$env:THUMBPRINT' is not valid: the string character ':' at position '4' is not expected.'. Please see https://aka.ms/arm-template-expressions for usage details.
2020-05-27T12:31:54.1361090Z ##[debug]Processed: ##vso[task.issue type=error;]Deployment template language expression evaluation failed: 'The language expression '$env:THUMBPRINT' is not valid: the string character ':' at position '4' is not expected.'. Please see https://aka.ms/arm-template-expressions for usage details.

如果我在

中省略方括号,也会出现类似的错误
"defaultValue": "$env:THUMBPRINT",

【问题讨论】:

嗨@Alexander Farber,Nilay 下面的回答是否有助于解决您的问题?检查this rule,如果有帮助,您可以考虑接受它作为答案。这只是一个提醒:) 【参考方案1】:

您需要在部署任务上设置覆盖参数。删除您添加到模板中的所有默认值。你的任务 yaml 看起来像:

- task: AzureResourceManagerTemplateDeployment@3
  inputs:
    deploymentScope: 'Resource Group'
    action: 'Create Or Update Resource Group'
    overrideParameters: '-certificateThumbprint $(Thumbprint) -sourceVaultResourceId $(vaultId) -certificateUrlValue $(certUrl)'

$(paren) 语法是您在任务定义中引用变量的方式 - 所以将它们更改为您命名变量的任何名称。

【讨论】:

谢谢布赖恩。我今天终于设法让我的管道正常工作 - 通过调用 replacetokens@3 任务(请参阅我自己的答案),但你的建议看起来更好。【参考方案2】:

您可以通过在其后执行另一个 PowerShell 步骤并执行 Write-Host 来验证您的变量 Thumbprint 是否具有该值。

Write-Host $env:THUMBPRINT

您可以使用 $env:THUMBPRINT 引用您在 ARM 模板参数中创建的变量

这是一个参考链接:https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch

【讨论】:

谢谢 Nilay,但是当我在我的 ARM 模板中尝试 ` "defaultValue": "[$env:THUMBPRINT]",` 或 "defaultValue": "$env:THUMBPRINT", 时出现语法错误(请参阅我的更新问题)。 @AlexanderFarber bmoore-msft 的建议是正确的做事方式。不要为此使用替换令牌。使用覆盖参数。是的,您可以使用 $(param) 来引用变量。【参考方案3】:

以下是对我有用的方法,但 Brian 建议使用 overrideParameters 效果更好,因此我将其设置为可接受的答案。

首先是我使用了错误的格式来设置变量。

对于正确的字符串外推,我必须使用两次 $ 字符(如在 $($Cert.Thumbprint) 中),我真的不需要 ;isOutput=true,因为它是一个单一的工作:

# import the self-signed certificate ccg-self-signed-cert into the Keyvault
- task: AzurePowerShell@5
  inputs:
    azureSubscription: '$ parameters.ArmConnection '
    ScriptType: 'InlineScript'
    azurePowerShellVersion: '3.1.0'
    Inline: |
      $Pwd = ConvertTo-SecureString -String 'MyPassword' -Force -AsPlainText
      $Base64 = 'MIIKqQ____3000_CHARS_HERE______1ICAgfQ=='
      $Cert = Import-AzKeyVaultCertificate -VaultName $(KeyVaultName) -Name my-self-signed-cert -CertificateString $Base64 -Password $Pwd
      echo "##vso[task.setvariable variable=Thumbprint]$($Cert.Thumbprint)"
      echo "##vso[task.setvariable variable=SecretId]$($Cert.SecretId)"

然后我添加了一个任务来替换我需要的 3 个值:

# replace Thumbprint, SecretId and KeyvaultId in the sfcluster-params.json file
- task: replacetokens@3
  displayName: 'Replace tokens in sfcluster-params.json'
  inputs:
    rootDirectory: '$(Build.SourcesDirectory)/pipelines/templates/'
    targetFiles: '$(Build.SourcesDirectory)/pipelines/templates/sfcluster-params.json'
    encoding: 'auto'
    writeBOM: true
    actionOnMissing: 'fail'
    keepToken: false
    tokenPrefix: '$('
    tokenSuffix: ')'

虽然我的整个 sfcluster-params.json 文件如下(KEYVAULTID 来自 keyvault ARM 部署):


    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": 
        "clusterName": 
            "value": "my-sfcluster"
        ,
        "certificateThumbprint": 
            "value": "$(THUMBPRINT)"
        ,
        "sourceVaultResourceId": 
            "value": "$(KEYVAULTID)"
        ,
        "certificateUrlValue": 
            "value": "$(SECRETID)"
        
    

最后我已经部署了 SF 集群:

# deploy SF cluster by ARM template and use the SF Cluster certificate thumbsprint as admin cert
- task: AzureResourceManagerTemplateDeployment@3
  inputs:
    deploymentScope: 'Resource Group'
    azureResourceManagerConnection: '$ parameters.ArmConnection '
    subscriptionId: 'XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX'
    action: 'Create Or Update Resource Group'
    resourceGroupName: '$ parameters.resourceGroupName '
    location: 'West Europe'
    templateLocation: 'Linked artifact'
    csmFile: '$(Build.SourcesDirectory)/pipelines/templates/sfcluster.json'
    csmParametersFile: '$(Build.SourcesDirectory)/pipelines/templates/sfcluster-params.json'
    deploymentMode: 'Incremental'

【讨论】:

以上是关于如何将 Azure 管道变量传递给 AzureResourceManagerTemplateDeployment@3 任务使用的 ARM 模板?的主要内容,如果未能解决你的问题,请参考以下文章

如何将Azure管道变量传递给AzureResourceManagerTemplateDeployment @ 3任务使用的ARM模板?

无法将环境变量传递给 azure 管道 yaml 中的 powershell 脚本(非内联)

如何使用 azure 数据工厂下载 blob

如何在数据工厂管道中将路由传递给 Azure 函数(C#)http 触发器?

在 azure 中的发布管道之间传递变量(触发 azure 管道扩展)

azure管道:访问机密变量