Automated deployment is a regular feature of the modern enterprise. Today, systems are so big that no one human or team can meet their maintenance demands. The best way to ensure the reliability of an enterprise architecture is to automate it.
Automation is good, but getting it right requires some forethought. There's no one-size-fits-all solution. Rather, you can use a variety of patterns to meet your automated deployment needs. These patterns center around the principles of GitOps. In GitOps, the source code repository is the sole source of truth in the application deployment process. The center of all deployment activity under GitOps is a source code repository powered by Git.
I see two prevalent patterns in GitOps. I call one the Continuous Integration/Continuous Development (CI/CD) Controller pattern and the other the SCM Controller pattern. This article explores the details of each.
The CI/CD Controller pattern
In the CI/CD Controller pattern, an independent application or service is aware of the state of one or many source code repositories. It executes a CI/CD deployment automatically when code changes within a particular repository.
You may have heard of controller applications including ArgoCD, Jenkins, and TeamCity, and controller services such as Travis CI and CircleCI.
At the operational level, the CI/CD controller knows the state of any particular source code management (SCM) repository either by polling the SCM repository periodically or by installing a webhook in it that calls back to the controller when the code state changes, for example when someone merges code or deletes a file in the repository.
Once the controller is aware of a state change in the SCM, it automatically executes a set of tasks in response to the notification. These tasks are specified in a predefined script.
The tasks that the script executes are defined according to the operation of the particular CI/CD process. Some scripts might execute tasks that run a set of tests in a predefined testing environment. Upon successful testing, the CI/CD Controller moves the code onto a production environment in a data center (as this figure illustrates).
Other scripts might have more extensive tasks, such as creating virtual machines (VMs) that the script configures as a Kubernetes cluster. The controller then moves the source code into that Kubernetes cluster and runs a wide variety of tests—from integration tests, to performance tests, to security tests—on that code. When testing is complete, other scripts might destroy the cluster to avoid incurring unnecessary costs from leaving unused resources behind.
[ Learn more by downloading An introduction to enterprise Kubernetes. ]
Granted, this type of CI/CD process is complex. Regardless of the simplicity or complexity of the CI/CD process, the important thing to understand about the CI/CD Controller pattern is that there is an application external to and independent of the source code repository that controls all CI/CD activity. And that controller knows about and reacts to changes made in the SCM state.
The SCM Controller pattern
The SCM Controller pattern takes a different approach to application deployment than the CI/CD Controller pattern. In the SCM Controller pattern, source code that controls CI/CD deployment activity is colocated in the same Git repository as the application source code. Under the SCM Controller, the SCM service can internally execute actions such as builds, tests, and the eventual release to a staging or production target. And, if it doesn't have the capabilities it needs for some of the work, the SCM service has access to the required ancillary services the CI/CD process requires.
The essential principle defining the SCM Controller pattern is that executing CI/CD activities is done directly within the source code repository. No external application is looking into the SCM. Rather, the SCM is in charge of it all.
Most modern SCM repository services such as GitHub, BitBucket, and GitLab support the SCM Controller pattern. They can execute CI/CD tasks based on a state change in the particular repository.
The figure below illustrates this principle. In this case, when a code merge happens in the SCM, a deployment script is executed. The deployment script has the information and ability to access the external resources relevant to the given CI/CD process.
In some cases, the SCM service can create the internal resources required to execute the deployment process. For example, some SCMs can spin up internal VMs upon which code is built and tested. Then, when testing succeeds, the internal VMs are destroyed, and the code is deployed onward to the production target.
There can be a wide variety of deployment activities under the SCM Controller pattern. But, no matter how many tasks are executed, the important thing to remember is that under the SCM Controller pattern, the SCM system is the starting point for any deployment process. It's the boss.
Pros and cons
Both of these patterns—CI/CD Controller and SCM Controller—have pros and cons.
The CI/CD Controller pattern's biggest pro is that it provides the versatility to monitor repositories among various SCM service providers. The con is that it incurs a greater maintenance burden. Remember, under the CI/CD Controller pattern, the controlling application (such as Jenkins) interacts with the SCM as an external agent. Every repository has its own operational model and peculiarities that need to be accommodated. This can get to be a chore when the CI/CD Controller manipulates a variety of SCM services.
On the SCM Controller pattern side of the fence, the basic pro is the unification of source control and deployment management. Adding deployment behavior into the SCM process makes the SCM system a one-stop-shop development experience. In addition to being the sole source of truth for code, the SCM also becomes the sole source of truth for deployment processing. Scripts within the SCM itself describe everything about the given CI/CD process. Some IT shops find this approach attractive.
A significant con of the SCM Controller pattern is that repositories that do a lot of VM building and compute-intensive activity internally need to be hosted on machines that are much more powerful than those that do nothing more than simple source code management. There is no magic. Intensive build and deployment activity can require machines with a lot of CPU horsepower. This type of CPU can get expensive. An 18-core CPU can run in excess of $1,000, while a standard, commodity 4-core CPU runs a little over $100. This is a 10x price difference. Whether your company is using a managed cloud service or you're hosting machines in your own data center, when all of a company's build and deployment activity happens under the SCM Controller pattern, it can expect to incur this degree of added expense.
Another con is that excess merge requests on a code repository not related to the application can result in unnecessary deployments. When different teams manage builds (ops) and apps (dev), it can get messy.
In terms of the pros and cons of the CI/CD Controller and SCM Controller patterns, it comes down to the eternal tradeoffs:
- Price vs. performance
- Ease of use vs. robust security
- Central management vs. decentralized independence
Both patterns have compelling benefits and drawbacks. Deciding which direction to go is as individualized as the companies considering which pattern to implement.
Putting it all together
GitOps is still in its early stages of adoption in IT. According to a survey on Twitter by GitLab in June 2020, most respondents had not yet looked into adopting the practice. But, nearly a quarter were using GitOps, and more than 10% were planning to implement adoption. Although this is not a formal survey, these are encouraging numbers.
[ For more insight, read An architect's guide to DevOps pipeline: Continuous Integration & Continuous Delivery (CI/CD). ]
It takes time for things to catch on in IT. After all, Docker was introduced in 2013, but it took a good five years for the technology to gain significant momentum. There's a good chance that GitOps will enjoy similar acceptance.
As GitOps adoption increases, so will its variety of styles and patterns for implementation. The CI/CD Controller pattern and SCM Controller pattern are two of many others that will follow. Understanding the CI/CD Controller pattern and SCM Controller pattern and how they work will surely help as you contemplate implementing GitOps in your organization.