tutorial

Monitoring Cyclops with Vigilmon: Keeping Your Kubernetes Developer Self-Service Portal Available

How to monitor Cyclops with Vigilmon — tracking UI availability, the Cyclops controller health, Helm chart rendering, and module deployment workflows with external HTTP and heartbeat monitors.

Cyclops is the Kubernetes UI framework that turns Helm charts into type-safe developer self-service portals. Platform teams define modules backed by Helm charts; developers fill out generated forms to deploy applications without writing YAML. When Cyclops goes down — the UI is unreachable, the controller is crashed, or Helm rendering fails — developers can't deploy, update, or manage their applications. The platform team becomes a bottleneck for every change. Vigilmon gives you external monitoring that watches Cyclops from outside the cluster and alerts the moment developer self-service is broken.

What You'll Build

  • A Vigilmon HTTP monitor for the Cyclops web UI
  • A monitor for the Cyclops API backend
  • A heartbeat monitor to verify the Cyclops controller is processing module reconciliations
  • Alert channels so your platform team knows before developers start filing tickets

Prerequisites

  • Cyclops installed in a Kubernetes cluster
  • The Cyclops UI exposed via an Ingress or LoadBalancer service
  • A free account at vigilmon.online

Why Monitoring Cyclops Matters

Cyclops is a developer-facing service — its availability directly impacts developer productivity. Unlike background infrastructure tools, users notice immediately when Cyclops is down because they can't do their work.

UI downtime is the most visible failure. Developers access Cyclops through a web browser to deploy new applications, scale existing ones, or roll back bad deployments. If the UI pod crashes or the Ingress route breaks, developers get a browser error and immediately escalate to the platform team.

Controller failures are less visible but equally disruptive. The Cyclops controller reconciles Module resources — it watches for changes to Module objects and applies the corresponding Helm chart to the cluster. If the controller crashes, developers can submit changes through the UI, but those changes never apply. The UI appears functional while nothing actually deploys.

Helm rendering failures surface as errors in the UI when a developer tries to deploy a module. If a template has a syntax error after a chart update, or if a required value type changes, developers hit errors they can't debug themselves — they need platform team intervention.

Backend API unavailability breaks the connection between the Cyclops UI (frontend) and the controller (backend). The UI loads, but all operations — listing modules, creating deployments, fetching module schemas — fail with API errors.


Step 1: Expose the Cyclops UI and API

Cyclops runs with a frontend UI service and a backend API service. By default:

  • Frontend (UI): port 3000
  • Backend (API): port 8080

If not already exposed, create an Ingress for both:

# cyclops-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cyclops
  namespace: cyclops
  annotations:
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
spec:
  rules:
    - host: cyclops.internal.yourdomain.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: cyclops-ui
                port:
                  number: 3000
    - host: cyclops-api.internal.yourdomain.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: cyclops-ctrl
                port:
                  number: 8080

Verify both are accessible:

# Check UI
curl -s -o /dev/null -w "%{http_code}" \
  https://cyclops.internal.yourdomain.com/
# Expected: 200

# Check API health
curl -s https://cyclops-api.internal.yourdomain.com/healthz
# Expected: 200 or {"status":"ok"}

Step 2: Add Vigilmon HTTP Monitors

In the Vigilmon dashboard:

  1. Go to Add Monitor → HTTP
  2. Add the UI monitor:

| Field | Value | |---|---| | Name | Cyclops UI | | URL | https://cyclops.internal.yourdomain.com/ | | Method | GET | | Expected status | 200 | | Check interval | 2 minutes | | Timeout | 15 seconds | | Alert after | 2 consecutive failures |

  1. Add the API health monitor:

| Field | Value | |---|---| | Name | Cyclops controller API | | URL | https://cyclops-api.internal.yourdomain.com/healthz | | Method | GET | | Expected status | 200 | | Check interval | 2 minutes | | Timeout | 10 seconds | | Alert after | 2 consecutive failures |

Both monitors are critical: the UI check confirms developers can reach the portal; the API check confirms the backend controller is running. An outage in either one blocks developer self-service.


Step 3: Monitor Module List API

The most valuable functional check is verifying that Cyclops can list deployed modules. This proves the controller is connected to the Kubernetes API and can read Module resources:

# Test the modules endpoint
curl -s https://cyclops-api.internal.yourdomain.com/api/modules
# Expected: JSON array (possibly empty) with 200 status

Add a Vigilmon monitor for this endpoint:

| Field | Value | |---|---| | Name | Cyclops modules API | | URL | https://cyclops-api.internal.yourdomain.com/api/modules | | Method | GET | | Expected status | 200 | | Response body contains | [ | | Check interval | 5 minutes | | Timeout | 15 seconds |

