Skip to content

GitOps

This page helps you keep Goiabada’s Kubernetes files in a Git repository that Argo CD or Flux applies.

  1. Generate each environment’s files in a directory of its own, running the setup wizard once per environment. Each one answers its own URLs, namespace and database, so each gets a manifest of its own rather than patches over another’s:

    goiabada-deploy/
    ├── components/
    │ └── common/
    │ └── kustomization.yaml
    ├── production/
    │ ├── goiabada-setup.yaml
    │ ├── goiabada-k8s.yaml
    │ ├── goiabada-secrets.sealed.yaml
    │ ├── goiabada-encryption-key.sealed.yaml
    │ └── kustomization.yaml
    └── staging/
    └── ...

    Commit goiabada-setup.yaml, the answers file, and goiabada-k8s.yaml. Never commit goiabada-secrets.yaml: add it to .gitignore.

  2. Put the Secrets in the repository sealed, or leave them out, as Secrets describes: a sealed file per Secret with SealedSecrets, an ExternalSecret per Secret with the External Secrets Operator, or Secrets created from your terminal, which the repository then leaves out. Sealed files and ExternalSecrets let the GitOps tool rebuild an environment from the repository alone.

  3. Write the patches every environment shares in a Kustomize component. This one raises the auth server’s CPU limit, as Resource limits suggests for a higher sign-in peak. Save this as components/common/kustomization.yaml:

    apiVersion: kustomize.config.k8s.io/v1alpha1
    kind: Component
    patches:
    - target:
    kind: Deployment
    name: goiabada-authserver
    patch: |-
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: goiabada-authserver
    spec:
    template:
    spec:
    containers:
    - name: authserver
    resources:
    limits:
    cpu: "1"

    The target selects the Deployment by kind and name alone, so the patch fits every environment’s namespace. A patch without one matches only a Deployment in the namespace its own metadata names, and Kustomize refuses it when it names none.

  4. Write each environment’s kustomization. This one also caps the auth server’s database pool at 10 connections, for a smaller database. Save this as production/kustomization.yaml:

    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    resources:
    - goiabada-k8s.yaml
    - goiabada-secrets.sealed.yaml
    - goiabada-encryption-key.sealed.yaml
    components:
    - ../components/common
    patches:
    - target:
    kind: Deployment
    name: goiabada-authserver
    patch: |-
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: goiabada-authserver
    spec:
    template:
    spec:
    containers:
    - name: authserver
    env:
    - name: GOIABADA_DB_MAX_OPEN_CONNS
    value: "10"

    Leave the sealed files out of resources if you create the Secrets another way. Check what it builds before you commit it:

    Terminal window
    kubectl kustomize production
  5. Point your GitOps tool at each environment’s directory, with Argo CD or Flux below. These steps are tested with Argo CD v3.5.6 and Flux v2.10.0.

A setting the wizard asks, other than a password, belongs in the answers file, and everything else in a patch:

Change How
URLs, namespace, the database’s host, port, name, user and TLS, routing, the HTTPS certificates, NetworkPolicies, mesh ports, the auth server’s replicas, metrics, images, labels and annotations, the rate limiter Regenerate with the new answer
Resources, node selectors, tolerations, affinity, the admin console’s replicas, a server setting the wizard doesn’t ask A patch in the environment’s kustomization, or in the component when every environment shares it
A new Goiabada release Regenerate every environment with the new release’s wizard
A password or key Change it in the Secrets, as Rotate secrets describes, and in their source when something else owns them

To regenerate, run the wizard over the environment’s answers file, from its directory, with the answer that changes. It leaves the Secrets as they are:

Terminal window
cd production
./goiabada-setup-linux-amd64 --answers=goiabada-setup.yaml --keep-secrets --authserver-replicas=3
git diff

Review the diff, commit and push, and the GitOps tool applies it. The answers file records the new answer, so the next regeneration keeps it. Run it again on a deployment has the rest.

Set a server setting the wizard doesn’t ask, such as GOIABADA_DB_MAX_OPEN_CONNS, as an env entry of the container, as the kustomization above does, rather than by patching the ConfigMap. It overrides the ConfigMap’s value of the same name, and applying it rolls the pods. A patched ConfigMap doesn’t roll them: the pods keep the old value until something restarts them.

A change made in the cluster by hand, such as a kubectl scale, doesn’t last: Argo CD’s self-heal reverts it at once, and Flux at its next reconciliation. Make the change in the repository.

One Application per environment, in the namespace Argo CD runs in, here production’s. Register the repository’s credentials as Argo CD’s documentation describes:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: goiabada-production
namespace: argocd
spec:
project: default
source:
repoURL: https://git.example.com/platform/goiabada-deploy.git
targetRevision: main
path: production
destination:
server: https://kubernetes.default.svc
namespace: goiabada
syncPolicy:
automated:
prune: true
selfHeal: true

Argo CD builds the kustomization itself. prune deletes what leaves the manifest, such as the NetworkPolicies when you regenerate with them turned off, and selfHeal reverts changes made by hand. An Application pointed at a deployment you applied with kubectl takes its objects over, and rolls the pods once if its patches change them.

A GitRepository for the repository, and one Kustomization per environment, in the namespace Flux runs in. The secretRef names a Secret holding the repository’s credentials, as Flux’s documentation describes:

apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: goiabada-deploy
namespace: flux-system
spec:
interval: 1m
url: https://git.example.com/platform/goiabada-deploy.git
ref:
branch: main
secretRef:
name: goiabada-deploy-auth
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: goiabada-production
namespace: flux-system
spec:
interval: 10m
sourceRef:
kind: GitRepository
name: goiabada-deploy
path: ./production
prune: true
wait: true
timeout: 5m

prune deletes what leaves the manifest, and wait holds the Kustomization not ready until every object it applied is, the pods included. To apply a commit without waiting for the intervals:

Terminal window
flux reconcile kustomization goiabada-production --with-source

When you answered yes to creating the namespace, the manifest declares it, and the GitOps tool owns it with everything else. Deleting a Flux Kustomization that prunes, or an Argo CD Application with cascading deletion, then deletes the namespace and everything in it, Secrets you created by hand included.

Sealed files and ExternalSecrets come back with the rest when the environment is applied again. Secrets created from your terminal don’t: create them again, with the same values, as Secrets explains. For a namespace that must outlive the GitOps tool’s objects, answer no to creating it, and create it outside the repository. To switch an environment that already runs, never just regenerate: follow Switching a running deployment first, or pruning deletes the namespace.

The Internal TLS guide’s files go in the environment’s directory, beside its kustomization, and its patches in that kustomization’s patches. They name the namespace goiabada, so they belong to the environment deployed there rather than to the component.