How to unpack or fetch a value of a nested variable stored in Azure DevOps Build Piplines' Variables group? - azure

Is it possible to use variable inside a variable in Powershell script with Azure Pipelines variables?
SCENARIO
Two variables are set in Azure Pipelines Variable group - DeploymentCredentials
a. DeployUATApiPassword = "123456"
b. DeployPRODApiPassword = "789654"
Another variable is set in the Variables section of the pipeline as DeploymentEnvironment
At runtime, the value of the DeploymentEnvironment variable is set as either UAT or PROD
Based on the enviornment, I want to fetch the password which is stored as a variable, defined in the variables group. At runtime, it should work something like...
# setting the value of the variable to UAT
Write-Host "##vso[task.setvariable variable=DeploymentEnvironment]UAT"
Now DevelopmentEnvironment variable has the value UAT, In another step, I want to fetch the Password for the UAT deployment environment, which is only known at runtime.
# I want to get the Password
# The following works! but not useful for me, UAT is hard-coded!!
$deployPwd = $(DeployUATApiPassword) # works! but not useful for me, UAT is hard-coded!!
# I want to get the Password
# the following doesn't work, I only know the environment at runtime
# Replaces the inner variable to `DeployUATApiPassword`
# Raises an error, DeployUATApiPassword : The term 'DeployUATApiPassword' is not recognized as the name of a cmdlet...
$deployPwd = $(Deploy$(DeploymentEnvironment)ApiPassword)
# All the following didn't work either, but no error...
Write-Host $('Deploy$(DeploymentEnvironment)ApiPassword') # Output: DeployUATApiPassword
Write-Host $($("Deploy$(DeploymentEnvironment)ApiPassword")) # Output: DeployUATApiPassword
Write-Host { 'Deploy$(DeploymentEnvironment)ApiPassword' } # Output: 'DeployUATApiPassword'
Write-Host { Deploy$(DeploymentEnvironment)ApiPassword } # Output: DeployUATApiPassword
Write-Host { $(Deploy$(DeploymentEnvironment)ApiPassword) } # Output: $(DeployUATApiPassword)
Similarly, I tried to fetch the pwd in several ways, nothing worked.
For instance, one of the ways was to create another variable DeployApiPassword and I did set the value of the variable to Deploy$(DeploymentEnvironment)ApiPassword. No luck in this either...
$deployPwd = $(DeployApiPassword) # Output: DeployUATApiPassword
DESIRED OUTPUT
I want to fetch the password from one of the variables which is set in a variables group. The password variable name contains the deployment environment. Deployment environment is only set at runtime.
# I know something is wrong with the following, but that's how I want to run.
$deployPwd = $(Deploy$(DeploymentEnvironment)ApiPassword)
Write-Host $deployPwd # output: *** (of course, the pwd is hidden, but at least it fetches)

Variables set in Azure Pipelines Variable group would be used as environment variables in PowerShell task. So, basically, you need to get the value as :
$environment = $env:DeploymentEnvironment
$deployPwd = $env:DeployUATApiPassword
At the same time, as your want to dynamically get the password based on the environment, you may try the following:
$environment= $env:DeploymentEnvironment
Write-Host "Deployment Environment is " $environment
$realName = $("Deploy${environment}ApiPassword")
$pwd = [Environment]::GetEnvironmentVariable($realName)
#I used UAT password, check it here
Write-Host $pwd.Equals("123456")
Output:

I noticed that the value returned by 'Deploy$(DeploymentEnvironment)ApiPassword' is a string type, however $() accepts a variable not a string.
In the secret variables official document, it says the secret cannot be referenced directly like normal variable. You have to manually explicitly map them in using the Environment section.
You will need to use if statement. And in the Environment Variables sections
Map the secret variables to variables UATpassword and PRODpassword and Then refer to them in the scripts using $env:UATpassword
From below log, we can see the password is retrieved in the script.

Related

Assign Azure Powershell variable to DevOps Pipeline variable

How can I assigned the $NewIP variable precalculated in this step to a DevOps pipeline variable called $pipeline_ip?
You should use logging command if you want to assign powershell variable to Azure DevOps variable
echo "##vso[task.setvariable variable=pipeline_ip;]$NewIP"
Update after clarification:
If you use syntax like:
$NewIP = $(pipeline_ip)
Then $(pipeline_ip) would be replaced with the value before script will be executed.
And if you use syntax like
$NewIP = $env:PIPELINE_IP
then you will refer to environment variable and since all DevOps variables are mapped (except secret variables - here you need to express this excplicitly) it would also work.
However, these are two ways of doing that.
You can use two methods:
$NewIP = $(pipeline_ip) Macro syntax variables
$NewIP = $env:PIPELINE_IP Set variables in pipeline

