An introduction to GitOps

GitOps takes the familiar and proven DevOps practices such as version control and CI/CD and applies them to automating infrastructure. The basic idea of GitOps is to place a Git repository at the center of your infrastructure declarations and use it to manage the current state and past history of your application infrastructure.

This approach means that the repository always represents the current state of a production environment. Using tools such as CI or CD, you can reproduce and roll-back environments to previous versions from that repository. GitOps is a simple and effective infrastructure as code (IaC) management tool for smaller projects and teams. But as your needs scale, the limitations of GitOps become clear.

You can read other articles to dig into the details (Reasons to adopt GitOps, Limitations of GitOps, and Fundamental flaws of GitOps). This article aims to weigh up the pros and cons of the patterns and workflows behind GitOps.

How to make your developers self-serving with an Internal Developer Platform

The pros of GitOps

Lightweight and vendor-neutral

The underlying Git protocol is open source, not resource-intensive, and usable on a wide variety of platforms and setups. Unless you are reliant on the features offered by a certain hosted Git vendor, you can move your GitOps workflow where you like, run processes locally, in a CI, or in myriad other ways you want to trigger them.

Uses familiar tools and processes

Most developers are familiar with using Git workflows and automated processes for testing and building code.

Developers use Pull Request to update config in Git repository 

When using GitOps implemented well, a developer pushes code as usual to the codebase’s repository and triggers tests and deployments. Teams declare all infrastructure and processes declaratively. If someone wants to change what’s created or triggered, they make changes to a relevant text file (Probably YAML, JSON, or something similar), commit the change to version control following typical practices, and change future workflows.

Brings devs and ops closer together

DevOps aimed to bring developers and operations teams closer together and not think of their roles as so separated and frequently “in the way” of each other. In reality, the tools may have changed, but in most cases, team dynamics stayed the same, and while DevOps created a plethora of great new tools and practices, it didn’t always solve the communication issues. By bringing Ops closer to where developers work, GitOps further aims to solve this problem. Instead of Developers and Operations blocking each other, GitOps allows developers to get on with their work and for operations to focus on the quality of service work, keeping service level agreements adhered to, and other more specialized work.

A clear change history

Git records who made changes, to what, and when. Because of this record, you can use any standard Git interface to view an audit trail and revert changes if you need to. You can test different sets of configurations on branches and share the sets of configurations to team members if you need to.

Immutable and reproducible deployments

Building on the above pro, the nature of tracking changes to configurations in Git means that any build or deployment is reproducible and immutable, which is a perfect pairing with Kubernetes to create the environments and build assets you need.

The cons of GitOps

Doesn’t fix bad practices

We tend to think that switching technology choices fixes problems your team, company, or project might have. Switching technology could help you identify underlying human or product issues but won’t fix them for you. GitOps is no exception. If you have teams or team members who don’t want to change their ways of working or relinquish their “territory,” then GitOps won’t change anything. Depending on what processes you’re switching from, poorly implemented GitOps can leave you in a worse place than you were before.

A proliferation of repositories

As your application and the infrastructure that supports it grows in complexity, how do you handle the repositories needed to represent it?

For example, a company grows from 1 team to 4, each working on a component of an application. Each of those teams needs four environments for different purposes. Do you use one repository for infrastructure code and use branches or tags to separate each need? 

GitOps approach with one Git Config repository

Or do you use one repository for each environment per team?

GitOps approach with multiple independent Git Config repositories

How do you separate concerns between the repositories or branches? With Kubernetes namespaces or separate Kubernetes instances?

Now imagine that someone needs to change an aspect of infrastructure. Which repository or branches do they make a change to, and who merges that change?

None of these questions are impossible to answer and manage, but it’s worth thinking about how to scale GitOps before making the switch.

Git is not designed for programmatic updates

Updates to code that is part of a continuous delivery workflow are generally automated to handle the frequency of changes. For large active teams, this can lead to multiple automated processes writing to the same files simultaneously, causing conflicts that a human needs to resolve.

It’s possible to mitigate this by adding more repositories, but then you run into the issues outlined above.

Hard to audit

While there are strategies to match the state of different environments to Git (tags, branches, etc.), again, knowing what matches to what as an application scales becomes difficult without extra tooling.

Imagine you are required to audit an application for a regulatory purpose. You first need to trace back which repository matches the component, find the configuration file that matches the feature or function, and then finally look at the history of commits to that file to see when the change was made and what it was. A large complex application could consist of dozens of repositories, configuration files, and developers, leading to hundreds of potential data points to dig through. You can add additional tooling from spreadsheets up to observability tooling, but this contradicts the supposed simplicity of GitOps, and creates more work for Ops teams, another factor GitOps tries to prevent.

No help for secrets management

Complex and enterprise applications need ways to manage secrets (authentication and sensitive details) outside of CI/CD and version control. As it places a Git repository at the center of infrastructure management, GitOps doesn’t offer any way to help manage secrets. If all your repositories are private, then maybe you can use them to store secrets, but this is generally a bad idea. Again, as the number of repositories grows, so does the task of tracking down what values are where when you need to update or share them with team members. This lack of affordance for secrets management means that you need additional tooling, again creating extra work for Ops teams.

Is GitOps right for you?

Like any other technical solution, switching to using GitOps will not fix your technical or organizational issues with deployments. However, if you are already using and familiar with Git and wish to consolidate your infrastructure definitions into the same workflows, GitOps is worth considering. Before you do, make sure that you resolve your development and operations teams’ responsibilities and interactions. If you don’t do this before the switch, any underlying communication or responsibility issues will remain and perhaps even become worse. Have in place a strategy for how you will scale GitOps to more complex applications. If you think this scaling will happen sooner rather than later, you may want to consider a different approach, such as a dedicated Internal Developer Platform (IDP), that encompasses the needs of multiple teams and applications in one cohesive tool.

How to make your developers self-serving with an Internal Developer Platform