1

I have a requirement to load the variables inside a variable group into an azure keyvault. We do not want to link the variable group to the keyvault in order to be able to close the keyvault external network access.

So I started developing a powershell script that lists the variable group variables using az cli devops extension and stores it into a powershell var.

Then I iterate for each var and try to build the var name in Azure Devops format $(var) so I can use it with Set-AzKeyVaultSecret.

The problem: It seems the variable name has to be hardcoded for the Azure Devops pipeline to be able to convert it to it's real value.

Example:

$pipelineVarEnc = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$('variablename')"))

Does not work:

        $Name = $var.Name
        $command = '$pipelineVarEnc = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$(' + $Name + ')"))'
        Invoke-command $command

Anyone knows how to bypass this issue?

  • 1
    Correct - the AzDO macro expansion happens _before_ the script is parsed and executed by the PowerShell runner - so you can't make AzDO dynamically resolve it in the middle of the script – Mathias R. Jessen Jun 28 '22 at 14:36
  • @MathiasR.Jessen that makes sense. However I have also stored the commands in a separate script and invoked the script from another Azure Devops task and had the same result. It cannot recognize the value of $Name so although I'm passing $(bananas) it complains about bananas not being a command. Is there any known way to populate a keyvault from a variablegroup using a pipeline without hardcoding variable names? – Jorge Rodrigues Jun 28 '22 at 14:46

1 Answers1

1

Refer to the following PowerShell script:

$token = "PAT"

$url="https://dev.azure.com/{ORG}/{PROJECT}/_apis/distributedtask/variablegroups/{VariableGroupID}?api-version=6.0-preview.2"

$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))

$response = Invoke-RestMethod -Uri $url -Headers @{Authorization = "Basic $token"} -Method Get  -ContentType application/json


ForEach ($variable in $response.variables)

{
  #echo $variable

  
  $variablenames =  $variable | Get-Member | Where {$_.MemberType -like 'NoteProperty'} | Select-Object  -Property name

  ForEach ($name in $variablenames.name)
  {
     $varaiblename = $name

     $variablevalue =  $variable.$name.value

     echo  $varaiblename
     echo  $variablevalue

     $Secret = ConvertTo-SecureString -String '$variablevalue' -AsPlainText -Force
     Set-AzKeyVaultSecret -VaultName 'xx' -Name '$varaiblename' -SecretValue $Secret

  }
     
}

In the PowerShell Script, it uses the Rest API: Variablegroups - Get to get all variables in the Variable Group.

We can modify the response format to get all variable names.

Finally, we can get the variable value based on the variable name.

In this case, we can iterate over all variable names and values without hardcoding.

Kevin Lu-MSFT
  • 20,786
  • 3
  • 19
  • 28