CD_pipeline

CD Pipeline ArgoCD

General

We use Argo CD for the CD part of our CI/CD pipeline.

The Argo CD Applications are stored in our GitLab repository under https://gitlab.com/the-microservice-dungeon/devops-team/ci-cd/argocd.


Default repo sync are 3 minutes.


Argo CD-Controlled Deployments

Infrastructure

Name (alphabetical) Description
ArgoCD Can monitor and update itself
cert-manager Generates and renews TLS certificates
gitlab-runner GitLab group runner for MSD and MSD-Players
kafka-rabbitmq-connector Infrastructure service connecting RabbitMQ with Redpanda
kube-prometheus-stack Monitoring stack
kube-prometheus-stack-crds CRDs for the monitoring stack
longhorn Storage management
mariadb MariaDB, required by game, gamelog, trading, and robot
msd-dashboard-backend Our core service dashboard-backend, also deploys a SurrealDB
msd-dashboard-frontend Our core service dashboard-frontend
postgresql PostgreSQL, required by map
rabbitmq Message Queue
redpanda Redpanda Operator, Redpanda Cluster, plus separate CRD deployment
sealed-secrets Encryption and decryption of our secrets

Core-Services (ant Test-Player)

Name (alphabetical) Description
game Our core service game
gamelog Our core service gamelog
map Our core service map
msd-dashboard-backend Our core service dashboard-backend, also deploys a SurrealDB
msd-dashboard-frontend Our core service dashboard-frontend
player-thelegend27 Test player
robot Our core service robot
test-monte24 Test player

Files and Dirs

Type Path
Repo root
Description
Folder a-first/ Contains general files that are executed or applied before Argo CD
File a-first/first.yaml The initial Argo CD Application that is applied to the cluster when running argocd.sh
File a-first/sealed-secret.pem Contains the public Sealed Secrets certificate; all secrets must be encrypted with kubeseal using this key before being committed to GitLab
Folder application/ Contains all Argo CD Applications
Folder application/bootstrap-manifests/ Target location referenced by the initial Argo CD Application during the installation process.
This folder contains the Argo CD applications: argocd-application.yaml, bootstrap-coreservices-repo.yaml, bootstrap-infra-repo.yaml, and bootstrap-player.yaml
Folder application/core-services Contains all Argo CD Applications related to our core services
Folder application/infrastructure Contains all Argo CD Applications related to our infrastructure
Folder application/no-deploy Contains folders with Argo CD Applications that are either not yet deployed to the cluster or have been temporarily removed from Argo CD monitoring
Folder application/player Contains all Argo CD Applications related to our player services
Folder app/ Contains folders, for our kubernetes stack, with kustomization
Folder app/core-services Contains folders for each of our core services. Each subfolder includes a Kubernetes manifest
Folder app/infrastructure Contains folders for each infrastructure component. Each subfolder includes a Kubernetes manifest

Argo CD File Structure

The following section explains where specific files are located and how they affect the cluster.

There are several ways to pass values to Helm charts:

  • Directly within the application.yaml file as a string or valuesObject
  • Through the Helm chart itself by referencing a folder within the chart (e.g. application.yaml + Helm values file)
  • By including a second source and referencing it via an alias as the values path for the Helm chart
  • By referencing a Kubernetes Kustomization manifest

We have chosen two methods for deploying applications to the cluster using Argo CD:

  • Defining Helm values directly in the application.yaml via the helm.valuesObject
  • Using a kustomization.yaml manifest

Folder: application

Argo CD applications are organized by type: core-services, infrastructure, or player.


Simple application.yaml Example with Explanation

The following is a minimal example of an Argo CD Application using a Helm chart as the source:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: <Project name in Argo CD>         # Name of the application in the Argo CD UI
  namespace: argocd                       # Namespace where Argo CD is installed
spec:
  project: default                        # Project assignment within Argo CD (usually 'default')
  source:
    repoURL: "<Source repo>"              # Repository URL that hosts the Helm chart
    chart: "<Chart name>"                 # Name of the Helm chart to deploy
    targetRevision: "<Chart tag>"         # Version (tag) of the Helm chart to use
  destination:
    server: "https://kubernetes.default.svc" # Target Kubernetes cluster (default = in-cluster)
    namespace: <target namespace>             # Kubernetes namespace where the chart will be deployed
  syncPolicy:
    automated:                            # Enables automatic synchronization
      prune: true                         # Remove resources not tracked in Git anymore
      selfHeal: true                      # Automatically fix drift (e.g., manual changes)
    syncOptions:
      - CreateNamespace=true              # Create the target namespace if it does not exist

