Azure Management Studio and Blob Container ACLs

Here’s a quick tip I recently learned from my friend, and Cerebrata evangelist, Mike Wood . . .

When using Cerebrata’s Azure Management Studio to work with Windows Azure blob storage, you need to explicitly tell AMS to retrieve the access permissions for blob containers.  By default, AMS will only list the containers.

no_acls

To make this tool even more useful, instruct AMS to retrieve the permissions when listing the containers.

  1. Under the “Tools” menu at the top, select “Options”.
  2. In the “Options” window, go to the “Blob” tab.
  3. In the “Blob behaviour” section, check the box next to “Fetch Blob Container ACL when listing Blob Containers”.

set_option

This will instruct AMS to get the permissions and thus color highlight the containers.  Ooooh . . . pretty colors!

with_acls

How is AMS getting this info to know what the permission is for the containers?  Simple – it’s just calling into the Windows Azure storage API.  The Get Container ACL operation retrieves the blob container permissions.  If we open Fiddler and take a look at the requests AMS is making, we can see 4 requests for my example – one to retrieve the list of containers and one for each of the containers.

Note: I instructed AMS to not use HTTPS for connections.  I did this only to make visualizing the requests/responses in Fiddler easier.  I would recommend HTTPS for most production scenarios.

all_reqeusts

Let’s look at just the request to get the ACL for the “myimages” container.

request-response

Notice the “x-ms-blob-public-access” response header.  It is set to “Container”.  This indicates full public read access for the container and blob data.  Therefore, AMS colors this container a lovely shade of green.

A word to the wise – there is a reason why this option is not enabled in Azure Management Studio by default.  If the storage account contains many containers, this could result in many extra requests to Windows Azure to determine the ACL – one roundtrip per container.  This could slow down your time to view all the containers.  If you just have a few containers, it’s probably not a big deal as this request/response dance happens pretty fast.

So that didn’t exactly turn out to be a quick tip.  But, still hopefully useful.  Enjoy!

Advertisements

Sending Text Messages from Your Windows Azure Service

Recently I was waiting at O’Hare for a flight back to Columbus.  I fired up Evernote to catch up on some Windows Azure articles I wanted to read (I save a lot of things to Evernote).  One of the first articles I read was a CodeProject article by Luke Jefferson at Red Gate.  Luke’s article provides a really nice basis for using Cerebrata’s PowerShell Cmdlets and Twilio for sending SMS messages when your Windows Azure service has “issues”.

This got me thinking – could I write something similar (I was inspired) before I returned home to Columbus?  I’d like to tweak it a little to run as a Windows Azure worker role.  I would have to do most of the writing without the crutch of the Internet (remember – no WiFi at O’Hare and no WiFi on my plane).  I would have a brief internet connection before getting on the plane if I used my awesome Nokia Lumia 900 for tethering.  This is doable!

The timing couldn’t have been better!  I remembered seeing a Twitter message earlier in the day from @WindowsAzure announcing a new promotion from Twilio to get some free messages for Windows Azure customers.  Perfect time to try this out!


By the way, if you don’t have Windows Azure yet, now is a good time to get it.


While Luke’s article on CodeProject uses PowerShell cmdlets, I wanted to try it with regular C# code and run the solution in a simple Windows Azure worker role.  To do so I would need to work with the Windows Azure Service Management API.  As Luke points out in his article, the Windows Azure Service Management API is a  REST API.  He does a great job of explaining the basics, so be sure to check it out and head over to MSDN for all the details.

Unfortunately there is not yet a nice .NET wrapper for this API.  I took at look at Azure Fluent Management library, but it didn’t yet have all the features needed for this little pet project (but looks to be cool – something to keep an eye on).  Thankfully, I remembered I had read Neil Mackenzie’s excellent Microsoft Windows Azure Development Cookbook and it contained a recipe for getting the properties of a hosted service.  Bingo!  This recipe is a very helpful one (like many in Neil’s book) and I had the code standing by in a sample project I put together while reading Neil’s book.  With the starting point for using the Windows Azure Service Management API in place, the only thing I needed now was an API for working with Twilio

Time to fire up the phone tethering feature, sign up for Twilio, and download their API.  I decided to use the twilio-csharp client library and installed that via NuGet.  Easy enough.  With everything that I needed downloaded, it was time to power down and get on the plane.

The basics of what I wanted to do are pretty simple:

  1. Get the properties of a specific Windows Azure hosted service
  2. Check if the service is Running or not
  3. If the service is not Running, send a SMS message to me to let me know that something is not right.
  4. Sleep for a little bit and then repeat the process.

