Initial thoughts on deploying with Octopus

I recently began using Octopus to deploy our line-of-business web application. Previously I had configured (TFS) to do this. The web application was already being built using as part of our (CI) pipeline, so I had configured to also take care of the (CD) too.

I had three deployments configured. One for (which was triggered automatically by the build) and one each for our and environments. The former deployment was to an on-premise server and was to give the developers an environment where they could test their changes. This environment would always have the latest changes as it was triggered by the build server as part of the pipeline. The and environments were both web sites and would be triggered manually. We didn’t want un-tested changes going into our or environments.

In the beginning, the and deployments were configured under . This all worked perfectly well until Microsoft updated their Powershell scripts to use the latest RM (Resource Manager) versions. As the deployments to Azure environments use Powershell scripting under the covers, this had the effect of breaking our Azure deployments to our and environments. At this point, we could no longer deploy to the or environments.

I initially investigated fixing the underlying Powershell scripts to use the updated RM versions, but this involved re-writing some quite complex scripts, and I wasn’t comfortable doing this. I then looked to see if Microsoft has provided any updates for this script but there didn’t appear to be any. As a temporary workaround I decided to write some scripts to do get the job done. I used to deploy to our and environments.

I wrote two scripts. One for deploying to and one for deploying to . They both followed the template below. The heavylifting of the deployment is the synchronize command. This effectively checks for any changes between the local and remote servers and updates to the latest as necessary.

Hide Copy Code

option batch abort
option confirm off
option transfer binary
open ftp://mytestenvironment:mypassword
cd /site/wwwroot
synchronize remote "C:\Builds\TFS\MyWebApp\Latest" /site/wwwroot

This worked well enough but wasn’t bulletproof. It would sometimes fail when unable to copy one of the assemblies. The assembly was being cached by the Azure web server, and so the deployment would fail. I got round this problem by writing a Powershell script to stop / start the Azure web hosting.

The deployment scripts performed the following tasks.

  1. Stop the Azure web site (Powershell script)
  2. Deploy the latest changes (using WinSCP)
  3. Start the Azure website (Powershell script)

I have previously written an article on how to stop / start an Azure web site here.

So although all these scripts worked and deployed to the Azure environments successfully, having to write and maintain these scripts seemed a bit klunky. I wanted something more robust for our pipeline than a bunch of hand written scripts.

This is where Octopus comes in. I’d very briefly looked at Octopus at a previous company I worked for. I decided I would use this for our deployments to our Azure environments. I would still keep the on-premise pipeline for but use Octopus to deploy to our Azure environments. I created an account with Octopus and began configuring our deployments. It took me a morning to get everything working. I won’t go through a step-by-step guide as these can already be found within the Octopus documentation on their website (and as every deployment configuration is unique it probably wouldn’t be a very useful exercise anyway).

I was very impressed with just how easy and flexible it was to configure our deployments. The documentation was very helpful and all the options and settings all seemed intuitive. If you’re familiar other IDEs then Octopus will not be difficult to pick up.

I have a script that is part of our pipeline that creates a nuget package from our published artifacts and pushes this nuget package to our Octopus environment. I downloaded and installed the Octopus tools onto our build server which then allows me to invoke the octo.exe command.

Here are the two commands the pipeline invokes for creating the necessary nuget package and then pushing this to our Octopus environment.

Hide Copy Code

octo.exe pack --id MyWebApp --version %1 --basePath "C:\Builds\TFS\MyWebApp\Latest\websharelatest" --outFolder outputfolder

Hide Copy Code

octo.exe push --package=outputfolder\MyWebApp.%1.nupkg --overwrite-mode=OverwriteExisting --server= --apiKey=API-QWERTY123456 --debug --LogLevel=debug

When we’re ready to deploy to our Azure environment(s), we simply create a new release within Octopus and deploy the latest nuget package which our pipeline has already made available for us.

All in all, moving to Octopus has totally streamlined our pipeline. It is far more robust and uses a first class technology now instead of the myriad klunky scripts it used previously. We haven’t had a single issue since switching to Octopus. If you really want to take your deployments to the next level, then I’d highly recommend looking into Octopus.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Dominic Burford

A father, cyclist, vegetarian, atheist, geek and multiple award winning technical author. Loves real ale, fine wine and good music. All round decent chap.