Can I enumerate a variable group in VSTS? - powershell

TL;DR: Search and replace placeholders in a text file with the decrypted values of secrets in a variable group.
I would like to use a PowerShell script to receive a variable group in a release pipeline and then iterate through the list, performing search-and-replace on a file being released.
The variables in the variable list are secrets so I want to overwrite the placeholders in the file with the decrypted value of the variables.
The values of the variables are environment specific, so I do not want to provide the values at build time and do not want to include the decrypted values in a stored artifact.
The file being search-replaced will be used in an execution at release time but will not be deployed to a host, so will be destroyed upon completion of the pipeline execution.

The Tokenization task from the Visual Studio Marketplace does this job well. You'll need to install it into your Azure DevOps organisation, it's available at https://marketplace.visualstudio.com/items?itemName=TotalALM.totalalm-tokenization
By default the Tokenization task uses double underscores to identify the placeholders. It will replace any text that that matches the name of a variable in your release definition as long as it's surrounded by double underscores.
So if you want to write the value of a variable called MySecretVariable into your file you'll need to add a place holder like __MySecretVariable__ into the file where ever you want that value to be written.
The Tokenization task will write any encrypted values into the file in plain text but in the release logs they will be obfuscated.
If you're storing your variables in a variable group just link that to the release definition and set the scope to the appropriate environment.

So, I've found that, as long as I have a Base64 token configured for Variable Groups (click 'Show all scopes' when creating a new PAT) then I can call GET https://dev.azure.com/{organization}/{project}/_apis/distributedtask/variablegroups/{groupId}?api-version=5.1-preview.1 to get the variable group I need.
The above, however, will not return a value for secrets, although there is a hack/workaround for this (involving multiple pipeline steps).
The advisable route is to create a Key Vault in Azure and perform the processing either in Powershell or code.
As I need the decrypted key values passed into my application via a repeated find-replace, I have implemented a Powershell script in one Release pipeline step and consume the output in the next step.

Related

Set Release name in web.config when deploying with Azure DevOps

We're building and deploying our application to 30 separate web apps every night, and I would like to know which release every web app is currently on. For instance "Release-12345".
The value exists in the release variable Release.ReleaseName from Release variables (MS doc), but I have no idea on how to make my pipeline use that value. My approach for now is to write it to the web.config, and the let the application read that value on demand. But if there's another, more efficient or "correct" way of doing it, I'm open for anything.
It's a classic usage of "replace tokens" tasks, there are many extensions in the marketplace, the most popular is Replace Tokens.
You need to add a placeholder in the web.config, for example:
<add key="Release_number" value="#{Release_number}#" />
In the release variables you need to add a variable Release_number with the value $(Release.ReleaseName), and add the Replace Tokens task in your release pipeline with configuration of:
Target Files: web.config
Token Prefix: #{
Token Suffix: }#
Now, the task will search inside the web.config file strings that match the pattern and will replace them with the value from the release variables.

Azure DevOps - Can we reuse the value of a key in the same variable group?

I have lots of URL values and their keys. But there is no way to batch import the variables and the "value" controls are also not text boxes in the Variables Group page to perform chrome browser extensions assisted find and replace.
If this is possible, what is the syntax to refer to the key?
As in, I have a variable App.URL : www.contoso.com.
I am using the key to substitute value in my next variable like this Login.URL : $(App.URL)\Login and this doesn't work.
GitHub link : https://github.com/MicrosoftDocs/vsts-docs/issues/3902#issuecomment-489694654
This isn't currently available, not sure if it will be. Can you create a task early in your pipeline that sets the variables you need in subsequent tasks/steps? This gives you more control as you can store the script along with your source. You could then use a pipeline variable for the environment you're in and let your script use that to set values appropriately.
See Set variables in scripts in the MS docs.
If it's not possible to re-architect your app to concatenate the url strings in the application, what the previous commenter said about creating a simple script to do that for you would be the way to go. Ie:
#!/bin/bash
#full login url
fullLoginUrl=$APP.URL\$LOGINSUFFIX
echo "##vso[task.setvariable variable=Login.URL]$fullLoginUrl
Otherwise, perhaps playing around with the run time vs compile time variables in YAML pipelines might be worth trying.
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#understand-variable-syntax

Rundeck implicit variable

Run dick gives us the ability to define options to be entered by the its GUI, is there any capability to have job variable based on the input without the end user of the job seeing it?
E.g, if the the user choose the product and the environment and the product behind LB, I want to use a script internally to define new job variable and assign it the port number that could be used later on within the job steps.
Yes, there is.
You can add a new option whith Allowed Values set to Remote URL, then put the URL to your script which will return the actual value based on other options.
For exmaple
http://localhost/cgi-bin/getPort.py?environment=${option.environment.value}&product=${option.product.value}
Rundeck Manual option-model-provider

Setting up email content in editable email notification for Jenkins jobs

I started out by writing html code in the "Default content" section but that is not meeting my requirements since all the information I want to include in the email (html) is not available.
My questions are :
How can I set an environment variable in post build actions that I can then use in the default content section ? Is that even possible ?
How can I the know the path of a file present in the workspace after the build is done. The path contains a folder that is named using timestamp and I was looking for a way to get to the build results folder for the current build easily. Is there a way ?
You can use ${ENV, var="VARNAME"} (where VARNAME is the environment variable that you want to reference) anywhere in your HTML
As for your build folder, if it's a random timestamp during the build, you can't reference it unless you save that value to a properties file and then read it with ${PROPFILE,file="FILENAME",property="PROPERTYNAME"}
If you are using Jenkins's build timestamp BUILD_ID then you can reference that as any other environment variable.

Jenkins How can i upload a text file and use it as a parameter

I have a txt file that is holding a string inside, I want to be able to use this string in one of my scripts, so I'm wondering if there is a way to set the content of the file as one of the build properties or parameters which I'll be able to use in my scripts it should be the same as using one of the build environment properties.
For example : ${JOB_NAME} which is holding the the job name, so in the same way I want to access the content of the file which is holding some value inside.
Is it possible?
You can upload a file from your computer to the workspace through the File parameter of the job.
You can use Extended Choice plugin parameter, to read value(s) from a file and display them in a dropdown/radio-button/checkbox for the user to select, dynamically, every time the build is triggered.
You can use EnvInject plugin to read value(s) from a file and inject them into the build as environment variables, so that they can be used by the rest of the build steps/scripts.
Your question is very unclear on what your are trying to do. Pick one of the 3 methods above based on what you need, or clarify your question.