如何将ARM模板任务输出的SecureString变量传递给同作业的第二个ARM模板任务
解决ARM模板输出SecureString在后续任务中作为SecureString参数为空的问题
问题场景
我在测试Azure DevOps中带有SecureString输出和输入的ARM模板部署流程:
- 第一个任务部署CosmosDB,输出SecureString类型的连接字符串,任务配置如下:
- task: AzureResourceManagerTemplateDeployment@3 displayName: "Create CosmosDB" inputs: deploymentScope: 'Resource Group' azureResourceManagerConnection: ${{ parameters['ServiceConnection']}} subscriptionId: $(SubscriptionID) action: 'Create Or Update Resource Group' resourceGroupName: '$(ResourceGroup)' location: 'West Europe' templateLocation: 'Linked artifact' csmFile: '$(Pipeline.Workspace)/drop/armtemplates/cosmosdb_deployment.json' csmParametersFile: '$(Pipeline.Workspace)/drop/armtemplates/cosmosdb_parameters.json' deploymentMode: 'Incremental' deploymentOutputs: 'ArmOutputsCMDB' overrideParameters: '-SubscriptionName $(subname) -VersionToDeploy $(VersionToDeploy) -CosmosResourceName $(CosmosResourceName) -DatabaseID $(DatabaseID) -ContainerID $(ContainerID) -PartitionKey $(PartitionKey) -CosmosDBmaxThroughput $(CosmosDBmaxThroughput)' continueOnError: false
- 尝试在第二个任务中,将该输出作为
SecureString类型的参数-CosmosDbConnectionString $(ArmOutputsCMDBPrimaryConnectionStringCosmos)传入,但值为空。 - 我用PowerShell脚本将输出转换为标记为
issecret=true的变量,依然无效:
- task: PowerShell@2 displayName: "Create variables from Cosmos output" inputs: targetType: 'inline' script: | $outputs = ConvertFrom-Json $($env:ArmOutputsCMDB) foreach ($output in $outputs.PSObject.Properties) { Write-Host "##vso[task.setvariable variable=$($output.Name);issecret=true]$($output.Value.value)" } continueOnError: false
注意:当第二个任务的参数类型设为string时变量有值,改为securestring就为空;而直接使用Azure DevOps库中的秘钥作为SecureString参数传递给ARM模板是正常的。
问题原因
ARM模板部署任务输出的SecureString会被Azure DevOps自动标记为敏感数据,直接通过环境变量传递时,SecureString类型的输出受安全机制限制无法解析出实际值,导致后续任务读取为空。
解决步骤
1. 确认ARM模板输出定义正确
在cosmosdb_deployment.json的outputs部分,确保输出类型为SecureString且正确引用CosmosDB连接字符串:
"outputs": { "PrimaryConnectionStringCosmos": { "type": "SecureString", "value": "[listConnectionStrings(resourceId('Microsoft.DocumentDB/databaseAccounts', parameters('CosmosResourceName')), '2023-04-15').connectionStrings[0].connectionString]" } }
2. 修正PowerShell脚本的变量标记
需要同时添加isoutput=true标记让变量跨任务传递,且确保Write-Host命令为单行(换行会导致命令失效):
- task: PowerShell@2 displayName: "Create variables from Cosmos output" inputs: targetType: 'inline' script: | $outputs = ConvertFrom-Json $env:ArmOutputsCMDB foreach ($output in $outputs.PSObject.Properties) { Write-Host "##vso[task.setvariable variable=$($output.Name);issecret=true;isoutput=true]$($output.Value.value)" } continueOnError: false
3. 用任务引用方式传递变量到第二个任务
不能直接用$(变量名)引用secret变量,需通过任务输出的方式获取。假设第二个任务是ARM部署任务,配置如下:
- task: AzureResourceManagerTemplateDeployment@3 displayName: "后续部署任务" inputs: # 其他必要配置(如连接信息、模板路径等) overrideParameters: '-CosmosDbConnectionString ${{ dependencies['Create CosmosDB'].outputs['PrimaryConnectionStringCosmos'] }}' dependsOn: Create CosmosDB
注意:必须添加dependsOn指定第一个任务名称,确保任务执行顺序正确。
4. 验证第二个任务的ARM模板参数类型
确保第二个任务使用的ARM模板中,CosmosDbConnectionString参数类型为SecureString:
"parameters": { "CosmosDbConnectionString": { "type": "SecureString", "metadata": { "description": "CosmosDB连接字符串" } } }
额外说明
- 标记为
issecret=true的变量不会在日志中显示,也不能通过Write-Host输出验证,只能通过实际传递到ARM模板中测试生效情况。 - 如果第二个任务是其他类型(如PowerShell),需用
$(任务名称.变量名)的方式引用,但同样无法在日志中打印该变量值。
内容的提问来源于stack exchange,提问作者Sergio
相关产品推荐
相关产品推荐

