# 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 ```bash # 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: ```yaml 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: ```yaml 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: ```bash # 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: ```bash 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: ```bash 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: ```yaml 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 ```bash kubectl get pods -l app.kubernetes.io/name=gitops-status-server ``` ### View logs ```bash kubectl logs -l app.kubernetes.io/name=gitops-status-server ``` ### Test endpoint ```bash 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: ```bash 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