I am happy to announce that the Windows Azure team has added cloud services support to the ServiceManagement API in the Windows Azure SDK for PHP. A few weeks ago I wrote a post (Service Management with the Windows Azure SDK for PHP) that outlined the service management functionality that was available in the Windows Azure SDK for PHP at that time. Since then, the Windows Azure team has added support for cloud services management. The team has also published a tutorial on using the service management API: How to use service management from PHP. Since that tutorial contains all the information you need to get started, I will simply cover the highlights in this post.

Note: The new support for cloud services management does not include support for Windows Azure VM management. This support, however, is on the roadmap for the Windows Azure team.

What is service management?

The Windows Azure Service Management REST API allows you to programmatically create, modify, and delete Windows Azure services (such as storage services and cloud services). In applications that require it, the functionality available in the Windows Azure management portal can be automated with the service management API. The ServiceManagement class in the Windows Azure SDK for PHP currently wraps much of the Windows Azure Service Management REST API. Functionality that has not yet been wrapped is on the road map for the Windows Azure team.

What’s new in the ServiceManagement class?

As I wrote a few weeks ago, the ServiceManagement class in the Windows Azure SDK for PHP includes methods for managing storage services and affinity groups. With the latest release of the SDK, methods have been added to support cloud service management. The new methods include createHostedService, createDeployment, changeDeploymentConfiguration, and swapDeployment (among others). These methods will allow you to create a new cloud service (formerly called a hosted service) with createHostedService:

require_once 'vendor\autoload.php';
 
use WindowsAzure\Common\ServicesBuilder;
use WindowsAzure\ServiceManagement\Models\CreateServiceOptions;
use WindowsAzure\Common\ServiceException;
 
try{
    // Create REST proxy.
    $serviceManagementRestProxy = ServicesBuilder::getInstance()->createServiceManagementService($conn_string);
 
    $name = "myhostedservice";
    $label = base64_encode($name);
    $options = new CreateServiceOptions();
    $options->setLocation('West US');
    // Instead of setLocation, you can use setAffinityGroup
    // to set an affinity group.
 
    $result = $serviceManagementRestProxy->createHostedService($name, $label, $options);
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here: 
    // http://msdn.microsoft.com/en-us/library/windowsazure/ee460801
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}
 

After creating a new cloud service, you can deploy your code to the service with createDeployment:

require_once 'vendor\autoload.php';
 
use WindowsAzure\Common\ServicesBuilder;
use WindowsAzure\ServiceManagement\Models\DeploymentSlot;
use WindowsAzure\Common\ServiceException;
 
try{
    // Create REST proxy.
    $serviceManagementRestProxy = ServicesBuilder::getInstance()->createServiceManagementService($conn_string);
 
    $name = "myhostedservice";
    $deploymentName = "v1";
    $slot = DeploymentSlot::PRODUCTION;
    $packageUrl = "URL_for_.cspkg_file";
    $configuration = base64_encode(file_get_contents('path_to_.cscfg_file'));
    $label = base64_encode($name);
 
    $result = $serviceManagementRestProxy->createDeployment($name,
                                                     $deploymentName,
                                                     $slot,
                                                     $packageUrl,
                                                     $configuration,
                                                     $label);
 
    $status = $serviceManagementRestProxy->getOperationStatus($result);
 
    echo "Operation status: ".$status->getStatus()."<br />";
}
 
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here: 
    // http://msdn.microsoft.com/en-us/library/windowsazure/ee460801
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}

Note: A project must be deployed to a cloud service as .cspkg file, and the file must be stored as a blob in a storage account under the same subscription as the cloud service.

Once your code is deployed, you can make changes to the deployment by uploading a new service configuration (.cscfg) file. For example, if you wanted to scale a deployment to run 3 instances of your application, you would edit the <Instances> element (<Instances count=”3” />) in a local version of the service configuration file and upload it to your service with changeDeploymentConfiguration:

require_once 'vendor\autoload.php';
 
use WindowsAzure\Common\ServicesBuilder;
use WindowsAzure\ServiceManagement\Models\ChangeDeploymentConfigurationOptions;
use WindowsAzure\ServiceManagement\Models\DeploymentSlot;
use WindowsAzure\Common\ServiceException;
 
try{
    // Create REST proxy.
    $serviceManagementRestProxy = ServicesBuilder::getInstance()->createServiceManagementService($conn_string);
 
    $name = "myhostedservice";
    $configuration = file_get_contents('path to .cscfg file');
    $options = new ChangeDeploymentConfigurationOptions();
    $options->setSlot(DeploymentSlot::PRODUCTION);
 
    $result = $serviceManagementRestProxy->changeDeploymentConfiguration($name, $configuration, $options);
 
    $status = $serviceManagementRestProxy->getOperationStatus($result);
    echo "Operation status: ".$status->getStatus()."<br />";
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here: 
    // http://msdn.microsoft.com/en-us/library/windowsazure/ee460801
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}
 

If you want to swap deployments between the staging and production environments, you can do so with swapDeployment:

require_once 'vendor\autoload.php'; 
 
use WindowsAzure\Common\ServicesBuilder;
use WindowsAzure\Common\ServiceException;
 
try{
    // Create REST proxy.
    $serviceManagementRestProxy = ServicesBuilder::getInstance()->createServiceManagementService($conn_string);
 
    $result = $serviceManagementRestProxy->swapDeployment("myhostedservice", "v2", "v1");
}
catch(ServiceException $e){
    // Handle exception based on error codes and messages.
    // Error codes and messages are here: 
    // http://msdn.microsoft.com/en-us/library/windowsazure/ee460801
    $code = $e->getCode();
    $error_message = $e->getMessage();
    echo $code.": ".$error_message."<br />";
}
 

Note: The example above assumes that you have a deployment in staging with deployment name “v2” and a deployment in production with name “v1”. After calling swapDeployment, “v2” will be in production and “v1” will be in staging. The swapDeployment method will still work if you only have a single deployment (in staging or production). For example, suppose you had deployment “v1” in staging and wanted to promote it to production (even though you have no deployment in the production environment at the time). You can do this by calling swapDeployment(“myhostedservice, “v1”, “somename”) where “somename” is simply a placeholder deployment name.

As I mentioned earlier, there is a lot more detail (and lots more examples) about the entire ServiceManagement class in this tutorial: How to use service management from PHP. If you read the tutorial and exercise the service management API, we’d love to hear your feedback in the comments.

Thanks.

-Brian