How do I replace the connection string element - azure-devops

I have an issue I cannot seem to solve using XML Transform. My web.config contains the following
<connectionStrings>
<add name="SQLConnString"
connectionString="yada yada"
providerName="System.Data.SQLClient"/>
</connectionStrings>
My QA server and above has this
<connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider">
<EncryptedData>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" />
</EncryptedData>
</connectionStrings>
What task do I use in DevOps to achieve this kind of transform or what's the best way to go about this kind of transformation.
jc

Not sure the exactly caused you mentioned is what, but you can use File transform task to achieve the above transformation. I have tested it again and it work very fine on my side.
steps:
- task: FileTransform#1
displayName: 'File Transform: '
inputs:
folderPath: '$(System.DefaultWorkingDirectory)'
enableXmlTransform: true
xmlTransformationRules: '-transform **\*.Dev.config -xml **\*.config'
fileType: xml
For the rules syntax in this task definition, please follow:
-transform <path to the transform file> -xml <path to the source file> -result <path to the result file>
In your scenario, you need also ensure your transform file is configured available. Before run it in azure devops pipeline, you can verify it firstly here.
Updated in 2/20/2020:
Based on your comments, the trouble for you to apply file transform is on transforma file configured. Though you have got the method of powershell, but I also help you written a transform file so that you can have more choice here.
<connectionStrings xdt:Transform="Remove">
<add name="SQLConnString"
connectionString="yada yada"
providerName="System.Data.SQLClient" />
</connectionStrings>
<connectionStrings configProtectionProvider="RsaProtectedConfigurationProvider" xdt:Transform="Insert">
<EncryptedData>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" xdt:Transform="Replace"/>
</EncryptedData>
</connectionStrings>
You can see my transformation result:

Related

How to ignore special characters in File Transformation Task of Azure DevOps Pipeline

I am having xyz.config file like below. I have created xyx.Release.config file to use in File Transformation task.
<formatters>
<add template="Timestamp: {timestamp}
Message: {message}
name="Reduced Text Formatter" />
</formatters>
After the File Transformation task in pipeline it transformed as below. The special characters are replaced after the execution of File Transformation task.
<formatters>
<add template="Timestamp: {timestamp}
Message: {message}
-
</formatters>
Anyone please let me know how to ignore special character transformation as part of File Transformation task.
Thanks in advance.
Mohan
As far as I know, the File transform task doesn't support to ignore special character transformation.
The file transfrom task will use the built-in method to do the file transform option. It doesn't support to use custom method to do the option.
Here is the doc about the built-in method: Web.config Transformation Syntax for Web Project Deployment Using Visual Studio
It supports overall replacement of strings, but currently does not support replacing only the part of value in the string and ignoring others.
For a workaround, you can use the replace method then just change the part of value in the string to keep the format of the string.
For example: xyx.Release.config
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<formatters>
<add template="Timestamp: test1
Message: test2
" name="Reduced Text Formatter" xdt:Transform="Replace" xdt:Locator="Match(template)" />
</formatters>
</configuration>

Azure Devops release - File Transform - Provided node is empty or a comment

I am trying to transform a .config file from an XML transform file in a release stage. I am using the standard File Transform task. I added a transform.xml file (which isnt linked to a legitimate release) to my artifact and can see it. When i try and use it I get the following System.Debug output:
2020-05-01T17:25:21.6011428Z Processing substitution for xml node : connectionStrings
2020-05-01T17:25:21.6022113Z ##[debug]Provided node is empty or a comment.
2020-05-01T17:25:21.6025339Z ##[debug]Provided node is empty or a comment.
2020-05-01T17:25:21.6027416Z ##[debug]Unable to find node with tag 'configSections' in provided xml file.
2020-05-01T17:25:21.6028615Z Skipped Updating file: xxxxxxxx.config
The contents of the transform.xml file are as below:
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings xdt:Transform="Replace">
<add name="XX" connectionString="user id=XXX;password=XXXXX;data source=XXXXXXXX"/>
</connectionStrings>
</configuration>
Azure Devops release - File Transform - Provided node is empty or a comment
I could not reproduce this issue with following configuration file and your transform file:
Configuration file web.config (code sample from XML transformation example):
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="DefaultConnection"
connectionString="Data Source=(LocalDb)\\MSDB;DbFilename=aspcore-local.mdf;" />
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<authentication mode="None" />
<compilation targetFramework="4.5" debug="true" />
</system.web>
</configuration>
Then create a Web.test.config with your contents of the transform file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings xdt:Transform="Replace">
<add name="XX" connectionString="user id=XXX;password=XXXXX;data source=XXXXXXXX"/>
</connectionStrings>
</configuration>
Note:
XML transformation will be run on the *.config file for transformation configuration files named *.Release.config or *.<stage>.config. So, we could not use the transform.xml instead of *.<stage>.config.
As the test result, the connectionStrings string in the web.config was replaced:
Please check the document File transforms and variable substitution reference for some more details.
Hope this helps.

