Strategy for deploying multiple web configurations from a build
Asked by Tomas Klumker:

We currently have a workflow that looks something like this:

* We have a development, test, staging and production environment
* We have branches in source control that match these environments
* We merge into these branches via pull requests
* Pull request merges trigger builds in bamboo for that branch
* Successful builds of that branch trigger a Bamboo deploy of that branch into it's matching environment

What we are looking to do is just have one branch that builds, and have that build be promoted from one environment to the next from within Bamboo's deployment area. The problem we are facing is that we have .net web.config transforms that are executed at the build stage that have environment specific setup within them. If we are deploying to each environment based on a single build, how do we specify which configuration to use and when does that transform occur?

My initial thought is to generate each environment's transform file within the build and save them as artifacts to pass on to the deployment project, and then use them there to deploy to their respective environments. Does this approach seem valid? This seems like a common scenario, so I was just wondering how others may look to solve this problem.


Answers:
author: Gretchen
body: If you do the build and deployment in bamboo (using build AND deployment plans) this shouldn't be a huge complication as long as the configuration files do not need to be compiled into the application that gets deployed.

For example with .NET you have webconfig files that are environment specific.

If you build your application normally (environment agnostic) and then in your deployment plan create tasks that merge the webconfig files into the deployment location. If some kind of compile or something is required, you might have to come up with a way to do your transforms for all environments every time (segregating them on the filesystem within the bamboo working directory)

The only tricky part is getting the config files in the correct place so you can grab them in the deploy plan.

Because bamboo deployments have environments that contain the tasks specific for that environment this should be fairly easy. You can do build activity (msbuild, devenv tasks etc.) in the bamboo deployment plan so think about how you might use that.

The way we did it was to create a single deployment folder in the repo and pull that every time. Make sure that the files you need in ALL environments are available in the build artifacts so that you can pull them in during the deployment process.

So everything would be in every build but the deployment plan would select the files it actually needed in order to push them to your servers.

It wasn't perfect but it did work.

Every build has the potential to be deployed to all environments but the env configuration step needs to be handled in the deployment plan, not the build plan.There would be a bit of scripting to get the correct files in the correct location to deploy, but isn't there always?

Hope this helps.

comments: author: Tomas Klumker
body: Yes, this sounds like the approach we were considering and seems to make the most sense. It helps to bounce it off others to sanity check it. Thanks!


author: Chris G
body: I am struggling to get around the same issue and this solution makes a lot of sense to me when dealing with the configuration files. Where it seems to get trickier is with the actual dll's that are getting built and deployed. Our CI and CD process is built out with individual plans for each environment and the build part builds the dll's semi-specific to the environment. For instance, our dev and testing builds contain debug symbols and don't optimize the code (and maybe a couple other setting variables) whereas our staging and production builds don't contain debug symbols and do optimize.

This would force the build plan to do multiple builds, though I'm just realizing now that it wouldn't be a build for every environment but rather two builds, which is a lot better but still adds a significant amount of execution time for each build plan. Now I'm wondering if it's even worth it to have different build settings or just always build production ready dll's. Has anyone else solved this problem?


author: Chris G
body: Reading through both answers a little more thoroughly I think they pretty much address the issue I'm struggling with. I guess ultimately CI and CD are processes that are meant to work and rarely look super clean and pretty.


author: Daniel Wester
body: You can generate it into the artifact like you mentioned (dev.json, qa.json, prod.json etc) and then have a flag in each env to designate the file to use. The problem that you might run into is when you add the next env - do you really want to do another build in order to just get another config file into place.

Depending on your situation you might want to look at configuration management tools (Ansible is pretty light weight) and have it maintain the configuration files). Or failing that - create another build which does the configuration pieces and then have a different deployment plan to send that out.


Tags: bamboo-administration