How to Substitute XML web.config and JSON appsettings.json Values Dynamically in Azure DevOps CI/CD Pipelines
Managing environment-specific configuration values such as deployment timestamps, connection strings, or secrets in your .NET web applications is critical. Azure DevOps pipelines offer a straightforward way to replace these values dynamically during your CI/CD processes without modifying your source code.
This article covers variable substitution inside XML web.config and JSON appsettings.json files using pipeline variables. It shows how to dynamically update these variables at runtime with PowerShell scripts, and how to implement this in both Classic GUI pipelines and YAML pipelines.
Overview of Variable Substitution
Azure DevOps File Transform task supports:
- XML Variable Substitution: replaces values in appSettings, connectionStrings, and configSections in XML config files (like web.config).
- JSON Variable Substitution: replaces matching keys in JSON files (like appsettings.json).
No need for special tokens in your config files; the task matches pipeline variable names with existing keys and replaces their values during the pipeline execution.
Configuring Your web.config and appsettings.json
You can keep your config files simple without placeholders:
Sample web.config
<appSettings>
<add key="DeploymentDate" value="DefaultValue" />
<add key="AdminUserName" value="admin" />
</appSettings>
Sample appsettings.json
{
"DeploymentDate": "DefaultValue",
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=MyDb;"
}
}
Creating Pipeline Variables
Define pipeline variables that exactly match the keys you want to replace.
- In GUI pipelines, go to the Variables tab → Add variable (e.g., DeploymentDate)
- In YAML pipelines, define variables as:
variables:
DeploymentDate: '2025-06-26 16:38:00 UTC'
Tip: Mark variables Settable at queue time in the GUI if you want to override them manually when queuing a build or release.
File Transform Task Configuration
This task performs variable substitution inside config files.
GUI Pipeline Configuration
- Add the File Transform task
- Specify Target files (relative to the root of your artifact), e.g.:
**\web.config
**\appsettings.json
The following screenshot shows how it is configured for substituting variables in the web.config file:
Put this task above the IIS Web App Deploy task (or other tasks you have for the deployment).
YAML Pipeline Configuration
The following is an example of how you do the same in YAML.
steps:
- task: FileTransform@2
displayName: 'File Transform: '
inputs:
xmlTargetFiles: '**\web.config'
Note: If your build publishes artifacts, folderPath should point to the extracted location containing your config files.
Dynamically Setting Variables with PowerShell
To inject dynamic values like the current date/time into your pipeline variables, you can use PowerShell Script tasks.
PowerShell Script to set DeploymentDate
The following PowerShell scripts get the current UTC date-time and insert it into the DeploymentDate variable created in the pipeline:
$deploymentDate = (Get-Date).ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss")
Write-Host "##vso[task.setvariable variable=DeploymentDate]$deploymentDate"
GUI Pipeline Configuration
- Add a PowerShell task before the File Transform task
- Paste the above script in the Inline Script box
The following screenshot shows how the PowerShell Script task is configured using the GUI interface:
YAML Pipeline Configuration
If you configure the tasks using YAML, the task will look like the following:
steps:
- powershell: |
$utcNow = (Get-Date).ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss")
Write-Host "##vso[task.setvariable variable=LastDeployment]$utcNow"
displayName: 'PowerShell Script'
Task Sequence in CI and CD Pipelines
The following lists show where you put these tasks in the CI/CD pipelines for building and deploying an ASP.NET website.
CI Pipeline Task Order
The PowerShell task can be run anytime before you run the File Transform task. However, the File Transform task must be run after building the solution. So, in the following list, it is placed after the build solution and test assemblies tasks.
- PowerShell task to set pipeline variable values
- Use NuGet / NuGet restore
- Build solution
- Test assemblies
- File Transform task (substitutes variables in config or appsetting files)
- Publish artifact
CD Pipeline Task Order
- PowerShell task to set pipeline variable values
- File Transform task (variable substitution)
- Deployment tasks (e.g., Azure App Service Deploy, IIS Web App Deploy, etc.)
Practical Examples: BuildDate in CI & DeploymentDate in CD
In this example, we'll have two AppSettings entries in the web.config file: BuildDate and DeploymentDate. The BuildDate will store the date and time when the website is built by the CI pipeline. And the DeploymentDate will store the date and time when the CD pipeline is run to deploy the website.
Build Date in CI Pipeline
The CI pipeline will have a variable named BuildDate. It is the same name as the AppSettings key in the web.config file. The following PowerShell script will be used to set the BuildDate variable's value to the current UTC date and time.
$buildDate = (Get-Date).ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss")
Write-Host "##vso[task.setvariable variable=BuildDate]$buildDate"
The YAML snippet for the PowerShell and FileTransform tasks will look like:
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
$buildDate = (Get-Date).ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss")
Write-Host "##vso[task.setvariable variable=BuildDate]$buildDate"
- task: FileTransform@2
inputs:
folderPath: '$(Build.ArtifactStagingDirectory)'
xmlTargetFiles: '**/web.config'
Note: The folderPath in the FileTransform task should use the same path that is used to store the artifact.
Deployment Date in CD Pipeline
The CD pipeline will have a variable named DeploymentDate. This is the same name as the AppSettings key in the web.config file. The following PowerShell script will set the value of DeploymentDate to the current UTC date and time.
$deploymentDate = (Get-Date).ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss")
Write-Host "##vso[task.setvariable variable=DeploymentDate]$deploymentDate"
The YAML snippet for the PowerShell and FileTransform tasks in the CD pipeline will look like:
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
$deploymentDate = (Get-Date).ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss")
Write-Host "##vso[task.setvariable variable=DeploymentDate]$deploymentDate"
- task: FileTransform@1
inputs:
folderPath: '$(System.DefaultWorkingDirectory)'
xmlTargetFiles: '**/web.config'
Limitations and Best Practices
- Only existing keys in your XML or JSON files are replaced; new keys are not created.
- Variable names are case-sensitive and must exactly match key names (including nested JSON keys with dot notation).
- For JSON arrays, index notation (e.g., DBAccess.Users.0) can be used.
- Only string substitutions are supported in JSON.
- Variable substitution occurs after XML transform tasks.
- Ensure PowerShell variable setting tasks run before the File Transform task.
- In YAML, use logging commands ##vso[task.setvariable ...] to dynamically set variables.
Conclusion
Using Azure DevOps File Transform's variable substitution with dynamically set pipeline variables lets you manage environment-specific values elegantly and automatically in your CI/CD pipelines.
Whether you use Classic GUI pipelines or YAML, this approach maintains clean source config files and adapts them at build or release time with minimal manual effort.
Comments
Insight is best when shared. Found it useful or confused by something? Leave a comment — your thoughts might help others and keep the discussion growing!