How to build and deploy Azure Cloud Service with multiple configurations in VSTS Release management? - asp.net-mvc

We are using Team Services to maintain our web projects and Azure for hosting. At now, there are several Web Roles (asp mvc) and Worker Roles which is being hosted as Cloud Services. We are going to setup Continuous Integration and Delivery for them.
As you know, Team Services Build Definitions suggest to use Azure Cloud Service Template for building and Azure Cloud Service Deployment Task to deploy. We’ve tried it for single cloud service and it works.
In our case, there are web project (web role) and scheduler (worker role) as separate Cloud Services and they should be deployed simultaneously (in sequence), let it be DEV environment. But we have much more environments: dev, qa, ta, demo, preview, production, etc. Furthermore, each of them has slightly different web.config, ServiceDefinition.csdef and ServiceConfiguration.cscfg. And it became much more complicated task than just deploy one Cloud Service.
Questions are:
Should we build dozens of Cloud Service pachages (artifacts) and later decide which of them deploy or not? Could you suggest how to do it in a proper way? (in most cases it will be only Dev environment and we will waste time and resources for building other artifacts).
Will it be better to build one common artifact and later replace all configurations for specific environment? (It’s more complicated task because Cloud Service package zipped on several occasions with preconfigured ServiceDefinition and ServiceConfiguration)
What is the best way to replace configuration tokens (web.config, serviceconfiguration, etc) in Deployment mode, or it should be done while projects is being built?
I would be grateful if you suggest any best practices.

For azure cloud project, it’s better to apply changes to the project per to the environment before build, so you can build the project during the release process.
Regarding to deploy to corresponding environment, you can configure artifact filter with build tag.
For example:
Add a file (e.g. json, xml or txt) to project that used to determine which environments the release should deploy
Add a PowerShell task to build definition to read the data from that file (step1) and add build tag(s) through logging command (Write-Host "##vso[build.addbuildtag]build tag")
Add Publish Build Artifacts task to upload the source files
Create a release definition and link artifacts and add multiple environments
Configure Pre-deployment conditions for each environment: Enable Artifact filters=>Select artifact=>Specify build tags
Add tasks and variables (e.g. visual studio build) for each environment to deploy to corresponding environments.
On the other hand, regarding replace value, there are many ways, such as Replace Tokens, XDT Transform

Related

how to create deployment pipeline using jenkins

What does it mean by deploying code from dev to prod environments using Jenkins. Can anyone please help. I currently have the source code in my gitlab. I need to deploy this code from dev env to prod env
Thanks in advance.
Source code present in GitLab is just the files that is needed to create a WAR/EAR/JAR to run the application.
It's the environment files if present which makes the application behave slightly different on each environment i.e. DEV/PROD the data that you see on DEV will not be the same that you see on PROD(application is live), as developers tend to test/modify code/data to ensure that the application works as excepted. This is fine on DEV but is a big no-no on PROD as it will impact business.
Deploying code from dev to prod environments just means building the application with the right environment files e.g DEV points to xyz DB but prod points to abc DB.
All this can be achieved with jenkins and if your project uses maven/gradle then with a single line command you can achieve the above.(A bit of googling will help you here)
If your project doesn't involve Maven/Gradle then you will have to replace the environment file each time a build happens based on a parameter which can be passed from jenkins.
This whole process is part of DevOps culture. In simple terms it looks like this:
Developer pushes changes to source control (i.e. gitlab).
Build server (i.e. Jenkins) automatically downloads latest changes and builds an application (i.e. creates setup files or just the binaries). Usually you run tests (unit, integration, automation tests etc.). If something fails then developers get notified about it. This whole process is called continuous integration.
If everything went right then you can deploy your application to production. This part of the process is called continuous deployment.
It's a common strategy for web apps. For larger projects QA team tests the software and the software gets deployed once QA team approves it.

TFS release mangement of console applications

I have a console application where I need some ideas on how to build/release the config part of the application. When running locally in VS the config file is called app.config. After a build the file changes to .exe.config. We are using XDT transformation for building the config file to the different enviroment. But what would be the smartest way to ensure the naming convension is correct when release the build version to a server?
Seems you want to use TFS Build and deploy to multiple environments via Release Management.
For handling configuration in Release Management, there are two techniques generally used Config Per Environment and Tokenization.
If you prefer a clean separation between build and deploy. To achieve that, recommend tokenizing configuration.
More details please take a look at this wonderful blog: Config Per Environment vs Tokenization in Release Management
Environment specific application settings values configured in the app.config are tokenized. Above blog's method essentially inserts tokens into setting values during the build process. When deployed the tokens are replaced with matching Release definition configuration values.
Besides, for an example of a separate build and release solution, you could also take a look at this blog: Using web.config transforms and Release Manager – TFS 2017/Team Services edition (similar to app.config)

Copy files into Azure App Service

