From hate to love - why I moved to VSTS

This is a short post about my journey from hating to really loving VSTS. In fact, for the last few years I was a hardcore fan of TeamCity and really couldn't find any other tool, which would fit my needs. In fact, VSTS was the last thing I'd use to work on a daily basis(mostly because of my bad experience with TFS/VSO). I'll explain what was the reason of changing my mindset.

Learning curve

What surprised my a lot was actually the learning curve of VSTS. I was used to really digging deeper into configuration to actually make magic happen. Here you just grab something and use it. Want a Grunt runner? It's already installed, not need for some 3rd-party stuff. Want to groups some tasks and reuse them? Just go for tasks groups and use them anywhere you want. Also no annoying "default branch" from TeamCity(in pre 10.0 era) is present so working with your git project is a piece of cake.

All in one place

This is something, which I like the most - I have my codebase, builds and releases, all in one place. No more switching between different tools to do a code review, tweak a build and deploy it. It's easy to use, easy to configure and to monitor.

Technology stack

Other tools are perfectly fine when used with .NET platform. But they're not designed for it - and you feel it. Don't get me wrong - I'm aware of the fact, that creating such applications are not a trivial tasks. But after all those years, I've finally come to a conclusion, that having a tool designed specially for your technologies really makes things easier.

Ready for a cloud

The last but not least - since VSTS integrates with Azure seamlessly, I can develop my cloud applications or move from on-prem without much effort. Just use one of many Azure tasks in your build/release and watch how everything is being collected and deployed. No need to configure additional plug-ins - the best thing here is, that once you use it, you'll ask yourself "why other things can't be so easy?".

Those are just a few reasons why I chose VSTS as my main tool for building and managing my applications. I strongly recommend you to give it a chance, even if you disliked it on the first try - especially with recent and upcoming updates, which makes it even better.

Getting serious with Juju - multiple models, management and constraints

In the last introductory post for Juju we'll cover working with multiple models, basic management and setting some constraints. For now you should be familiar with the basic concepts and probably be able to work with a simple model. It's time to check what it's all about.

Multiple models

As I mentioned in the previous posts, by default a bootstrap creates two models - admin and default. The former is designed for managing some internal stuff, the latter is what you have access to and can work with. Initially it seems reasonable, but sooner than later you'll understand, that having everything(web applications, big data, analytics etc.) in on place just muddles things. To separate concerns we can have multiple models residing on the same controller.

Models listed with juju models command show both machines and cores count

You can add a new model easily either with a GUI(with a "Start a new model" button) or with a CLI(using juju add-model <model_name> command). To switch active model you can do the same - either select it from a dropdown or with a juju switch command.

Importing & exporting models

The important thing is Juju is the possibility to import/export a model. With this feature you can easily share an infrastructure you've modeled or use model designed by other experts. The best thing about this is the fact, that you pass only an idea - a physical part is detached from a model. What is more, since models are just YAML files, you can easily version them using a version control system of your choice. Take a look how a simple model is descibed:

series: xenial
    charm: "cs:trusty/wordpress-5"
    num_units: 1
      "gui-x": "300"
      "gui-y": "300"
      - "1"
    charm: "cs:mysql-57"
    num_units: 1
      "gui-x": "695"
      "gui-y": "395"
      - "0"
  - - "mysql:db"
    - "wordpress:db"
    series: xenial
    constraints: "arch=amd64 cpu-cores=1 mem=1792 root-disk=30720"
    series: trusty
    constraints: "arch=amd64 cpu-cores=1 mem=3584 root-disk=30720"

As you can see, all "beings" like charms, relations and machines are here and can be customized without interacting with Juju. 


When it comes to management features, Juju comes with two major concepts - commands restrictions and network spaces.


It's always a good idea to restrict potentially dangerous features of a tool or an application you're using. When it comes to Juju, we have two groups - destroy and remove. A good reference which command falls to which group can be found here. The important thing about this is that in most case a user will be affected by those restriction only when it logs again. If you go with following commands:

juju disable-command destroy-model
juju destroy-model <model>

You won't have problems with removing a model. Another thing is using --force switch with Juju commands. Have in mind that this means, that all your restrictions will be bypassed.

Network spaces

Since infrastructure made with Juju can become quite complicated, some advanced networking features are available. One of those are "spaces", well described in the documentation:

A space is made up of one or more routable subnets with common ingress and egress rules. The Juju operator can model this topology in such a way that applications gain the required network connectivity without generating complex network IP maps that are not portable. This gives the operator much better and finer-grained control over all networking aspects of a model and its application deployments.

To make the long story short - spaces let you orchestrate your subnets and ease connection between them when it comes to communication. What is more, once spaces are configured, you can constraint deploying charms to the particular ones. 

To only downside of this is the fact, that currently spaces are only supported by MAAS so it's not available out of the box. Still, if you're interested in such feature, take a look here.


The last but not least thing are constraints. They allow you to set some limits when it comes to setting a machine. The important thing here is the difference between different cloud vendors - depending on the cloud, some constraints can be available or generating conflicts. 

Constraints have two characteristic:

  • work on "a better" basis - you are passing the minimum requirement for a component
  • can be ignored by passing a null value

You can set constraints either for an environment(controller), a model, an application or a machine.

You may wonder what is the purpose of working on "a better" basis. To understand reasons behind this setting you have to change your mindset a little when working with Juju - it is designed to provide the best performance to coordinated components, not to manage them in terms of used resources. It's all about modeling a solution which works flawlessly.


In this short journey we've learned some basic stuff in Juju. We know what are the main components, how a model is built and how we can manage it. We'll come back to Juju in future to create custom charms with Azure resources.