As if the definition of DevOps wasn't convoluted enough, with it comes its misunderstood partner - Continuous Integration, Delivery, and Deployment. Note, that I said "partner" as in singular. Much like an antiquated emperor that requires an orator to remember and announce his title/name, CI/CD/CD is hilariously still referred to in full. You can be in the flow of a conversation, but as soon as you turn the topic to Continuous Integration, Delivery, and Deployment, you'll be spitting those 16 syllables constantly to everyone's annoyance (including your own). That or you'll refer to it as CI/CD/CD and, in context of something like AWS, juniors and non-tech workers alike will believe you're some sort of alphabet savant.
Not only is the name for this "thing" confusing but the definitions for it are ambiguous. If you ask a manager, they'll talk about delivering value to customers. If you ask a developer, they'll start rattling off tools, processes, and code. If you ask a marketer, they'll tell you it's the solution to every problem in your organization. If you ask a salesman, they'll go into time saved, metrics, and potential gains to the company's bottom line. If you ask an Agile Coach, they'll probably confuse you even more and yell about CI not being CD and CD not being ... CD.
"Don't worry about it. In fact, just call it CI/CD."
"Is the CD for Continuous Delivery or Deployment?"
"Get out Jerry."
And so when our heroic team is tasked with implementing this mystical process, where does one start?
A Practical Definition
When I first started trying to tackle this beast, I wound up in some video series where a CTO tried to explain Continuous Integration, Delivery, and Deployment. It was 50% diagrams/lines and 50% him saying the CI/CD syllable incantation in full. By the end, I was convinced that this was some technology consultant's scheme for easy money.
In an attempt to save developers out there some time and frustration, let me give you a practical definition of Continuous Integration, Delivery, and Deployment (CI/CD):
CI/CD is having a semi to fully automatic process of safely adding new code to old code and releasing it to users.
Yes, yes, yes, we can throw in all sorts of definitions, tangents, and agile manifesto quotes into this pot just as you could pour orange juice into your chicken noodle soup. But we won't. Why? Because from the perspective of a developer, this is what you'll be doing in your day-to-day implementation.
"I have my current code. I want to safely add (remove) some new code. I want those new changes to be deployed. I want this done as automatically as possible."
This definition brings a lot more focus. In fact, with it in hand, I'll bet you're able to think up all sorts of potential avenues to make this happen.
Okay, so we've got a good focal point in place. However, when constructing your first "CI/CD Pipeline," which is just everything involved in moving your code from local to being deployed, there are 3 main goals to keep in mind. Conveniently, we can categorize these goals using our CI/CD/CD trio. We'll state them as questions that you can ask yourself while constructing your own CI/CD pipeline:
1. What needs to happen to ensure new code, from multiple developers, can be safely added to existing code? (AKA Continuous Integration)
Think tests, version control, code review, and builds.
2. What needs to happen in order to make sure that our codebase can be released to our production environment at any time? (AKA Continuous Delivery)
Think Quality Assurance (QA) testing, product managers reviews, user testing and feedback, and various environments to test the code on (i.e. deploying to a Development or Staging environment to test everything before releasing).
3. What needs to happen to make it so that our code will automatically deploy when updated? (AKA Continuous Deployment)
Think scripts and processes that will watch, for example, a Git branch in your codebase and automatically deploy it when it's both changed AND approved.
Now if you're feeling a bit overwhelmed, since these goals can seem grandiose when coming from a gung-ho manager's mouth at 9AM, they're not rules...they're GOALS. When accomplished, they're going to look somewhat different for every organization and team. For example, if you're a one-man army, your CI/CD pipeline might look like this:
a) Have a github repository for the codebase (Continuous Integration)
b) Before merging in new code, run unit-tests (Continuous Integration)
c) Deploy new code to a staging environment, a deployed infrastructure that mimics your production one, and make sure it works (Continuous Delivery)
d) If (c) passes, merge the new code into your main branch and have it automatically deploy to your production environment (Continuous Deployment)
However, if you're a larger team with far more deploys and testing needs, then your CI/CD pipeline will have more steps and details. But the primary, end goal is still the same:
Having a semi to fully automatic process of safely adding new code to old code and releasing it to users.
A Practical Approach
"Definitions and Goals are great, but where do I start??"
Even though we've built more clarity, how does one sit the hell down and actually get this done? Well first, I'm going to assume you've got some sort of codebase (app) that you work on locally and that's ultimately deployed somewhere for users to use. Second, let me ask you a question:
What steps do you currently take to move your codebase from your local machine to your production infrastructure or hosting solution?
Use this step-by-step to answer the above question:
1. List out all of the steps that need to be taken to get your code from local to production.
Write out this list as if you were going to do it manually. "I'd run tests on it. Then I'd have it reviewed. Then we'd merge it." etc etc.
2. With that list, which of these steps can be automated?
Something like code review can't be automated, but running your suite of tests or deploying it to your infrastructure can be.
3. With the steps that can be automated, what scripts would you need to write, or what tools can you use, to automate them?
For example, you may have a list of every command you need to run to get your codebase live on whatever your hosting / IaaS service is. That would be a candidate workflow that could be scripted.
Do you see where we're going with this? Once you've done the above 3 steps, you have a list of all the work you need to do to construct your Continuous Integration, Delivery, and Deployment pipeline. Now you can get to work and watch your business managers smile like stock photo models!
But What About All the CI/CD Services?
"But Cole, what about Jenkins / CircleCI / TravisCI / SemphoreCI / Etc? They'll figure out if we don't invite them..."
Indeed. Here's the thing, contrary to popular opinion, you don't need any of these to set up CI/CD. If you've finished that list from the above, what does it mainly consist of? Scripts. And so all you truly need is whatever is required to run said scripts.
Now for most folks, that's going to be a remote server. One that's unchained from the emotional baggage of any developer's localhost. One with just enough permissions and just enough software to do all of the automation you've scripted.
...and if you've ever deployed any application to a remote server before, you've done this. You've provisioned a server, given it just enough stuff to run your application code, and then given internet/internal facing users access to your server and the app. Well, setting up a "CI/CD Server" is nearly the same. The main differences are going to be:
1. The needed dependencies to run your scripts.
2. Access / permissions needed for the CI/CD server to grab your codebase.
3. Access / permissions needed for the CI/CD server to deploy your codebase to your production infrastructure or hosting solution.
In a sense, you have an entirely new application to deal with, develop, scale, and deploy. THIS is where the 3rd party CI/CD services and solutions start coming into play. They abstract this process away from you and allow you to just focus on writing those automation scripts. Usually in their own language or syntax.
However, it really can be as simple as setting up another server to do those steps above. I bring this up because all too often when talking about CI/CD, folks will jump right to all of the 3rd party solutions. And while I believe using those is the right direction for 90% of the teams out there, talking about them first can distract from how straightforward CI/CD can be. Instead of figuring out what needs to be done, folks will pick a tool first, and then shove their square CI/CD needs into the tool's round capabilities.
That being said, if you DO know what needs to be scripted and automated, selecting a CI/CD service or solution becomes far easier. Do you want to self host it? Do you like their language/syntax? Is their documentation a dumpster fire? You get the picture.
A Difficult Investment for Incredible Simplicity
Why then, if this is such a straight forward concept, is it relatively difficult to implement? Well, in our current DevOps ecosystem, it's the skill feedback loop. Unlike development where you can make a change and know instantly if it's working, DevOps systems (i.e. CI/CD pipelines) can take from minutes to an hour to see if what you've done is right. On top of that, you're often testing these architectures outside of your local machine...meaning there's real costs involved with learning.
So, for example, let's say you've set up a fleet of servers to handle your CI/CD. And let's say your automation workflow is supposed to test and deploy your codebase to either a staging, development, or production set of servers. Well, in order to make sure things are accurate, you're likely going to be testing this in live infrastructure. Furthermore, what if one of the server configurations is bad? Now you've got to dive into the servers, change their configurations, possibly reboot them, and wait, all to see if the fix you added worked. If it takes you 5 to 10 minutes to make and deploy that change, and you have to make 50 to 100 changes before everything is running smoothly...
BUT. That feeling you get when that first, long-winding automation system runs smoothly? Unparalleled. Watching your team make some changes to the code, push it up to version control, review, merge it, and have it automatically deployed is something to behold. Though the process of building one of these systems is long, it MASSIVELY shortens the feedback loop between your developers, business folk, and users.
What is Continuous Integration, Delivery, and Deployment (CI/CD)?
"Well, continuous integration, delivery, and deployment lets us continuously deliver value to our key stakeholders by continuously integrating and deploying new features."
"Now answer it without using the words continuous, integration, delivery, deployment, and any modifications of those words."
"Um...it, uh, helps us help our stakeholders...contin...I mean, a lot more often."
"And...can you elaborate?"
The definition of this practice isn't an easy one to pin down. I think that it's primarily the result of so many different disciplines being involved with it. Managers. Marketers. Salesmen. Developers. Operations. Product. So many folks have their hand in the pipeline and, to each of them, it means something different in their day-to-day job.
But in terms of figuring out what work needs to be done and how this all PRACTICALLY comes together? Well, again, it's as simple as having a semi to fully automatic process of safely adding new code to old code and releasing it to users.
J Cole Morrisonhttp://start.jcolemorrison.com
Cloud Architect, Software Engineer, former Techstars Hackstar, AWS Solutions Architect, and Founder at awsdevops.io