Service Management with the Windows Azure SDK for PHP

[Updated Aug. 10, 2012: I’ve updated this post so that the code examples work with the new connection pattern in the Windows Azure SDK for PHP. For more information, see New Connection Pattern in the Windows Azure SDK for PHP.]

Since the June 7th release of the “new” Windows Azure SDK for PHP, the Azure team has been working hard to add functionality that will (eventually) wrap the complete Windows Azure REST API. One area that they have been working on (and that may have slipped under your radar) is Service Management. The ServiceManagementRestProxy class currently provides programmatic access to much of the storage services-related functionality that is available in the management portal (such as creating storage services, creating affinity groups, accessing storage service properties, etc). While this is just a subset of what can be done via the Service Management REST API, the available functionality can be useful in building applications that need programmatic access to storage services.

In this post, I’ll try to give you enough information to get started with service management via PHP (I’ll assume you have already created a Windows Azure account and a storage account). Of course, to dig into the details yourself, you can always check out the Service Management classes on Github.

Get the PHP Client Libraries for Windows Azure

All the details for getting the PHP Client Libraries for Windows Azure (and other components of the Windows Azure SDK for PHP) can be found here: Download the Windows Azure SDK for PHP. Note that for the code snippets in this article, I followed the instructions for using Composer to install the client libraries (hence, the snippets reference the ‘vendor\autoload.php’ autoloader file).

Set up your connection

To connect to the Service Management endpoint, you need your Windows Azure subscription ID and the path to a valid management certificate. You can obtain your subscription ID through the management portal, and you can create management certificates in a number of ways – I’ll use OpenSSL, which you can download for Windows and run in a console.

You actually need to create two certificates, one for the server (a .cer file) and one for the client (a .pem file). To create the .pem file, execute this:

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

To create the .cer certificate, execute this:

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

