A Brief Introduction to GitOps

The basic idea of GitOps is to focus on Git as the only reliable data source (single source of truth) that always contains a complete image of the desired state of a system. The image of this system is stored declaratively in configuration files and can thus be versioned in Git, just like other source code. GitOps is usually implemented using tools that continuously mirror the declarative image from Git with the actual system. This ensures that the system contains the same configuration as Git and vice versa at all times.

GitOps is a logical extension to the idea of infrastructure-as-code, which allows infrastructure to be defined using code, primarily in public clouds. Architecturally, GitOps makes it possible to separate the continuous integration (CI) of an application from its actual deployment process. This is possible because the deployment process is no longer executed directly in the Git repository using a pipeline, but by a remote watcher in the target system that processes changes in the Git repository asynchronously. This means that it is no longer necessary, for example, to store access data for the production system in a CI/CD pipeline, which increases security. It is also possible to define multiple target systems without having to make changes to the actual Git repository or the CI/CD pipeline.

GitOps vs. Continuous Delivery vs. DevOps

As the name GitOps suggests, there is some relationship to DevOps. In short, GitOps can be understood as a subset of DevOps. The goal of DevOps is to bring the operation of software close to development through automation and continuous delivery (CD), configuration management, containerization, orchestration, monitoring and more.

GitOps is another tool in the DevOps toolbox for configuration management and Infrastructure as Code (IaC). The basic idea of GitOps becomes most clear when compared to Continuous Delivery.

Continuous Delivery Approach

In classic Continuous Delivery, the source code is stored by the developers in the source code management. From there, the CI server fetches the data, performs the build and tests, and stores the application created in the build (consisting of one or more artifacts, for example a Docker image) on a server (artifact repository or registry).

The application is then deployed from the CI server. The configuration for the deployment can be done in the CI server or also stored and versioned in Git.

GitOps approach

Like the Continuous Delivery approach, GitOps relies on all information being maintained in the source code management system. The difference, however, is that the deployment environment synchronizes its state directly from Git and the CI server does not take over the deployment. So the configuration must be versioned in Git. Since this is treated like code, it is referred to as "Infrastructure as Code". GitOps approach

GitOps Advantages

Many are already using GitOps, but most of the IT industry is now realizing the full potential of GitOps. This brings us right to the reasons why GitOps is so great:

Change history for environments.

An application environment can only be changed by updates to the configuration in the associated Git repository. This means a complete history of desired state changes - including a record of who made that change and why. This history can also be read through the already used and appreciated Git user interface.

Rollback to previous state

Once all of our changes are stored as Git history, it is easy to roll back an environment to any previous state. By undoing a few commits, we can return to a state that worked before.

Secure deployment processes

Once all changes to the cluster go through the GitOps repository, human and machine users (Continuous Integration) no longer need access to the cluster. This reduces the attack surface immensely, especially if it means reducing network access to the Kubernetes API.

The deployment process, regardless of its implementation, can run inside the cluster and load the configuration from Git. Access to the API is restricted by role-based access control (RBAC). This increases the security of the cluster by preventing any malicious changes via the API server.

Lightweight approval procedures

Developers are not allowed to modify production environments in many companies. Whatever is behind the distrust and the requirement for a four-eyes principle, GitOps provides a simple way to implement it.

The exact implementation depends on the Git server used; but basically the strategy is to give developers the right to make pull requests to the Git repository, while another group has the right to reviews and merges. Most Git servers provide an excellent user interface to review changes and approve pull requests - so this solution is not only cheap, but also very user-friendly.

Modular architecture

GitOps consists of three parts: the Git repository, the deployment process, and probably a process that automates version updates in the Git repository. All three can evolve or be replaced independently.

On the one hand, a component writes to the Git repository, and on the other hand, a component reads from it. The structure of the Git repository is thus the contract between these components.

Since this is a rather loose coupling, both sides can be implemented in different ways with different technologies.

Tool-independent architecture

