The Good, The Bad, and Windows Azure
Just a quick post that outlines some of the trials and tribulations that I have encountered with Windows Azure over the last month of development with Windows Azure.
All in all it has been a big learning experience, and painful at times. Documentation from MS is outdated and spotty at best, so you are left trolling the internet for solutions that you can trust.
Thankfully, I have had a Microsoft insider helping me out.
MS Provides the Azure SDK that installs a Compute Emulator and a Storage Emulator. These are intended to mimic the real cloud. Getting these installed is fairly straight forward. Understanding how they work on the other hand, as well as attaching the debugger, and getting diagnostics information is a bit challenging.
Long story short, cloud platforms are great, and I still believe in Azure, but hopefully soon, they will do some things to make working with Azure easier for me, as an engineer. Thus far I have spent 50% of my time dealing with behavioral inconsistencies between the local SDK and the real cloud, 25% idle time just waiting for packages to deploy and spool up, and maybe 25% of my time actually refactoring my code to work in a scalable high availability environment.
The nice parts…
- If you structure your applications correctly, you can build highly available and highly scalable applications.
- If you structure your applications correctly, you can click a button, publish a new instance of your application to a staging environment, test it, then click another button, and your application that was in “staging” is now in production. That is srsly hot!
- There are a lot of infrastructure resources at your fingertips, i.e. hosted services, cloud storage, multiple cores, huge disk volumes, etc. The downside is that there is a boat load of stuff that you need to learn to get proficient with azure (but this is no different from rackspace or amazon). The other downside is that you could inadvertently get a big bill if you aren’t careful about how you organize, orchestrate, and program your applications.
Things you should know…
- You will need to create a “cloud project”, and, depending on your needs, add a “Web Role” and/or a “Worker Role” to this cloud project.
- The cloud project can pull in existing “Web Projects” into web roles, and can also pull in existing “Class Libraries” as worker roles.
- In order to “deploy” to your local development environment, you will need to set the cloud project as the startup project
- If your web project that is associated with the web role, contains virtual directories (aka virtual applications in IIS 7.x) you will need to add special configuration to the cloud project’s ServiceDefinition.csdef, here is a great post “Running Multiple Websites in a Windows Azure Web Role”
- Your web applications may have trace diagnostics, well they don’t show up in the compute emulator by default, so you may need to “Implement Tracing to the Azure Compute Emulator”
- The out of the box storage emulator expects sqlexpress to be installed. I never install sqlexpress, I normally install sql developer or better. So in this case you will need to tweak your configuration settings for the storage emulator. You can use the DSInit command from the windows azure sdk command prompt to configure sql server, read more here
- You can use visual studio or 3rd party tools to browse your local storage account and diagnostics logs. Check out this link to learn how to browse your development storage from the VS.NET IDE. If you are into 3rd party tools, my favorite 3rd party tools for viewing local and cloud based storage and diagnostics information is to use Cerebrata Cloud Storage Studio and the Cerebrata Azure Diagnostics Manager
Things to avoid
- virtual directories. virtual directories were a pain in the neck before azure even existed, they are still very painful. if your application has virtual directories, consider re-organizing your architecture, because it just gets more painful when you move from your local environment into the cloud.
- mixing web services with web applications. before the cloud, it is typically frowned upon to host your web services and your customer facing web site in the same application. before you move to the cloud, you may want to make sure that your applications have proper separation of concerns. you may want to add additional instances for your services and if the services are hosted by the customer’s web application, the you could have a scaling issue.
- don’t count on things like app pool name, file system paths – every time you deploy a new instance, the instance gets a new app pool name. if you are expecting your files to live in a known location like C:\somedir, you may be surprised to find that sometimes your files end up in E:\some directory that microsoft chooses or F:\some other director that microsoft chooes, etc.
- loosing your certificates – various aspects of azure require certificates. my advice is to generate some certificates with exportable private keys, check them into version control, and share them with the other developers on your team. if Joe doesn’t have the same certificate as me, and he mucks with say the storage account that is baked into the configuration files, and he checks in his code, he will break my development experience and if either of us push to the real cloud the cloud will be broken.
- writing to the local file system – many apps write to the local file system. if you publish a new instance, you get a shiny new file system. if you overwrite an existing publication, you get a shiny new file system, with all of your old files being MIA. if you need to persist files that are critical to your app, use blob storage.
- using assemblies that require 32 bit mode – if an app running in your web role has an assembly that requires 32 bit mode, then you will need to login to the remote desktop for your instance after you deploy it, hunt down the application pool associated with your virtual server or virtual application and set its “Enable 32 bit applications” property to “true”
- trusting that VS.NET will publish all dependent assemblies into the proper publish directory – if you application has many dependent assemblies, like say, MS Sync Framework, MVC, SQL CE, etc, my advice to you is to create a directory just for dependent assemblies, and do this for each application that you need to deploy. I literally spent hours tracking down assembly references that were non-standard .NET framework assemblies.
Things that need to be re-worked… seriously… no joke…
- Logging, Monitoring and Instrumentation – the documentation on this is so fragmented its not even funny. As a software engineer, I need to write a few lines of instrumentation code to see what my code is doing at runtime, and I need to be able to analyze that data. MS has given us a flashy new SL portal that gives us a lot of power, how about giving us a few buttons to turn off / on Azure Diagnostics Tracing, and Windows Event Logs? Why the hell do I need to write a program, custom code, or buy a 3rd party tool to enable this feature?
- Stopping and Starting + Deploying Instances is seriously slow. I spend 30 minutes between integration test cycles just on performing an upgrade of an existing instance and getting the instance online again. There has got to be a better way. Actually, I have been logging into the remote desktop of my instance and making tweaks there, but this is a seriously bad practice. I have also resorted to emailing / ftp-ing files that I need to get into the cloud to some http addressable location, and then downloading them onto my instance. Once again, this is a seriously BAD practice because my local environment is not in parity with what’s in production.