In ASP.NET MVC application, I can replace the web.config values with the value coming from Variable Group in Azure DevOps when deploying our codes to the live host
Is there a way I can do the same for application that only consist of only Angular scripts?
I know there is environment.ts file that can be used for replacing the configuration by environments
but I am hoping to use the Variable Groups in Azure DevOps as it's more convenient for us to use when we deploy our codes to the live host.
You can use Token Replacement extension to replace settings inside environment.ts file. It could look like this:
- task: qetza.replacetokens.replacetokens-task.replacetokens#4
inputs:
targetFiles: 'environments/*.ts'
encoding: 'auto'
tokenPattern: 'default'
writeBOM: true
actionOnMissing: 'warn'
keepToken: false
actionOnNoFiles: 'continue'
enableTransforms: false
useLegacyPattern: false
enableTelemetry: true
And then you should put token in env file to be replaced
export const environment = {
production: #{VARIABLE_TO_BE_REPLACED}#
};
However, as Daniel already mentioned it will result in coupling with Azure Devops.
Related
This is a question on how to use a static value for VSTest unit tests run on Azure DevOps Pipeline.
When I develop a unit test that depends on my Web API, I put URL of the Web API hosted on my local dev machine in appsettings.json and this works great. However, when the unit test is run on Azure pipeline, of course it cannot access the Web API hosted on my machine and it fails. I can change the appsettings.json file to point to Web API on Azure but I wish there is a way to always point to the WebAPI on Azure when the unit test is run on the pipeline, overriding the setting in appsettings.json. Is there such a way?
For the Azure pipeline Release, I know I can set variables for app services with Azure App Service Settings task (https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/deploy/azure-app-service-settings?view=azure-devops). Not sure similar functionality is available for VSTests.
You can use File Transform task to substitute the variables in appsettings.json file with pipeline variables. See here for more information
So you can add a File Transform task before the build task. Then define a variable(eg. TestData.Url) in your pipeline variables.
See below yaml example.
- task: FileTransform#1
displayName: 'File Transform: '
inputs:
folderPath: '$(system.defaultworkingdirectory)'
enableXmlTransform: false
fileType: json
targetFiles: '**/appsettings.json'
There are other tasks can do the same work. You can check out task Set Json Property, and task Magic Chunks
You can also put the URL of the Web API in the TestRunParameters section of runsettings file or Properties section of testsettings file. And modify your test code to get the URL from testsettings/runsettings files. Then you can use overrideTestrunParameters attribute of Vstest Task to override the URL. See Vstest task document for more information.
You need to have two appsettings files. One for dev (you local test) and the other for production (AzureDevops pipeline).
Like this if you need to make some changes to test locally you change only the dev one.
There are 10+ project in my solution. One project has config, name Variable.release.config file which has all the application variable, connection string and other web.config's module which needs to replaced with Azure variable from Library. This config file is used by all the project. The solution has Asp.net MVC website which has it's own web.config, web.release.config. I am trying to xml transform variable from Variable.release.config, It is transforming everything in web.config but value of endpoint variable in client section of endpoint address is not getting replaced.
Previously I was using Azure App Service Deploy and following is its YAML:
steps:
- task: AzureRmWebAppDeployment#4
displayName: 'Azure App Service Deploy: abc-tst'
inputs:
azureSubscription: 'ABC Technologies(XXXX-XXX-XXX-XXX-XXXXXX)'
WebAppName: 'ABC-tst'
deployToSlotOrASE: true
ResourceGroupName: 'abc-tst'
SlotName: T2
packageForLinux: '$(System.DefaultWorkingDirectory)/$(Release.DefinitionName)/drop/ABC.Frontend.zip'
enableXmlTransform: true
enableXmlVariableSubstitution: true
It was not replacing variable in endpoints. I came across several article that says only endpoint can not be replaced with xml transformation I need to use 3rd party tools to transfer Replace Token
I tried with following steps:
File transform
Replace Token
Azure App Service Deploy
But it didnt replaced endpoint variable address in web.config though it xml transformed was success and in logs Replace token has replaced the token of that variable.
After that I modified my release task as given in bellow image after reading this answer.
Is there any way to replace variable value in endpoint address or am I missing anything?
Are you sure you have all configured as it should be?
I tried this replace token in release pipeline and all went fine. Are you sure you have traget files properly configured?
Do you have such output in logs?
2020-05-28T07:11:02.8850410Z replacing tokens in: D:\a\r1\a\repos\stackoverflow\38-endpoint-replace\Web.config
2020-05-28T07:11:02.9045428Z 1 tokens replaced out of 1
2020-05-28T07:11:02.9048164Z replaced 1 tokens out of 1 in 1 file(s) in 0.079 seconds.
Please try to add such powershell step to check file content before and after replace token step.
Note
Be aware that that my last advice my cause to keep this in logs. If you have sensitive data please revoke them after or remove from file for test purpose.
I tried with many azure task by extracting file then transforming it and again zip it to the same location. But nothing worked. I removed all the task and just kept one task of "Azure App Service Deploy" with following YAML:
I had modified my we.release.config endpoint with following:
<endpoint address="#{variable1}" binding="basicHttpBinding" bindingConfiguration="TransPortCertificateBinding" contract="Contract1" name="Service1"
xdt:Transform="SetAttributes" xdt:Locator="Match(address)"/>
Previously the Match was applied on contract which failed to transform the value from library variable.
I have about 20+(and growing) app settings in local.settings.json file of my .net core azure function app. The only way to add these to function app in the portal as part of the deployment is to use a long concatenated string of all appsettings in key value format which is very messy, error prone and hard to maintain.
I am looking for a neat way if possible to add the appsettings to the function app as part of the function app deployment process.
P.S. I am using terraform to create the function app and Not interested to use the ARM template solution which is even messier.
If you want to add the appsettings to the function app as part of the function app deployment task. You can use variables to make it a little easier to maintain. You can check below steps.
Define the key/values of appsettings in the pipeline variables.
You can aslo define the variables in the YAML file:
variables:
key1: value1
key2: value2
Then then refer to variables in appsettings field of app service deployment task
- task: AzureRmWebAppDeployment#4
inputs:
AppSettings: '-key1 $(key1) -key2 $(key2)'
Another workaround is to use Azure App Service Settings task to add the appsettings to the function app. (You don't need to define appSettings field for app deployment task if App Service Settings task is used to add appsettings)
- task: AzureAppServiceSettings#0
displayName: Azure App Service Settings
inputs:
azureSubscription: $(azureSubscription)
appName: $(FunctionApp_Name)
appSettings: |
[
{
"name": "key1",
"value": "$(Key1)",
"slotSetting": false
},
{
"name": "key2",
"value": "$(Key2)",
"slotSetting": false
},
{
"name": "MYSQL_DATABASE_NAME",
"value": "$(DB_Name)",
"slotSetting": false
}
So by using above workarounds, you only need to change the values in the pipeline's variables to change the appsettings for function app.
You can also use terraform to add appsettings to you function app. Please check out the detailed steps in this tutorial Automating infrastructure deployments in the Cloud with Terraform and Azure Pipelines.
While looking for a solution i found this newly available ellipsis button next to the appsettings box. Clicking on it opens a new dialog where i can add app settings in key value pairs in a table format (similar to variable groups), each in separate line and easily maintainable (each setting can be deleted). On clicking OK it generates a string of all parameters.
I think this should be good enough to maintain appSettings for the function app.
Below is the screenshot
I have an Azure App Service Deploy task in my pipeline to deploy my Web Api Core app to the Azure App Service. The task has the following yaml -
- task: AzureRmWebAppDeployment#4
inputs:
ConnectionType: 'AzureRM'
azureSubscription: 'myserviceconnection'
appType: 'webAppLinux'
WebAppName: 'mytestwebapp'
packageForLinux: '$(Build.ArtifactStagingDirectory)/**/*.zip'
AppSettings: 'TestWebApp/TestWebApp/appsettings.json'
I have been following this document on how to update the settings in .json files. From what I could understand, I had to create a variable in the pipeline which matches the key I need to update. Let's say I have the following Json structure in my appsettings.json -
{
"AllowedHosts": "*",
"ServiceConfiguration": {
"Key1": "value1",
"Key2": {
"Key3": "value3",
"Key4": "value4"
}
}
}
Suppose I have to update key1 to somenewvalue1 and key2.key3 to someothervalue3 and so on. So I created new variables by hitting the Variables button on the pipeline and added Key1 and key2.key3 as variables with appropriate values (as a side note, the value is a constant string, but I want this to be a dynamic value which will be provided by another task in the pipeline). Also, I provided the path for the appsetting file as shown in the image below -
But, when I run the pipeline, I get the following error-
Error: BadRequest - Parameter name cannot be empty. (CODE: 400)
I came across this SO question and also created the app setting on azure portal, but this also didn't work
What am I doing wrong here.
As a side question, As seen in the first image, what is the difference between File Transformation & Variable Substitution Options and Application and Configuration Settings and when to use what.
EDIT
Based on the comment, I was able to resolve the issue, so no more errors and I was able to verify the updated setting in the azure portal.
However, when I see the appsetting.json from Kudu inside the Site wwwroot folder under Browse Directory, I couldn't see it updated. Why are these valuees different, and if so, which value is actually considered.
Thanks
So it seems that one expects JSON containing the settings, and not a file path.
As for the settings file not updating, that is expected.
This is updating the settings in the Configuration tab of the App Service, which will be passed to your app as environment variables.
It won't update the file.
Instead it sets settings that override settings in the file (at least by default if you the default host builder).
It'll only override settings you specify.
I'm currently trying to use the launchSettings.json file to manage the environment variables of the application, so my Setup.cs file can manage the environments in the way of env.IsDevelopmentEnvironment(), etc.
In VSTS, how do I go about setting the environment variable ASPNETCORE_ENVIRONMENT on an Azure Deployment task? Or should it get in the dotnet publish task I've got in my build steps?
Because ASPNETCORE_ENVIRONMENT is an environment variable, you can just specify it on Azure.
See the Stack Overflow answer on How and where to define an environment variable on Azure.
If you want to keep your deployment process idempotent, I'd suggest using this deployment step to set on the Azure Web App.
https://marketplace.visualstudio.com/items?itemName=pascalnaber.PascalNaber-Xpirit-WebAppConfiguration
Technically it adds release settings to the web.config as well, which isn't necessary for a core app, but importantly, it also sets the Environment Variables for the Azure host.
Provided you have specified to use environment variables in your Startup.cs:
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables(); //override settings with environment variables
var config = builder.Build();
Configuration = config;
}
So if you have a release variable: appsetting.ASPNETCORE_ENVIRONMENT = Release, you will find that $env:ASPNETCORE_ENVIRONMENT will indeed be "Release" if you're checking via the PowerShell console on Kudu.
I'm actualy using this extension to override all of my appsettings.json variables as well as ASPNETCORE_ENVIRONMENT at release-time instead of tokenzing some appsettings.{environment}.json file. I can just override with environment variables by using the right naming convention in my VSTS Release Variable names.
For example, if my appsettings.json has this structure:
{
settings: {
secret: {
foo: "bar"
}
}
}
I can override with a release variable such as:
appsetting.settings:secret:foo = "bar"
Then go check $env:settings:secret:foo on the Azure Web App after deployment
Without doing anything additional in my source or uzipping a web deployment package, tokenizing a config file and then re-zipping prior to msdeploy, I've got enviornment-specific configurations.
You can install the Replace Token extension and then add a Replace Token task in your build/release definition. This task could replace the strings in a file with the variable value you added in the build/release definition.