Azure DevOps Release transform/replace tokens - azure-devops

I have 2 config files, ConnectionStrings.config and ConnectionStrings.Release.config. These files are used to store various connection strings we use in our app.
<?xml version="1.0" standalone="yes"?>
<ConnectionStrings xmlns="http://tempuri.org/ConnectionStrings.xsd">
<Service>
<Name>MyService</Name>
<Address>http://localhost/#{ConnectionString}#/MyServiceService.svc</Address>
<ClassName>MyClass, MyClass</ClassName>
</Service>
</ConnectionStrings>
When we deploy locally we use the normal ConnectionStrings.config without any replace tokens in the file. The .release.config is the one that has the tokens.
I'm using these 2 market place tasks
[Tasks in my release pipeline]
1
From what I understand, the transform task is taking the .release.config file and "renaming it" .config, then the replace tokens task replaces the necessary tokens with variables in my pipeline. Finally I copy these to my target. My source of the copy task is my Git working directory in Azure.
When I check the results, I don't see the ConnectionStrings.config changed at all and its just copied over like if it was a local deploy.
What am I doing wrong?

It seems that you are using this extension: XDT Transform. After installing it in my organization, there are 2 external tasks: XDT tranform task and Replace Tokens task in release pipeline.
below is my repository structure, the ConnectionStrings.config and ConnectionStrings.Release.config.
And my release pipeline looks like below.
I create a pipeline variable ConnectionStrings, and set its value to hello_world, use the PowerShell script gc _215\ConnectionStrings.config to print the replaced result. Creating a new release we can see below log.
Thus it works as expected.

Related

Azure DevOps Pipeline using old connection string

I have an Azure DevOps pipeline which is failing to run because it seems to be using an old connection string.
The pipeline is for a C# project, where a FileTransform task updates an appsettings.json file with variables set on the pipeline.
The variables were recently updated to use a new connection string, however, when running a Console.PrintLn before using it and viewing it on the pipeline, it shows an outdated value.
Many updates similar to this have been run in the past without issue.
I've also recently added a Powershell task to echo what the value is in the variables loaded while the pipeline is running, which does display the new value.
I've checked the order of precedence of variables and there shouldn't be any other variables being used.
There is no CacheTask being used in this pipeline.
Does anyone have any advice to remedy this? It seems that the pipeline itself is just ignoring the variables set on the pipeline.
There is a problem with the recent File transform task version v1.208.0.
It will shows the warning message and not update the variable value correctly.
Warning example:
Resource file haven't been set, can't find loc string for key: JSONvariableSubstitution
Refer to this ticket: File transform task failing to transform files, emitting "Resource file haven't been set" warnings
The issue is from Task itself instead of the Pipeline configuration. Many users have the same issue.
Workaround:
You can change to use the File Transform task Version 2 to update the appsettings.json file.
Here is an example: Please remove the content in XML Transformation rules field and set the JSON file path

Web.config variable update not working with Azure DevOps pipeline (File Transform)