Example application.yaml with helm.valuesObject

When using an Argo CD Application based on a Helm chart, and the values block is manageable in size, and no additional resources (such as sealed-secrets.yaml) need to be deployed, the Helm values can be defined directly within the Application manifest.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: <Project name in Argo CD>
  namespace: argocd
spec:
  project: default
  source:
    repoURL: "https://gitlab.com/api/v4/projects/42239222/packages/helm/stable"
    chart: "<Chart name>"
    targetRevision: "<Chart tag>"
    helm:
      valuesObject:
        port: 8080
        targetPort: 8090
        image:
          name: registry.gitlab.com/the-microservice-dungeon/devops-team/msd-image-registry/player-thelegend27
        env:
          - name: GAME_HOST
            value: "http://game.game.svc.cluster.local:8080"
          - name: RABBITMQ_HOST
            value: "rabbitmq.rabbitmq.svc.cluster.local"
          - name: RABBITMQ_PORT
            value: "5672"
        ingress:
          enabled: true
          hostname: <application-name>.microservice-dungeon.de
          path: /
          classname: nginx
  destination:
    server: "https://kubernetes.default.svc"
    namespace: <target namespace>
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Example application.yaml for MariaDB with reference to the apps folder

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: mariadb
  namespace: argocd
spec:
  project: default
  source:
    repoURL: "https://gitlab.com/the-microservice-dungeon/devops-team/ci-cd/argocd.git"
    targetRevision: main
    path: apps/infrastructure/mariadb
  destination:
    server: "https://kubernetes.default.svc"
    namespace: database
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Folder: apps

This folder contains all Kustomization files. As with the application folder, the structure is divided by type: core-services, infrastructure, and player. Within the corresponding subfolder, a directory named after the application is created. The kustomization.yaml file is placed inside this directory and is referenced by Argo CD.


Example Kustomization for MariaDB with reference to the folder apps/infrastructure

The following files are located in the folder apps/infrastructure/mariadb:

Name Description
cm-mariadb.yaml Contains a ConfigMap for MariaDB
kustomization.yaml The Kustomization file
mariadb-sealed-secret.yaml The MariaDB root secret, already sealed/encrypted
mariadb-user-secret.yaml The MariaDB user secrets, already sealed/encrypted
mariadb-values.yaml The values file used for deploying MariaDB

Argo CD looks at the kustomization.yaml file and renders the Helm chart based on its contents for deployment.

The following block shows the content of the kustomization.yaml file for MariaDB:

  • Under resources, the additional files to be deployed are listed. If there are no additional resources, this section can be commented out.

  • Under helmCharts, the Helm charts to be deployed are defined — in this case, only the MariaDB chart. It is important to specify the releaseName and namespace to ensure proper rendering by Kustomize.

  • Finally, the valuesFile defines the Helm values file to be used.

kind: Kustomization
apiVersion: kustomize.config.k8s.io/v1beta1
resources:
  - mariadb-sealedsecret.yaml
  - mariadb-user-sealedsecret.yaml
  - cm-mariadb.yaml

helmCharts:
  - name: mariadb
    repo: oci://registry-1.docker.io/bitnamicharts/
    version: 20.4.1
    releaseName: mariadb
    namespace: database
    valuesFile: mariadb-values.yaml

Miscellaneous and Issues

  • kube-prometheus-stack cannot be updated
    • Error: metadata too large
    • This is a known issue in the community caused by overly large CRDs
    • Solution Step 1: In apps/infrastructure/kube-prometheus-stack, disable CRD generation in the values file
    • Solution Step 2: Create a separate application.yaml specifically for the CRDs with the sync option replace=true. This ensures the CRDs are always recreated rather than managed through metadata. Splitting them out is necessary to avoid replacing the entire kube-prometheus-stack during updates.
  • Redpanda can’t find CRDs
    • No CRDs are installed automatically
    • The Helm chart does not provide an option for installing CRDs
    • Solution: Reference the CRDs directly from GitHub as an additional source within the same application.yaml
Last modified May 10, 2025: modify devops cluster docs (17549c6)