Update – Auto Packaging using CSPack and Azure SDK 1.6

This post is related to two of my previous posts:

Azure 1.5 ate my diagnostics

I had diagnotics working quite happily until SDK 1.5 came out.  Then all of a sudden data was no longer being transferred to  Azure storage.  Even more mysteriously diagnostics would happily transfer data to Azure storage when being emulated locally, but not when on the Azure cloud (in other words a nightmare problem)

I didn’t get around to investigating why till this week.  I saw that several people had the same problem, and assumed that the problem was that I wasn’t configuring the diagnostics correctly in the OnStart method.

Finally I saw this forum thread.  The thead described that if you upload your solution from visual studio diagnostic works correctly, but not when deployed from the build process.  I tried for myself, and yep diagnostics would magically work when the solution was deployed from Visual Studio.  This finally clued me into the fact that the problem had nothing to do with the code, but everything to do with packaging.  Which leads us to this update on Auto Packaging your Azure solution.

Configuring Your Azure Continuous Integration process with CSPack and SDK 1.6

My previous post on using CSPack to automatically build your deployment packages is largely still correct.  But as of (I assume SDK 1.5) there’s a new EntryPoint property.

So you need to specify the name of the DLL that is the entrypoint to your solution.  In mycase HuzuSocial.App.dll.  So my AzureProperties.txt file now looks like this:

TargetFrameWorkVersion=v4.0
EntryPoint=HuzuSocial.App.dll

Now configured correctly, Diagnostics works as expected from our Continuous Integration process.

Automating Azure 1.4 Packaging using MSBuild and CSPack

Update 20/06/12 – A working sample of the below can be found in my Nant.Builder nuget package.

Our team recently upgraded to the August 2011 Azure tools update, which provided some nice new features, but completely broke our automated build process.  This was because the way Azure builds were created was modified (although in fairness it now seems to be more inline with Msdeploy builds).  Fixing this was pretty painful, so I thought I’d blog it.

There are 2 steps to creating an Azure package:

  1. Use MSBuild to create a MSDeploy package with the appropriate configuration
  2. Use CSPack to use the MSDeploy package files to create the Azure package you’ll deploy to the cloud.

Compiling your solution for Azure using MSBuild on the command line

First we need is to build a MSDeploy package with the correct configuration.  If you’re using web.config transforms (and you really should be) this also ensures that the web.config file is set with the correct transforms.  So we want to execute MSBuild with the following parameters:

msbuild.exe YourSolution.sln
/p:Configuration=Release
/p:DeployOnBuild=true
/p:DeployTarget=Package
/p:AutoParameterizationWebConfigConnectionStrings=false

This will create a MSDeploy package.  The AutoParameterizationWebConfigConnectionStrings flag is required if you’re using web.config transforms – because we’re not using MSDeploy to actually deploy our package we can’t rely on it to populate the connection string.  If the value is set to true your connection string will look like this:

connectionString="$(ReplacableToken_HuzuSocialDB-Web.config Connection String_0)" />

Clearly this would fail once running on Azure.  With the flag set to false, the connection string is transformed along with any other settings.

Using CSPack on the command line to create your Azure package

We now want to take the MSDeploy package files and turn them into a Azure package.  First we need to find the MSDeploy package files – these should be located in the obj directory of your Web App.  The location is set in the Package/Publish Web settings in the properties of your web project, however, I wouldn’t recommend changing the defaults:

If you navigate to the obj directory, you’ll want to then drill into the directory named after the Release-Configuration you supplied to MSBuild, eg:

The directory we are actually interested in is PackageTmp as this is what MSDeploy uses to create the package, but most importantly here you will find the transformed web.config file.

We can now point CSPack at the PackageTmp directory.  The CSPack executable lives in the bin directory of Azure SDK

C:\Program Files\Windows Azure SDK\v1.4\bin

So to build our package we run CSPack with the following params

cspack.exe C:\HuzuSocial\HuzuSocial.Azure\ServiceDefinition.csdef
/role:HuzuSocial.App;C:\HuzuSocial\HuzuSocial.App\obj\Release\Package\PackageTmp
/rolePropertiesFile:HuzuSocial.App;.\AzureRoleProperties.txt"
/sitePhysicalDirectories:HuzuSocial.App;Web;C:\HuzuSocial\HuzuSocial.App\obj\Release\Package\PackageTmp
/out:C:\HuzuSocial\HuzuSocial.Azure\HuzuSocial-Azure-Release.cspkg

There’s a lot going on here, so I’ll break it down line by line

cspack.exe C:\HuzuSocial\HuzuSocial.Azure\ServiceDefinition.csdef

This tells CSPack where your ServiceDefinition file is located.  Next:

/role:HuzuSocial.App;C:\HuzuSocial\HuzuSocial.App\obj\Release\Package\PackageTmp

This specifies where the files to create the role are located, in our case, this the PackageTmp directory that MSBuild created for us, as described above.  Note that the role name, in this example HuzuSocial.App must match the WebRole name as specified in the ServiceDefinition file:

<WebRole name="HuzuSocial.App" vmsize="Small" >

Next:

/rolePropertiesFile:HuzuSocial.App;.\AzureRoleProperties.txt"

This is optional if you’re working on .Net 3.5 but if you’re working with .Net4 you need to tell CSPack that you’re targetting framework v4.  This is done by creating a txt file that you can then point CSPack at, in our example we have the file in the same directory as CSPack, but it you can store it anywhere (I actually have added it to our solution).  The entry in the file is as follows:

TargetFrameWorkVersion=v4.0

Update 08/12/11 – As of SDK 1.6 you also need to specify EntryPoint parameter, especially if you’re working with Diagnostics.  See this post for more details.

Next:

/sitePhysicalDirectories:HuzuSocial.App;Web;C:\HuzuSocial\HuzuSocial.App\obj\Release\Package\PackageTmp

Here we are telling CSPack how the physical files are to be packaged for deployment to Azure.  Here we are specifying the name of our role, our site name, as defined in the ServiceDefinition file, and finally where the files are located.  (It is here I believe that we can define multiple sites to be hosted in one role).  Finally we have:

/out:C:\HuzuSocial\HuzuSocial.Azure\HuzuSocial-Azure-Release.cspkg

This is the most straightforward param, simply telling CSPack where the package file should be output and what it should be called.

Conclusion

You should now be able to automate the above in your build tool of choice, I use NAnt.  Meaning everytime someone on the team checks in we have a new Azure package ready for deployment.  Next steps would be for the package to be deployed into a staging role automatically using CSRun, if I get round to this I’ll blog it as well.

We can also conclude that all of this is very non-obvious.  Microsoft do not make it easy to do Continuous Integration (CI), especially with Azure packages.  They have improved the tooling to deploy to Azure from your desktop, however, the whole point of CI is to ensure all your tests have passed, there’s no build errors etc.  Deploying from your desktop circumvents all of these, not to mention introducing a human element into deployment that could break something.  I feel MS really could help us out by making all the above a lot more straight-forward.

Useful Posts

I couldn’t have created this post without the following invaluable info:

http://tomkrueger.wordpress.com/2010/07/27/azure-deployment-issue-after-upgrading-to-visual-studio-2010-and-net-4-0/
http://zvolkov.com/blog/post/2010/05/18/How-to-Publish-Web-Site-project-using-VS2010-and-MsBuild.aspx
http://blog.jayway.com/2011/03/20/configuring-automatic-deployment-of-a-windows-azure-application-using-teamcity/