I am working on a website that will be deployed to various environments - Dev, UAT and Production - and each of them has different config settings defined through the use of config files.
The deployment process consists of two steps:
Publish the latest build output
Copy and replace the default config files with the one specific to the environment were the deployment is being done (these files are currently under source control)
I am trying to automate the deployment process using VSTS and Azure App Services but I couldn't find any task or option that would let me copy files into an App Service.
What is it the best way to implement this deployment process?
You can make this much easier on yourself by using config transforms for your web.config file.
Basically, make sure that you've defined a Build Configuration for each environment. Debug and Release are defined out of the box for Visual Studio MVC projects. You can add as many configurations as you want, such as a UAT configuration.
Once you have your configurations defined, make sure there's web.[your build config].config file located beneath your web.config in the Visual Studio solution explorer. Within each of these build configuration specific transform files, you can override settings as needed.
To close the loop, you can specify a build configuration to target when creating a build in VSTS. This will automatically execute the transform for the build configuration you've selected.
More details on build configs and web.config transforms here.
Alternatively, you could specify your app settings and connection strings directly in the Application Settings of your Azure Web App. These override anything in your deployed web.config file. What I like about this approach is that you don't have to expose sensitive information like connection strings to other developers on your team, and it removes the minor complexity of web.config transforms.
Kudu api give you the ability to upload and download files from azure web app with overwrite
The git:
https://github.com/projectkudu/kudu/wiki/REST-API
Not sure if vsts have this ability.
I recently did what you describe with Jenkins . Now I'm trying to integrate Jenkins to vsts
Hope it give you an answer

Create environment with multiple servers - TFS Release Management

Is there a way (or some plugin/add-on) to add servers to an environment in TFS Release Management 2015?
I came from a team that used Octopus Deploy for DevOps. One thing that was extremely helpful was the ability to add multiple servers to an environment. Then, when you execute deployment steps on an environment, it applies those actions to all the servers that are part of the environment -- making deployments super easy. I have yet to find similar functionality in TFS Release Management and it's quite sad. They have a concept of an environment, but it's more like a "stage" than a logical/physical group of servers. To deploy the same step to multiple servers in an environment, you have to re-create the step multiple times or specifically write the names of all the servers in each step. Sad!
There isn’t the feature that execute deployment steps on an environment and applies to all the servers that in the environment.
But for web-based release management, you can provide a comma separated list of machine IP addresses or FQDNs along with ports for many steps/tasks of remote deploy, such as PowerShell on Target Machines, IIS Web Deployment and so on.
There is an article that may benefit you: Environments in Release Management
Regarding server and client based release management, there is environment that can include multiple servers, but you need to add steps multiple times for each server. I recommend that you use web-based release management.

Azure build configurations vs service configurations

To paraphrase this rather long question:
Why would you need more than 2 build configurations for their project when used in conjunction with service configurations ?
I have a cloud service that contains multiple websites which needs to be deployed onto a number of different Azure platforms, one for Test, one for UAT, and one for Live.
Each environment needs a different host header defined for the website it deploys e.g. test.myportal.com, test.myservice.com, uat.myportal.com, uat.myservice.com, live.myportal.com and live.myservice.com.
This means I need to define a ServiceDefinition for each environment, fine so far.
In previous related questions I've seen (Azure: Is there any way to deploy different instance sizes for test/production, Azure connection string best practices (step 4, and using $(Configuration) instead of $(TargetProfile) in the .ccproj file), people have mentioned that you will need X configurations (meaning build configurations). This doesn't make sense to me, as I only need two build configurations (Debug and Release) for the way that the code is built, rather than how the service is configured. Rather, what I need are three service configurations.
My question is, am I right in thinking that a build configuration should only be used for how the code is built and that people who create multiple different build configurations for service configuration are wrong? (That's not the best word to use, I admit)
To further explain how I'm implementing a solution around this, I continue below:
I'm configuring my CI build server for MSBuild to take an additional parameter, TargetProfile, alongside Configuration.
The MSBuild commands for my environments look like this:
For Test:
msbuild mySolution.sln /p:TargetProfile=Test /p:Configuration=Debug
For UAT
msbuild mySolution.sln /p:TargetProfile=UAT /p:Configuration=Debug
For Live
msbuild mySolution.sln /p:TargetProfile=Live /p:Configuration=Release
For my cloud service, I use three ServiceDefinition.csdef files, one for each environment: ServiceDefinition.Test.csdef ServiceDefinition.UAT.csdef ServiceDefinition.Live.csdef. These are kept in a '/config/' folder.
In my cloud server ccproj file I only have two Configurations, Debug and Release, with a task in BeforeBuild :
<Target Name="BeforeBuild">
<Copy SourceFiles="configs\ServiceDefinition.$(TargetProfile).csdef" DestinationFolder="$(OutputPath)" />
<Move SourceFiles="$(OutputPath)ServiceDefinition.$(TargetProfile).csdef" DestinationFiles="$(OutputPath)ServiceDefinition.csdef" />
</Target>
This then ensures that I only ever need two build configurations, but can have as many service configurations as I like, just by changing the TargetProfile parameter that I pass into MSBuild.
To reprise my question:
Am I right in thinking that a build configuration should only be used for how the code is built, and that people who create multiple different build configurations for service configuration are wrong ?
One possible use case of different build configurations might be when a service needs to be deployed to multiple product platforms for different customers with different feature sets. In such a scenario, it might make sense for the build process to customize the individual feature sets (e.g. via the use of C# Preprocessor Directives) for performance and security reasons.

Resources