5

I'm trying to use the lower() function in a YAML template, but do not understand the behavior. I've a variable group named Infra.Environment.ShortName with the value "Dev". In my YAML template, I've defined a variable from a variable group:

  variables:
  - name: environmentShortName
    value: $(Infra.Environment.ShortName)

In a task, I refer to this variable:

- task: AzureResourceGroupDeployment@2
  displayName: 'Deploy Storage Account'
  inputs:
    azureSubscription: ${{ parameters.subscription }}
    resourceGroupName: mst-${{ lower(variables.environmentShortName) }}-infra
    location: '$(Infra.Environment.Region.Primary)'
    csmFile: '$(Pipeline.Workspace)/$(Build.DefinitionName)/Resources/infra-storageAccount.json'
    csmParametersFile: '$(Pipeline.Workspace)/$(Build.DefinitionName)/Resources/infra-storageAccount.parameters.json'
    deploymentOutputs: ArmOutputs

I've experimented with different expressions, but do not understand why I cannot convert the variable group value to lowercase:

resourceGroupName: mst-${{ lower(variables.environmentShortName) }}-infra

=> mst-Dev-infra (lower does not seem to work)

resourceGroupName: ${{ format('mst-{0}-infra', lower(variables.environmentShortName)) }}

=> mst-Dev-infra (format works, but lower does not)

resourceGroupName: $[format('mst-{0}-infra', lower(variables.environmentShortName))]

=> $[format('mst-{0}-infra', lower(variables.environmentShortName))] (expression not evaluated)

resourceGroupName: mst-${{ lower(variables['Infra.Environment.ShortName']) }}-infra

=> mst--infra (empty value)

resourceGroupName: mst-${{ lower('Dev') }}-infra

=> mst-dev-infra (lower works with a constant value)

user14098243
  • 131
  • 1
  • 4

2 Answers2

5

The solution was to use runtime variables as the variable group is not resolved at compile time. Runtime expressions have some limitations, but the following works:

  - name: environmentShortName
    value: $[lower(variables['Infra.Environment.ShortName'])]

    resourceGroupName: mst-$(environmentShortName)-infra
user14098243
  • 131
  • 1
  • 4
3

Following snippet will work correctly and write "mst-test-infra" as the output:

variables:
  environmentShortName: TEST

steps:
- powershell: Write-Host "${{ format('mst-{0}-infra', lower(variables.environmentShortName)) }}"

This is because the variable set to literal value and the value is known on a compile time.

If the value of the environmentShortName is dependant on another variable, like:

environmentShortName: $(System.TeamProject)

The lower() will not work correctly and behaves just like you described. There is (my) logical explanation: the expression ${{ variables.environmentShortName}} is resolves at compile time and perhaps your variable value is not ready yet to be resolved.

To deal with a such behaviour, consider to change a location where lower() is applied and move it to a variable declaration part:

variables:
  environmentShortName: ${{ lower(variables['System.TeamProject'] ) }}

steps:
- powershell: Write-Host "mst-$(environmentShortName)-infra"
Alexander Volok
  • 5,630
  • 3
  • 17
  • 33
  • 1
    Thanks Alexander, does not work in my case as the variable comes from a variable group and is not a predefined variable. But your suggestions helped me finding the solution. – user14098243 Aug 31 '20 at 14:23
  • 2
    Nice, perhaps makes sense to publish your findings as the answer, so someone else with a similar circumstances will re-use your fix. – Alexander Volok Aug 31 '20 at 14:28