New to Kestra?
Use blueprints to kickstart your first workflows.
Audit a Dataflow job for JOB_STATE_FAILED or JOB_STATE_CANCELLED and alert Slack on breach or an unreachable Dataflow API.
A Dataflow pipeline that fails does not necessarily page anyone - Dataflow's own
console shows the job's state, but nothing watches it on a schedule unless a
Cloud Monitoring alert was deliberately wired up for that specific job. This blueprint
reads a Dataflow job's currentState through GetJob, Google's own documented 15-value
JobState enum, flags JOB_STATE_FAILED or JOB_STATE_CANCELLED, and alerts Slack the
moment that happens or the Dataflow API itself cannot be reached.
periodic_job_check (io.kestra.plugin.core.trigger.Schedule) runs every 30 minutes, shipped disabled so you can validate a manual run first.probe_job_status (io.kestra.plugin.gcp.dataflow.GetJob, allowFailure: true) reads job_id's currentState.evaluate_job_health (io.kestra.plugin.core.debug.Return) classifies UNREACHABLE (currentState undefined), AT_RISK (JOB_STATE_FAILED or JOB_STATE_CANCELLED), or HEALTHY (every other documented state, including in-progress ones).route_by_health (io.kestra.plugin.core.flow.Switch) branches on that classification: HEALTHY logs the current state, AT_RISK pages Slack naming the failed state, UNREACHABLE pages Slack that the API could not be reached, and the defaults: block catches any unexpected classification value.log_audit_complete always runs last, printing the classification regardless of which branch fired.errors block alerts Slack separately if the flow itself fails outside these handled branches.JobState enum rather than an inferred signal from downstream data freshness.HEALTHY/AT_RISK/UNREACHABLE) so a broken audit (bad credentials, an invalid job ID) is never mistaken for a healthy job.job_id.GetJob used as a standing health check.GetJob is a single read with no memory of the last check and no notification path of its own. Kestra supplies the schedule, the risk classification as a first-class branch, and an execution history that shows exactly when a job first failed and how long it took anyone to notice.
dataflow.jobs.get permission.Local testing: Google Cloud Dataflow is a fully managed, serverless service with no official self-hosted or local emulator - Dataflow jobs run on Google's own managed workers, not in a container you control. Validate this flow against a real GCP project and a real (even minimal, quick-to-finish) Dataflow job rather than attempting a fully local run - this has not been exercised in this environment.
GCP_PROJECT_ID / GCP_SERVICE_ACCOUNT: GCP credentials used by GetJob, matching this plugin's own documented connection pattern (see this repo's other GCP blueprints, for example gcs-object-encryption-compliance-gate.yaml).SLACK_WEBHOOK_URL: Slack incoming webhook used by alert_at_risk, alert_unreachable, and the errors block.SECRET_, base64-encoded, and read back in flows with {{ secret('NAME') }} - for example SECRET_GCP_SERVICE_ACCOUNT=$(echo -n '<your-service-account-json>' | base64). This keeps credentials out of the flow YAML but, per Kestra's own documentation, offers no encryption at rest or access control beyond the host environment; use the Enterprise secrets backend for stronger guarantees.job_id (STRING, default "sample-dataflow-job-01"): Dataflow job audited.location (STRING, default us-central1): regional endpoint for the job.outputs.probe_job_status.currentState / .createTime / .currentStateTime / .metrics: the audited job's own fields for every successful call.outputs.evaluate_job_health.value: HEALTHY, AT_RISK, or UNREACHABLE for every run.job_id and location.GCP_PROJECT_ID, GCP_SERVICE_ACCOUNT, and SLACK_WEBHOOK_URL secrets.log_healthy fires.job_id at a job you know failed (an intentionally broken template is an easy way to produce one in a test project) and re-run; confirm alert_at_risk fires naming JOB_STATE_FAILED.periodic_job_check once you trust the check.job_id values with io.kestra.plugin.core.flow.Loop to audit every critical pipeline in a project in one pass.currentStateTime against now() to also flag a job stuck in JOB_STATE_RUNNING far longer than expected, a distinct kind of risk from an outright failure - this blueprint deliberately keeps to terminal-state detection only, to avoid date-arithmetic logic that was not verified against a live Dataflow job in this environment.LaunchTemplate/LaunchFlexTemplate task (via a Subflow call passing through the new job's jobId) for same-execution failure detection on a critical pipeline launch, instead of waiting for the next scheduled sweep.io.kestra.plugin.gcp.dataflow.CancelJob (verified real, with a drain option for a graceful stop) behind the same double-gated auto_remediate/dry_run pattern this repo's other sentinels use - deliberately not attempted here, since JOB_STATE_FAILED/JOB_STATE_CANCELLED are both already-terminal states with nothing left to cancel.JOB_STATE_FAILED and JOB_STATE_CANCELLED are both terminal per Google's own API reference - there is nothing left to cancel or drain on a job already in either state. CancelJob is a real, verified task in this plugin, but it is only meaningful against a job still in a non-terminal state, which is a different audit than the one this blueprint runs; see How to extend.JobState has 15 documented values, not just the four most people name. Verified against Google Cloud's own Dataflow REST API reference: JOB_STATE_UNKNOWN, JOB_STATE_STOPPED, JOB_STATE_RUNNING, JOB_STATE_DONE, JOB_STATE_FAILED, JOB_STATE_CANCELLED, JOB_STATE_UPDATED, JOB_STATE_DRAINING, JOB_STATE_DRAINED, JOB_STATE_PENDING, JOB_STATE_CANCELLING, JOB_STATE_QUEUED, JOB_STATE_RESOURCE_CLEANING_UP, JOB_STATE_PAUSING, JOB_STATE_PAUSED. This blueprint only treats JOB_STATE_FAILED/JOB_STATE_CANCELLED as a breach; every transitional and successful state is HEALTHY.allowFailure: true is what lets UNREACHABLE be classified instead of failing the execution outright. A base Task property, not specific to this plugin; without it, an invalid jobId or missing IAM permission would abort the flow before evaluate_job_health ever runs.Switch case keys are quoted strings matching the classifier's exact output. "HEALTHY", "AT_RISK", and "UNREACHABLE" must match evaluate_job_health.value verbatim; the defaults: block exists specifically to catch any value that does not match one of those three cases.GetJob against the wrong location returns a 404/not-found from the Google Cloud Dataflow API, which this flow classifies as UNREACHABLE. Verify the job's exact regional location in the GCP Console before configuring the input.