Archive for the ‘continous integration’ Category

Deploying your Server Roles: Using MSDeploy for Enterprise Deployments.

 

This is an update that builds upon the previous posts about how We do Deployments.

 

The development environment is simple

The previous posts built upon our remote deployments.  These examples were pretty trivial and not realistic, for the fact that in our development, testing, and staging environments we deploy an entire application to a single server.  That includes a web application, database migrations, batch jobs, ect.. 

 

A production environment needs Roles

All production environments I have deployed to have at least two roles.  Usually a Web Server and a Database Server.  In many cases we would have a web farm which is a number of web servers with identical configurations that have a hardware device that sits in front of them (Load Balancer).  This type of environment requires that your database migrations need to only run on the database server.  It is possible to update the database from a webserver deploy but this means that you may need to pass through a sql connection string with sql authentication.  I do not like that option because in production I prefer to have service accounts (windows accounts) act as the credentials to authenticate to the database server.  By doing this it allows me to have a consistent deployment where security always works.   But, using Windows authentication becomes troublesome if your production environment is all not part of a windows domain.  I have found that more often than not, in hosting environments, the servers are usually built as standalone servers.  This causes a problem with trying to deploy your database changes through your web server.  MSDeploy does not propagate the clients windows credentials to other network connections when it runs. 

 

My work around was to introduce a concept of deployment Roles.  This helps clean up the deployment to make it simpler.  A side benefit, is that the deployments to each role become more efficient.  Lets explore the Roles:

I created to Roles:

  • Web – This includes the webserver / web application code. Configuration files are updated to point to the production database instance at deployment time.
  • Database – This includes running the database migrations and optionally supports additional data loads.  The additional data loads are used to load code tables and other look up data that is not configurable in the application.

 

So how does this change the previous examples?

First I have a call to my deploy script for each Role, here is an example of setting this up in CruiseControl.Net

image

The first call updates the webserver but includes the database server address so that the deployment will update the appropriate connection strings in the config files. This call runs the Web role.

The second call updates the database server, and runs the database role.

 

The role is actually passed to the script through the deploy.cmdargs parameter. Since this is a string the role is just being passed through in the calls to MsDeploy. Notice my script to call msdeploy does not change, or reference an additional parameter.

image

Now my actual deployment script just needs to branch its install logic based on a parameter value of web or database.  It is pretty simple.  I will show a nant example, but I have already started to move these types of scripts to powershell.  There are many reasons for that, but ultimately I think of powershell as being the default scripting language for the servers that we are using.  Since the there are built in support for IIS and Sql Server in powershell it only makes sense to use this tool over other scripting tools.

Here is my new build file for deploying roles.

image

 

I know I have breezed over how these scripts are wired together, but I hope that the concept still makes sense.  I will update the Code Camp Server project with these files as well as the powershell versions of them soon.

Kick It on DotNetKicks.com

Using MSDeploy to automate your Enterprise Application remote deployments.

MsDeploy is a newish technology that is a bit schizophrenic.  What I mean is that it is a tool that is useful to both Developers and Administrators but it is not clear from the documentation how to best use the technology and how to approach it. I believe it stated as a Server Administrator tool and the team was able to work in an integration with Visual Studio which made it into a more robust framework, but at the same time left is command line interface with so many options that it is challenging to get a grasp on.  To top that off the Web Platform Installer uses the MsDeploy packages as a way to distribute packages through that tool.  After working through some various ways to use the technology I have settled into some commands that work well for our projects.

 

Let me set the context of how we are using the tool and what we already had in place so that you can better understand if my use of MsDeploy will work for you. At Headspring we use Continuous Integration on all of our projects and as a result, once our software is built by our build server the next logical step is to deploy our software to a server and than run User Interface tests against the application. Most of our projects are web applications running on ASP.Net MVC using Sql Server as the back end.  We install our software using a lightweight zipfile that contains the web application files, database migration scripts and a deployment script which can poke config files and execute our database migration tool.  We already have all the pieces in place to deploy our application on a local machine.

 

Up until know we have used two methods to deploy instances to remote machines.  The first methods was to install Cruise Control.Net on the server and have it monitor our source control repository for a new installation package being committed to the repository. Once it sees a new package CCNet will pull down the package, install it locally and go on its merry way.  The second method, is to kick off the deployment from the build server and connect over the network to the target database to run upgrades and then xcopy the files to a unc share.  Both of these methods require setting up some configuration on our target servers. My goal with our deployments is to reduce the amount of per server configuration we do on each server and use some conventions to make each server look similar to one from a different project.

 

Using MSDeploy allows us to do the following.

1. Remove the need to install cruise control on the target server and update the configuration for cruise control on each target server.  We do have to install MSDeploy on each server but we do not have to mess with any configuration after that.

