Git is a mission critical tool for software development that enables pull request and code review workflows. Pull requests promote visibility into incoming changes to a codebase and encourages communication, discussion, and review of changes.
Pull requests are a pivotal feature in collaborative software development and changed the way teams and businesses build software. Pull requests bring transparency and measurability to a formerly opaque process. Git pull requests helped enable the evolution of DevOps processes into software development. System administrators, who typically were hesitant to change, are now embracing new software development practices such as agile and DevOps.
Systems administration as a craft has a sloppy history. System administrators previously would manage hardware manually by either connecting to and provisioning machines in a physical server rack or over a cloud provisioning API. In addition to the manual provisioning process, large amounts of manual configuration work was a regular routine. Administrators would keep custom collections of imperative scripts and configurations, cobble them together, and place them in various places. These scripts could break at any time or get lost. Collaboration was challenging as the custom tool chains were not regularly documented or shared.
The DevOps movement arose from this primordial swamp of systems administration. DevOps borrowed the best ideas from software engineering and applied them to systems administration, where the cobbled-together tools became version-controlled code.
IaC is one of the biggest revelations of DevOps. Previously system administrators favored custom imperative scripts to configure systems. Imperative software follows a sequence of steps to achieve a desired state, such as:
Imperative software is often error prone and easy to break by changing the sequence of events. Modern software development has trended away from imperative patterns and towards declarative software patterns.
Declarative software follows a declaration of an expected state instead of a sequence of commands. Here’s a comparison of imperative vs declarative devops statements.
While the imperative statements might read:
- Install an operating system on this machine
- Install these dependencies
- Download code from this URL
- Move the code to this directory
- Do this 3 times for 3 other machines
The declarative version of this would simply read: 4 machines have software from this URL, installed at this directory.
IaC encourages and promotes declarative system administration tools over custom imperative solutions. This led to the emergence of technologies like Docker Containers, Ansible, Terraform, and Kubernetes, which utilize static declarative configuration files. Human readability and consistent reproducible state are the beneficial outcomes. These configuration files were naturally added to Git for tracking and review. This is close but not quite GitOps.
Many of the traditional system administration problems have been solved at this point in DevOps history. Configuration files and tools are now stored in a central location, documented and accessible by many team members. Commits and pull requests were used to track modifications to the configuration and foster collaboration discussion and review. The only remaining problem with this stage is that the configuration still feels disconnected from the live system. Once a configuration pull request is approved and merged to the repo, the live system is manually updated to match the state of the static repo. This is the exact problem GitOps solves.
The GitOps idea was first hatched and shared by WeaveWorks, an enterprise Kubernetes management firm and has since proliferated throughout the DevOps community. GitOps is an extension of IaC and declarative configuration discussed above. GitOps adds some magic to the pull request workflow that syncs the state of the live system to that of the static configuration repository.