Skip to content

Deploy using GitOps

Our infrastructure and deployment definitions can be found in the infrastructure as code repository.


The core idea of GitOps is having 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're interested in further reading on GitOps, check out the Guide to GitOps , , The GitOps FAQ , and OpenGitOps . We use Argo CD as our GitOps operator.


Our scripts should work on Ubuntu or other Linux distributions but are mainly tested on Windows with Git Bash. Start with installing some tools that are required by our scripts:

Most of the sensitive information needed for script execution is stored in GitLab CI-Variables. They are fetched and exported by the boot/ script. Some additional variables have to be set by the developer beforehand. Follow the instructions in the boot/env_template file for that purpose.


If you don't plan to use a Gitlab clone of our repository, you need to remove the calls to boot/ from our scripts. You then need to export the environment variables yourself before executing scripts.

Learn at Setup Gitlab how you can set up your own Gitlab clone of our repository.

Provision and Deploy

EuroDaT uses four different deployment stages dev, qa, qa-int, and prod. A stage may contain multiple environments, e.g., qa-gcp to deploy to different cloud provider targets.

To deploy a stage <stage> to a cloud provider <cloud provider> with the management cluster in <mgmt cluster cloud provider>, simply run

./boot/ -s <stage> -c <mgmt cluster cloud provider>
./boot/ -s <stage> -c <cloud provider> -m <mgmt cluster cloud provider>

The first script provisions and deploys a management cluster that hosts the GitOps controller for that stage. The second script provisions the environment, and deploys EuroDaT using this controller. Environments of a stage share the same GitOps controller.

Both scripts have a set of flags which control their behaviour:

  • -d: This flag is used to destroy the respective cluster. For the management cluster this simply runs Terraform with the destroy option. In the case of the normal clusters the script is called which first deletes all the corresponding Argo CD apps and then proceeds to destroy the cluster with Terraform.
  • -t: With this flag only the Terraform commands are executed. This can be useful to either create an empty cluster as a playground or to fetch the kube-config files. For example if the management cluster was provisioned with the pipeline you will not have the kube-config files on your computer. Simply run the script with the -t flag to create them locally.
  • -p: Makes the scripts executable from the pipeline. With this flag set the scripts won't work from you local setup because boot/ will be skipped since the pipeline has access to the CI Variables anyway.
  • -c: Selects a cloud provider target. Only GCP (-c gcp) is currently supported.

EuroDaT GitOps

The following will explain our GitOps approach in more detail. You already learned about the most important scripts and which set the stage- and environment-specific values and then bootstrap the templated scripts of the boot/ directory. These scripts fetch variables from GitLab, build the clusters with terraform and finally deploy the app-of-apps-<stage>.yaml Argo CD application. The differences between the cloud providers are encoded in the values-<stage>-<cloud provider>.yaml files.

The App-of-Apps Application

The app-of-apps application serves as an umbrella application that deploys our cluster resources in a series of Argo CD sync-waves and configures values such as the kubernetes clusters' API.

After applying the app-of-apps manifest,

  1. the app-of-apps Argo CD application deploys the app-of-apps Helm Chart.
  2. the app-of-apps Helm Chart deploys the Argo CD applications of the templates subdirectory.
  3. the applications in templates/* finally deploy EuroDaT Helm charts to the kubernetes clusters.


The EuroDaT Helm charts are fetched from the package registry of the trustee-platform GitLab repository, EuroDaT images from the container registry within the same Gitlab repository. The EuroDaT release version can be specified using deployedRelease in the values-<stage>-<cloud provider>.yaml file of the app-of-apps Helm chart. To update EuroDaT, change this number.

Promotion of Changes to the Next Stage

Changes and new releases pass through all stages until they reach production. All tests must succeed before the current version can be promoted to the next stage.


Changes are promoted in the order dev, qa, qa-int, and prod. The nightly stage does not take part in promotions.

  • dev is where the everyday development takes place, dev environments are pinned to branches of our repository. dev promotes to qa by creating a release.
  • nightly deploys the current version of the main branch and is used for nightly test runs on all cloud providers targets.
  • qa is pinned to the latest released version of EuroDaT and is used to run extensive tests. qa promotes to qa-int on successful completion of its tests.
  • qa-int is a production-grade EuroDaT deployment that is used to test integration with use cases of EuroDaT. qa-int promotes to prod.
  • prod is, well, production.

The promotion from dev to qa occurs if a EuroDaT release is created. For promotion from dev to qa and qa to qa-int, the pipeline automatically opens a merge request to merge the changes into the next stage. Promotions to prod are manual. Only selected accounts can approve merge requests for promotion, enforced by GitLab code owners.

The workflow of a promotion from the dev to qa to qa-int now looks something like this:

  1. A new tag is created in the trustee-platform repository.
  2. The pipeline in the trustee-platform repository creates a release and a merge request that changes the version to deploy in the qa stage.
  3. An eligible developer approves and merges the prepared promotion.
  4. Argo CD notices the change and deploys the new release.
  5. After a successful deployment, a PostSync-Hook triggers the creation of a Kubernetes Job which in return triggers the pipeline in the eurodat-trustee-iac repository via the GitLab API.
  6. The pipeline runs the e2e-tests and creates a merge request to change the version to deploy in the qa-int stage.
  7. An eligible developer merges the changes into qa-int.
  8. Argo CD notices the change and deploys the new release.

This process is repeated for every EuroDaT release.