The response body check for [ confirms the endpoint returns a JSON array, not an error object — a lightweight way to catch API-level failures without needing authentication.


Step 4: Heartbeat Monitor for Module Reconciliation

Module reconciliation is the core Cyclops workflow: when a developer deploys through the UI, the controller picks up the Module change and runs Helm to apply it to the cluster. A stalled controller produces no error visible to the developer — their change is accepted but never applied.

Create a CronJob that deploys a test module and verifies it reconciles:

# cyclops-reconcile-probe.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: cyclops-reconcile-probe
  namespace: cyclops
spec:
  schedule: "*/20 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          serviceAccountName: cyclops-probe-sa
          containers:
            - name: reconcile-probe
              image: bitnami/kubectl:latest
              env:
                - name: HEARTBEAT_URL
                  valueFrom:
                    secretKeyRef:
                      name: vigilmon-secrets
                      key: cyclops-reconcile-heartbeat-url
              command:
                - /bin/sh
                - -c
                - |
                  set -e
                  # Check the cyclops-ctrl deployment is available
                  READY=$(kubectl get deploy cyclops-ctrl -n cyclops \
                    -o jsonpath='{.status.readyReplicas}')
                  DESIRED=$(kubectl get deploy cyclops-ctrl -n cyclops \
                    -o jsonpath='{.spec.replicas}')

                  if [ "$READY" != "$DESIRED" ]; then
                    echo "FAIL: cyclops-ctrl $READY/$DESIRED replicas ready"
                    exit 1
                  fi

                  # Check the CyclopsUI deployment is available
                  UI_READY=$(kubectl get deploy cyclops-ui -n cyclops \
                    -o jsonpath='{.status.readyReplicas}')
                  if [ -z "$UI_READY" ] || [ "$UI_READY" -lt 1 ]; then
                    echo "FAIL: cyclops-ui has no ready replicas"
                    exit 1
                  fi

                  # Check no modules are stuck in error state
                  ERROR_MODULES=$(kubectl get modules --all-namespaces \
                    -o jsonpath='{range .items[*]}{.status.reconciliationStatus.status}{"\n"}{end}' \
                    2>/dev/null | grep -c "error" || true)

                  if [ "$ERROR_MODULES" -gt 2 ]; then
                    echo "FAIL: $ERROR_MODULES modules in error state"
                    exit 1
                  fi

                  wget -qO- "$HEARTBEAT_URL"
                  echo "Cyclops reconciliation heartbeat sent"

Create the RBAC for the probe service account:

# cyclops-probe-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: cyclops-probe-sa
  namespace: cyclops
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cyclops-probe-reader
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list"]
  - apiGroups: ["cyclops-ui.com"]
    resources: ["modules"]
    verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cyclops-probe-reader-binding
subjects:
  - kind: ServiceAccount
    name: cyclops-probe-sa
    namespace: cyclops
roleRef:
  kind: ClusterRole
  name: cyclops-probe-reader
  apiGroup: rbac.authorization.k8s.io

Apply and create the Vigilmon heartbeat monitor:

kubectl apply -f cyclops-probe-rbac.yaml
kubectl apply -f cyclops-reconcile-probe.yaml
  1. Go to Add Monitor → Heartbeat
  2. Name: Cyclops module reconciliation
  3. Expected interval: 20 minutes
  4. Grace period: 5 minutes
  5. Store the heartbeat URL:
kubectl create secret generic vigilmon-secrets \
  --from-literal=cyclops-reconcile-heartbeat-url='https://vigilmon.online/heartbeat/YOUR_TOKEN' \
  -n cyclops

Step 5: Configure Alert Channels

Cyclops downtime is developer-facing — alerts should go to both the platform team (who fix it) and be visible enough that you act quickly.

  1. In Vigilmon: Alert Channels → Add Channel → Slack Webhook
  2. Add your #platform-alerts Slack webhook
  3. Assign it to all Cyclops monitors

For UI downtime (developers are immediately impacted), add a direct Slack channel for the developer experience team:

  1. Add Channel → Slack Webhook
  2. Add your #dev-platform-status channel webhook
  3. Assign it to the Cyclops UI monitor only

This separates operational noise (API and reconciliation issues) from user-facing outages, so the developer experience team can proactively communicate about UI availability.


What You're Now Monitoring

| Component | Monitor Type | What It Detects | |---|---|---| | Cyclops UI | HTTP | Web portal unreachable for developers | | Cyclops controller API /healthz | HTTP | Backend controller pod crash | | Cyclops modules API | HTTP | Controller disconnected from Kubernetes API | | Module reconciliation | Heartbeat (20 min) | Controller stalled, deployments not applying |

With these monitors in place, your platform team knows about Cyclops failures within 2–4 minutes — before developers start filing tickets asking why their deployments aren't applying.


Conclusion

Cyclops shifts Kubernetes complexity from developers to platform teams, but only when it's running reliably. Every minute of Cyclops downtime translates directly to developer friction — deployments blocked, rollbacks delayed, on-call engineers fielding "why isn't my app deploying?" questions. External monitoring with Vigilmon makes Cyclops availability a first-class operational concern, giving your platform team the same visibility into the developer portal that they have into the applications running on top of it.

Get started free at vigilmon.online. The Cyclops UI HTTP monitor takes under two minutes to configure, and the module reconciliation heartbeat gives you coverage for the failure mode that matters most: a working-looking portal where changes silently fail to apply.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →