An article by Steve O’Gallagher
Recently I have been spending some time in the world of Amazon Web Services as we’ve been building scalable cloud-based applications for some of our more forward-thinking clients. Agility. Scalability. Configurability. I’m amazed that last one is actually a legitimate word, but it is appropriate. AWS and other platforms like it can take you a few good steps towards the promise of digital orchestration.
Livestock vs. Pets
A significant weapon found in the AWS arsenal is a service called CloudFormation. This tool offers the ability to map out in a JSON or YAML file the blueprint for your entire cloud-based infrastructure: your web servers, your databases, your queued messaging systems, your state machines, lambda functions, security settings and access control. What does this do for you? It means you can treat your infrastructure like livestock instead of pets. Stay with me.
Pets, if you’ve ever had them, they are great. They can do a lot for you, but they require a lot of time, effort and cost in return. Importantly, this time and effort usually needs to be customised for each pet individually and you grow attached to them. Livestock on the other hand can theoretically do the same things pets can do (a friend of mine genuinely has a pet sheep. It’s not for everyone, I understand, but it validates my comparison so I’ll allow it), but they are easily replaceable without the need for individual customised attention or the shedding of tears.
If you harness the power of Autoscaling Groups in your infrastructure and include health checks, your cloud-based solution can look after itself automagically. One of your web servers isn’t working properly? Terminate it. A new clone will pop up to replace it and run scripts you’ve written to automatically install all your dependencies and run your apps on launch. A ton of users are suddenly hitting your servers because your website says you’re giving away free iPhones? No worries. You had setup your CloudFormation to check your instances’ CPU and it’s automatically adding extra servers to cope with the strain. No petting required in return. Once you stop giving away free swag and the web traffic dies down your surplus livestock will be culled automatically. Web server costs: optimised.
While reading the above you may have already copped on to the fact that this kind of infrastructure certainly lends itself to continuous integration. Once you’re happy that your infrastructure is giving you everything your app will require, you can spin up another identical stack reusing the same working template and call it your staging environment. Same again for production. Then you can make use of AWS CodeDeploy which can be executed by your continuous integration triggers to automatically update your application with the latest code and start it up with whatever scripts you’ve written to get it going. Amazon has its own CI tool called CodePipeline, but CodeDeploy can be integrated with whatever CI setup you prefer thanks to its CLI.
Let’s say your application makes digital toasted sandwiches. Stay with me again here. First it slices the bread, then adds the fillings, toasts it, and then adds some sauce at the end to make a delicious fictional sandwich made of 0s and 1s. Each of these steps is completed by a Lambda function: it takes in the partially-built sandwich as its input, performs a task, and returns it as an output when its task is done. It doesn’t care what step happened before it or what happens next. It just knows it has some form of sandwich and it performs its task on it. This is a huge strength in future-proofing your process for changes. If later on you realise that the sauce should (obviously) be added before toasting so that you get a heated sauce at the end rather than a lukewarm sandwich cooled down by sauce straight out of the digital fridge, you can just reorder the stateless tasks without breaking everything. Hard coding synchronous processes is sometimes entirely necessary for a particular application, but wherever possible keeping your features in stateless silos allows for future changes and minimises technical debt.
So you’ve built your application using stateless functions that live in the cloud; concerns are fairly well separated. One step further is to make use of state machines. A state machine is exactly what you might imagine: a set of computational steps which handle the state of a particular process. The sequence of tasks that makes your revolutionary Digital Toasties is governed by a state machine which sets the order in which the sandwich passes through the lambda functions, correctly scopes the amount of information each state receives to execute its task, and tells you exactly where in the pipeline your sandwich is at any given moment. By using a state machine effectively you can effectively encase your process in a glass box and see what’s happening at at all times. Beyond knowing how long until your toastie is ready, you can find out how long each individual process is taking, what information each task is receiving along the way, what their outputs are and a smattering of other stats that can help you to fix issues and optimise your processes.
Ready for Scale
What this all ultimately leads to is the ability to react quickly to changes in your application’s market place and preparing up front for an increase in future scale. If your product becomes a success you can automatically increase the size of your infrastructure to support it. Adding a new feature becomes as easy as slotting in a new lambda function without having to unpick reams of interdependent code to make room for it. Changes to processes or infrastructure is as straightforward as editing a text file. Less time spent stroking and fussing over your unique little pets means more time to focus on and improve your digital products. Go make yourself a toasted sandwich and plan your orchestration.
In Part 2 I’ll be highlighting some more specific AWS Do’s and Don’ts picked up along the way which could save you some potential headaches.