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.
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.
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.
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/review. Each branch is
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.
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
- The feature branch is merged to
mainand 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 merges
_gitlab/agents/stagingbranch, which updates the
productionjob is triggered manually, and merges
_gitlab/agents/productionbranch, deploying to the