At several occasions I was asked: "Is it possible to call the Service Management API from a service that already runs within Windows Azure?"

The simple answer is: yes. And this blog post describes how, and it provides sample code for download. So, rather than long explanations you can take the software developer approach and just look at the code.

Overview

  • 1. Create a certificate for authentication and upload its public key as a .cer file via the portal at http://windows.azure.com/ under "Manage my API certificates"
  • 2. Create a new Hosted Service project via the portal at http://windows.azure.com/
  • 3. Export the certificate you created in step (2) on your local machine to a .pfx file and protect it with a password and username
  • 4. Upload the .pfx file in the "Certificates" section under the hosted service you created in step (3) on the portal at http://windows.azure.com/
  • 5. Download the latest version of the Microsoft.Samples.WindowsAzure.ServiceManagement.dll from the csmanage samples at this location
  • a. http://code.msdn.microsoft.com/windowsazuresamples
  • 6. Create a new cloud project in Visual Studio and add Microsoft.Samples.WindowsAzure.ServiceManagement.dll to it
  • 7. In the .csdef file in the Visual Studio project add a "Certificate" entry and specify in what location the certificate shall be installed
  • 8. In the .cscfg file in the Visual Studio project add a "Certificate" entry and specify the thumbprint of the certificate you uploaded via the portal
  • 9. In your Visual Studio solution use the Microsoft.Samples.WindowsAzure.ServiceManagement.dll to call into the Service Management API
  • 10. Publish your solution to the cloud and enjoy

Details Steps (1)-(5)

My previous blog post describes in detail how to do step (1).

Step (2) should be straightforward for you if you have ever used the portal at http://windows.azure.com/. After having logged into your project, just click the "+ New Service" link and then on "Hosted Service".

For step (3), there are many possibilities. One is to start mmc.exe, File->Add/Remove Plug-in->Certificates->Add->My User Account->Certificates-Current User->Personal->Certificates->Righ-click on certificate you want to export->All Tasks->Export...->Yes, export private key->Next->type in pwd etc.

As a result of step (3) you have a .pfx file. In the portal at http://windows.azure.com/ go to the hosted service you created in step (2) and add the .pfx file under "Certificates"->"Manage" (see below).

Step (5) should be clear from the description above.

 Programming the Service

For following this description I suggest you download a simple sample I created here.

First of all, let's have a look at the .csdef file.

    1 <?xml version="1.0" encoding="utf-8"?>

    2 <ServiceDefinition name="CloudService2" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">

    3   <WebRole name="WebRole1">

    4     <InputEndpoints>

    5       <InputEndpoint name="HttpIn" protocol="http" port="80" />

    6     </InputEndpoints>

    7     <Certificates>

    8       <Certificate name="ServiceManagementCert" storeLocation="CurrentUser" storeName="My"/>

    9     </Certificates>

   10     <ConfigurationSettings>

   11       <Setting name="DiagnosticsConnectionString" />

   12       <Setting name="SubscriptionId"/>

   13       <Setting name="CertificateThumbprint"/>

   14     </ConfigurationSettings>

   15   </WebRole>

   16 </ServiceDefinition>

 

The important part here is the "Certificates" section. It specifies that there is a certificate that we call "ServiceManagementCert" (you can chose the name as you want) and, most importantly, the location of the certificate. When you try to load the certificate in your code, you can refer to this location.

The .cscfg file then assigns a certificate thumbprint to the certificate name. Remember that the .cscfg file contains your settings, so when you change the certificate you just need to upload a new .cscfg. The .cscfg looks as follows:

    1 <?xml version="1.0"?>

    2 <ServiceConfiguration serviceName="CloudService2" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">

    3   <Role name="WebRole1">

    4     <Instances count="1" />

    5     <Certificates>

    6       <Certificate name="ServiceManagementCert" thumbprint="PUT YOUR THUMBPRINT HERE" thumbprintAlgorithm="sha1"/>

    7     </Certificates>

    8     <ConfigurationSettings>

    9       <Setting name="DiagnosticsConnectionString" value="UseDevelopmentStorage=false" />

   10       <Setting name="SubscriptionId" value="PUT YOUR SUBSCRIPTION ID HERE"/>

   11       <Setting name="CertificateThumbprint" value="PUT YOUR THUMBPRINT HERE"/>

   12     </ConfigurationSettings>

   13   </Role>

   14 </ServiceConfiguration>

You see the certificate thumbprint on the portal (see picture above). You need to insert it twice because we also need it as a setting so that we can load the certificate in our code.

Also put in the subscription id in the .cscfg file.

In the code, you can now do something like this:

   30         public static X509Certificate2 GetCertificate(ref string errorString)

   31         {

   32             string certificateThumbprint = RoleEnvironment.GetConfigurationSettingValue("CertificateThumbprint");

   33             if (String.IsNullOrEmpty(certificateThumbprint))

   34             {

   35                 errorString = "CertificateThumbprint cannot be found. Please check the config file. ";

   36                 return null;

   37             }

   38 

   39             X509Store certificateStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);

   40             certificateStore.Open(OpenFlags.ReadOnly);

   41             X509Certificate2Collection certs = certificateStore.Certificates.Find(X509FindType.FindByThumbprint, certificateThumbprint, false);

   42             if (certs.Count != 1)

   43             {

   44                 errorString = "Client certificate cannot be found. Please check the config file.";

   45                 return null;

   46             }

   47             return certs[0];

   48         }

Note that the store name and store location is as we have specified it in the .csdef file.

After you have done this, you can call any operations on the IServiceManagement interface.

Concluding Remarks

If you run the sample on your local box, you need to have the certificate installed in "My" and "CurrentUser". Very much like if you run csmanage.exe on your box. You can also publish the sample to the cloud after following the above steps.

The sample calls List-Os-Versions on the Service Management API, which shows all OS versions supported on Windows Azure.

Here is a screenshot: