“Infrastructure as code”, the idea of using code and code-like constructs to manage your infrastructure, has always been a core concept of DevOps. It leverages the programmability of virtual and cloud infrastructure to bring new flexibility to application teams. It simultaneously gives Dev teams unprecedented ability to drive change into infrastructure and gives Ops teams the capability to maintain guardrails and safety while enabling those developer abilities.
What is GitOps?
As Git is the de facto trusted repository, GitOps creates an operations management structure taking DevOps best practices used for application development (such as collaboration, version control, and CI/CD tooling) and applies them to infrastructure automation.
This structure means that common Git workflow techniques can be used to manage change flow, the expected state of the system is easily visible to the whole team, and the human and technical resources in the system are working in a common language (i.e., code).
GitOps is typically described as having four key attributes:
- The entire system is described in code
- The desired state of the system is versioned in Git
- Changes in an authoritative location/branch in Git can be automatically applied to the system
- Automation ensures that the system always matches the state described in the authoritative location
With this setup, common change flow patterns for code will work. A simple Pull Request mechanism can be used to provide approval for changes going into the system and an automation system, such as Flux, can apply those new changes to an environment. This provides a simple workflow for all that effectively matches familiar code delivery patterns.
GitOps & the Database
As is often the case in DevOps conversations, the persistence layer, or database, is usually overlooked. There are good reasons for this. After all, databases are a different animal to Kubernetes clusters. Databases are stateful things where the order of changes is crucial. ‘Configuration by convergence’ does not often work where data structures are concerned. Databases can be massive pieces of clustered infrastructure unto themselves that rival Kubernetes in complexity — with the added bonus that they store critical data assets for the company. As a result, it is often easier for teams to leave database changes to traditional means — even if that means creating a bottleneck in their delivery flow.
How Liquibase Solves the GitOps Database Problem
Liquibase helps teams fit the flow of database changes nicely into GitOps. Let’s use the four common descriptors for GitOps to explain why and how.
1 – Describe as code
Liquibase is one of a very few database change management tools that use a control file; in Liquibase terms, a “changelog” defines changes. Unlike tools that use simplistic groups of SQL files in a folder and implicit behaviors, Liquibase explicitly defines the order and behavior of each change in a changelog file or set of changelog files. This is done through a combination of sequence and metadata.
This enables anyone reviewing the changes to:
- Know exactly what the authors intended
- Clearly identify changes and merge points
- Understand what specific changes will be applied
- Provide visibility to anyone inspecting the file to know what changes have been applied and when
2 – The desired state is versioned in Git
Liquibase’s changelog files are plain text files that can be easily stored and versioned in Git (or your source control of choice). Because they are text, all familiar workflows and capabilities in Git effectively review and manage the changelog files. That means processes such as Pull Requests for adding changes serve as clear approval channels. It is also easy to pick specific versions of the file, see change progression over time, track how changes were added or modified for audit purposes, and so on.
3 – Changes are automatically applied
Automation is central to anything with ‘Ops’ in the name these days. Liquibase’s fundamental purpose is to provide a tool that applies known, structured changes to databases in a scriptable manner. As a result, the tool has many interfaces with which to do so. The most obvious for GitOps is the command line, which is easily integrated into any automation tool that can run a command shell. Equally useful is the official Liquibase container image which is easily consumed in cloud-native environments. For those who prefer to create their own container images, Liquibase, an open source tool, publishes assembly instructions and example Dockerfiles for doing so. There are also adapters for Maven, Spring, ANT, NodeJS, and other tools to help enable developers and other change creators.
4 – Automatically ensure the system matches a defined state
Liquibase, as with many database change automation tools, operates on incremental change handling. In other words, it can tell when changes are already present and just add any missing changes. However, unlike other tools, Liquibase provides several capabilities to inspect databases. For example, Liquibase can take snapshots of a database at a point in time and then compare the actual database to that snapshot. This provides a crucial level of Observability (O11y) into the database for any out-of-band changes — which may have quality or security implications.
GitOps and Cloud-Native are trends in the DevOps movement that are accelerating. With the acceleration, the issue of database change automation cannot be left behind as it has been for most of the DevOps movement so far. Liquibase, as one of the most widely used tools for handling DevOps-style database change automation, is well-positioned to help teams moving into Cloud Native environments and GitOps methodologies.