To my way of thinking cloud native applications are how we should have been building applications all along. My belief is rooted in how I believe apps should be architected which is not an opinion shared by all. I already know several people whom I respect who disagree with me. After several years of architecting clouds and enterprise applications and now having built bepublicloud.com, my own cloud native application, I'm convinced I'm right.
My rules for cloud native application development are:
1. DO NOT manage the cloud within the application. Application management is a separate domain and should be kept separate. If you cannot use one of the many existing tools to manage your application then build a management app, but do not consolidate it with the app.
2.Believe in the power of encapsulation; trapping the complexity of each layer within that layer and exposing only the simplest interface required to the layer above. Think low coupling and high cohesion. It's a great design principle for a reason! Plan for every service you use, because you will use some, to be replaced. Encapsulate them so they can be swapped out easily and painlessly.
3. Start with a multi-vendor deployment, don't just plan for it. There are lots of little things you need to learn about each cloud vendor. Some provide robust API's, some use third parties. Some have great support, some have next to none. Some have great management portals, tools, and/or API's while others are the bare minimum. And price is NOT an accurate indicator.
4. Test the speed and error conditions of cloud services before you use them, you might be surprised. I make calls to several third party cloud services via REST within bepublicloud and I was surprised at the speed of most, while one proved so unreliable due to the vendor's growth issues I couldn't risk putting it into production.
5. Expect the hardware and services to fail. The focus needs to be on continuous availability, albeit with degraded service when necessary. Netflix has the right model having multiple zones within each Amazon region, and multiple regions, so a user's access and experience will NEVER be offline.
6. Understand the long term ramifications if you decide to use vendor specific/proprietary services. As soon as a cloud application begins making calls to the hardware layer, whether to provision resources or provide a status, by definition you break cohesion and amplify coupling. In the real world the result is an application paired to a particular cloud. I believe the application should be portable across clouds. The upside is vendor independence. The downside is a whole lot more work building software services you could otherwise buy (email distribution, queue management, site search, payment processing, etc.).
7. Not all servers are equal in the cloud. Cloud server pricing is predicated on overprovisioning, selling more slices of a box than there really are. Most applications are input/output bound and waiting for instructions as users are figuring out what they want. Amazon differentiates with High-CPU and High-Memory instances, but not everyone does. Performance is the line of demarcation, so research by deploying apps on multiple instance types to get an idea of the ideal target environment. This is true of both public and private clouds.
8. Adopt a strong source code management solution that supports multiple users with remote capabilities. I have settled on Git having tried Mercurial and a few others. Git is by far the easiest to learn, most common used, and most robust. I can manage my codebase with ease, get friends to pitch in from time to time, and keep everything sane.
9. An agile approach works best leveraging working prototypes, continuous builds, and a focus on the user experience first.
10. Automated testing is paramount. Spend the time and money where it counts, on the user interface and feature/functionality. The heavy lifting (80-90%) of testing previous features with each new version (regression testing) can be done through automation.
In building bepublicloud.com the code base is PHP running in Ubuntu on Amazon EC2. The storage services come from Amazon S3, RackSpace CloudFiles, Microsoft Azure Blob, and Nirvanix (although is not priced competitively and therefore disabled as of now). In the few, isolated cases where for development speed I adopted Amazon services, such as their email service and queue service, the functions are encapsulated and optional to program execution. Sure the application would be degraded, however users would still have the access they need. As a result bepublicloud's code can run on any IaaS cloud, and I even have my choice of PaaS clouds which support PHP should I go that route. My design criteria was simple - no single point of failure in a world of failure. I trap every exception I can with recovery routines and robust log messages so I can manage the app without coupling to a provider's platform.
As a new service that is unmarketed, bepublicloud has very little traffic today, but I'm preparing for success just in case. My next step is to use memcache for session data so sessions are preserved as servers are added and removed. I am ready, when needed, to move to a cloud MySQL instance to give me rapid scalability. I won't use one service, but at least two.
I am now looking at virtualization on top of virtualization. To get the power benefits, is it possible to deploy linux containers on top of a Large Amazon instance and then divide up my resources as I need them. A large instance is four times the size of a small instance at four times the cost; however it also has more native storage, is ebs optimized and has high I/O.
There are plenty of use cases where an application is appropriately built on a Platform, especially applications with limited relevancy (specialized applications) or limited time (marketing). In those cases time to market trumps vendor independence.
Like all software development, the rules are really guidelines. There are always exceptions.