The modularity from point 5 leads us directly to the fact that a GitOps architecture brings together the best tools in a flexible way. Virtually any known Git server does it for the Git part; and Flux or ArgoCD, meanwhile, can take care of synchronizing the repository and the cluster.

JenkinsX, on the other hand, is a tool that can cover all parts of this process. This includes creating Git repositories and updating to new versions once a new Docker image is built.

Leverage existing knowledge.

By using Git at the center of the deployment process, you can leverage the existing Git expertise that most developers and IT staff already have. There is no need to introduce new tools to search deployment histories or deploy commits. Everything happens using tools that everyone knows. 8. comparing different environments

When you have a range of environments from development to user acceptance testing (UAT) to production, keeping track of all their differences can be a pain.

Thanks to declarative configurations in Git repositories, comparison is now as easy as between a group of YAML files. Very good tools exist that allow you to implement this. In addition, creating a new environment from scratch is extremely simple: just copy the customized YAML files into a new repository.

Integrated backups

Since the state of the environment is stored in Git, nothing will ever be lost even if something happens to the etcd store of the Kubernetes cluster. So the state of the cluster is automatically backed up as well.

Test changes as you would with software

You can test changes that might break the cluster the same way you would with applications. You simply push the changes to a branch and run them through a CI pipeline. The CI tool is able to run tests and set the status of the pull request to green or red depending on the result.

Once everything is tested and verified, the code is allowed to be merged onto the master branch. This sounds very straightforward, but automated testing is an often neglected task in infrastructure management. GitOps doesn't make this any easier, but at least you're relying on the already familiar Git workflow that you use in other places.

Highly Available Deployment Infrastructure

It is important to keep deployment infrastructures permanently up and running. Git servers are usually already set up in a replicated, highly available way. All developers need access to source code most of the time, so using Git as a deployment source is not an additional burden on Git itself.

Argo CD

With the increasing interest in GitOps, there are also quite a few tools that implement GitOps in Kubernetes and take over the task of synchronizing the resources. One of the most popular tools in the area of GitOps and Kubernetes is Argo CD. Argo CD is a declarative open-source GitOps continuous delivery tool for Kubernetes. It has been available on Github since 2018 and is developed by Intuit. In Argo CD, individual applications are defined that have an origin repository and are to be synchronized into a target system. Argo CD offers a variety of features and integrations that make it possible to customize its behavior. The GitOps paradigm is in the foreground here and Argo CD tries to provide best practices in the area, but does not impose them on the user.

Argo CD is installed directly into the Kubernetes cluster via kubectl or helm as an operator and creates its own Kubernetes resource (CRD), which can be used to define applications to be synchronized into the cluster. Any configuration is stored in Kubernetes resources, which allows Argo CD to run itself using the GitOps paradigm.

Argo CD offers a very wide range of features:

  • Application Deployment: it is possible to deploy applications using a variety of tools, such as kubectl, helm, kustomize, ksonnet or custom plugins.
  • Web interface: Argo CD offers a web interface that simplifies the configuration of applications.
  • Multi Cluster: It is possible to mirror applications across cluster boundaries.
  • Multi Tenancy: An integrated Dex Server [5] allows remotely managed users to authenticate to Argo CD. Alternatively, additional local users can be configured.
  • Rights Management: It is possible to allow or deny access to specific resources within Argo CD for users.
  • Custom Health Checks: Argo CD offers extensive options for checking the health of an application and passing this on to the Kubernetes resource in the event of problems. In doing so, users can implement their own health checks using the Lua programming language.
  • Notifications: Argo CD does not offer direct support for notifications, however there are third-party projects that add this functionality.
  • Extensibility: Argo CD's Kubernetes-native approach allows customizations to be made directly to the Kubernetes resources themselves.

In addition, one also has the ability to define plugins to deploy applications, but they must be available in the pod at runtime. Custom hooks can be created to perform tasks if a resource is mirrored.