I’ve finally caved in after a webinar yesterday in which this question came up for what seems like the 100th time. So I thought I’d blog it and send people here for the full explanation in the future.
Back in the good old bad old days when Microsoft Azure was first released there were hardly any services. Compute, which in those days was known as “Azure Hosted Services”. There was a SQL database service and some add-on bits of infrastructure to make it easy to build apps – a Security Token Service called the Access Control Service and an app messaging service called “Service Bus”. These bits were packaged up in to something called “Windows Azure App Fabric”. That name was eventually dropped when people got confused between “App Fabric” and the “Fabric” that runs and orchestrates operations inside the Azure data centres.
“Azure Hosted Services” were what you used when you wanted some computers to do some computing for you. There were 2 types of compute roles. Web Roles and Worker Roles. You might typically build a cloud app with say a web front end (for which you’d very likely use Web Roles) and say a middle tier (for which you’d very likely use Worker Roles) and a database back end for which you’d use the SQL DB service I mentioned earlier.
The computers (Windows Servers) that lived in these Roles were known as “instances”. You could have say a Web Role with multiple instances and you could dynamically add and remove instances as the app was running. You could do this with Worker Role instances too.
So you had the instances (servers) inside the roles and the roles lived inside another container called a Hosted Service. All the bits of compute inside a Hosted Service could talk to each other over a common network infrastructure. You could specify which ports were open to each computer (they were all closed by default) and you could connect ports up to a load balancer which was in turn connected to the Internet. So a Hosted Service was like a container for the compute parts of your app. One important thing it was granted, so you could talk to the compute within it, was an IP address that was connected to the Internet (via the aforementioned load balancer).
So here was the idea. As a dev, you’d write some code that would run on your Web Role and some other code that would run on your Worker Role. You’d package that in to a special file called a “Cloud Service Package” (.cspkg). You’d then describe the boxology of your app in couple of XML files in which you’d define the roles you had, how many instances of each role and how powerful each instance was. For example you might have a medium (2 cores, 3.5GB RAM) instance for the Worker Role and a Large instance (4 cores, 7GB RAM) for the Web Role. One file (.csdef) had things like ports and instance sizes, the other (.cscfg) had things like how many instances were in each role.
All you had to do was create these 2 files (you could use Visual Studio) and send them to Microsoft. Then somewhere between 8 and 15 minutes later your app would be live and running on the Internet. Fantastic. No management of infrastructure. Azure would do all the service management, patching, security fixes, failure-management etc for you.
Eventually, this way of doing things - “Hosted Services” - got renamed to “Cloud Services”.
OK, so then customers started saying “…well, I’d love to use Azure but I’d just like to start with an architectural model that’s more like what I have in my own data centre today. I can see how cloud services are great if I write apps to fit exactly in to the cloud services architecture but most of my apps are a few years old and they aren’t written that way – how can you help?”.
So on the 22nd June 2012, Microsoft announced Azure Virtual Machines. Dead easy to create a VM – click New, VM, then select a machine from a gallery. Answer a few questions like what you’d like the machine name to be what you’d like the password to be and so on and a few minutes later you’re running a server.
Virtual Machines were designed to fit in to the existing Cloud Services infrastructure and this is where the majority of the confusion comes from. Because when you look in the portal – it definitely looks like Cloud Services and Virtual Machines are 2 separate things: they are, but they are related:
So, if you go in to Cloud Services and click “New” – you’ll be able to create a Cloud Service as I’ve described it in the opening part of this blog-post with Web Roles and Worker Roles and integrated service management, fault management, automatic patching, SPs, security fixes and all that goodness. You’ll get to a question that asks you to supply a .cspkg and a .cscfg. SO at this point it wouldn’t appear to have anything to do with Azure Virtual Machines.
But when you get to page 3 of the New VM Wizard, it asks you to either create a new cloud service, or to put the VM in to an existing cloud service:
As I said earlier, VMs leverage the existing Cloud Services architecture. So when you create a VM, it will end up living inside a Role which will live inside a Cloud Service.
You normally don’t see the Role and you’re not all that interested in it anyway. By default, the Role will have the same name as the machine-name. But you have to either put your VM in to an existing Cloud Service or create a new one. This will give any VMs you put in to the same cloud service network access to each other. They will all be deployed on to a common network that is isolated from all the other VMs in Azure. Just like the Cloud Services I described in the opening part of this post. You also get access to a load balancer and you get an IP address that is connected to the Internet.
By default, if you create a new Cloud Service, the wizard will give it the same name as the server. Resist the temptation to accept the default at this point. In the pic above – you can see it wants to create a Cloud Service called plankysrv1.cloudapp.net. Now let’s imagine some time later, you add a new machine called plankysrv2 to this cloud service. It’s going to be confusing referring to plankysrv2 using the DNS name plankysrv1.cloudapp,net. So a much better strategy would be to name the Cloud Service something neutral – say, in this case “plankysrv.cloudapp.net”.
The thing about a Cloud Service, currently, is that whether it’s a “pure” Cloud Service or one that wraps around some Azure Virtual Machines, is that you get a single IP address connected to the Internet. Which means you get a single DNS name too. So you can see a name that doesn’t reference a specific server makes sense.
This is all fine if you don’t connect any of your Azure Virtual Machines up to the outside world. Most of the servers in your private datacentre are not connected directly to the Internet. But what if you create a web-front end across say 3 IIS web servers? Well, that’s where the load balancer comes in. Each Cloud Service has a load balancer connected to the Internet. If you connect your 3 web servers’ HTTP ports up to the load balancer then HTTP requests from the Internet will be load-balanced across all 3 servers.
But what if you want to do some configuration to a specific server and you want to RDP in to it? In that case, the load balancer can map different ports for you. So an example might be that to access different servers you use their port number in the RDP client.
When the load balancer sees an RDP request coming in on port 50268, it knows to send the data to plankysrv2 on the default RDP port (3389). So you don’t need to make any port modifications to the server at all. The Azure load balancer takes care of it for you. When you set up RDP access to your Azure Virtual Machines, you can either set up the port mapping explicitly yourself (like I’ve done in the table above). Or you can just let Azure find a spare high-numbered port for you. This is called “Automatic” and it looks like this when you go through the wizard:
OK – so here is what I see in the Cloud Services node, BEFORE I create a new Azure Virtual Machine:
If I now create a new VM called plankysrv1 and put it in to a Cloud Service called plankysrv.cloudapp.net – this is what I’ll see in the Cloud Services Node:
So that sort of proves that Azure Virtual Machines always end up in Cloud Services. You have no choice. But how can I tell which VMs are in that service? If I drill in to the service and select the Instances tab – it shows me:
I’m now going to add plankysrv2 in to the plankysrv.cloudapp.net Cloud Service – a la:
In the Cloud Services node, it won’t make any difference, but if I drill in to the Instances tab within the plankysrv.cloudapp,net service, then I’ll see 2 servers now:
You might also notice, in the New VM wizard, when you pick a specific Cloud Service, you can’t change the Region once you’ve made the choice. And that’s because a Cloud Service lives in one and only one Region. So whatever region the cloud service is in, that’s where your Azure Virtual Machine will be created. You aren’t offered a choice to change it.
OK, so I’ve now got 2 new Azure Virtual Machines (plankysrv1 and plankysrv2). I’m going to delete both of them. Here is the Virtual Machines node before I delete them:
…and here it is afterwards:
…so with all the Azure Virtual Machines gone – you’d think the Cloud Service would also disappear wouldn’t you? It forced you to create a Cloud Service with your first Azure Virtual Machine so it should therefore logically undo it when you delete the last Azure Virtual Machine? But that’s not what happens. Because it’s impossible to have an Azure Virtual Machine without an associated Cloud Service. But you can have an empty Cloud Service. It just sits there a bit like an empty shopping bag waiting for you to one day put something back in to it. So if you want to get rid of it – you have to explicitly delete it from within the Cloud Services node. Here is a screenshot of the Cloud Service empty but still in existence:
…however, if we take a look on the Instances tab – it’s empty:
I hope that’s given you a little bit of an understanding of the relationship between Cloud Services and Virtual Machines. If you always remember an Azure Virtual Machine cannot exist without a Cloud Service, but a Cloud Service can exist without an Azure Virtual Machine – it can be empty. That basic idea will see you through.
Planky == @plankytronixx