A skilled developer and architect will keep abreast of these changes, and apply key lessons to the work they do. This enables the creation of better, more scalable, more robust and more cost-effective systems. It is often said that it is cheaper to learn from the mistakes of others than from your own! One of the great things about the developer community is the willingness to share information and lessons learned—good and bad.
As we move into an increasingly cloud-based application landscape, key design patterns need to be applied to best take advantage of the capabilities that cloud architectures offer. Fortunately, a Platform as a Service like Pivotal CF wraps up a lot of the lessons learned into a method of software deployment that is reliable, scalable and MUCH easier than prior methods.
There are many interesting approaches to designing software in this cloud-age, and the 12-Factor App is an interesting and useful example of one such approach.
In this episode, Simon takes a tour through the concept of the 12-Factor App and why it might be the right approach for you to take with your software design.
PLAY EPISODE #7
- Subscribe to this feed
Find more episodes of All Things Pivotal podcast
- Feedback: firstname.lastname@example.org
- Links Referred to in the Show:
- To learn more about 12-factor apps, see their website here.
Welcome to the All Things Pivotal Podcast, the podcast at the intersection of agile, cloud and big data. Stay tuned for regular updates, technical deep dives, architecture discussions and interviews. Please share your feedback with us by emailing email@example.com.
Hello everyone and welcome back to the All Things Pivotal podcast. Awesome to have you back here. My name is Simon Elisha, CTO and senior manager of field managing here at Pivotal Australia and New Zealand.
Interesting topic we’re going to be talking about today. As many of you may know, I’m very passionate about software architecture and building things the right way. The right way depends on your perspective and there are many learnings about how the right way works.
I can tell you that the right way that I learned when I started off as a developer and mainframe programmer is not necessarily the right way today but there are elements that we can share and we can learn from.
One of the things I see in good software architects and infrastructure architects are people who are willing to challenge their own thinking, to learn different ways of doing things and to understand what the state of the art is. What are other people doing and how are they building their applications? How can I apply this to what I’m doing?
Today I wanted to dive into a particular concept or a manifesto that is not the way to do things or the best way to do things necessarily but is a very good and strong indication of how you may want to go about your work.
This is the concept of the 12 Factor App. The 12 Factor App was a sort of manifesto created. It actually came out of Heroku who did a lot of great work in terms of how you should build web scout apps for current requirements and how that may work in a cloud spaced world. I think there are a lot of ideas here that are worth considering and understanding and it’s interesting.
Many software developers I speak to maybe haven’t come across some of these ideas or these concepts. By wrapping them up in this 12 Factor App sort of short cut, essentially it helps summarize some of the key learnings and things that you should think about when you’re delivering and deploying applications.
I want to go through them with you today, familiarize you a little bit with some of the concepts of why they’re important and just cover off what it means and why we should think about it.
Let’s go through them. There’s only 12 factors so we’ll go through each one in turn. The first one is around code base. The idea is to have one code base tract and revision control with many deploys. For many of you who go, ‘Of course you’d have a code base in revision control, wouldn’t you.’ The number of projects that I’ve worked into and seen that they don’t quite have that nailed down is somewhat scary.
Really, all your application code lives in one repository and people use git, they use subversion, there’s all religious wars about what particular repo is right. I don’t really care. Just have one that works and is effective for you and your team.
What this means is that the code base can be deployed into local machines for development work and can be easily submitted to. This also ties in to a continuous integration type pipeline approach. You need to have one code base in revision control, not lots and lots of different versions all around the place. Your strategy around branching and versioning again can come down to local requirements but get some code base, get some version control.
The second factor is dependencies. Explicitly declare and isolate your dependencies. This is the bane of many developers existence. The old, ‘It works on my laptop and when I go to production it doesn’t work.’ That’s because a library version is different, something change, there’s a particular configuration in your environment, et cetera.
One of the great things that we have within Pivotal CF is the ability to have build packs that take care of a lot of these dependencies for you. They’ll go out and make sure you have the right version of Java or the right version of a dependent gen or the right version of some other component that you need to build your application to create drop for deployment.
Making sure you declare and isolate those dependencies will make your life so much easier otherwise you’ll just be fixing things all the time.
The third one is around config. This is about storing config in the environment. This doesn’t mean hard coding or anything. Perish the thought. I don’t want to see any hard coding. I’ve seen some absolute doozies in my time. What we want to do is store the configuration alongside the application itself. As we deploy to different environments, the particular components that change.
Things like where does my particular database live in test versus production, those are also changed as you go along but are tracked effectively. Again, Pivotal CF makes this easy with some of the service binding that it does and we’ll talk about that more shortly but essentially you want to make sure that the config piece is equally tracked as the code piece is tracked.
The fourth one is backing services. This is about treating backing services as attached resources. In any large scale system and loosely coupled systems you’ll have many services that you talk to. They’ll be databases, caches, queuing system for example, maybe an email system. All this should be accessed through an endpoint, typically a URL and typically they’re secured by a username or password.
They may be running on the same machine, they may be running on different machines, they may be running in completely different areas. There may be third party servers. You need to effectively treat these as attached resources that are easily and cleanly bound too. Again, the service binding capability within Pivotal CF makes this really, really easy and kind of a native experience just what you would expect to do.
Treating components as services frees you from a lot of the complexity and a lot of the tight coupling that can cause systems to be brittle and also are anti-patents to building highly scalable systems. We want to be consuming lots of loosely coupled independent services to be able to scale effectively in the future.
The fifth factor is build release and run. Strictly separate the build and run stages. We want to do a lot of the heavy lifting, a lot of the hard work in the build stage of bringing together all the components, doing the compilation, getting all the assets together so that the run stage is made much more simple and much more consistent.
Again, Pivotal CF takes care of a lot of this for you because it does that build piece. It creates all the components required to run the actual processor application on the Pivotal CF platform, but it does this for you at push time. When you do CF push, it does all the aggregation for you, it does all the building components for you so you don’t have to worry about it which, again, makes it nice and easy to have this separation between what I’m building and what I’m running.
Now, number six, processors. We want to execute the app as one or more stateless processes. I’m going to say that again: one or more stateless processes. This is probably one of the most important things to keep in mind when you’re trying to build a truly scalable, distributed, cloud ready application. Statelessness. You do not want to be storing temporary bits of information along a processing cycle within the particular process that it’s running in. It needs to be stored in some store of state.
This could be a database, this could be a cache. There are lots of options but it will not be within the process that’s actually doing the work. This is very important because if you have eliminated state from your application or from your components in the application, you make it far more fault tolerant. It can also scale in a trivial, yet amazingly powerful fashion.
You can go from having one process to having a hundred processes to having a thousand processes, scaling up appropriately based upon the aggregate power that you have within those processes to process tasks.
Because there is no state within those particular processes, if we lose a process through error or hardware malfunction it doesn’t matter because the traffic is automatically and seamlessly routed to other processes in the environment that can handle that work. Because there is no state in that process, it doesn’t say, ‘Hey, I don’t know who you are. I can’t process your work.’ It says, ‘Hey. Bring on the work. I know where to get the state, run the process and give you the answer back that you need.’
An immensely important and powerful design patent. Always follow it for your own good because things will always need to scale at some stage. They’ll need to be fault tolerant at some stage. This is actually the easiest way to do it.
Number seven is around port binding. It says to export your services via port binding. This is typically taken care of for you. Certainly, Pivotal CF takes care of this for you. It binds the services that you deploy automatically. It gives you a nice DNS name. It can even randomly assign a DNS name for you in terms of some funky naming mechanisms as well.
Essentially, what you want to do is make sure that all services you build are presented via a particular port or a particular URL that can be accessed. This gives you clean, again, separation from what’s going on rather than having to do a whole lot of mod rewrites and rerouting of traffic to different process elements.
You want each service to be presented independently on its own port or through its own service so it can be consumed easily. This also helps you present services to the public in an efficient way.
Number eight is around concurrency. This is around scaling out via the process model. The whole idea here is to say we want to go with volume. It’s kind of like an army of ants. Each ant in and of their own can’t do a great deal but a lot of ants together can get a lot done. By having lots and lots of processes doing the work, we can scale independently and appropriately parts of our application that need that scale.
This is completely opposite to that old fashioned approach of saying, ‘Let’s get a hunking great box and it’ll be the biggest one we ever need to think of and that’s what we’ll grow in.’ We want to have a concurrency model whereby we can grow and shrink dynamically and very quickly. This, of course, takes advantage of cloud based applications. The elasticity of the cloud that we want to use whether its on premises or in public cloud, we want to be able to grow and shrink our application based on prevailing workload.
Number nine is around disposability. This again changes your mental model. This is about maximizing robustness with having fast start up and graceful shut down. In a nutshell, it means that processors should start almost instantaneously. When you shut them down, there should be no house keeping or extra work that you have to do. They just go away.
Again, because they’re stateless there shouldn’t be anything needed to be taken care of at close down time. What this means is that you can scale your application up very quickly and you can close it down very quickly without anything going wrong. This concept of disposing of instances that aren’t working well, rather than trying to fix them, is again a big mental shift for a lot of people.
Summarize for some people as the pet versus cattle metaphor. If you have pets you name them, you look after them, you don’t want them to ever die because you love them. Cattle are grown for a particular purpose and sent off to market and away they go. In the application world, our processes need to be cattle rather than pets. We want them to be disposable.
Instead of trying to fix a particular instance that is misbehaving, I’ll terminate it and replace it with a new one. If I’m seeing constant issues with that instance then I know it’s a code issue and I’ll go through my development life cycle to fix the code and deploy a fix in production through that particular channel.
Speaking of which, number ten. Development and production parity. Keep your development staging and production as similar as possible. This ties into agile software delivery, continuous integration, continuous deployment type of concepts but really it’s about saying you don’t want development or production to get so out of skew that one doesn’t reflect the other which means you can’t fix one another. You want them to be reasonably close.
This again takes a mindset change and a process change for many organizations where we move from very infrequent, big bang releases of our software to far more frequent, smaller changes to our software. Instead of having a once a year part of, ‘Hey, we’ve deployed some software,’ we may deploy every quarter. We may deploy every week. In some organizations we may deploy every day. Some more modern organizations deploy multiple releases a day. Very small increments, but the change dealt between what’s in development, what’s in production is kept to within a reasonable amount.
Number 11, logs. Treat your logs as event streams. This is so important. Without correct telemetry in your environment you have no idea what is going on and when complex issues come up that can be terribly hard to fix and understand. One of the great things about Pivotal CF as a platform is it does all the streaming logs for you and aggregates them together in the one places so you can send it to the tool of your choice. Everything is wired up to do the logging for you.
By having all the logs together, you can see what is happening in your environment. You shouldn’t be using logs just as a reactive tool or something you go and check when it goes wrong. You should be monitoring them all the time to understand what is normal. Then, when you start to see deviations from normal you can start taking proactive action rather than reactive action.
The final thing is, number 12, admin processes. You should run your administrative or management tasks as one off processes. We all have been there. Three in the morning, really tired, something has gone wrong. You just write a bit of SQL to do something on the database and you know what, you could put it in source control, you could write it as a process or you could just log into your favorite SQL editor, issue the code directly against the database and get on with the night.
A shortcut sounds great but for longevity it doesn’t work because it creates things that have changed the environment that you don’t know. You’ve created processes that may be repeated many many times that aren’t well encapsulated as code themselves. It’s very important to create a process, even if it’s a one off process, that will do the particular task.
This means you can review that process, you can understand what that process was and funnily enough, many of these processes end up becoming recurring things that are either run on a more regular basis or actually get folded into the application itself.
That’s a bit of a summary of the 12 Factor App concept. Again, not the answer to all the world’s ills but some great design ideas and thought processes that you should put your mind to. I’ll link to it in the show notes as a far more detailed ePub version of that which will talk you through some of the nuances and the details of that.
One of the great things is that we can encapsulate and codify and be opinionated about a lot of these design elements. Pivotal CF encapsulates a lot of these components and really encourages you as a developer to build your application a particular way to get advantage of all the goodness of the platform as a service.
It says write your code this way. Make it easy for you to push your code to this platform that will encapsulate and take care of a lot of those factors for you so that you can have resilient scalable and effective applications that can be deployed on premises or in the cloud as you see fit.
I hope that was useful for you. Bit of a dive into some architecture. We’ll certainly be talking a lot more about architecture in the future. Until then, love to get your feedback. Podcast@pivotal.io and of course visit us at the web page as well.
Let others know if you’re liking the podcast and we do like to hear your feedback, good or bad because we want to make this better for you all the time. Until then, thanks so much for listening and keep on building.
Thanks for listening to the All Things Pivotal podcast. If you enjoyed it, please share it with others. We love hearing your feedback, so please send any comments or suggestions to firstname.lastname@example.org.
About the Author