How to set an environment variable with PowerShell in Azure Devops release pipeline?

I have a function which will return a result. I am setting that result as an environment value in a pipeline. When I am invoking environment variable it's not printing the next two lines.
Write-Host "Before env : $result"
write-host "##vso[task.setvariable variable=message]$result"
[![enter code here][1]][1]
In other stage I invoked message other variable but it's not printing the next two lines.
write-host "After env : $(message)"
[![enter code here][2]][2]
My only challenge was not getting the last two lines which is ASDB_REPORT / ASDB_REPORT_TEST
If you set an environment variable with PowerShell in release pipeline, please refer to this doc: Set variables in scripts.
$result = 'crushed tomatoes'
Write-Host "##vso[task.setvariable variable=sauce]$result"
# Write-Host "sauce: $(sauce)"
Please note that "Subsequent steps will also have the pipeline variable added to their environment. You cannot use the variable in the step that it is defined." Thus you could access to the new variable with macro syntax and in tasks as environment variables.
Write-Host "sauce: $(sauce)"
Write-Host "my environment variable is $env:SAUCE"
However, you can't pass a variable from one job to another job or from one stage to another stage of release pipeline, unless you use multi-stages YAML. Please refer to Set a multi-job output variable for details.

How can assign the value of a sensitive output variable to an environment variable?

I am automating my terraform script in a GitHub Workflow
In my terraform script, I have a sensitive output variable like this:
output "db_password" {
value = aws_db_instance.db.password
description = "The password for logging in to the database."
sensitive = true
}
I am deploying (terraform apply) the script in a GitHub action workflow.
After a successful deployment, I need to store the password in a secured storage (Azure KeyVault) . I have a bash command to do that.
I need to have the value of the db_password in an environment variable.
How can I assign the value of a sensitive output variable to an environment variable?
Is there a better way of doing this?
I suggest to use terraform output after terraform apply. And then you can store the output to a Bash/shell variable or a file without it being printed out.
e.g.
terraform apply # as before
MY_SECRET=$(terraform output db_password)
azureInterface keyvault store $MYSECRET # a totally made-up line, no clue about Azure
The drawback is that it might:
show up in the console output for the last command
is visible in ps as command line argument
So a revised solution is to store in a temporary file
CREDENTIALS=$(mktemp -t tmp.XXXXXXXXXX)
terraform output db_password >$CREDENTIALS
# and now use the $CREDENTIALS file as input to Azure
rm -rf $CREDENTIALS

Substitute variables with variable in azure devops

I have below variables.
variable value
stage dev
admin $($(stage)-admindata)
dev-admindata 4000
But these multiple substitutions are not working for variable admin.
Please let me know how to solve this.
admin values should be 4000 when I use it in yaml or in json file, Currently I am getting $(dev-admindata)
At this moment, the value of nested variables (like $($(stage)-admindata)) are not yet supported in the build/release pipelines.
If you want to give different values to the admin variable depending on the value of stage varibale. As a work around you can write a script in the powershell task to judge, e.g. If the value of the stage variable is dev, then assign the value of the dev-admindata variable to the admin variable.
if ($(stage) -eq "dev"){
$admin = $(dev-admindata)
}
else{
xxxxx
}
For the similar issue ,you can refer to this case.

Azure pipeline concatenating variable names and accessing new variable value

In my Azure pipeline I have 2 vairables $name1 = hello $name2 = world. Those variable value change at run time.
I can concatenate those 2 variable value which will create $helloworld variable.
How do I access $helloworld value? $Helloworld variable is also declared in the pipeline
I'm trying to pass the value of this variable as an argument to the powershell
The following doesn't seem to work $($(name1)$(name2))
You just need to refer it as,
Let's say you had $name1 = 'hello' and $name2 = 'world'.
$($name1)$($name2) = 'helloworld'
You may use $helloworld = "$name1 $name2", please have a try.
The update:
Please have a try with the commands below:
$name1 = "h"
$name2 = "w"
New-Variable -Name "${name1}${name2}" -Value 'helloword' -Force
$hw
Azure pipeline concatenating variable names and accessing new variable value
AFAIK, this issue is about nested variables rather than the concatenate variable.
As you test, you can get the helloworld by the ($name1)($name2), but we could not access value in $helloworld by the nested variable $($(name1)$(name2)).
That is because the value of nested variables (like $($(name1)$(name2))) are not yet supported in the build pipelines at this moment.
You could add your request for this feature on our UserVoice site (https://developercommunity.visualstudio.com/content/idea/post.html?space=21 ), which is our main forum for product suggestions.
Hope this helps.

Resources