2

I have a set of databases that I am trying to work with in Azure Devops. I have a variable group that has various pieces of information for each database. The variables follow a convention of . CoreUserName, CoreIPAddress TestUserName, TestIPAddress FooUserName, FooIPAddress

The databases come into the template via parameterized array of strings that I am doing a foreach over. What I need is a way to resolve the value of the variables for the current item in the array.

Say the array is passed in like this:

dbPackages: ['Core','Test']

I need a way to take Core and append UserName (to CoreUserName) and then resolve the value of the CoreUserName variable.

I know that nested parameters "are not supported" but I am wondering if something like this can be accomplished with setting variables in a bash or powershell script? I just haven't figured out the proper syntax.

Ideas?

1 Answer 1

4

Here's two possible syntaxes. I'm assuming you're defining dbStages as a parameter and doing foreach loop in the pipeline....

As Environment Variables

All pipeline variables are available at runtime as environment variables, so it's possible to access them in several different ways programmatically. Here I'm passing Core/Test/Foo as an env value and then accessing it as an environment variable.

parameters:
- name: dbStages
  type: object
  default:
  - Core
  - Test
  - Foo

variables:
- group: myVariableGroup

steps:
- ${{ each dbPrefix in parameters.dbStages }}:
  - task:PowerShell@2
    inputs:
      targetType: inline
      script: |
        
        $prefix = $env:prefix
        $varUserName  = $prefix + "UserName"

        # access through $env
        $UserName = $env:$varUserName

        # access through Env: provider
        $UserName = Get-Item Env:$varUserName

        # access through .NET
        $UserName = [System.Environment]::GetEnvironmentVariable($varUserName)

      env:
        prefix: ${{ dbPrefix }}

You could go one step further, and de-reference CoreUserName to UserName by using the available Logging Commands. Subsequent tasks would be able to use the $(UserName) variable...


$UserName = $env:$( $prefix + "UserName" )
Write-Host "##vso[task.setvariable variable=UserName]$UserName"

Through Macro Syntax

The second option is to access the variables through the $() macro syntax. It's important to realize that parameters are resolved when the pipeline is compiled and variables are evaluated at runtime.

We can leverage compile time parameters to construct the macro syntax with the variable name you want to evaluate at runtime:

- ${{ each dbPrefix in parameters.dbStages }}:
  - task: PowerShell@2
    inputs:
      targetType: inline
      script: |
        
         # resolves into "$(CoreUserName)" at compile time
         # by is evaluated as "<value-of-CoreUserName>" at runtime
         $userName = "$(${{ dbPrefix }}UserName)"
         
Sign up to request clarification or add additional context in comments.

1 Comment

The macro syntax you provided ended up being the cleanest for me. "$(${{ dbPrefix }}UserName)" The env variable approaches did not seem to work as expected - probably my syntax.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.