Lately I’ve been working with startups who are interested in Windows Azure, but they want to use PHP, Ruby on Rails, or Python. Sometimes they also want to use Macs for their primary development machines, and they want to retain the tools they are comfortable with (e.g., github), which are typically Unix commands.
You absolutely can use Windows Azure for PHP, Ruby on Rails, or Python web development, and you can keep your Mac and all your usual development tools for those platforms. However, there is a bit of upfront work that needs to be done to get you to that point – and currently, some of that upfront work needs to be done on a Windows machine. As this scenario becomes more and more popular, I’m pretty sure that this upfront process will get simpler and simpler (whatever Microsoft doesn’t get to, the community will).
So until we reach a point where you can be blissfully unaware of what’s happening behind the scenes to run these languages on Windows Azure, somebody on your team needs to take responsibility for understanding how it all works and how to set things up.
I want to help. For simplicity, I’m going to talk about PHP for the rest of this post, but the same techniques would work for Ruby on Rails, Python, or Java (or Perl or any language that supports FastCGI and has an implementation that works on Windows Server). These concepts are useful for developers using C# or VB.NET as well, especially if you would rather use a tool like WebMatrix instead of Visual Studio.
Thanks to Bizspark, a startup can use Windows Azure for FREE for up to three years (and cheaper than retail after that). So while this might take you a couple of days to figure it out and set it up, it’s pretty worth it. This isn’t shared hosting … we’re talking a 99.9% uptime SLA and dedicated cores!
If you’re not ready to join Bizspark, go to www.windowsazurepass.com and use promo code PFOLEY to get a free 30-day trial – no credit card required.
Windows Azure has a hierarchical model for deploying compute resources (note that I’m leaving out some details):
At the top level, you have a service, which is a logical grouping of functionality. A complex solution might have multiple different roles – a role is essentially a specific definition of a virtual machine. For any given role, you can have multiple instances running, but each instance will look the same; this is a “stateless web app” model of scalable development – data is stored in SQL Azure or in Windows Azure storage (neither is shown on this model). You want to have at least two instances running in order to get high availability. If your traffic increases, you simply up the number of instances. Windows Azure seamlessly balances load across these instances.
This is amazingly powerful and flexible, but if you are building a web startup, you probably want to focus your energy on the actual web site – the grey boxes inside the instances. You probably want to start with an architecture that you know will work – that’s “good enough” – without having to think about all the possible fancy permutations.
And there are indeed fancy permutations – most enterprises will take advantage of Windows Azure’s excellent support for production and staging environments (the outer green box represents a subscription – a unit of billing which can contain multiple services):
Architecture is always driven by context. And a big part of a startup’s context is cost. The MSDN benefits in Bizspark include enough free Windows Azure resources to keep two instances running full time. While it might be super convenient and more “safe” to keep separate production and staging deployments running all the time, it’s not cost-effective for a startup on a tight budget.
A startup also needs to iterate quickly. You need to be able to have multiple versions of your site running at any one time so that you can perform A/B tests on the effects of various changes. In addition, you probably want a separation between your homepage and your “app” – and maybe even a separate site for administrative activities:
If you’re on your way to becoming the next facebook, it might make sense to put each site in a separate role … but you can support a significant amount of activity on a pair of instances, and you might as well use up all your free capacity before you start paying for more. It makes sense to run a bunch of sites on a single role.
There’s one more detail – most web solutions have some amount of background processing. The canonical way of doing this in Windows Azure is to have separate separate web roles and worker roles in the same service:
This is a great way to architect a solution – it provides for excellent resiliency and separation of concerns. However, it also adds more cost. Most startups can get by with a single web role that also contains the background processing:
In summary, if you own a web startup, you want to join Bizspark and use the MSDN benefits to get free Windows Azure compute resources. Your free resources are enough to run two instances full-time, so you want to get the most out of those instances. In practice, these means you are going to have a single role with two instances (two are required for high availability), and you are likely going to run several separate sites within that role. You are also going to run your background processing in the same role.
To implement this architecture, I recommend running a synchronization process that lets you publish site changes by copying files to Windows Azure storage. This has two big benefits:
- Site changes show up instantly (and you can rollback a bad change instantly as well)
- For most website changes, you won’t have to change the role at all
If you’ve set up your role to support PHP, then you don’t need to change the role just to change some .php files. While using a separate staging environment is technically safer, you can justify running test and production in the same role so long as it’s really easy to rollback bad changes. The only time you really need to fire up a staging environment is if you’re installing support for a brand-new technology or doing something like upgrading PHP itself. Since that’s a fairly rare occurrence, you can just do this manually. Extra small instances cost 5 cents/hour, so it’s not much of a financial burden to upload a new deployment for a few hours when you do need to test with an increased level of safety.
There are lots of resources explaining how to get up and running on Windows Azure – so many that it can be hard to know where to start. I recommend http://www.interoperabilitybridges.com/ to stay up to speed on all the projects that are supporting open source languages – like the Windows Azure SDK for PHP. I also learn a lot from Steve Marx and Wade Wegner – the idea for a synchronization utility came from them.
But if you’re like me, you don’t want to work through all the details – you just want to get started. The best resource I’ve found for that came from IRhetoric. This post provides a zip file that has everything you need to get started developing php on Windows Azure.
To go past “getting started” and get closer to production-ready, I think at least two more things are needed:
- A synchronization utility running in Windows Azure that pulls code files from Windows Azure storage
- A command-line utility for uploading files to Windows Azure Storage in order to deploy them (so they can be sync’d by the utility above)
Once running it looks something like this:
Using a zip file is handy for this sync process, because it makes uploading changes all-or-nothing. You could get fancy and do diffs, but I think it’s better to zip up whole sites – that makes it easier to rollback to previous versions if something goes wrong.
I’ve begun experimenting with an implementation of this … you can see what I’ve done by downloading this zip file. This is NOT production-quality code – I have not thoroughly tested it, and I haven’t implemented everything that’s needed (handling multiple sites, for example). This is just an example to give you an idea of what can be done.
Creating a command-line utility that can be added to your build script is fairly straightforward – just use the Windows Azure SDK for PHP and do something like this:
/* Write to blob storage */
$account = ‘accountname’;
$key = ‘biglongkeyfrommanagementportal’;
$container = ‘container’;
$uripath = ‘filename’;
$localfile = ‘filename’;
$storageClient = new Microsoft_WindowsAzure_Storage_Blob(‘blob.core.windows.net’, $account, $key);
$result = $storageClient->putBlob($container, $uripath, $localfile);
// check for errors, eh?
After I do a bit more exploring and testing, I’ll record a screencast showing how these things fit together. Eventually, I’d like to show an example that could be used as a complete, production-ready scaffold for a web startup. There are several additional items to check off before reaching production-ready:
- Polish the sync utility (support for multiple sites, clean up old files, support for background processing, better error handling/tracing/logging, documentation)
- Set up the role for Remote Desktop so that you can diagnose problems more easily (this can be a bit tricky the first time)
- Develop a build script that handles source control and deployment (and strive for continuous integration)
- Adopt reliable patterns for using SQL Azure and Windows Azure storage – potentially adopt different techniques for disposable development (prototyping) vs sustainable development
- Adopt patterns for local storage for development and UX testing – can’t rely on the dev fabric, because it must also work on non-Windows environments
- Adopt a reliable unit-testing practice for sustainable development
- Test, test, test
- Rinse and repeat for Ruby on Rails and Python (and whatever else startups seem to want)
I’ll keep experimenting, and I’ll write about these issues as I learn.
As I work through a “standard” architecture for web startups using Windows Azure, I can even envision automating the process of setting up and maintaining the Windows Azure role, similar to the way Windows Azure Companion works. It might even be possible to allow a simple Windows Azure role architecture to be enabled without ever requiring a developer to download the SDK – or even have to be on Windows. I envision a way to do that, but I have to work through the details.
If you’ve read this far and find this approach intriguing, I’d really like to hear from you. Feel free to leave a comment or email me at Patrick.Foley@microsoft.com. Let me know what you are working on and how I might be able to help.