ClusterMetadata icon
OutputValues icon
Return icon
Switch icon
Log icon
SlackIncomingWebhook icon
Schedule icon

GKE Cluster Health and Observability Compliance Gate

Audit a GKE cluster's node pool health and observability export on a schedule and alert Slack with the exact pools and services affected.

Categories
CloudInfrastructure

A GKE cluster can drift out of a healthy, compliant state in two ways that are each easy to miss: a node pool enters ERROR after a failed upgrade or a quota problem and stays there until someone opens the console, or loggingService and monitoringService get set to none, often as a quick cost cut during a migration, and audit logging silently stops long before a security review notices. This blueprint turns both into one Day 2 governance gate: it reads the cluster's real metadata, classifies what it finds, and alerts Slack with the exact node pool names and service values, never a guess.

This blueprint was created by Mohit Jeswani.

How it works

  1. probe_cluster (io.kestra.plugin.gcp.gke.ClusterMetadata) fetches the cluster's nodePools (each with its real name and status), loggingService, and monitoringService, with allowFailure: true so an unreachable cluster or bad credential does not stop the flow before it can be classified as PROBE_FAILED below.
  2. audit_node_pools (io.kestra.plugin.core.output.OutputValues) splits nodePools into bad_pools (ERROR, RUNNING_WITH_ERROR, or STATUS_UNSPECIFIED) and transitional_pools (PROVISIONING, RECONCILING, or STOPPING), both empty when probe_cluster produced no output at all.
  3. classify_cluster_health (io.kestra.plugin.core.debug.Return) returns PROBE_FAILED, CRITICAL (enough bad_pools to meet unhealthy_node_pool_threshold, or require_observability is true and loggingService or monitoringService, per observability_scope, is none), WARNING (a pool is merely mid-transition), or HEALTHY.
  4. route_by_cluster_health (io.kestra.plugin.core.flow.Switch) branches on that status:
    • HEALTHY: log_healthy logs the node pool count and both service values.
    • WARNING, CRITICAL, PROBE_FAILED: a SlackIncomingWebhook task alerts with the exact node pool names and service values involved, never an invented number.
  5. log_audit_summary always runs last and logs the final classification.
  6. The errors block posts to Slack if the flow itself fails outside the gate logic above.

What you get

  • A real answer to whether every node pool in a cluster is actually healthy, not just whether the cluster API responded.
  • A Slack alert naming the exact failed or transitioning node pools and the exact loggingService and monitoringService values, never an invented number.
  • A compliance check for observability export that catches the common "someone disabled it during a migration and forgot" drift, with the choice of auditing logging, monitoring, or both.

Who it's for

  • Platform and SRE teams who own GKE clusters and need to know about a failed node pool before an on-call page, not after.
  • Security and compliance teams who need proof that audit logging and monitoring export stay enabled on production clusters between formal reviews.
  • Teams evaluating the GCP plugin who want a working example of io.kestra.plugin.gcp.gke.ClusterMetadata.

Why orchestrate this with Kestra

ClusterMetadata is a single point-in-time read, GKE itself has no concept of a schedule, a threshold, or an alert built from what it returns. Kestra adds the recurring check, the node pool classification, the observability compliance check, and a Slack alert built only from the cluster's own reported values, all as one declarative YAML file you can version and review like code.

Prerequisites

  • A GKE cluster and a GCP service account with container.clusters.get permission (the roles/container.viewer role is enough, this blueprint only reads).
  • A Slack incoming webhook for alerts.
  • GKE is a managed Google Cloud service with no self-hostable open-source emulator, there is no local Docker container to start for the cluster itself. This plugin calls the Google Cloud Container API directly from the Kestra worker process, there is no sub-container taskRunner and no Docker network to join.

Secrets

  • GCP_SERVICE_ACCOUNT: service account JSON key used by probe_cluster.

  • SLACK_WEBHOOK_URL: Slack incoming webhook URL used by the alert tasks and the errors block.

    In Kestra OSS, set both as base64-encoded environment variables: SECRET_GCP_SERVICE_ACCOUNT, SECRET_SLACK_WEBHOOK_URL.

Inputs

Input Type Default Allowed values
cluster_project_id STRING my-gcp-project any GCP project ID
cluster_zone STRING us-central1-a any GKE zone or region
cluster_id STRING production-cluster any GKE cluster name
unhealthy_node_pool_threshold INT 1 any non-negative integer
require_observability BOOL true true, false
observability_scope SELECT both logging, monitoring, both

Quick start

  1. Create a GCP service account with roles/container.viewer on the project.
  2. Add the GCP_SERVICE_ACCOUNT and SLACK_WEBHOOK secrets.
  3. Set cluster_project_id, cluster_zone, and cluster_id to a real cluster and run this flow manually.
  4. Read log_audit_summary for the classification.
  5. Enable the hourly trigger.

How to extend

  • Read outputs.probe_cluster.masterAuth to compare the cluster's CA certificate against a known-good value and flag a private cluster whose control plane certificate rotated unexpectedly.
  • Add a second probe for a second cluster and reuse the same classification logic to watch a whole fleet from one flow.
  • Chain a downstream task after CRITICAL on a failed node pool that opens a ticket with the exact pool name already filled in, instead of only alerting Slack.

Pitfalls

  • PROVISIONING, RECONCILING, and STOPPING are normal during a planned upgrade or resize, this blueprint reports them as WARNING, not CRITICAL, specifically so a routine maintenance window does not page anyone.
  • loggingService and monitoringService default to GKE's own managed values on a correctly configured cluster, only an explicit none is a violation, an empty or null value from a very old cluster API version is not the same thing and is not checked here.
  • The service account only needs read access. This blueprint never calls an API that modifies the cluster, there is no remediation step because the Kestra GKE plugin has no task to drain, resize, or recreate a node pool, that has to be done with gcloud or the console.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.