RunCommand vs Custom Script Extension vs VM Applications
I’m sure that many of you would swear that Microsoft loves to confuse you. Currently, there are not three but four ways to run code on your machine.
Now, I know what you’re saying. “I just want to run this thing on my machine! Which do I choose?” Well, here I hope to clear that up.
First, all of the above work on both Windows and Linux. They also work on both Virtual Machines and Virtual Machine Scale Sets. However, their behavior for the latter differs.
Let’s start out with the simplifying the problem: there is rarely a reason to use Custom Script Extension.
Personally, I don’t have anything against Custom Script, which we hear call “CSE”. It’s a nice feature, just old. There are more modern things out there, notably Managed RunCommand, which can do everything that CSE can do but better. There is only one case where CSE still makes sense: on Virtual Machine Scale Sets.
Scale Sets (which we refer to as VMSS) are a bit of a different beast since you may want to run your code on every instance in the VMSS, or you may want to run it on a single instance. It’s the support for one or the latter that differentiates these features on VMSS. Here’s a table for clarification.
|Feature||Supports VMs||Supports Linux||Supports Windows||Supports Cross-VMSS||Supports VMSS Instance|
|Custom Script Extension||Yes||Yes||Yes||Yes||Yes|
Note that I’ve included the first three columns just to be obvious. You’d be surprised at the number of people who would infer that VMs, Linux, or Windows are not supported if I didn’t include them. As you can see above, RunCommand – whether it’s managed or not, does not support cross-VMSS operations. VM Applications is the complete opposite. It only supports cross-VMSS – meaning you run the same thing on every instance in the VMSS in one go.
CSE supports both, so you can have your cake and eat it too. So, if you want to run a simple command across every machine in the VMSS, CSE is still your best bet. For every other case, it’s a dinosaur.
So, now that we’ve removed CSE from the equation, let’s look at the RunCommand siblings.
First of all, I take no responsibility in calling it “Managed RunCommand”. This is a thoroughly confusing name. Internally, we call them RunCommand V1 and RunCommand V2. This should give you an idea on which you should use. Always prefer Managed RunCommand (V2) over RunCommand (V1).
Again, Managed RunCommand allows you to execute multiple scripts at once and have them depend on each other, along with a bunch of other cool things. Even cooler things are on the way, and those features will only be in Managed RunCommand. Unlike with CSE, there are really no exceptions here. Managed RunCommand is awesome and RunCommand is the old code that many customers will keep using until the end of time, so we’ll continue to support it.
That leaves us with the difference between Managed RunCommand and VM Applications. Here, the choice should also be obvious, but it really relies on who is creating this code and how long does it run.
VM Applications is designed for applications. These may be services or something else. We really don’t care, but the expectation is that it keeps running for some undetermined period of time. Like most applications, you can install them, update them, and remove them. They have versions. They are even replicated across regions with the assumption that some may be large.
RunCommand scripts don’t have versions. We run it once and then are done with it. You can tell us to run a script again, but we don’t really know that you’re running the same thing again. We have no memory of what we did. Sure, for Managed RunCommand we keep a list of the individually named commands, but if you remove one nothing happens on the machine. If you remove a VM Application, then we execute an uninstall script on the machine.
VM Applications can be managed through RBAC. You can say that Igor can deploy Application A but not Application B. You can’t do that with RunCommands.
Another big difference is that VM Applications can be created by one person and deployed by another. Those same applications can be versioned and enforced by policies. Again, these are completely foreign to RunCommand.
So, in summary, the following should be your decision process on which code delivery feature to use in Azure.
Do I need it to run just one time and forget about it, or is this a process that needs to remain running for some time? This is a process: Use VM Applications
This is a one time thing: Do I need it to run across an entire VMSS? If yes, then use CSE If no, then use Managed RunCommand