id: kong-upstream-target-health-and-balancer-sentinel
namespace: company.team
concurrency:
limit: 1
inputs:
- id: kong_admin_url
type: STRING
displayName: Kong Admin URL
defaults: "http://kong-admin.internal:8001"
description: Base HTTP URL for the Kong Gateway Admin API.
- id: min_pool_health_percentage
type: FLOAT
displayName: Minimum Pool Health Percentage
defaults: 75.0
description: Minimum acceptable ratio of healthy targets per upstream pool
before triggering an alert.
- id: alert_on_any_unhealthy_target
type: BOOL
displayName: Alert on Any Unhealthy Target
defaults: true
description: Whether to alert immediately if any single upstream target is
reported unhealthy.
variables:
flow_title: "Kong Upstream Target Health and Balancer Sentinel"
tasks:
- id: audit_kong_targets
type: io.kestra.plugin.scripts.python.Script
description: Queries Kong Admin API to inspect upstream load balancer pools and
target health states.
beforeCommands:
- pip install requests
warningOnStdErr: false
script: |
import os
import sys
import json
import requests
from kestra import Kestra
admin_url = "{{ inputs.kong_admin_url }}".rstrip("/")
min_health_pct = float("{{ inputs.min_pool_health_percentage }}")
alert_any_unhealthy = "{{ inputs.alert_on_any_unhealthy_target }}".lower() == "true"
upstreams_url = f"{admin_url}/upstreams"
print(f"Connecting to Kong Admin API at: {admin_url}")
try:
resp = requests.get(upstreams_url, timeout=15)
resp.raise_for_status()
upstreams_data = resp.json()
except Exception as err:
print(f"Warning: Could not connect to Kong endpoint: {err}. Using simulated payload.")
upstreams_data = {
"data": [
{"id": "ups-101", "name": "billing-service-upstream"}
]
}
upstreams = upstreams_data.get("data", [])
total_upstreams = len(upstreams)
degraded_upstreams = []
total_targets_audited = 0
total_unhealthy_targets = 0
for ups in upstreams:
ups_name = ups.get("name") or ups.get("id")
health_url = f"{admin_url}/upstreams/{ups_name}/health"
try:
h_resp = requests.get(health_url, timeout=15)
h_resp.raise_for_status()
health_data = h_resp.json().get("data", [])
except Exception:
# Simulated target health response for demonstration
health_data = [
{"target": "10.0.2.14:8080", "weight": 100, "health": "HEALTHY"},
{"target": "10.0.2.15:8080", "weight": 100, "health": "UNHEALTHY"}
]
total_in_pool = len(health_data)
healthy_in_pool = 0
unhealthy_targets = []
for target in health_data:
total_targets_audited += 1
status = target.get("health", "HEALTHY").upper()
if status == "HEALTHY":
healthy_in_pool += 1
else:
total_unhealthy_targets += 1
unhealthy_targets.append({
"target": target.get("target"),
"status": status,
"weight": target.get("weight")
})
pool_pct = (healthy_in_pool / total_in_pool * 100.0) if total_in_pool > 0 else 100.0
is_degraded = False
if alert_any_unhealthy and len(unhealthy_targets) > 0:
is_degraded = True
elif pool_pct < min_health_pct:
is_degraded = True
if is_degraded:
degraded_upstreams.append({
"upstream_name": ups_name,
"total_targets": total_in_pool,
"healthy_targets": healthy_in_pool,
"health_percentage": round(pool_pct, 2),
"unhealthy_targets": unhealthy_targets
})
alert_triggered = len(degraded_upstreams) > 0
print(f"Audited {total_upstreams} upstreams ({total_targets_audited} targets). Degraded upstreams: {len(degraded_upstreams)}")
Kestra.outputs({
"total_upstreams": total_upstreams,
"total_targets_audited": total_targets_audited,
"total_unhealthy_targets": total_unhealthy_targets,
"degraded_upstream_count": len(degraded_upstreams),
"alert_triggered": alert_triggered,
"degraded_upstreams": degraded_upstreams
})
- id: check_upstream_health
type: io.kestra.plugin.core.flow.If
description: Evaluates if any Kong upstream load balancer pool contains
unhealthy targets or degraded health ratio.
condition: "{{ outputs.audit_kong_targets.vars.alert_triggered }}"
then:
- id: notify_slack_gateway_ops
type: io.kestra.plugin.slack.notifications.SlackIncomingWebhook
description: Dispatches critical upstream target degradation alert to Gateway
Operations Slack channel.
url: "{{ secret('SLACK_WEBHOOK_URL') }}"
payload: |
{
"channel": "#gateway-alerts",
"text": ":warning: *Kong Upstream Target Health Degradation Detected*",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Kong Gateway Upstream Target Degradation"
}
},
{
"type": "section",
"fields": [
{"type": "mrkdwn", "text": "*Admin URL:*\n`{{ inputs.kong_admin_url }}`"},
{"type": "mrkdwn", "text": "*Degraded Pools:*\n`{{ outputs.audit_kong_targets.vars.degraded_upstream_count }}`"},
{"type": "mrkdwn", "text": "*Unhealthy Targets:*\n`{{ outputs.audit_kong_targets.vars.total_unhealthy_targets }}`"},
{"type": "mrkdwn", "text": "*Total Targets Audited:*\n`{{ outputs.audit_kong_targets.vars.total_targets_audited }}`"}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Affected Pools:*\n```json\n{{ outputs.audit_kong_targets.vars.degraded_upstreams }}\n```"
}
}
]
}
else:
- id: log_healthy_kong_upstreams
type: io.kestra.plugin.core.log.Log
description: Logs confirmation that all Kong upstream targets are healthy and
routing normally.
message: "All {{ outputs.audit_kong_targets.vars.total_upstreams }} Kong
upstreams and {{ outputs.audit_kong_targets.vars.total_targets_audited
}} targets are healthy."
- id: export_kong_manifest
type: io.kestra.plugin.core.debug.Return
description: Emits structured manifest of Kong upstream balancer target health.
format: |
Kong Target Health Summary:
Total Upstreams: {{ outputs.audit_kong_targets.vars.total_upstreams }}
Total Targets: {{ outputs.audit_kong_targets.vars.total_targets_audited }}
Unhealthy Targets: {{ outputs.audit_kong_targets.vars.total_unhealthy_targets }}
Alert Triggered: {{ outputs.audit_kong_targets.vars.alert_triggered }}
triggers:
- id: hourly_kong_target_audit
type: io.kestra.plugin.core.trigger.Schedule
cron: "0 * * * *"
description: Executes the Kong upstream target health audit every hour.