Multi-tenant deployments: Origins

Published on: 8 Jul 2016 by: Robert Erez

This post is a part of our Octopus 3.4 blog series. Follow it on our blog or our twitter feed.

Octopus Deploy 3.4 has shipped! Read the blog post and download it today!

Rather than dive into another how-to or what-is-it discussion about multi-tenant deployments, I thought I would take a bit of a walk through how it got to where it is today... and why it took so long!

Good Intentions

With almost double the number of votes as the second highest ranked suggestion in uservoice, providing support for tenanted deployments seemed like a feature that users were crying out for. We could see how such a feature might really make the lives easier for users who need to manage multiple customer deployments and were currently being forced to duplicate projects or environments as suggested in our available multi-tenant deployments guidance docs.

That realisation was back last year and it was originally slated for a 3.1.0 release in our public roadmap. Unfortunately as the saying goes, life got in the way (or in our case an "Azure deployment target" design pivot). In our determination to respond to user feedback (of limitations to the Azure deployment target), our hand was forced into pushing multi-tenant deployments into a proposed 3.2.0 build so that we could provide a new minor build with the relevant fixes. Given the user response to our design of Azure targets in 3.0.0 we appeared to have taken the wrong path and were keen to correct it ASAP. This was a lesson in getting better feedback from the community well learnt. We became keen to put a Community Driven Design process into better practice in the future.

One of our other popular uservoice suggestions at the time was around branching which involved the ability to manage and constrain deployments based on the package versions. After some internal discussions and an RFC, this feature eventually morphed into what we now call Channels. Once this feature was eventually complete we were keen to get it into the user's hands so that they could reap its benefits right away. That meant however, that rather than blocking the 3.2.0 release (with all its channel-y goodness) just to include multi-tenant deployments as we had committed to in our roadmap, that multi-tenant deployments would have to get pushed back again to 3.3.0.

RFC Published

"OK", I hear you all saying "surely now with everything else off your plate it should be perfect for inclusion in the next minor release, 3.3.0!" Well, we certainly thought so too. Targeting multi-tenant deployments as a top priority feature, we began internal design discussions on how it should look. Our original plan went down the path of representing tenants though the use of generic tags and tagsets, hoping that its generic nature would solve other architecture problems that users might have at the same time. With this approach multiple environments would need to be created to cater for the different tenants for that deployment phase, with tags & tagsets creating the organisational scaffolding to manage these groups of "tenant environments".

tag all the things

This approach has its pitfalls, not the least of which is mixing the concepts of an environment (something which constitutes part of a deployment phase that a release progresses through) and a tenant (something that facilitates parallel deployments to a given environment based on different configuration/variables). Thankfully our RFC got plenty of discussions started from our users and it got us thinking about if we had made the right architectural decision. This is a feedback loop that we are extremely lucky to be able to include in our design process since getting input from the actual users that the feature is intended for is invaluable.

The best BAs in the world working from the inside would have missed some of the key insights that you, the community have been able to provide.

A shout-out to a couple of key posts by @Matthew Abbott, @RichiCoder and @George Hemmings that reminded us that some of the core impetus for multi-tenant deployments was to facilitate safety checks to ensure customer deployments and settings go to the right machines at the right time. The complexity brought on by structuring everything with tags on top of environments, seemed to outweigh the theoretical benefits of its flexibility. This seemed like a clear case of YAGNI. Being able to see and work with your deployment process within the context of a tenant in an isolated manner would be much clearer if it was promoted to a first class entity in Octopus Deploy.

Thanks to everyone who commented on the original multi-tenant deployments RFC blog post. Your posts sparked renewed discussions amongst the team and it was decided that while some of the new ideas would be great additions, multi-tenant deployments clearly needed to be redesigned to have a first class status. While all this multi-tenant deployments design work was going on, other exciting new features were still being built for Octopus Deploy by other team members (you may have noticed some new faces in our team over the past few months!). Once again, the scope and depth of these changes necessitated a new minor release. The 3.3.0 release blog post once again had to indicate that multi-tenant deployments would be pushed back (hopefully) one last time.

(Note to self... avoid the roadmap making promises to include open features in specific versions)

Putting together the second RFC allowed us to iterate on previous concerns and provide a solution that seemed to be more in-line with how our users were hoping it would work. Another quick shout-out in this case to @Scott Brickey and @Blair Paine for providing food for thought on how multi-tenant deployments might work with permissions as well as @Mike Jacobs and @Andrew Newton for input into tenant variables. To help receive good responses, we posted our outstanding design questions directly to the community rather than hoping everyone would just "get it" and see where our gaps were. A few of you really gave great replies and told us your thoughts on these points to ensure we went down the right track. The generally positive reactions to this proposal gave us the confidence to let the rubber hit the road, whilst still keeping our eyes on the active posts.

Early Access Program

Internally we still had many design decisions around the specific implementation of certain concepts and behaviours but one of our guiding principles was to make multi-tenant deployments an additive feature. Given all the new dials and switches that we would be providing for those who needed the feature, we wanted to isolate the changes without confusing the system for users who didn't need multi-tenant deployments. There are plenty of Octopus Deploy setups out there (and you may be one of them) for whom their current set up "just works" and has no need to deploy the same release to multiple customers. For this reason we introduced the multi-tenant deployments feature toggle, which only once activated, will start showing the various components and features needed to manage multi-tenant scenarios. Even once the feature is enabled we ensure that your previous un-tenanted deployments can still keep deploying so that tenants can be created and perform deployments with existing releases at any point in time. One result of this last behaviour is that tenant variables are not snapshotted at the time of deployment and are instead incorporated at deploy time (don't worry we aren't touching normal project variables at this point!). We will go into more details behind this (and other) design decisions in future blogposts.

Due to the size of this new feature and the deviation from our initially proposed solution, we were keen to get our code into the hands of users who were interested and willing to provide feedback at an early stage of the process. Taking inspiration from the JetBrains Early Access Program, we introduced a similar approach to get regular unstable alpha builds out as the different functional pieces began to fall into place. This new Octopus Deploy Early Access Program allows us to provide the community yet another way to provide their feedback on the progress of new features (which in this case included development previews of parallel features such as elastic and transient environments) without having to fully commit ourselves to supporting an architectural design still in progress. Once again we got great feedback that influenced some of the direction that we went, even at this late stage. A big thank you to all of you who took time to download, install and play with the 3.4-alpha builds! We were given a big boost of confidence to hear user's positive experiences with the product, even in its partially complete form.

Currently in Beta

After much waiting we are pleased to provide the much demanded multi-tenant deployments feature in our latest 3.4.0-beta0001 release. It's not yet fully feature complete, but it's gotten to a stage that we are confident should have very little structural changes. We expect a second beta to be delivered in the next few weeks and a full RTW likely just a few weeks after that. Although we didn't mention everyone who provided feedback by name, rest assured that every response was invaluable to getting multi-tenant deployments where it is.

This journey has taught us the value of Community Driven Development in helping to shape large features where the users know best the problems that they need a solution for. The RFC, EAP and beta programs all combine to allow you, the users, to take part in the design process for the product that you want, and for this we are grateful.

It may have been a long time coming, but thanks to the support of our users I think it has taken a shape that better matches how you envisaged it would work but still easy to grok.

For more information on multi-tenant deployments, see our new guide.