如何在Azure DevOps管道中添加环境变量

11

我正在为使用Jest测试API和集成的Node应用程序设置Azure管道。源代码位于Azure DevOps上,代码部署在Azure Portal中。当我运行测试时,由于远程存储库从未检查.env文件,所以管道失败了。尽管环境变量在Azure Portal中通过配置存活在运行时中,但管道实际上无法访问它。

有哪些方法可以访问或创建新位置来存储环境变量,以便我的测试可以在虚拟机中运行?

目前我的解决方案(我不知道是否正确)是创建一个变量组,并重新定义所有环境变量,使得管道也可以读取这些变量,如下面的描述:https://damienaicheh.github.io/azure/devops/2019/09/04/how-to-use-variables-inside-your-azure-devops-builds-en.html

我的问题是:

  1. 这个方法正确吗?这里存储的变量与构建无关,也不是运行命令的输入,而是需要在源代码中使用的所有环境变量,以便在虚拟机中进行测试(例如:base_url、apiKeys等)。
  2. 如果这个方法正确,我怎样才能避免在管道中重新编写和重新分配所有的值呢?我可以引用整个变量组,让源代码能够解释吗?我希望避免像这样。
- env
  - API_KEY: $(apiKey)
  - MAPS_KEY: $(mapsKey)  
  - CLIENT_KEY: $(clientKey)  
  - CLIENT_SECRET: $(clientSecret)
  - 
  -
  - and so on... 


// looking for something like this
   -env: myVariableGroup

任何指向更好解决方案的帖子或文章?我考虑使用密钥保管库,但我认为这与逐个导入密钥本质相同。
1个回答

15
管道变量会自动映射到环境变量,所以不需要额外的工作。唯一的例外是密码变量,您必须显式地进行映射。

管道变量会自动映射到环境变量,所以不需要额外的工作。唯一的例外是密码变量,您必须显式地进行映射。

steps:
- script: echo $MYSECRET
  env:
    MYSECRET: $(Foo)

因此,声明、组或模板中的所有值都映射到环境变量

vars.yaml

variables:
  variableFromTemplate: 'valueFromTemplate'

build.yaml

variables:
  - group: PROD
  - name: variableFromDeclaration
    value: 'valueFromDeclaration'
  - template: vars.yaml  

pool:
  vmImage: 'ubuntu-latest'

steps:
- script: env | sort
- script: | 
    echo $VARIABLEFROMDECLARATION
    echo $VARIABLEFROMGROUP
    echo $VARIABLEFROMTEMPLATE
- pwsh: |
    
    $url = "https://dev.azure.com/thecodemanual/$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)?api-version=5.1"
    $build = Invoke-RestMethod -Uri $url -Headers @{Authorization = "Bearer $env:MY_SECRET"}
    Write-Host "Pipeline = $($build | ConvertTo-Json -Depth 100)"

    $status = $build.status
    Write-Host $status
  name: initial
  env: 
    MY_SECRET: $(System.AccessToken)

enter image description here

enter image description here

每个步骤都需要在env部分中定义secrets。作为解决方法,您可以尝试使用容器任务并在容器级别上定义env映射。

resources:
  containers:
  - container: string  # identifier (A-Z, a-z, 0-9, and underscore)
    image: string  # container image name
    options: string  # arguments to pass to container at startup
    endpoint: string  # reference to a service connection for the private registry
    env: { string: string }  # list of environment variables to add
    ports: [ string ] # ports to expose on the container
    volumes: [ string ] # volumes to mount on the container
    mapDockerSocket: bool # whether to map in the Docker daemon socket; defaults to true
    mountReadOnly:  # volumes to mount read-only - all default to false
      externals: boolean  # components required to talk to the agent
      tasks: boolean  # tasks required by the job
      tools: boolean  # installable tools like Python and Ruby
      work: boolean # the work directory

谢谢!看起来很有道理,我可以访问变量但无法访问密码。即使我明确定义了密码,在任务中也无法访问,因此它会打印为*****。https://github.com/microsoft/azure-pipelines-agent/issues/145 - Marvin
1
预期输出 ***。Azure DevOps 不允许您将秘密信息放入日志中。虽然有一种方法可以欺骗系统,但您不应该这样做。我扩展了我的示例以向您展示如何映射秘密信息。我添加了一个示例,您可以根据自己的组织和项目进行一些更改并运行它来查看效果。 - Krzysztof Madej
如果不使用Docker容器,那么从库到应用程序级别访问秘密变量的其他可能方式是不存在的吗?我也尝试过设置task.setvariables,但似乎只有在构建范围内才能访问这些变量。 - Marvin
它们是通过环境变量传递的,因此需要显式地进行映射。但你知道它们是环境变量,当你读取它们时,它们不会在代码中被替换。所以,当你将你的包带到其他环境中运行时,你需要在那里设置环境变量。@Marvin,我的回答有帮助你解决问题吗? - Krzysztof Madej

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