Before you begin your Windows Azure development experience in earnest, you should be aware that leaving development and test instances deployed and running in the cloud can be expensive. Be aware that you will be billed for deployed service instances, even if they are suspended, so it is important that you actually remove the instances when you are done using them. Microsoft has many options available for providing developers with their own “little patch” of the cloud fabric quilt; however, it is easy to exceed these limits if you are not careful or simply forget to remove them.
To give you some idea, my Windows Azure bill has been running over $500 per month for four hosted services and four storage services (plus a few extra instances in staging environments). This is for mostly idle instances (used for demo and training purposes). There are many variables in pricing outside the scope of this short blog post, so your costs could be much different. My purpose in drawing your attention to it here is to give you some financial sense as to why I view the information in this blog post important.
When developing Windows Azure cloud applications, you will want to make heavy use of the DevFabric and DevStorage. You should only deploy to the cloud when necessary to test your application in a way that cannot be easily done on your desktop. For example, it is impossible to gain much knowledge about the scalability of the Windows Azure Platform from an application running solely on the desktop, or even to observe many of the features of the cloud fabric such as a simulated instance failure.
The Windows Azure Developer Portal allows us to install and remove application deployments. The portal is very straight forward and easy to operate, but the process requires operator interactivity. A deployment can take 30 minutes to get running once it has been uploaded and deployed, so there can also be the problem of a developer having to wait and monitor the deployments before taking subsequent steps. As developers, we want to automate steps of our deployment that are easily identified and highly repeatable. Good news! Windows Azure may be managed through the developer portal, but its RESTful API has been exposed for automation purposes. You can read more about the Windows Azure Service Management REST API here on the MSDN website.
Microsoft has built a set of PowerShell CmdLets, which leverage this RESTful API thus allowing us to script our deployments and service removals, making them rapid and repeatable. You can get the PowerShell CmdLets off of the MSDN site here and there is a great “getting started” blog post on the MSDN site here. Using the Windows Azure CmdLets I have been able to automate my deployments and service removals, potentially saving myself hundreds of dollars per month in unnecessary charges (I’ll let you know next month exactly how much I saved).
My first experience with the Windows Azure Service Management CmdLets wasn’t entirely painless. I wasn’t able to get the “New-Deployment” CmdLet to operate properly out-of-the-box, and I ended up spending numerous hours trying to diagnose why. The traffic is encrypted over https and the Windows Azure error messages can often be deliberately vague for security reasons. Fiddler wasn’t of much use either, as Azure detected it’s man-in-the-middle certificate and refused to let me monitor the unencrypted https wire traffic. Failing to be able to watch the traffic, I attached a debugger to the Windows Azure Service Management CmdLet source code and monitored execution,. This allowed me to discover that the WCF Behavior interceptor which inspects outbound messages sent to the Windows Azure management endpoint and appends the required Version Number header to the request was unable to find the httpRequest property in the outbound message. The code assumed that this property would always be present (it didn’t check first) so an unhandled exception was being thrown causing the deployment to fail. I did not get to the bottom of why the header was missing (I’m hoping to find this out at a later time), but I revised the ClientOutputMessageInspector interceptor code to try to get the property first, and then add it if it did not exist. This seemed to fix the problem as I am now able to successfully deploy. My code revision follows. You can find the BeforeSendRequest method in the ServiceManagementHelper.cs, file, near line 206:
I’m interested in others have run into the same issue, or if it was local somehow to my experience. Please drop me a note and let me know.