I'm trying to use the task "File Transform" within my pipeline to modify a few values inside my web.config file during deployment.
I created the tasks as the following:
And in the pipeline, inside the variables, I set up the key & value that I want to replace in the XML file.
Everything seems to go fine, however, when I check the log, I see this
So, the file was simple skipped and the transformation didn't work.
The variable that I'm trying to modify in the web.config file has the following path inside the XML file
<aspNetCore>
<environmentVariables>
<environmentVariable name="x" value="y" />
</environmentVariables>
</aspNetCore>
</configuration>
I read the documentation multiples times, but it's not clear if I'm doing something wrong.
Please, could you provide some suggestion of what I need to check to make it work?
Thank you
According to the document about XML variable substitution:Variable substitution takes effect only on the applicationSettings, appSettings, connectionStrings, and configSections elements of configuration files. It does not apply to your environmentVariable element. It worked well on my side when I change value in appSettings element.
Please refer to the samples in the document about file transform.
I'm answering my own question.
Based on the comments that I received, the solution that I found was the following:
1- Use Replace Token Task (https://github.com/qetza/vsts-replacetokens-task#readme) in the pipeline AFTER the deployment. I also removed that "File Transform", since it wouldn't work for what I needed.
2- In the configuration, I pointed the root folder to the deployed application, no the Zip file, as instructed by this other question (Azure Dev ops replace tokens per environment in release pipeline)
3- In the web.config file, I used the token prefix and suffix, as suggested "#{token}#
4- Added the variables to the variable groups
After deploying, I checked that it worked fine.

Automate deploy of Machine Key in a shared config IIS

I'm using Azure DevOps to deploy an ASP.NET application to an IIS servers on-prem. The IIS servers are using a shared configuration so they need a custom Machine Key setup.
I can use XML transform to add add the machineKey entry in the Web.Config
<system.web>
<machineKey decryptionKey="{hex-key value}" validationKey="{hex-key value}"/>
</system.web>
but I don't want to have the actual keys in source control so I'll need to replace those values at deploy time. Substitution is easy enough for appsettings and connection strings but how can I substitute values in the System.Web section of the Web.Config?
How can I substitute values in the System.Web section of the
Web.Config?
What about consider to use one extension Replace token? For why I recommend it is because it can achieve the demand that it can only be replaced during the pipeline running.
Also, its usage is very convenient. Just need to specify the prefix and suffix in the task, and then make apply them in to your web.config file.
Then specify the corresponding variables with same name in Variables tab.
Only this, during the pipeline running, the task could find the corresponding token correctly and replace the value into it.
For detailed steps, you could refer to my previous answer for details: Use replace token task.

Unable to reference artifacts' build numbers in Release name format

I have three artifacts in my Azure DevOps Release pipeline with the following source aliases: _Client, _Database, _WebApp.
_Client is the primary artifact. I want to include each artifact's build number in the Release name.
I have used the following expression in "Release name format" under "Options" tab.
Release-$(rev:r) for Core Build-$(Release.Artifacts._WebApp.BuildNumber), Db Build-$(Release.Artifacts._Databaes.BuildNumber), Client Build-$(Release.Artifacts_Client.BuildNumber)
I expected it to name the release as "Release-74 for Core Build-29.0.0.69, Db Build-1.0.0.29, Client Build-2.1.0.34
Instead, it names it as "Release-74 for Core Build-$(Release.Artifacts._WebApp.BuildNumber), Db Build-$(Release.Artifacts._Database.BuildNumber), Client Build-$(Release.Artifacts._Client.BuildNumber)"
In initialize job log, it does show the artifacts and their respective build numbers as follows:
[RELEASE_ARTIFACTS__DATABASE_BUILDNUMBER] --> [1.0.0.29]
[RELEASE_ARTIFACTS__CLIENT_BUILDNUMBER] --> [2.1.0.34]
[RELEASE_ARTIFACTS__WEBAPP_BUILDNUMBER] --> [29.0.0.69]
[RELEASE_RELEASENAME] --> [Release-74 for Core Build-29.0.0.69, Db Build-1.0.0.29, Client Build-2.1.0.34]
Is it because it can't resolve the artifact build numbers while creating the pipeline or perhaps there is another way to achieve this?
The same behavior in my release, it looks like the Artifacts variable got their value only after the release will start, so it's impossible to put them in the release name.
As a workaround, you can add a simple command-line task that use the logging command to update the release name:
echo ##vso[release.updatereleasename]Release-$(rev:r) for Core Build-$(Release.Artifacts._WebApp.BuildNumber), Db Build-$(Release.Artifacts._Databaes.BuildNumber), Client Build-$(Release.Artifacts._Client.BuildNumber)

VSTS Pipeline Deployment of ARM Error: Could not find any file matching the template file pattern

I am trying to deploy an Azure ARM script in VSTS Pipeline.
I "Published" the Artifacts in the Build Step and Downloaded the Artifacts in the Release Step. The Log seems to indicate that it found the ARM script (After much trial and error. The prescribed manner found here does not seem to work at all).
I however get Error: Could not find any file matching the template file pattern
Incidentally, I get this error even if can't find the file (which makes sense..but not when it actually does find the file). The ARM script deploys correctly when I deploy manually in Azure Portal.
I am using the Azure Resource Group Deployment step in the release pipeline.
I'm not sure what other information might help troubleshoot this, but request and hopefully I can get it to you.
Thanks
2018-12-14T18:32:06.6009951Z ##[section]Starting: Azure Deployment:Create Or Update Resource Group action on ChrisGroup
2018-12-14T18:32:06.6015952Z
==============================================================================
2018-12-14T18:32:06.6016124Z Task : Azure Resource Group
Deployment
2018-12-14T18:32:06.6016287Z Description : Deploy an Azure resource manager (ARM) template to a resource group. You can also start, stop, delete, deallocate all Virtual Machines (VM) in a resource group
2018-12-14T18:32:06.6016444Z Version : 2.141.4
2018-12-14T18:32:06.6016526Z Author : Microsoft Corporation
2018-12-14T18:32:06.6016655Z Help : [More Information] (https://aka.ms/argtaskreadme)
2018-12-14T18:32:06.6016801Z
==============================================================================
2018-12-14T18:32:06.9610677Z Checking if the following resource group exists: ChrisGroup.
2018-12-14T18:32:07.2734470Z Resource group exists: true.
2018-12-14T18:32:07.2736899Z Creating deployment parameters.
2018-12-14T18:32:07.2809876Z The detected encoding for file 'D:\a\r1\a\IAC\ARM.json' is 'utf-8'
2018-12-14T18:32:07.3021166Z ##[error]Error: Could not find any file matching the template file pattern
2018-12-14T18:32:07.3030720Z ##[section]Finishing: Azure Deployment:Create Or Update Resource Group action on ChrisGroup
As per request:
In the Template Parameters field I put
-dailyreports_name '$(IACWeb)' -dailyreportsapi_name '$(IACAPI)'
and OMG... It's supposed to be a path to a variables file. UGH
Once I put into the Override Template Parameters, it works.
Microsoft should probable reword the label to "Template Parameters File"
You need to put the parameters being passed in into the "Override template parameters". The "Template parameters" field is actually a reference to a file location.
##[error]Error: Could not find any file matching the template file pattern
Check few things here :
check all parameter names (case sensitive) in the parameter file and template file.
if you are using yml file for azure devops pipeline,
check all overrideParameters are correctly mentioned
overrideParameters: '-environment "${{parameters.environment}}"' #for example
check csmParametersFile , csmFile path in the yml
For me, the issue turned out to be that I had to select specific build number while creating the release. If don't use specific build and just leave latest version option by default, then this error comes.
When migrating from Classic to YAML deployments:
Seeing:
##[error]Error: Could not find any file matching the template file pattern,
may be because you're referencing Pipeline Artifacts through the inputs csmFile and csmParametersFile, without actually having access to them in your pipelines stage. You may need to download the artifacts first, as seen in the second stage in this answer.
A quick check to see if this is the case would be to by-pass your artifacts, and point the mentioned inputs directly to your azuredeploy.json and azuredeploy.parameters.json files where they are located in your repo.