Example GitOps repository structure
This page describes an example structure for a project that builds and deploys an application to a Kubernetes cluster with GitOps and the GitLab agent for Kubernetes.
You can find an example project that uses this structure in this GitLab repository. You can use the example project as a starting point to create your own deployment project.
Deployment workflow
The default branch is the single source of truth for your application and the Kubernetes manifests that deploy it. To be reflected in a Kubernetes cluster, a code or configuration change must exist in the default branch.
A GitLab agent for Kubernetes is installed in every Kubernetes cluster. The agent is configured to sync manifests from a corresponding branch in the repository. These branches represent the state of each cluster, and contain only commits that exist in the default branch.
Changes are deployed by merging the default branch into the branch of a cluster. The agent that watches the branch picks up the change and syncs it to the cluster.
For the actual deployment, the example project uses the GitLab agent for Kubernetes, but you can also use other GitOps tools.
Review apps
Ephemeral environments such as review apps are deployed differently. Their configuration does not exist on the default branch, and the changes are not meant to be deployed to a permanent environment. Review app manifests are generated and deployed in a merge request feature branch, which is removed when the MR is merged.
Example deployment
The example project deploys to two permanent environments, staging and production, which each have a dedicated Kubernetes cluster. A third cluster is used for ephemeral review apps.
Each cluster has a corresponding branch that represents the current state of the cluster:
_gitlab/agents/staging
, _gitlab/agents/production
and _gitlab/agents/review
. Each branch is
protected and
a project access token
is created for each branch with a configuration that allows only the corresponding token to push to the branch.
This ensures that environment branches are updated only through the configured process.
Deployment branches are updated by CI/CD jobs. The access token that allows pushing to each
branch is configured as a CI/CD variable. These variables
are protected, and only available to pipelines running on a protected branch.
The CI/CD job merges the default branch main
into the deployment branch, and pushes
the deployment branch back to the repository using the provided token. To preserve the
commit history between both branches, the CI/CD job uses a fast-forward merge.
Each cluster has an agent for Kubernetes, and each agent is configured to sync manifests from the branch corresponding to its cluster. In your own project, you can different GitOps tool like Flux, or use the same configuration to deploy to virtual machines with GitLab CI/CD.
Application changes
The example project follows this process to deploy an application change:
- A new feature branch is created with the desired changes. The pipeline builds an image,
runs the test suite, and deploy the changes to a review app in the
review
cluster. - The feature branch is merged to
main
and the review app is removed. - Manifests are updated on
main
(either directly or via merge request) to point to an updated version of the deployed image. The pipeline automatically mergesmain
into the_gitlab/agents/staging
branch, which updates thestaging
cluster. - The
production
job is triggered manually, and mergesmain
into the_gitlab/agents/production
branch, deploying to theproduction
cluster.