5.7 KiB

GitOps Status Server Helm Chart

A minimal HTTP server that serves GitOps status information as JSON for monitoring and observability purposes.

Overview

This chart deploys a lightweight nginx-based server that exposes a single endpoint (/status.json) containing GitOps synchronization status, drift information, and changed files. It's designed to be consumed by Grafana's Infinity datasource or other monitoring tools.

Features

  • Minimal footprint: Uses nginx-unprivileged with minimal resource requirements
  • Secure by default: Runs as non-root with read-only root filesystem
  • Internal only: ClusterIP service for cluster-internal access
  • ConfigMap-based: JSON content stored in ConfigMap for easy updates
  • ArgoCD compatible: Automatically rolls deployment when ConfigMap changes
  • Production-ready: Includes health checks, security contexts, and resource limits

Installation

Using Helm

# Install with default values
helm install gitops-status ./charts/gitops-status-server

# Install with custom namespace
helm install gitops-status ./charts/gitops-status-server -n monitoring --create-namespace

# Install with custom values
helm install gitops-status ./charts/gitops-status-server -f custom-values.yaml

Using ArgoCD

Create an Application manifest:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: gitops-status-server
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/your-org/observability-stack
    targetRevision: main
    path: charts/gitops-status-server
    helm:
      values: |
        statusJson:
          repo: "my-repo"
          server: "my-server"
          sync_status: "SYNCED"
          drift_count: 0
          files: []
          last_check: "2026-04-21T10:00:00Z"
  destination:
    server: https://kubernetes.default.svc
    namespace: monitoring
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

Configuration

Key Values

Parameter Description Default
replicaCount Number of replicas 1
image.repository Container image repository nginxinc/nginx-unprivileged
image.tag Container image tag 1.25-alpine
service.type Kubernetes service type ClusterIP
service.port Service port 80
service.targetPort Container target port 8080
resources.limits.cpu CPU limit 100m
resources.limits.memory Memory limit 64Mi
statusJson JSON content to serve See values.yaml

Custom Status JSON

Override the status JSON content in your values:

statusJson:
  repo: "production-apps"
  server: "prod-cluster-01"
  sync_status: "SYNCED"
  drift_count: 2
  files:
    - "deployment.yaml"
    - "service.yaml"
  last_check: "2026-04-21T12:30:00Z"

Usage

Access the Status Endpoint

From inside the cluster:

# Using the service DNS name
curl http://gitops-status-server/status.json

# With namespace
curl http://gitops-status-server.monitoring.svc.cluster.local/status.json

Grafana Infinity Datasource Configuration

  1. Add an Infinity datasource in Grafana
  2. Configure URL: http://gitops-status-server.monitoring.svc.cluster.local/status.json
  3. Parser: JSON
  4. Use fields from the JSON response in your dashboard

Example query fields:

  • sync_status - Current sync status
  • drift_count - Number of drifted resources
  • files - List of changed files
  • last_check - Timestamp of last check

Updating Status Data

Manual Update

Edit the ConfigMap directly:

kubectl edit configmap gitops-status-server -n monitoring

The deployment will automatically roll out with the new content due to the ConfigMap checksum annotation.

Automated Update via Pipeline

Use kubectl in your CI/CD pipeline:

kubectl create configmap gitops-status-server \
  --from-file=status.json=./status.json \
  --dry-run=client -o yaml | kubectl apply -f -

ArgoCD Hook (Advanced)

Create a PostSync hook that updates the ConfigMap with current sync status:

apiVersion: batch/v1
kind: Job
metadata:
  name: update-status
  annotations:
    argocd.argoproj.io/hook: PostSync
spec:
  template:
    spec:
      containers:
      - name: update
        image: bitnami/kubectl
        command:
        - /bin/sh
        - -c
        - |
          # Update status.json with current sync status
          kubectl patch configmap gitops-status-server \
            --patch '{"data":{"status.json":"..."}}'
      restartPolicy: Never

Security Considerations

  • Runs as non-root user (UID 101)
  • Read-only root filesystem
  • No privilege escalation
  • Minimal capabilities (all dropped)
  • No external network access required
  • ClusterIP only (no external exposure)

Resource Requirements

Minimal resource footprint suitable for small clusters:

  • CPU: 50m request / 100m limit
  • Memory: 32Mi request / 64Mi limit

Troubleshooting

Check pod status

kubectl get pods -l app.kubernetes.io/name=gitops-status-server

View logs

kubectl logs -l app.kubernetes.io/name=gitops-status-server

Test endpoint

kubectl run -it --rm curl --image=curlimages/curl --restart=Never -- \
  curl http://gitops-status-server/status.json

Common Issues

Pod not starting: Check security context compatibility with your cluster's PSP/PSA policies.

Empty response: Verify the ConfigMap is mounted correctly:

kubectl describe pod -l app.kubernetes.io/name=gitops-status-server

Service not accessible: Ensure you're accessing from within the cluster and using the correct namespace.

License

This chart is part of the observability-stack project.

Maintainers

  • DevOps Team