如何在Azure DevOps管道中配置环境变量?

11
我有一个配置为从JSON文件和环境变量读取应用程序设置的Azure函数(.NET Core):

我有一个配置为从JSON文件和环境变量读取应用程序设置的Azure函数(.NET Core):

var configurationBuilder = new ConfigurationBuilder()
                                .SetBasePath(_baseConfigurationPath)
                                .AddJsonFile("appsettings.json", optional: true)
                                .AddEnvironmentVariables()
                                .Build();

BuildAgentMonitorConfiguration configuration = configurationBuilder.Get<BuildAgentMonitorConfiguration>();

appsettings.json 的结构如下:

{
  "ProjectBaseUrl": "https://my-project.visualstudio.com/",
  "ProjectName": "my-project",
  "AzureDevOpsPac": ".....",
  "SubscriptionId": "...",
  "AgentPool": {
    "PoolId": 38,
    "PoolName": "MyPool",
    "MinimumAgentCount": 2,
    "MaximumAgentCount": 10
  },
  "ContainerRegistry": {
    "Username": "mycontainer",
    "LoginServer": "mycontainer.azurecr.io",
    "Password": "..."
  },
  "ActiveDirectory": {
    "ClientId": "...",
    "TenantId": "...",
    "ClientSecret": "..."
  }
}

其中一些设置已经在Azure Function中配置为环境变量。一切都按预期工作:

Azure函数应用程序设置

现在的问题是如何在构建管道中配置一些变量,这些变量将用于单元测试和集成测试。我尝试添加一个变量组,并将其链接到管道:

Azure DevOps任务组

但是环境变量没有被设置,测试失败了。我在这里漏掉了什么?


2
这些是保密值吗?如果是的话,我认为你需要将它们显式地映射到任务上。 - 4c74356b41
@4c74356b41 是的,这些是秘密。我不确定你所说的“明确地将它们映射到任务”是什么意思,请详细说明一下? - Rui Jarimba
1
请查看此答案:https://stackoverflow.com/questions/53962581/using-environment-variables-in-a-curl-request-on-azure-devops/53962774#53962774 第二个代码块展示了如何将秘密变量映射到给定任务的环境变量。 - 4c74356b41
谢谢@4c74356b41 - 如果我理解正确,这些秘密变量不是设置为环境变量,我需要使用bash或powershell来设置它们? - Rui Jarimba
@4c74356b41 很遗憾,我没有使用YAML,但还是谢谢你的时间 :-) - Rui Jarimba
显示剩余2条评论
4个回答

17
我也有同样的用例,在此我想通过Azure构建管道设置一些环境变量,以便测试用例可以访问该环境变量来使测试通过。直接使用EXPORT、ENV命令设置环境变量对于后续任务不起作用,因此要为后续任务设置环境变量,请按照https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch中提到的语法进行操作,即使用脚本标记设置task.set变量。
使用构建管道正确设置环境变量的方法。
- script: |
    echo '##vso[task.setvariable variable=LD_LIBRARY_PATH]$(Build.SourcesDirectory)/src/Projectname/bin/Release/netcoreapp2.0/x64'
  displayName: set environment variable for subsequent steps
请注意空格,因为这是yaml格式。上述脚本标签设置变量LD_LIBRARY_PATH(在Linux中用于定义.so文件路径)到所定义的目录。
这种设置环境变量的方式也适用于后续任务,但如果我们像下面提到的那样设置环境变量,则环境变量将针对特定的shell实例设置,并且不适用于后续任务。
错误的设置环境变量的方法:
- script: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(Build.SourcesDirectory)/src/CorrectionLoop.HttpApi/bin/Release/netcoreapp2.0/x64
  displayName: Set environment variable

您可以使用类似的语法来设置您的环境变量。


感谢分享。不幸的是,我没有使用yaml,但希望这对其他遇到同样问题的人有用。 - Rui Jarimba
@RuiJarimba 你可以将此标记为答案,这样对其他人来说很有帮助。似乎人们更喜欢这个答案。 - Shubhanshu Rastogi
我没有找到任何官方文件解释这个“##vso[task.setvariable variable”任务。只是好奇为什么微软没有记录这个。 - Jing He
顺便提一句,我刚刚发现这个语法##vso[task.setvariable variable=one]secondValue'是在流水线内部给变量赋值,而不是给shell的环境变量赋值。 - Jing He
@JingHe 这个语法是一个Azure DevOps日志命令。这些命令被脚本用来与构建代理通信。文档在这里:https://learn.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?view=azure-devops&tabs=bash - Furynation
显示剩余2条评论

