We use GitOps here at Auxo, all our code is stored on GitHub and we use GitHub action as our CI/CD tool, on this blog you will learn about how we think about GitOps and how it is being managed for all the projects in the company.
What is GitOps?
GitOps is a way of implementing Continuous Deployment for cloud-native applications. It focuses on a developer-centric experience when operating infrastructure, by using tools developers are already familiar with, including Git and Continuous Deployment tools.
The core idea of GitOps is to have a Git repository that always contains declarative descriptions of the infrastructure currently desired in the production environment and an automated process to make the production environment match the described state in the repository. If you want to deploy a new application or update an existing one, you only need to update the repository - the automated process handles everything else. It’s like having cruise control for managing your applications in production.

Before we start thinking about how to deploy or create the product infrastructure we do some research first and understand the “settings“ of the application, we deploy all the projects managed by us in Kubernetes (cloud-native approach), taking that into account we have the following categories of “environment configuration“:
- Application Version: This configuration is being managed as the tag of the container which is being deployed, any time a new change is pushed to the repository a new tag is generated to be deployed.
- Kubernetes Specific Settings: This includes replicas, health checks, volumes, and other Kubernetes-related information in the form of YAML manifests.
- Static Business Settings: Settings that are stored in “.conf“ (or language-based config file) files and do not change in any environment.
- Non-Static Business Settings: This is the same thing as the previous point, but includes settings that change between environments or cannot be stored as static configurations such as secret keys, database URLs, etc.
Infrastructure as Code (IaC)
We separate the infrastructure for each project into its own repository, one repository per environment, each project repository is known as a “live“ repository which contains the actual state of the resources being used on the cloud provider, we build modules in order to don’t repeat code and being the more modularized and structured as possible.
.png)
About the implementation, we create a separate repository per project and per environment, which means each project has two IaC repositories, one for development infrastructure and the other one for production infrastructure, with this approach we are totally sure each client can access their own IaC code without having access to any other client code, also, in case our client wants to maintain the code we can bring the access without exposing any other client, you can find id using the next naming convention: <client>-<environment>-<infrastructure>.
Configuration
We are managing all our configuration values, secret and public on Google Secrets manager, each project has a secret manager that contains all that is on the .env file, then, on the deployment plan, our continuous deployment pipeline grabs the secret and converts it to a file only accessible inside the running pod as we run all our projects inside Kubernetes.
.png)
Application Code
We use Github as our git repository manager, each client has its own repository per development area, which means one for the frontend and the other for the backend, with this approach we are totally sure each client can access their own application code without having access to any other client code, also, in case our client wants to maintain the code we can bring the access without exposing any other client.
Continuous Integration
We think continuous integration is the ability to have a revision control system for the project’s source code, and all artifacts required to build the project should be placed in the repository. The system should be buildable from a fresh checkout and not require additional dependencies.
We follow the next principles:
- Maintain a code repository per project and area
- Automate the build and the deployment
- Make the build self-testing
- Fast builds with the most recent changes
- Having separate environments, at least two, one for testing and another one for production
- Make it easy to get the latest deliverables
- Everyone can have access to the latest build
.png)
Continuous Deployment / Delivery
We use a mix between continuous deployment and delivery, all our process is almost automated, as soon a new push is sent to the development branch it triggers a new build and deploys to this environment and the same happen when a new push is sent to the production branch, in order to avoid deploying incorrect builds we have a pull request process where any new change is reviewed by our development team before sending it to any environment.