Pluralsight blog Where devs, IT admins & creative pros go for news, tips, videos and more.
3,500+ tech & creative courses authored by experts - unlimited & online Get it now →
April 1, 2014

How to control Windows Azure with Python

By shutterstock_160965899

Linux developers regularly use Python for small pieces of work because you can script situations very easily. It’s become a popular way to enable small tasks of configuration and deployment. Windows Azure, Microsoft’s cloud, is no different. Python is a first class citizen in Windows Azure with the availability of the Python SDK. Let’s take a look at how we can deploy an image from the vmdepot to Windows Azure programmatically using Python with nothing other than a Windows Azure subscription.

Setting up a management certificate

Any interaction with Windows Azure needs two things:

  • A subscription ID
  • An X509v3 management certificate

Let’s assume that you’re using Linux to run the script. (If not, contact me and I’ll explain how you can use Windows to do the same.) If openssl isn’t installed then use the following from a root prompt:

yum install openssl

The following will create a .pem file which can later be translated in to a .cer, exported and uploaded to Windows Azure.

openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout elasta.pem -out elasta.pem

To export the .cer use the following:

openssl x509 -inform pem -in elasta.pem -outform der -out elasta.cer

There you have it, a management certificate which can be uploaded to your Windows Azure subscription. When this is done you should be able to interact with Windows Azure programmatically.

Login into Windows Azure using your Microsoft account or Windows Azure Active Directory credentials. The management portal can be located at https://manage.windowsazure.com.

Select the settings tab:

Select Management Certificates from the menu:

The bottom app bar contains an upload button:

Select this button and upload the .cer file:

You should see something like this for the certificate entry in the results pane.

To help with the explanations for this post I’ve written a Python script which is available here:

https://github.com/elastacloud/python-vmdepot-deploy

You can read the setup instructions as to how to use the script. The purpose of this post is to walk through some of the key features of the Windows Azure Python APIs which will help you develop fully automated deployments.

To use any of the Service Management functions in Windows Azure we need a Service Management object:

self.sms = ServiceManagementService(vars.subscription_id, vars.certificate_path)

This will be used for everything we do going forward. As you can see this takes a certificate and a subscription ID as parameters.

Constructing a virtual machine

A virtual machine image is a template from which we can construct virtual machines. In this case we will be using a CentOS image and copying from a location called the vmdepot which is maintained by MS Open Tech, a wholly owned subsidiary of Microsoft.

We can check whether the named imaged we have previously copied and registered exists by listing all named images in our subscription to see if there is an occurrence.

def _image_by_name(self, name):
        # return the first one listed, which should be the most stable
        for i in self.sms.list_os_images():
            if name in i.name:
                return True
        return False

If not, we can continue with our workflow.

The following shows a succinct of creating a storage account which needs a name and location. As I’m based in London I’ll use the “North Europe” datacenter which is in Dublin, but there are over 10 datacenters in existence throughout the world with a bunch more being built. When the storage account is created it allows up to 200 TB of blobs to be stored, and is protected by 2 512 bit AES, which can be used to access the account. The logical unit to store blobs in is called a container, so we’ll need to create one of those so that we can store our copied image.

self._create_storage_account_if_not_exists(vars.storage_account_name, vars.deploy_location)
account_key = self._get_primary_account_key(vars.storage_account_name)
self._create_container_if_not_exists()

We should now be able to copy the blob from a remote location. This is done using an API provided by Windows Azure called CopyBlob. The implementation of this is here:

 self.blob_service.copy_blob(container_name=Constants.storage_container_name, blob_name=Constants.vhd_blob_name, x_ms_copy_source=Constants.centos_minimal_image)
self._wait_for_async_copy(Constants.storage_container_name, Constants.vhd_blob_name)

As you can see this is an asynchronous method which allows any blob to be copied from a remote location. The great thing about this API is that you can use it to copy any HTTP endpoint from within or outside Windows Azure and it costs nothing to use. The downside is that there is no SLA with this.

The blob can then be registered as an image within your Windows Azure subscription and you should be able to use this to create multiple virtual machines.

self.sms.add_os_image(label=Constants.image_name, media_link=storageimage_uri, name=Constants.image_name, os='Linux')

The script will create a “cloud service” which is the public endpoint that contains the virtual machines and then setup a public endpoints with port forwarding to the VMs so that you can SSH into them. The script is written in such a way that if you choose the same cloud service each time it will add another VM to the cloud service with an open port ready to SSH into from port 22 upwards incrementally.

We’re copying the image from the vmdepot which contains the image. With this I’m copying and registering the CentOS minimal image in my subscription.

https://vmdepotneurope.blob.core.windows.net/linux-community-store/community-32167-508624a5-01d1-4d57-b109-df2af5b4b232-1.vhd

You can browse the vmdepot here:

http://vmdepot.msopentech.com/List/Index

Lastly, we’ll use a very simple algorithm to determine the vms that are already deployed to the cloud service by looking at the underlying blobs as each virtual machine has a virtual hard drive (.vhd) in the Storage Account.

index = -1
blob_exists = True
while blob_exists:
	index += 1
            blob_exists = self._blob_exists(Constants.storage_container_name, "elastavm" + str(index) + ".vhd")

vm_media_link = self._make_blob_url(vars.storage_account_name, Constants.storage_container_name, "elastavm" + str(index) + ".vhd")

self._create_vm_linux(vars.storage_account_name, vars.storage_account_name, "elastavm" + str(index), vm_media_link, vars.deploy_location, index, vars.username, vars.password)

The upshot is that we can add multiple virtual machines to our cloud service.

All of the above is taken from the Setup.py file. You can see all of the above code here:

https://github.com/elastacloud/python-vmdepot-deploy/blob/master/elastacloud/pyvms/Setup.py

Follow the instructions on the readme.md to enable use of the script and you should be ready to go.

You can clone the Windows Azure SDK for Python here:

https://github.com/WindowsAzure/azure-sdk-for-python

Enjoy!

About the Author

is a Director of UK based cloud and big consultancy Elastacloud. He is a Microsoft Azure MVP and Insider and a regular open source contributor most notably for the popular framework Azure Fluent Management. He is very focussed on bringing big data technologies to Microsoft Azure and helping make it a better place for non-.NET developers. He can be followed at @azurecoder and reached at richard@elastacloud.com.


Discussion