2
我也遇到了从构建任务生成EF SQL脚本时的这个问题。根据文档,在“变量”选项卡中定义的变量也会作为环境变量提供给进程。

请注意,变量也可以通过环境变量传递给脚本。使用这些环境变量的语法取决于脚本语言。名称大写,用_代替.,并自动插入到进程环境中。

对于我的情况,我只需要加载连接字符串,但需要处理JSON文件和环境之间密钥大小写不同的情况:
var config = new ConfigurationBuilder()
              .AddJsonFile("appsettings.json", true, true)
              .AddEnvironmentVariables()
              .Build();

var connectionString = config["connectionString"] ?? config["CONNECTIONSTRING"];

谢谢分享,我迟早会试一试。 - Rui Jarimba
如果变量是机密的,则应手动导出。 - Ariel Moraes
@ArielMoraes,你可以举个例子吗? - Professor of programming

1
如果您正在使用bash,那么他们的示例不起作用,因为他们在文档中错误地引用了变量。相反,应该是:

存储秘密

#!/bin/bash
echo "##vso[task.setvariable variable=sauce]crushed tomatoes"
echo "##vso[task.setvariable variable=secret.Sauce;issecret=true]crushed tomatoes with garlic"

检索密码

错误:他们的示例

#!/bin/bash
echo "No problem reading $1 or $SAUCE"
echo "But I cannot read $SECRET_SAUCE"
echo "But I can read $2 (but the log is redacted so I do not spoil the secret)"

正确:

#!/bin/bash
echo "No problem reading $(sauce)"
echo "But I cannot read $(secret.Sauce)"

0

为FileTransform@1配置Variable Groups中的KeyVault Secrets

以下内容将读取Variable Group中使用的KeyVault Secrets,并将它们添加到环境变量中,以供FileTransform@1使用

设置KeyVaultenter image description here 创建Variable Group并导入要在Pipeline中使用的值。enter image description here

在此示例中,我们使用了:

    - ConnectionStrings--Context
    - Cloud--AuthSecret
    - Compumail--ApiPassword

设置名称以匹配 keyVault 名称:(您可以将它们传递到 yml 步骤模板中)

#这些参数是为了支持从 KeyVault 获取“机密”的库 > 变量组 > #KeyVault 密钥不能包含 "_" 或 "." 作为 FileTransform1@ 需要 #此脚本会将 "--" 键替换为 ".",并将其添加到 "env:" 变量中,以便 Transform 能够执行其操作。

parameters:
- name: apiSecretKeys
  displayName: apiSecretKeys
  type: object
  default:
    - ConnectionStrings--Context
    - Cloud--AuthSecret
    - Compumail--ApiPassword
stages:
   - template: ./locationOfTemplate.yml
     parameters:
       apiSecretKeys: ${{ parameters.apiSecretKeys }}

...构建API - 发布到.zip文件

在“作业级别”上设置变量组

variables:
  #next line here for pipeline validation purposes.. 
  - ${{if parameters.variableGroup}}:
      - group: ${{parameters.variableGroup}}
  #OR
  #- VariableGroupNameContinaingSecrets

模板文件:(魔法)

parameters:
  - name: apiSecretKeys
    displayName: apiSecretKeys
    type: object
    default: []
steps:
  - ${{if parameters.apiSecretKeys}}:
  - powershell: |
      $envs = Get-childItem env:
      $envs | Format-List
    displayName: List Env Vars Before
  - ${{ each key in parameters.apiSecretKeys }}:
      - powershell: |              
          $writeKey = "${{key}}".Replace('--','.')
          Write-Host "oldKey  :" ${{key}}
          Write-Host "value   :" "$(${{key}})"
          Write-Host "writeKey:" $writeKey              
          Write-Host "##vso[task.setvariable variable=$writeKey]$(${{key}})"
        displayName: Writing Dashes To LowDash for ${{key}}      
   - ${{ each key in parameters.apiSecretKeys }}:
       - powershell: |
           $readKey = "${{key}}".Replace('--','.')
           Write-Host "oldKey  :" ${{key}}
           Write-Host "oldValue:" "$(${{key}})"
           Write-Host "readKey :" $readKey
           Write-Host "newValue:" ('$env:'+"$($readKey)" | Invoke-Expression)
         displayName: Read From New Env Var for ${{key}}      
   - powershell: |
       $envs = Get-childItem env:
       $envs | Format-List
     name: List Env Vars After adding secrets to env
  1. 运行任务 - 任务: FileTransform@1

祝您愉快 ;)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接