Azure DevOps VSTest task - appconfig settings - azure

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.

Related

Environments are not automatically created in Azure Devops when declared in yaml pipeline config

I'm new to Azure Devops. I would like to have devops pipeline environments to be created automatically during pipeline flow. So the 5th line below should create environment if it does not exist:
- deployment: Deploy
displayName: Deploy job
pool:
vmImage: $(vmImageName)
environment: 'production'
Instead I'm getting:
What am I missing?
To automate environment creation I could also use Terraform but this time I cannot find terraform resource config responsible for that.
I had a similar problem and found that the documentation lists some possible reasons for why this can happen:
Quote from learn.microsoft.com:
Q: Why am I getting error "Job XXXX: Environment XXXX could not be
found. The environment does not exist or has not been authorized for
use"?
A: These are some of the possible reasons of the failure:
When you author a YAML pipeline and refer to an environment that does not exist
in the YAML file, Azure Pipelines automatically creates the
environment in some cases:
You use the YAML pipeline creation wizard in the Azure Pipelines web
experience and refer to an environment that hasn't been created yet.
You update the YAML file using the Azure Pipelines web editor and save
the pipeline after adding a reference to an environment that does not
exist.
In the following flows, Azure Pipelines does not have
information about the user creating the environment: you update the
YAML file using another external code editor, add a reference to an
environment that does not exist, and then cause a manual or continuous
integration pipeline to be triggered. In this case, Azure Pipelines
does not know about the user. Previously, we handled this case by
adding all the project contributors to the administrator role of the
environment. Any member of the project could then change these
permissions and prevent others from accessing the environment.
If you are using runtime parameters for creating the environment, it
will fail as these parameters are expanded at run time. Environment
creation happens at compile time, so we have to use variables to
create the environment.
A user with stakeholder access level cannot create the environment as
stakeholders do not access to repository.
In our case, the problem was using runtime parameters for creating the environment.
You have the environment name 'production' hardcoded, so your problem might be related to one of the other cases.

Azure replace token for Service model endpoint for Asp.net MVC in pipeline release task

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.

How to manage config for different environments like dev prod uat when code deployed through Azure CI DevOps?

I have a Develop branch in VSTS and build(CI) definition is successful. Now, I want to deploy build to Dev and UAT and PROD environments. If release is success, then all environments will have Dev settings, since Dev build/Dev branch web.config have dev settings. How can I manage UAT/PROD/DEV settings for respective releases.
Note: Dev settings mentioned in web.config of Develop branch.
Update 1:
For below XML file, values need to be modified at runtime based on different environments.What need to be configured in Release pipeline for .xml file value changes.
<RPSServer>
<Sites>
<Site SiteName="default">
<SiteId>123546</SiteId>
<ReturnURL>Custome URL</ReturnURL>
</Site>
</Sites>
</RPSServer>
In above xml file, SiteId and ReturnURL will be different for DEV,UAT and PROD
If you have a release pipeline then using variables can help with that.
Not sure where did you deploy to, however both the Azure App Service Deploy and IIS Web App Deploy tasks now support file transforms and variable substitution. In case you are deploying the app through Azure App Service Deploy task, there is File Transforms & Variable Substitution Options that can do transform.
You can also use XDT Transform extension that can apply transform for config file, so you can include/add the related configure files in release artifact, then configure transform per to release environments.
Another way is that you can replace the value in configure file through Replace Tokens or Tokenization task.
You can reference the following blogs to do that:
Using Tokenization (Token Replacement) for Builds/Releases in
vNext
Tokenize your VSTS pipeline the easy way!
Manage Web.config Values between Environments in Release Management
and TFS
-
UPDATE:
It's also available to replace the tokens for *.xml files. For example with the Replace Tokens extension, we can edit the xml file as below, then set variables for different environments/stages.
<RPSServer>
<Sites>
<Site SiteName="default">
<SiteId>#{SiteId}#</SiteId>
<ReturnURL>#{URL}#</ReturnURL>
</Site>
</Sites>
</RPSServer>
Reference below screenshots:

Defining which project should be deployed to an Azure Functions app from source control

