GitOps is a broad term, which generally describes some processes used when deploying cloud-native applications.
A source control repository is used as a mechanism to provide a declarative description of the current state of some infrastructure.
The idea is that this source control repository is updated when there is a change, such as a new version or a change to the infrastructure.
Some automated process detects the change and updates the environment to become eventually consistent with what is described within the repository.
GitOps uses tools that developers are familiar with already, hence the git part of GitOps. I’ve also seen online, people refer to SvnOps, but GitOps seems to be the most used term.
How does this look in practice?
There are usually two source code repositories surrounding an application, the application source repository and some form of control repository.
The application repository is traditionally used in a deployment pipeline, and in this case, works the same.
The application source code is updated and on the back of a change, an artifact is produced such as a Docker image, and is uploaded to a repository.
The control repository is not traditionally used in a deployment pipeline, but it is an incorporation of different concepts that may be used with other tools.
The control repository will contain configuration, version information, and infrastructure as code. This control repository describes the current state of how you want the application to be deployed.
Automated processes, which can be push or pull-based, will then aim to update the environment to match what was described within the control repository.
Push and Pull based Automation
Push based automation is generally implemented by using triggers.
When a change is made to the control repository, some kind of trigger is triggered which then starts the deployment process.
This kind of process is common when using CI/CD systems such as Jenkins or Circle, basically any system which relies on triggers.
Pull based automation is generally implemented by having some kind of operator, which exists to look for changes.
The operator should live in the same environment or cluster as the application to deploy, and will periodically check the control repository for changes, applying them where necessary.
Which is better?
Pull based is almost always preferred over push-based for the following reasons:
- Credentials are not required to push to the environment, greatly improving security
- Push based deployments could be tampered with outside of the deployment process
Isn’t storing configuration in a repo an anti-pattern?
The answer is, it depends.
Anything that is sensitive should never be stored in source code.
It is expected that some configuration will exist within the control repository, it will be needed for the application to run. It is also handy to use to view what the current state of the application should be using.
Anything sensitive should either use an encrypted value (good) or a pointer to a secrets store (better).
Do you have to use Kubenetes with GitOps?
The answer is no, in fact, kubenetes has not been mentioned at all until this point.
GitOps is a pattern or framework, so can be applied to different technologies.
Kubenetes is a great tool, which will no doubt help you achieve pull based automation, but it is undoubtedly possible on other platforms.
A good example would be in the current project I am working on, GitOps is achieved by utilising AzureDevOps as the source control and CI/CD deployment mechanism, and ECS Fargate used as the platform.
The flow works as follows: