auto-syncing kubernetes ingress to uptime monitors
i keep forgetting to add uptime monitors when i deploy new services. so i wrote a cronjob that does it for me.
wfd · 2026-02-28T02:01:00 · 3 min
css columns ruined my portfolio grid
CSS columns fill top-to-bottom, which breaks reading order. I built a manual masonry system that fills left-to-right instead.
wfd · 2025-10-06T05:28:00 · 2 min
github.com
stakater/IngressMonitorController
from auto-syncing kubernetes ingress to uptime monitors
unfolding paper…
wfd / Feb 28, 2026 / 3 min
auto-syncing kubernetes ingress to uptime monitors
Stub
i haven't finished writing this yet. i publish drafts early as part of WFD 17.
i keep forgetting to set up uptime monitors. i'll deploy something, move on, and two weeks later realize it's been unreachable because i never added it to the dashboard. it takes two minutes to add one manually. i just never remember.
so i wrote a cronjob that watches my kubernetes ingress resources, diffs them against existing monitors, and creates whatever's missing. it runs every five minutes. i don't have to think about it anymore.
how it works
a shell script mounted into a kubernetes cronjob via a configmap. it talks to an external uptime API.
deployment
flowchart LR
tf_values["values.yaml"] -->|"loaded into"| tf_helm["helm_release"]
tf_secret["kubernetes_secret (api_token)"] -->|"depends_on"| tf_helm
tf_helm -->|"deploys"| cj["CronJob (*/5 * * * *)"]
cm["ConfigMap (sync.sh)"] -->|"mounted into"| cj
secret["Secret (API_TOKEN)"] -->|"env var"| cj
sa["ServiceAccount (ingresses: get, watch, list)"] -->|"identity for"| cj
if a host's /health endpoint returns 200 with something recognizable ("status": "ok" or similar), it creates a keyword monitor that checks for that string. otherwise it falls back to a basic status monitor on the root URL. keyword monitors are better because a service can return 200 while being functionally broken.
the script checks both root and /health URLs before creating anything, so it's idempotent. if the API token is missing it exits cleanly instead of erroring. it also rate-limits API calls between creates.
the pod runs non-root with a read-only filesystem and all capabilities dropped. concurrencyPolicy: Forbid prevents overlapping runs.
stakater already did this
stakater/IngressMonitorController is a full kubernetes operator for this exact problem. 715 stars, Apache-2.0, supports eight providers including UptimeRobot, StatusCake, and Pingdom. uses a custom EndpointMonitor CRD.
IngressMonitorController
my cronjob
approach
operator with CRDs
shell script in a cronjob
providers
8
1
discovery
opt-in per service via CRD
automatic from ingress resources
health probing
no
yes (keyword monitors)
complexity
full operator lifecycle
one script, one configmap
the key difference is opt-in vs opt-out. their operator requires you to create an EndpointMonitor resource for each service you want monitored. mine monitors everything in the namespace by default. adding new providers to theirs also means writing Go and contributing upstream.
the tradeoff is that mine is less robust. 5-minute polling instead of event-driven, single provider, and it doesn't clean up monitors when i delete an ingress.
arguments against
stakater's operator already exists and is battle-tested
a shell script in a cronjob is not serious infrastructure
adding a monitor manually takes two minutes
arguments for
i don't want to deploy a full operator for this
i don't want to create a CRD every time i deploy something new
i have a handful of services and i keep forgetting
this might grow into something better or it might stay as a script that scratches an itch. haven't decided yet.