We have a collection of Azure Function Apps in c# net core. Each App contains a small number of Azure Functions. All Function Apps reside in a single git repository.
We would like some of our environments to deploy automatically from source (e.g. bitBucket or gitHub).
How do we configure the project so that Azure knows which project in source relates to which created Function App?
I have searched around this problem for a number of days and have not seen any results that sit outside of "it just works" so can only assume that we are missing something fundamental.
I'd recommend using Azure DevOps (formerly VSTS) to deploy to Azure, you use YAML to define a build pipeline which can publish an artifact from each of your function apps. The artifacts then get picked up by a release pipeline and can be deployed to Azure.
The basic building blocks of this are, firstly some YAML like this in your build pipeline for each project:
...
steps:
# a script task that let's you use any CLI available on the DevOps build agent, also uses a variable for the build config
- script: dotnet build MyFirstProjectWithinSolution\MyFirstProject.csproj --configuration $(buildConfiguration)
displayName: 'dotnet build MyFirstProject'
# other steps removed, e.g. run and publish tests
- script: dotnet publish MyFirstProjectWithinSolution\MyFirstProject.csproj --configuration $(buildConfiguration) --output MyFirstArtifact
displayName: 'dotnet publish MyFirstProject'
# a DevOps named task called CopyFiles (which is version 2 = #2), DevOps supplies lots of standard tasks you can make use of
- task: CopyFiles#2
inputs:
contents: 'MyFirstProjectWithinSolution\MyFirstArtifact\**'
targetFolder: '$(Build.ArtifactStagingDirectory)'
# now publish the artifact which makes it available to the release pipeline, doing so into a sub folder allows multiple artifacts to be dealt with
- task: PublishBuildArtifacts#1
displayName: 'publish MyFirstArtifact artifact'
inputs:
pathtoPublish: '$(Build.ArtifactStagingDirectory)\MyFirstProjectWithinSolution\MyFirstArtifact'
artifactName: MyFirstArtifact
# now repeat the above for every project you need to deploy, each in their own artifact sub-folder
Next you create a release, which in its simplest form picks up the artifacts and does one or more deployment, here's a simple one which deploys two function app projects:
Within a deployment stage (right hand side above), you can define your release process, again in its simplest form you can just deploy straight to production or to a slot, although until function slots are out of preview you could also spin up another function app and deploy and test there.
This screenshot shows a simple deployment which uses a standard Azure Function App deployment from Azure DevOps:
Within your deployment stage you can define which artifact is deployed and after running your build pipeline for the first time you'll get to see all the available artifacts that it created.
All or parts of the above can be automated from pushing a branch (or other triggers such as on a schedule). Notifications and "gates" can be added as well if you want manual intervention before release or between release stages.
There are also other ways to cut this up, eg with multiple build pipelines, it’s basically completely flexible but the above are the elements you can use to deploy one or more function apps at a time.

How to setup a VSTS build definition to publish Azure Functions with this configuration?

We are using VS 2017 on a single solution with multiple projects and we right mouse click and deploy 3 C# Azure Function to two different Azure Function apps with slots.
How do you set up the VSTS build definition to accomplish this on every check in?
We are using the DLLs and setting up the function.json this way. I don’t know if we need to deploy differently based on this type of configuration.
"scriptFile": "..\\bin\\target.dll",
"entryPoint": "target.Application.Run"
I was able to create a VSTS deployment through the following steps
Solutions structure
Build Configuration Steps
Sync from master branch
Added Nuget Restore using default options
Added MSBuild Step with the followign optons
Project : vstsSolution.sln (Selected using '...')
MSBuild Version: Latest
MSBuild Architechture: MSBuild x86
Clean: Checked
Create Log File: Checked
Added App Service Deploy for Function App1
Azure Subscription: Target Subscription
App Service Name: Target Function App
Deploy to slot: If you check this it allows you to select the actual slot you want to deploy to
Package or folder: FunctionApp1\bin\Debug\net461
Added App Service Deploy for Function App1
Package or folder: FunctionApp2\bin\Debug\net461
Make sure you selected "Hosted VS2017" Agent Queue for this build.
All Build Steps
Triggers: Enable Continuous Integration. So that both function app deploy every time you check-in.
Continuous Integration

Resources