GitOps
About
GitOps is code-based infrastructure and operational procedures that rely on Git as a source control system, that leverages Git as the single source of truth.
You use Git pull requests to verify and automatically deploy system infrastructure modifications.
An evolution of Infrastructure as Code (IaC).
Primarily used with operating models for Kubernetes
based infrastructure and applications.
But there are tools coming to market that support direct Terraform
manipulation.
Benefits
GitOps shares many of the same benefits as an agle feature branch
workflow.
The first major benefit is ease of adoption due to the usage of common tools.
It brings transparency and clarity to an organization's infrastruscture needs around a central repo. It also allows to quickly experiment with new infrastructure configurations. If a new change don't behave as expected, a team can use Git history to revert changes to a known good state.
How it works
To achieve a full GitOps install, a pipeline is required.
ArgoCD, Jenkins, Bitbucket Pipelines or CircleCi. (To automate and bridge the gap between PRs and the Orchestration system)
Once this pipeline hooks are established and triggered from PRs, commands are executed to the orchestration piece.
Example
CI
The CI step will run tests and make sure it should be runnable and will also build the main branch and make a Docker image, by executing the Dockerfile
inside the project.
name: CI GitOps
on:
push:
branches: [main]
jobs:
build:
name: Build Project
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Build and push image to DockerHub
uses: docker/build-push-action@v1.1.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
repository: ${{ secrets.DOCKER_USERNAME }}/repositoryname
# To also tag the DockerHub image with the release commit SHA
# You could also tag the image with the release tag (Don't know how)
tags: ${{ github.sha }}, latest
- name: Update Kubernetes resources
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
# This considers the Kubernetes files to be on the same repository, but
# in prodution they should be in another GitHub repository.
# So this should try to edit the files from another GitHub repository.
run: |
cd k8s
kustomize edit set image goserver=$DOCKER_USERNAME/your-image-name:$GITHUB_SHA
- name: Commit
run: |
git config --local user.email "action@github.com"
git config --local user.name "Github Action"
git commit -am "Bump docker version"
-name: Push
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
repository: your-github-username/your-another-github-repository
The DOCKER_PASSWORD
will be an Access Token generated in DockerHub.
CD
Kubernetes Manifest
We can create the Kubernetes manifest files with kind
.
kind create cluster --name=<cluster-name>
Create this files inside k8s
in the infra projects folder.
...
...
To get the correct image version, you may use Helm
that will handle the package name at runtime??.
Or use Kustomize
which will update the deployment.yaml
file everytime a change happens.
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
images:
- name: goserver # The pod name configured in deployment.yaml
newName: docker-username/your-image-name
newTag: version-sha
Every time you want to update the running version, you change the version-sha
to the one of the last commit, in kustomize.yaml
, and kustomize will behind the scenes update kubernetes.
Will be the agent to keep checking for changes.
It is installed inside Kubernetes.
Last updated