XDT Transform not working for applicationHost.xdt on Azure - Environment variables are ignored

It seems like environment variables are being ignored in my xdt transform for applicationHost.
I've created the following file applicationHost.xdt on azure in the \home\site folder. It does NOT perform the transform on applicationHost.config
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">>
<system.applicationHost>
<applicationPools>
<add name="%WEBSITE_SITE_NAME%" xdt:Locator="Match(name)">
<recycling disallowOverlappingRotation="true" xdt:Transform="Insert" />
</add>
<add name="%WEBSITE_IIS_SITE_NAME%" xdt:Locator="Match(name)">
<recycling disallowOverlappingRotation="true" xdt:Transform="Insert" />
</add>
</applicationPools>
</system.applicationHost>
</configuration>
If I adjust the %WEBSITE_SITE_NAME% to say "dev-mysitename.com" the transforms work properly.
Why are the Environment variables not working properly? I need this to work so my different environments will work properly.
You cannot use Environment Variables like this. Its just not possible.

Change all Web.*.config files in first stage in release pipeline

I need to change the items inside appsettings on all the Web.*.config files in first stage step. That is I can't do transformation in every step in release pipeline. The reason is that I use Episerver DXC/DXP.
I have 4 stages; "Upload Package", "Integration", "Preproduction", and "Production".
The values is stored i Azure Key Vault.
Is there any smart way to do this?
Did you read the guide on config transforms for DXC? https://world.episerver.com/digital-experience-cloud-service/development-considerations/environment-configurations/
If File transformation is not suitable for your project, what about using powershell script to do the item change?
Sample:
Here is my example web.product.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="service.tasks" type="HRNetTaskService.TaskConfigurationSection, TaskService" />
</configSections>
<connectionStrings>
<add name="Production" connectionString="xxxx" providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="RestServiceUrl" value="https://sample.net" />
</appSettings>
</configuration>
Now I want to update the connectionString of .config file. Add replace.ps1 into repos with below scripts, then call this replace.ps1 file in Powershell task via passing corresponding dynamic value:
Param(
[string]$source,
[string]$connectionstring
)
$webConfig = $source
$doc = (Get-Content $webConfig) -as [Xml]
$root = $doc.get_DocumentElement();
$activeConnection = $root.connectionStrings.SelectNodes("add");
$activeConnection.SetAttribute("connectionString", $connectionstring);
$doc.Save($webConfig)
Here $(ProductValue) is the variable that you configured in Azure key vault. Its call way is same with the pipeline variable. Just you need link the Azure key vault into azure devops, then combine it with Variable group.
What I was trying to do was replace variables in config files from Azure Key Vault before transformation on config files because it can't be done (at this point) during the release pipeline when using Episerver DXC. What I did was replacing them during the build pipeline instead.
Made the variable substitution in Powershell during the build pipeline. Import the Key Vault secrets as separate task before the Powershell task, list all the one I would use as environment variables in the Powershell task.
The environment variables I named the same as the one it should replace in the config files (ex SomeApiKey_Integration). Go through the config files, look for two anything between two double underscores and replace them with value from the environment variable ((Get-ChildItem $variable).Value).
In the config files and environment variable they are named as previous stated, SomeApiKey_Integration. Key Vault name and environment variable value as SomeApiKey-Integration.

Update Build number in App config xml file on build pipeline

I have a build pipeline in Azure DevOps, I need to update the build number in my apconfig exe file that will be $(Build.BuildNumber).
I just tried this way:
Adding a variable name = BuildNumber value = $(Build.BuildNumber).
And in my apconfig.exe file have a key same like <add key="BuildNumber" value="1812201901" />.
Why I have tried like this way: thinking like it will update in the config file if variable name match with the key.
But it is not working. can anyone please help? I have just started in CI/CD.
Update Build number in App config xml file on build pipeline
Just like the Shayki said, using the Replace Tokens extension should be the directly way to resolve this issue.
But since you need to request to get this extension, as workaround, you could also use power shell scripts to resolve this issue, you can check below my test powershell scripts:
$currentDirectory = [IO.Path]::GetDirectoryName($MyInvocation.MyCommand.Path)
$appConfigFile = [IO.Path]::Combine($currentDirectory, 'App.config')
$appConfig = New-Object XML
$appConfig.Load($appConfigFile)
foreach($BuildNumber in $appConfig.configuration.add)
{
'name: ' + $BuildNumber.name
'BuildNumber: ' + $BuildNumber.value
$BuildNumber.value = '123456789'
}
$appConfig.Save($appConfigFile)
As result, the app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<add key="BuildNumber" value="123456789" />
</configuration>
Note: Set the powershell scripts at the same folder of the app.config file.
Hope this helps.
You can use the Replace Tokens extension and in the apconfig.exe file put this:
<add key="BuildNumber" value="__BuildNumber__" />
Configure the task to search variables with __ prefix and suffix:
Now the value will be replaced with the value of the BuildNumber variable you configured (equal to Build.BuildNumber).