CI/CD with TFS/VSTS and Octopus Deploy

Building off my previous posts here and here about building multiple projects within a solution and troubleshooting packaging of your projects. We will now delve deeper into the Continuous Integration and Continuous Deployment pipeline that can ease the tensions of Deployment Aversion. Using two very powerful tools in your arsenal, you can streamline your deployment process and ensure that you are getting the biggest bang for your buck. Up until now we have identified our pipeline components and we have successfully, albeit manually, deployed our sample codebase to our destination servers. The question now is: can I streamline my pipeline using good ALM practices?


  1. You have your source code checked in
  2. Your build definition is in place
  3. You either have a partial Octopus Deploy project or similar

Setting up for success

Lets double check our Octopus Deploy Project. We will need to ensure that we have certain steps, configuration values, and settings.

Lets start out with cloning our already working deployment project.


Save our newly cloned project. We will get back this Octopus Project in a moment, but first we will need to do somethings with our TFS/VSTS build definition. In this example, we will expand upon our previous build definition and clone it. Why? Well first we know that it works and second it is easier to take away unneeded steps instead of trying to add and configure steps from memory. Cloning a Build Definition is very simple and straight forward. The below gif shows you how its done.


Since our build definition is only queued manually we will need to go and make some changes to the Triggers for the build to allow it to perform the CI for the beginning of our CI/CD pipeline. We will edit our newly cloned build definition and choose the Triggers tab and then select.  For now we will just check the Continuous Integration and leave the defaults.


Now each time there is a change to the codebase and change is checked in, this build definition will start and finish with our packages being pushed to Octopus Deploy. One of the many benefits here with the use of Triggers is that you can have multiple build definitions that can focus on specific branches and with CI/CD working in your favor your can get your code to testers or others for faster consumption and approval.


CI/CD Option 1

You are probably asking yourself why there is an Option 1 and 2. Well the fact of the matter is that with Octopus Deploy Extension you basically  perform can perform all of the steps of packaging, creating a new release, and finally queuing up a deploy.  Essentially, TFS/VSTS is now a one stop shop for building and orchestrating  your build and deployment pipeline.

How to perform Option 1

Going back to our CI/CD build definition we need to add a couple of more steps. Click add build step and select and add Create Octopus Release and Deploy Octopus Release.


Now we see that for our entire build definition we can build, test, package, publish, create and finally deploy a release. If you noticed that there was Promote Octopus Release, that task can be used in other build/deployment scenarios. For now, though, we are just going to use the create and deploy release.


Editing our create Octopus release step, we see a lot of options that we will need to fill out. We fill out the Octopus Deploy Server connection endpoint, we select the project name. For now we are going to use the Octopus defined version number, but later we can change this to be what ever SemVer compatible version number we want to display. Finally in the Deployment section we select our initial environment we would like to deploy to. After that because I like verbose logging for troubleshooting, select the Show Deployment Progress. This will ensure that we have a complete set of logs for our End-to-End test.


One thing to note here is that you add a lot of data for your release notes. This great for troubleshooting or even attempting to rollback to an earlier series of changesets.

We are going to kick off a manual build/release creation first, but to make sure that we are putting everything in the correct order.


and the end result without doing anything special with Octopus Deploy.


and now our Web application is still functioning.


Let’s go and make a change now in our source code, check it in and then see what happens.

Made some changes to our index page.


checked it in


Synced with the master (because this is a Git repo)


Build kicked off


Build finished and deployed


Now to validate against the working web application.

It worked. I made the change and the change was “automatically” reflected on the site. Now keep in mind this is simple way to perform this function. If you needed to perform a rolling deployment, or some other type, it would make sense t to adjust for Octopus Deploy process to accommodate those requirements.


CI/CD Option 2

Option 2 involves some manipulation of Octopus Deploy and not so much TFS/VSTS. If we leave what we were currently performing in TFS/VSTS from my previous post we will need to work and manipulate Octopus Deploy a little more.  So following the same example as above we will clone both the TFS/VSTS build and the Octopus Deploy project/build definitions, to ensure that we have a clean break from what worked  to what could work.

How to perform Option 2

There are a couple of items that we need to accomplish here. Because we have already cloned both the Basic Build definition and the Octopus Project, we will work with those cloned items in this mini exercise. For now we are not going to touch the clone of the build definition because it is generic and just performs the build and then packages and publishes the package( s ) to our Octopus Deploy internal NuGet repository.

First we will need to change how our Releases get created. After selecting your Process, find the Automatic Release Creation in the left hand side of the page. Select Project Triggers, this has moved from previous versions of Octopus Deploy and then select the create a release when a package is pushed.




Then we need to change the behavior of our Lifecycle (more information is here). The important fact here is that if we wish to stay away from modifying our build definition to automatically deploy we can do it within our Lifecycle. One key note here is that the default lifecycle allows for deployments to created environments. While this is not ideal, there is a way for us to create and manipulate a new Lifecycle to benefit our needs. For our cloned project we will need to “Choose a different lifecycle”.


Special note here is that the lifecycle once applied, will only be used by your deployment project going forward. Any previous releases that were created will use the previously assigned lifecycle. This can be confusing, but it makes sense because Octopus Deploy takes a snapshot of all of the variables and state of your project for each deployment.

Let’s go ahead and create a new lifecycle:

Click Library->Lifecycles-Add lifecycle


Then we need to give the new lifecycle a Name and add a Phase.  This is important because the phase helps us describe what we wish to do in each step of our deployment.


Adding a Phase means that you are going to be describing what happens to your deployment. After you click the Add Phase you will get this:


Give it a name and then click Add environment


Initially you will see and empty drop down box and a couple of radio buttons. Select your dev or other environment that you wish to deploy to first and then select Deploy automatically to this environment as soon as the release enters this phase. Then click Add.


Now it should look like this:


Click Save and we are almost there.

You can can multiple phases and multiple environments to each phase depending on your need. For this exercise, we are putting out the CI/CD basics that you can build upon for your future development and deployment efforts.

Now that I have created that lifecycle, I need to perform a couple more things to get everything wired up and in sync.

First, I need to go back to my project and change the lifecycle from Default to CI-CD Option2.


The next thing we have to do is change the Automatic Release Creation under the Project Triggers.  Warning here is that if you have an external NuGet or other repo that you are dealing with this option will most likely not work for you.  There may be an option 3 workaround, but I haven’t gotten to that state yet.

Click on Project Triggers and then


image check the “Create a release when a package is pushed to the built-in…” make sure you select the deployment step that contains your package, then click Save


Let’s test this out.


Our build was successful.


And it just works now.



From Option 1 it is clear that you can just use the Create Release step and not be dependent on both the Octopus Create Release and Octopus Create Deployment. Either option is viable and can be used interchangeably depending on your needs. You can have build definitions that work on specific branches of code for CI/CD and then use the promote package to your higher environments. The above technique while focused on a simple web application can be used for more complex deployment scenarios and applications.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s