Introduction
I have recently decided to take on Windows Azure a.k.a. The Cloud. I decided to precede the instant-sample by first getting a real understanding of what exactly the Windows Azure Platform is, and how it is going to affect/improve my development experience and product delivery. This blog post is the result of what I learnt.
What is Windows Azure
The Windows Azure Platform is the new Cloud Computing platform from Microsoft. It consists of mega data-centers located all around the world and customized versions of Microsoft Server 2008 R2 and Microsoft Hypervisor.
There are a couple of data-centers already in operation, and many are under construction and due to be completed during the next 2-3 years. In Chicago there is a 700 000 square foot complex, Dublin has 300 000 square foot, Austin has 250 000 square foot. These data-centers are built around Container Computing (where 2000-4000 servers are prebuilt into air-conditioned containers, ready to be plugged in.) Containers are delivered daily, positioned somewhere convenient and plugged in. The goal is to be able to grow the physical computing power at a moment’s notice, and in the same breath have the ability for quick recovery in the worst case disaster of mass hardware failures.
Microsoft found, from past experience, where the requirement for new servers world-wide exceeded
10 000 new servers a month. It took some hours to physically install each server into a rack and wire everything up before software could be installed. With Container Computing, Microsoft manages to save time on installation before new hardware can become operational.
The current specification for the servers is to be dual quad-core processors allowing for 8 physical cores. In most virtualization environments, multiple virtual processors share the same physical processor core. This works because not all computers use the full capacity of a processor 100% of the time. By swopping idle processors out of the physical core and replacing them with processors that have work to compute, virtual systems can run extremely efficiently and utilize the hardware better.
Microsoft developed a custom version of the Hypervisor virtualization system specifically for Windows Azure. This version only allows one virtual core per physical core. It is an extremely clever security mechanism which I will explain later.
Microsoft also customized Windows Server 2008 R2 creating Windows Azure. Windows Azure is a special build designed to run on the customized Hypervisor, and in the context of the Windows Azure AppFabric.
When all of these components are put together with multiple redundancies designed right at the core, you get The Windows Azure Platform a.k.a. The Cloud.
The Application Environment
Windows Azure offers the same environment that we’re all used to when developing for Windows or Windows Server. There are local disks, local memory, web servers (IIS is optional, as is Apache.) The difference is in how the environment is created and maintained. First, you are not allocated a static Virtual Machine. Virtual Machines are created as the demand increases and your application is deployed to the VM to facilitate its operation. This means that security updates are applied centrally by Microsoft and all new VM instances are immediately up to date.
It also means that when a VM instance is shut down during periods of low demand, any data in local memory or on the local disk is lost forever. Microsoft recommend that we refrain from utilizing these two resources, not only for the reason already mentioned, but also because there is no guarantee that the Load Balancing services will direct a specific user to the exact same VM instance between requests either.
Storage is provided in four flavors, Azure Tables, Blobs, Queues and SQL Azure. Each one of these has its own uses and functions. The first three are native types to Windows Azure. They follow known implementations as Tables (semi-structured storage), Blobs (unstructured storage) and Queues (semi-structured storage for passing instructions). SQL Azure is added as a mechanism for existing applications to migrate to The Cloud with little change except for a connection string.
Azure Tables are structured around entities created using the Entity Framework (or any LINQ enabled entity class.) Entities are stored in partitions based on the current date and have an internal timestamp and unique row identifier. Using LINQ, entities can be easily queried and updated directly from code, instead of having to first convert too- or from some other RDBMS format before your code can deal with the data. Azure Tables are designed to scale out massively, thus they are accessible from numerous locations to multiple clients without any bottleneck effect.
Microsoft says that you can store billions of records amassing to Terabytes of data that is just as fast as a well-designed, albeit smaller, SQL Server Table equivalent.
Blobs are designed for unstructured storage and are generally used to store copies of documents or images. However any form of data can be stored inside of a Blob and Blobs can be attached as virtual drives to any Virtual Machine instance. In this scenario, a Blob can be used similar to a local File System.
Queues are used to communicate data and tasks between Web and Worker Roles. Queues have an upper limit of 8Kb and should contain URI references to the data required to process the work packet.
All three of these mechanisms are automatically replicated three times across The Cloud to increase performance when querying or updating this data. This also increases data-redundancy as the fabric will automatically replace any corrupt copies with a fresh copy. Each data entry in one of these mechanisms is accessible through a URI using either HTTP or HTTPS in combination with SOAP, REST or JSON.
All data stored in any of these mechanisms is encrypted using your Applications encryption key, and can be flagged as either Public or Private. Public data can be read by everybody, but a valid Application encryption key is required to write any data.
Last there is SQL Azure, SQL Server for The Cloud. I can only say that SQL Azure is an attempt to accommodate existing applications on Windows Azure using ADO.NET to access data. To re-host an existing ADO.NET application simply requires redirecting your connection string. There are several drawbacks, for example SQL Azure does NOT mean that you can have billions of records amassing to Terabytes of data. It is a single SQL Server instance that is hosted alongside of your existing Azure application. It still has the same bandwidth constraints when reading/writing data; and you still have to worry about locking and unlocking resources as you are using them.
Applications are broken into two roles, the Web Role and the Worker Role. Each role is designed to function in a specific paradigm, the Web Role being the public interface to your application. This can contain web sites (ASP.NET, PHP, etc.) and Web Services (SOAP, REST or JSON) and is usually hosted inside of IIS, however Apache can be installed. Web Roles are to serve short running processes to the user, anything up to 30 seconds. Any process that will take longer than 30 seconds is recommended to be moved to a Worker Role.
Worker Roles are designed to replace Batch processing that is usually served by a Windows Service or *NIX daemon. Any process from a Web Role that will take longer than about 30 seconds to process should be strongly considered for a Worker Role instead. Worker Roles receive their instructions from a Queued message. This message would usually indicate a type of task and URI references to any data required to process the task. A Worker Role would then process the data, and usually on completion pushes a notification message to a Queue that the Web Process can use to notify the user of the completion of the task. Worker Roles can also act autonomously in the background waking up during a schedule to do a determined set of work and then to shut down again until the next schedule. Worker Roles can also be any kind of application, even a native Win32 application, PHP or JAVA.
The Development Environment
Most of us researching the Windows Azure Platform will be developers interested in developing a Cloud application. This section will attempt to inform you about what changes in your development environment you should expect. I develop using the Microsoft platform, and as such, this section will focus on Microsoft Visual Studio specifics. If you develop using PHP or other platforms, other steps will be required to achieve cloud compatibility.
That being said; if you use Microsoft Visual Studio and Microsoft.NET; very little has to change in the way you are used to developing already. Web Roles are normal ASP.NET web applications, or Silverlight if you so choose. They can also be standard ASP.NET Web Service, WCF Service or WF4 Workflow Service applications.
Most of us who have dabbled in the black arts of Silverlight development have been exposed to RIA Services and LINQ as an easy and efficient manner to connect to SQL Server databases on the server. Others have had the luxury to connect to standard web services using LINQ to XML.
Those of you who are still on pure ASP.NET might have attempted to use LINQ to SQL at some point as a neat way to get to your data as well. If you have not, I’d recommend you go skill up on LINQ right now, it is really powerful and easy to use.
This is important because the recommended storage mechanism for structured data is Azure Tables and will be accessed using LINQ. You have to inherit from a base class which is compatible with the Entity Framework. Using the Entity Framework to create your data storage classes and relationships and LINQ to read/write those classes makes for a much more natural development experience. This also means that if you have LINQ and Entity Framework in your existing application, the migration effort to a Cloud application is minimal.
Azure Tables
Azure Table Storage is designed to be massively scalable and a typical Azure Table can contain billions of records amassing to Terabytes of data. All of this data is multiply redundant, and access is faster than a standard SQL Server Table would be. Azure Tables are not structured, they are semi-structured. Each record is saved with the field names along with the data. This means that you can save multiple types of records in the same table, or change your entity structure over time.
There is no relational model, but by understanding and exploiting the native indexing and partitioning system of the Azure Table system, you can create data structures that react just like relational structures. First an Azure Table Entity has a PartitionKey, RowKey and Timestamp. The primary key is made up from the PartitionKey and the RowKey and each are strings that can store up to 1Kb of data.
For related entities, the child entity will contain unique references to the parent entity’s PartitionKey and RowKey providing an easy means to exploit the built in partitioning system for how data is committed to disk in Windows Azure.
Tables are automatically broken up into individual partitions based on the number of unique PartitionKeys that exist in the data stored inside of it. Partitions are controlled automatically through the fabric by isolating very busy partitions and making them accessible on dedicated servers. The RowKey provides a unique reference to each entity inside of a particular partition.
How you would go about creating a referential data structure in Azure Table Storage would be to store the parent entities using a unique reference for the PartitionKey. For this example we’ll assume that users accessing an online bank. Entities store data related to accounts, transactions and current balances. For the Account entity we will use the User Id as the partition key. For the transactions and current balances we will concatenate the User Id and the Account Id to create a unique partition. Because the User Id and Account Id are always known, queries can respond in quick times.
This mechanism allows Azure Tables to scale out massively and store Terabytes of data and billions of records without performance degradation. All of this data is stored on 3 nodes to enhance both access speeds and data redundancy. All data in the Azure Table is stored encrypted.
Data in an Azure table can be accessed using the URI [HTTP|HTPPS]://
.cloudapp.net/
/
/
using SOAP, REST or JSON. If the Azure Table is public then data can be read by any client; updating requires the encryption key.
Blobs
Blob Storage provide a means for you to store unstructured data much in the same way that you would store a bunch of images on the File System of a server. Blobs can be mounted as XDrives on the Virtual Machine instance where a particular service is running and accessed exactly like a file system would.
Blobs are useful for storing files and other data that is not (or cannot be) represented using the Entity Framework and LINQ. Documents, images and other custom user content fall in this category.
Blobs can also scale out massively and each entry is stored on 3 nodes to enhance both access speeds and data redundancy. All data in Blobs is stored encrypted and can be private or public.
Blobs are accessed using the URI [HTTP|HTTPS]://
.cloudapp.net/
using SOAP, REST or JSON. If the Blob is public then the data can be read by any client; updating requires the encryption key.
Queues
Queue Storage is not designed as permanent storage; they are used the same way that their counterparts are used every day. Queues provide the mechanism to send instructions between Web and Worker Roles.
Queues have restrictions in how they are used; one being that each queue entry cannot exceed 8Kb of data. This makes them inefficient at transmitting data between roles, rather you should transmit an instruction code and the URI to access either the Azure Table entry/entries or the Blob.
Queues also work slightly differently to normal every day queues when retrieving messages from them. They do not immediately delete queued messages, but rather make the message invisible to other readers for 30 seconds. It is the responsibility of the role that is processing the message to manually delete the message from the queue upon completion of the task. This is to prevent messages being unprocessed because a role has caused an exception during its operation.
Queued messages can scale out massively and each entry is stored on 3 nodes to enhance both access speeds and data redundancy. All queued messages are stored encrypted.
Queued messages are accessed using the URI [HTTP|HTTPS]://
.cloudapp.net/
using SOAP, REST or JSON.
SQL Azure
SQL Data Services is used to access SQL Azure and is used to provide a standard relational database model to Windows Azure. SQL Azure operates separately from Windows Azure and you do not have to have a Windows Azure account to access SQL Azure and the SQL Data Services. SQL Azure is accessed using standard ADO.NET and can be accessed from on-premises applications. This service is provided as a bridging mechanism where on-premises applications have to access the data in The Cloud, or where existing applications are migrated to Windows Azure.
SQL Azure is hosted in a database on the same node as the Web and Worker Roles, or in cases of high availability and accessibility, on a separate node. SQL Azure handles all system updates and upgrades and databases are always hosted on the latest version of the software. Many enterprise organizations have a vested interest in SQL Server and existing applications have to interoperate with Cloud based applications. SQL Azure allows these companies to leverage The Cloud.
SQL Azure however DOES NOT support billions of records in a table that measures its size in Terabytes. Because the service is not hosted across multiple nodes at the same time, bandwidth issues still exist when accessing data and users are responsible for maintaining locks on objects they are using. A dead-lock is still a very real possibility.
Security
For most of us, our biggest fear is that The Cloud is compromised by some malevolent hacker and all of our data is stolen. Since Microsoft platforms are the most targeted platform for malevolent people and applications, Microsoft have put great care into ensuring that our data is always secure.
Microsoft has taken some measures to ensure that we trust the facilities that they provide. The first of which is a unique encryption key, which is your own responsibility to keep secure, when you create your application. This key is passed to all of the reads and submits that your application does to the storage systems. All data is always encrypted, even if read access can be made public.
All data is accessible through HTTP and HTTPS. Microsoft recommends in the Security Best Practices to communicate to all data stores using HTTPS to prevent others from intercepting and “listening in” on your communications.
Microsoft have recommended practices for storing secured and encrypted data and even for handling logging messages caused by traces in the application.
Each Virtual Machine has the firewall turned on, and only ports specified by the developer during deployment are open for public access. Virtual Machines are constantly updated with the latest Service Packs and security patches.
Denial of Service attacks are partially (if not fully) mitigated by the Windows Azure load balancers, internal algorithms that detect Denial of Service attacks and mitigates by removing any affected Virtual Machine instances. Another key element is for the developer to choose the correct instance count and scale-out options during deployment. Other features are that the root OS for any VM is not directly accessible through the use of Virtual IP’s to access Web Roles.
Spoofing is prevented by using a complex VLAN setup that prevents spoofing across partitions or compromised nodes accessing the Fabric Controller through impersonation. Multi-cast traffic is blocked except for DHCP, and the communication between the root OS and the Fabric Controller is encrypted over an HTTPS connection.
Packet Sniffing is handled by the Hypervisor Virtual Switch which prevents sniffer attacks on other Virtual Machines on the same physical server. Physical switch hardware is used to restrict connections to the Virtual Machines to prevent spoofing on the internal network. If an attacker got past numerous mechanisms designed to prevent any attack, they would only be able to see any messages destined to the dynamic IP address of the compromised Virtual Machine.
As I mentioned earlier, Microsoft have modified Hypervisor to support only one Virtual Processor per physical Processor Core. This was done as added security to prevent any malicious hacker who managed to by-pass all of the security measures, and manages to gain access to the physical server. The hacker would only be able to see the registers on the physical core that the compromised Virtual Machine was running on. While it is much more efficient to run multiple Virtual Machines sharing the same Physical Core, it is a potential opportunity for a hacker to identify encryption keys during register swops when Virtual Processors are changed in the Physical Core. By only allowing a single Virtual Processor to run in each Physical Core, no register swopping is taking place, and no opportunity is gained to compromise encryption keys.
Microsoft has also contracted external top-tier penetration testing firms to assess the vulnerabilities, and strengths, of the Windows Azure Platform. Over a period of 7 weeks, numerous professional penetration testers were unable to mount a single successful attack against The Cloud.
By following Microsoft recommended Security Best Practices along with the inherent security of the Windows Azure Platform, you can create a robust, highly available, secure online application.