(For more information about Windows Azure certificates, see Overview of Certificates in Windows Azure. For a complete description of OpenSSL parameters, see the documentation at https://www.openssl.org/docs/apps/openssl.html.)

Edit (7/13/12): If you have download and imported your publish settings file using the Windows Azure Command Line Tools (details here), you can use the .pem file that the tools create instead of creating your own. The tools create a .cer for you and upload it to Windows Azure, and they put the corresponding .pem file in the .azure directory on your computer (in your user directory).

After you have created these files, you will need to upload the .cer file via the management portal, and you will need to make note of where you saved the .pem file (you’ll need the path to this file to create a Configuration object).

After you have obtained your subscription ID, created a certificate, and uploaded the .cer file to Windows Azure, you can connect to the Windows Azure managent endpoint by creating a connection string and passing it to the createServiceManagementService method on the ServicesBuilder class:

 require_once 'vendor\autoload.php';
  
 use WindowsAzure\Common\ServicesBuilder;
  
 $conn_string = "SubscriptionID=<your_subscription_id>;CertificatePath=<path_to_.pem_certificate>";
  
 $svc_mgmt_rest_proxy = ServicesBuilder::getInstance()->createServiceManagementService($conn_string);

Most of service management will be done through the ServiceManagementRestProxy class.

List available locations

The Windows Azure team has added some new data center locations recently, and I have trouble remembering the location names anyway, so the ServiceManagementRestProxy->listLocations method I find very helpful:

 $svc_mgmt_rest_proxy->listLocations();
 $locations = $result->getLocations();
 foreach($locations as $location){
       echo $location->getName()."<br />";
 }

Currently, the available locations are…

Anywhere US

Anywhere Europe

West Europe

Anywhere Asia

Southeast Asia

East Asia

North Central US

North Europe

South Central US

West US

East US

You will need to know what locations are available when you create a storage service or an affinity group.

Create a storage service

A storage service gives you access to Windows Azure Blobs, Tables, and Queues. To create a storage service, you need a name for the service (between 3 and 24 lowercase characters and unique within Windows Azure), a label (a base-64 encoded name for the service, up to 100 characters), and either a location or an affinity group. Providing a description for the service is optional. The location, affinity group, and description are set in a CreateStorageServiceOptions object, which is passed to the ServiceManagementRestProxy->createStorageService method. The following snippet shows you how to create a storage service by specifying a location. If you want to use an affinity group, you’ll need to create one first (see the section below) and set it with the CreateStorageServiceOptions->setAffinityGroup method.

 require_once 'vendor\autoload.php';
  
 use WindowsAzure\Common\ServicesBuilder;
 use WindowsAzure\ServiceManagement\Models\CreateServiceOptions;
  
 $svc_mgmt_rest_proxy = ServicesBuilder::getInstance()->createServiceManagementService($conn_string);
  
 $name = "mystorageservice";
 $label = base64_encode($name);
  
 $options = new CreateServiceOptions();
 $options->setLocation('West US');
  
 $result = $svc_mgmt_rest_proxy->createStorageService($name, $label, $options);

Once you have several storage services, you may need to list them and inspect their properties:

 $get_storage_services_result = $svc_mgmt_rest_proxy->listStorageServices();
 $storage_services_properties = $get_storage_services_result->getStorageServices();
  
 foreach($storage_services_properties as $storage_service_properties){
        $name = $storage_service_properties->getServiceName();
        echo "Service name: ".$name."<br />";
        echo "Service URL: ".$storage_service_properties->getUrl()."<br />";
        $properties = $svc_mgmt_rest_proxy->getStorageServiceProperties($name);
        echo "Affinity group: ".$properties->getStorageService()->getAffinityGroup()."<br />";
        echo "Location: ".$properties->getStorageService()->getLocation()."<br />";
        echo "------<br />";
 }

Note: The development team is working on making this scenario smoother, since it seems strange that the affinity group and location aren’t available on the ServiceProperties objects returned by getStorageServices().

Finally, you can delete a storage service by passing the service name to the deleteStorageService method:

 $svc_mgmt_rest_proxy->deleteStorageService("mystorageservice");

Create an affinity group

An affinity group is a logical grouping of Azure services that tells Windows Azure to locate the services for optimized performance. For example, you might create an affinity group in the “West US” location, then create a Cloud Service in that affinity group. If you then create a storage service in the same affinity group, Windows Azure knows to put it in the “West US” location and optimize within the data center for the best performance with the Cloud Services in the same affinity group.

To create an affinity group, you need a name, label, and location. You can optionally provide a description:

 use WindowsAzure\ServiceManagement\ServiceManagementService;
 use WindowsAzure\ServiceManagement\Models\CreateAffinityGroupOptions;
  
 $svc_mgmt_rest_proxy = ServicesBuilder::getInstance()->createServiceManagementService($conn_string);
  
 $name = "myAffinityGroup";
 $label = base64_encode($name);
 $location = "West US";
  
 $options = new CreateAffinityGroupOptions();
 $options->setDescription = "My affinity group description.";
  
 $svc_mgmt_rest_proxy->createAffinityGroup($name, $label, $location, $options);

As mentioned earlier, after you have created an affinity group, you can specify the group (instead of a location) when creating a storage service.

You can also list affinity groups and inspect their properties by calling listAffinityGroups, then calling appropriate methods on the AffinityGroup object:

 $result = $svc_mgmt_rest_proxy->listAffinityGroups();
 $groups = $result->getAffinityGroups();
 foreach($groups as $group){
        echo "Name: ".$group->getName()."<br />";
        echo "Description: ".$group->getDescription()."<br />";
        echo "Location: ".$group->getLocation()."<br />";
        echo "------<br />";
 }

Lastly, you can delete an affinity group by passing the group name to the deleteAffinityGroup method:

 $svc_mgmt_rest_proxy->deleteAffinityGroup("myAffinityGroup");

That’s it for now…hopefully enough to get you started with using the Service Management API to manage storage services. As always, if you have feedback, we’d love to hear it.

Thanks.

-Brian