2. We do not have to mess with setting up unc shares and deal with the mess.  It sounds like a silly thing but by getting away from the unc share we can also test our deployments from any machine and msdeploy is actually firewall friendly.  xcopy to a unc share is not firewall friendly which means that we cannot use it for all of our clients which means variations between our projects. 

3. We use msdeploy as a mechanism to distribute our deployment packages and then remotely execute the packages.  This means I can have a single instance of our Continuous Integration server which reduces the number of places to maintain configuration.  That is a big win.  This also means the log files for all of the deployments can be tracked in a single place.

4. Another benefit of using msdeploy to push our deployments means that I can easily setup new instances of a test configuration and push it to multiple servers without having to log into each machine.. This is good for efficiency.

Our use of MSDeploy now boils down to two steps.  Distribute and Execute.  We have some of our scripts in NAnt and we are in the process of migrating to PowerShell now that version 2.0 is available from the older operating systems.  Below is a sample of executing msdeploy from a NAnt script.

Calling MsDeploy from Nant

image

The dirPath  command tells MSDeploy to synchronize a directory from the source computer a target computer. This is a pretty easy command to understand.

The second command is the runCommand this command was added between the RC and 1.0 release of MSDeploy and I am so happy they added it. The run command is told to execute a command on the remote machine.  Since we are running installation scripts, they do not execute instantly and as a result the waitInterval and waitAttempts need to be specified so that the command does not timeout before it has completed running. other than that the output of the console application is piped back to the source computer.  The one caveat about the run command is that when it starts it runs from the C:\windows\system32 directory.  In order to work around this issue I have found that passing the directory of the command into the batch file that I run allows my batch files to first cd to that directory as its first step.  This is a pretty harmless thing to do and works pretty well.

This is what a sample deployment batch files looks like.

cd %1
rd ..\codeToDeploy\ /s /q
applicationNamePackage.exe -o..\CodeToDeploy\ -y
cd ..\CodeToDeploy\
cmd /c %systemroot%\system32\inetsrv\appcmd stop site applicationName_dev
iisreset
call dev.bat
cmd /c %systemroot%\system32\inetsrv\appcmd start site applicationName_dev

This is pretty basic and does some IIS commands as well. 

 

I am sure I left some information out, but I wanted to get a brain dump of our use of MSDeploy.

 

Long term I would like to see the use of PowerShell driving msdeploy and adding some configuration around each Server Role in an application and tie it to the servers needed for each environment.  I have started a project to put this together called psTrami but I have not put any of the code together yet, just some small spikes to prove it out.

 

More to come sometime soon…..

Kick It on DotNetKicks.com

Video of the Continuous Integration workshop

Early this week we  ( Jeffrey Palermo and I ) gave a Continuous Integration Workshop in Austin.  We were able to record the workshop and our company Headspring Systems made the recordings available on their website. There is just under 3 hours of video covering the following topics:

  • reducing risks using CI
  • automated builds
  • automated deployments
  • building software at every change
  • continuous database integration
  • continuous testing
  • continuous inspection
  • Software Configuration Management (SCM)

 

These are not professional videos by any means, but there seemed to be some interest in hearing how we do ci. I am personally excited that we have these videos because it will help me improve how I present this information in the future.

You can view the videos and download the slides from here:

http://www.headspringsystems.com/services/agile-training/continuous-integration-boot-camp/

 

Enjoy!

Kick It on DotNetKicks.com

Continuous Database Integration – video

At the continuous integration workshop Headspring Systems held in Austin this week one of the topics that we covered was Database Integration. We are still in the process of publishing the videos of the entire workshop but I thought I would publish this snippet (30 minutes) that talks about how We Do Database MigrationsJeffrey Palermo and I did this workshop and had a great time doing it. This demonstrates how to use the Tarantino toolset.

I hope  this is useful and would love to hear some feedback about what you like or hate about this approach.

 

Kick It on DotNetKicks.com

Free Continuous Integration Workshop in Austin Tuesday Sept 15th 1pm-5pm

 

I am doing a Continuous Integration Workshop next Tuesday.  The admission is free and will be held at the Microsoft Office. 

To register go here: http://www.headspringsystems.com/services/agile-training/continuous-integration/

 

This will cover the basics of what continuous integration is as well as the the advanced techniques like Database Configuration Management / Continuous Database Integration.  At Headspring we implement CI on all of our projects and we can provide some perspective on applying CI to .Net applications.  If there is anything of particular interest you would like to see at the workshop please feel free to comment below.

If you cannot attend this workshop I encourage you to read this book: Continuous Integration: Improving Software Quality and Reducing Risk and have a conversation with me.

See you then.

Kick It on DotNetKicks.com