Migrating web applications to Windows Azure
As Windows Azure pushes towards offering a full set of infrastructure as a service features, it becomes increasingly lucrative as a hosting platform for not just new applications, but also legacy implementations. In my previous post I outlined the current capabilities of Windows Azure. In this post I will look at Azure as platform for existing web apps and discuss some of its benefits and drawbacks.
Why migrate to the cloud?
As a prelude to the architectural discussion, I want to re-iterate the common drivers for migration. Four classes of reasons stand out, and each of these then reappears when discussing the actual architectures. These reasons are orthogonal: they can all co-exist in varying degrees.
- Scale. Suppose you have a web site that is simply too slow. You have identified the bottlenecks and know the best approach is to add front-end servers. The investment might be impractical – perhaps because of you need the servers only at extreme peak loads, or because getting the sufficient hardware would rip apart budgets you are unable to reconcile. Or, if you’re a startup, you simply may not have the money.
- Reliability. Your on-premise data center may have the capacity, but how is your geo-replication? For some apps, cloud can provide data security and service endpoint availability that far exceeds what you can do on-site with reasonable costs.
- Connectivity. Sometimes the essential benefit is the improved availability of your application. Maybe your IT department simply refuses to open your app to the world, or your application needs tunneled connections to several well-protected internal networks. Setting up Windows Azure Service Bus may well be easier than the political judo necessary to open the required connections.
- Flexibility. The cloud lets you set up – and tear down – resources at a phenomenal speed, and your request for extra machines or storage is not bounded by the spare capacity your datacenter may have. If a campaign website needs to prepare for a heavy-duty weekend, you may not have the servers available, and purchasing may be too slow or expensive.
What about costs? Notice that I didn’t mention cost reductions, even though you may quite well get considerable cost benefits. However, calculating the savings beforehand is often difficult. There are at least two scenarios where the cost argument works well: 1) continuing on-premises would incur non-linear costs (e.g. the investment required to found a totally server facility) and 2) when you need very elastic scaling (i.e. your peak load requires much more capacity than your average use).
Both these scenarios imply local investments that cannot be initially fully utilized – and perhaps never. This doesn’t mean that the cloud’s cost benefit only derives from capital expenditure. It’s just that the equations for operational expenditure become very muddled with details such as workforce costs for backup administration, estimated cost for loss of service and so on. Direct cost may be a reason to migrate, but it’s rarely the most important one.
If your application is fundamentally compatible with Web Sites (see below for problems that can disqualify you), that is probably the your path you should pick. You get a good dose of scalability with relative ease – basically, just upload your site to the cloud. Still, you need to understand a bit of Azure around WAWS.
The Web Sites service model offers you one gigabyte per subscription, divisible between 10 sites. But that’s the site’s static content you deploy, and you typically need dynamic storage where you can easily write and access in runtime. For this, Azure Database (formerly SQL Azure) or Azure Storage do the trick. For most existing applications you already have a database, so the database option is what you need – at least until your database grows to tens of gigabytes.
Starting up with Azure Database is mostly just an exercise in migrating the existing schema and data and changing connection strings, which makes it trivial to adopt. If you do happen to use some of the features not supported in Azure databases and can’t work around that, then you should probably look at hosting a SQL Server in a virtual machine (see below). Integrating with other applications (perhaps still running on-premises) can be done in various ways. The easiest option is to just point the on-premises apps to use the cloud database by changing the connection string, but there are usage scenarios where this results in too much latency and/or bandwidth costs.
If you’re in the habit of storing gigs and gigs of data on your web server’s local disk, you should get rid of it. The Azure Storage (blobs and tables, also messaging queues) is relatively easy to use, but doesn’t have an API-level equivalent in existing applications – you need to alter your code to benefit. For blobs (i.e. large files), the changes are usually semantically trivial, but require some mechanical effort.
Picking up non-relational Tables is more complex and usually involves replacing existing data storage logic. In particular, complex queries and performance-critical data retrievals require a new train of thought rather dissimilar from the relational database world. Luckily, you don’t typically need to adopt Table Storage in order to migrate an app. You might do it to improve scalability, though.
Once your application is online as a Windows Azure Web Site and your storage is set up, you’re good to go. Your monthly bill would consist of compute hours (if you exceed the limits for Web Sites free offering), storage (priced by combination of gigabytes stored, data transferred and transaction count, depending on your use) and bandwidth costs (per GB transferred). Now you’re there: your app is running, and somebody else takes care of your hardware and OS updates, and gives you a 99+% SLA in the progress. What’s next?
Becoming a cloud citizen
Let’s look at some ways your now newly cloud-born application can benefit from the resources around it.
Perhaps your application has a problem with distributing some large files to your customers around the world? Maybe you should pick up Azure CDN to quickly deliver your files into various locations around the globe. The costs involved are trivial, and CDN is enabled by checking a single box in the administration portal. The catch is that the files to be distributed must be in Azure Storage – more points for you if you ended up pushing your data there already.
Have a performance problem you cannot sufficiently fix by using ASP.NET Cache? Perhaps you need more cache space, or you need to share the cache between machines on a cluster. You could take on Azure caching and leverage a relatively simple API – or the increasingly common Memcached API – to store your CLR objects, XML files etc. in-memory right near your web servers. This can’t happen without altering your code to benefit from the cache, but the required changes are relatively simple.
Yet another approach might be to use Access Control Service to make it easy to integrate with 3rd party identity providers. Need to support logins from Facebook, Google or Live ID? While it does require some fiddling in your application code, the required changes are trivial for most applications (if they aren’t for you, then the required changes probably help you improve your architecture anyway).
These three examples serve to prove a point: While it may make sense to migrate to the cloud to gain non-functional benefits (reliability, cost, scale etc.), some of Azure’s services provide features that are cumbersome to produce locally. For example, setting up an on-premises caching cluster is a headache, and a CDN even more so (practically you’d end up buying the service – that’s better, but still takes real effort).
What problems can I expect?
It’s not all that rosy. There are a few things to be aware of with Azure Web Sites, particularly the free offering:
- Shared hosting (the free edition) doesn’t support custom domains – you’ll have to do with yourappname.azurewebsite.net. According to Microsoft, a fix is coming, but it won’t be free.
- In a similar vein, even the reserved instances do not support wildcard mappings (i.e. directing *.mydomain.com) to a single site, nor can you map root domains (just “mydomain.com” with no wwws in front). This, too, is getting fixed.
- The free offering has a 165 MB/day bandwidth limit (for outbound data) – you can agree to pay for more bandwidth, but then you sort of lose the point of being free. The limit is so low that it’s very easy to hit.
- Windows Azure Web Sites doesn’t have a solution for batch jobs or background workers. You’ll have to run a Virtual Machine (requires you to manage the OS updates) or convert the code into a Worker Role. Both options will cost you money.
- WAWS hosting is IIS 7.5 with .NET 4.0. No, that’s not IIS 8 and .NET 4.5 – if that’s what you need, get a VM. Of course, IIS 8 support is coming, probably fairly soon once Windows Server 2012 is out.
- There is no (real) SSL support. There is a certificate for azurewebsites.net, but if you need a custom domain (and use reserved instances), you still can’t upload your own certificate. Being fixed, of course.
In short, WAWS works great for simple sites. It is not perfect yet, but once the trivial issues (domain limitations, SSL etc.) get fixed, it has everything you need.
Then comes the question of whether Azure makes sense financially. If you need reserved instances and need the highest available SLA level, you want your application running in two instances. At the lowest tier of instance size this will set you back 2 x $0.12 / hour = $170/month (~$120 while WAWS is in preview) – plus the storage and networking costs. That is not exactly cheap if you were planning to run your blog on Azure. For any business application, the cost is probably negligible. For a personal site, you would still probably be better off by using a 3rd party hosting provider – starting from as low as a few dollars a month.
What if WAWS isn’t for you?
Most of WAWS problems can be solved by going for Web Roles or Virtual Machines. Migrating to the Cloud Services model using a Web Role is a good, forward-looking approach: you get the most native programming model for Azure, and scaling is a breeze. It does require code changes though, and the deployment and configuration story is more complicated than with Web Sites. If you can’t afford to make the changes now, a Virtual Machine like your current hosting server is a good alternative.
If you decide to the Web Role way, you need to solve the same storage dilemmas as with Web Sites. On the other hand, an app running on a Virtual Machine can use the VM’s local storage disks to store data. You can even run a local SQL Server, although for most applications it will be cheaper to migrate over to Windows Azure Database to avoid SQL Server licensing costs.
Both Web Role and the Virtual Machine approaches allow you to migrate your application to use the cloud paradigms piece by piece. A web application running in a VM can be iteratively improved to be more cloud-aware by pushing its local data onto Azure Storage, support scale-up by removing local critical state and so on. Once you’ve removed your dependencies on the local server, the site may well be ready to be turned over to a Web Site or a Web Role hosting model.
By all this, I’m not saying Virtual Machines are only an interim solution before your app has been migrated. Thousands of successful web sites running on Azure’s EC2 offering are a living proof that IaaS is a quite capable approach to web hosting. Still, a developer gets the maximum benefit from Windows Azure by using it as a PaaS platform.
Since you don’t get a discount for managing the OS yourself (i.e. computing hours on VMs cost the same as they do on PaaS offerings), you should aim at not doing that. On a small scale, that particular factor is unlikely to make a difference, but it does show the direction of the platform. After all, for many applications, an IaaS configuration is just a transition phase while waiting for availability of PaaS/SaaS approaches, where even more management is automated.