Get Hosted Service Properties

private HostedServiceProperties GetHostedServiceProperties(string subscriptionId, string serviceName, string thumbprint)
{
String uri = String.Format(ServiceOperationFormat, subscriptionId, serviceName);

ServiceManagementOperation operation = new ServiceManagementOperation(thumbprint);
XDocument hostedServiceProperties = operation.Invoke(uri);

var deploymentInformation = (from t in hostedServiceProperties.Elements()
select new
{
DeploymentStatus = (from deployments in t.Descendants(WindowsAzureNamespace + "Deployments")
select deployments.Element(WindowsAzureNamespace + "Deployment").Element(WindowsAzureNamespace + "Status").Value).First(), RoleCount = (from roles in t.Descendants(WindowsAzureNamespace + "RoleList")
select roles.Elements()).Count(), InstanceCount = (from instances in t.Descendants(WindowsAzureNamespace + "RoleInstanceList")
select instances.Elements()).Count()
}).First();

var properties = new HostedServiceProperties
{
Status = deploymentInformation.DeploymentStatus,
RoleCount = deploymentInformation.RoleCount,
InstanceCount = deploymentInformation.InstanceCount
};

return properties;
}

Send a Message if Not Running

     // Get the hosted service
     var serviceProperties = GetHostedServiceProperties(subscriptionId, hostedServiceName, managementCertificateThumbprint);

     // If the service is not running.
     if (serviceProperties.Status != "Running")
     {
          string message = string.Format("Service '{0}' is not running.  Current status is '{1}'.",
                                                   hostedServiceName, serviceProperties.Status);

          // Send the SMS message
          twilio.SendSmsMessage(fromPhoneNumber, toPhoneNumber, message);
     }
}

Putting it All Together

 private readonly XNamespace WindowsAzureNamespace = "http://schemas.microsoft.com/windowsazure";
 private const string ServiceOperationFormat = "https://management.core.windows.net/{0}/services/hostedservices/{1}?embed-detail=true";

public override void Run()
 {
 Trace.WriteLine("Staring Windows Azure Notifier Role", "Information");

// Get the configuration settings needed to work with the hosted service.
 var hostedServiceName = GetConfigurationValue("HostedServiceName");
 var subscriptionId = GetConfigurationValue("SubscriptionId");
 var managementCertificateThumbprint = GetConfigurationValue("ManagementCertificateThumbprint");

// Get the configuration settings for Twilio.
 var twilioId = GetConfigurationValue("TwilioId");
 var twilioToken = GetConfigurationValue("TwilioToken");
 var fromPhoneNumber = GetConfigurationValue("FromPhoneNumber");
 var toPhoneNumber = GetConfigurationValue("ToPhoneNumber");

// Create an instance of the Twilio client.
 var twilio = new TwilioRestClient(twilioId, twilioToken);

while (true)
 {
 // Get the hosted service
 var serviceProperties = GetHostedServiceProperties(subscriptionId, hostedServiceName, managementCertificateThumbprint);

 // If the service is not running.
 if (serviceProperties.Status != "Running")
 {
  string message = string.Format("Service '{0}' is not running. Current status is '{1}'.",
  hostedServiceName, serviceProperties.Status);

 // Send the SMS message
 twilio.SendSmsMessage(fromPhoneNumber, toPhoneNumber, message);
 }

 Thread.Sleep(TimeSpan.FromMinutes(5));
 Trace.WriteLine("Working", "Information");
 }
 

I had most of this put together before the stewardess informed me it was time to power down in preparation for landing. The only things I needed yet was a Windows Azure subscription ID, a Windows Azure management certificate thumbprint, and a hosted service to test this against. I have several Windows Azure hosted services running for various reasons, so all this was easy enough to get.

With all the necessary bits in place, it’s time to test this out.  In order to get this working in Windows Azure (as opposed to my local emulator) I would need to include my management certificate as part of the role I’m deploying.  When using the emulator, the certificate is already on my development machine so I didn’t need to do anything special.

Add the certificate to the role

I would also upload this certificate as a service certificate.

Windows Azure Hosted Service Certificates

With the certificates in place, I was ready to deploy the service as an Extra Small worker role.  I then picked one of my demo apps and told Windows Azure to shut it down.  Shortly after that, I received a new text message from my Twilio account!

While this was just a simple proof-of-concept, it was pretty cool and can be pretty powerful.

If you’d like the whole source code for this project, you can download it here.