New to Kestra?
Use blueprints to kickstart your first workflows.
Audit InfluxDB buckets for infinite retention with Flux buckets(), alert on breach, and optionally bound retention via the REST API.
InfluxDB documents retention period 0 as a deliberate, named setting: infinite
retention, data kept forever. That is sometimes exactly what you want - and
sometimes a bucket created for a quick test that nobody ever bounded, quietly
accumulating data and cost indefinitely. Nothing in InfluxDB itself flags that for
you. This blueprint runs Flux's own buckets() introspection function, finds every
bucket with retentionPeriod == 0, alerts Slack on breach, and can bound that
bucket's retention to a configured number of days through InfluxDB's own REST API -
never deleting existing data, only shortening the window going forward.
periodic_retention_check (io.kestra.plugin.core.trigger.Schedule) runs every 6 hours, always forcing auto_remediate: "false" and dry_run: "true" through its own inputs: override regardless of this flow's defaults. Shipped disabled so you can validate a manual run first.audit_bucket_retention (io.kestra.plugin.influxdb.FluxQuery) runs buckets() with fetchType: STORE, returning a uri to the stored result - each row carrying name, id, organizationID, retentionPolicy, and retentionPeriod (nanoseconds).evaluate_retention_risk (io.kestra.plugin.scripts.python.Script) reads that stored result and collects every bucket whose retentionPeriod is exactly 0, emitting infinite_count and infinite_buckets through Kestra.outputs.evaluate_retention_gate (io.kestra.plugin.core.flow.If) flags a breach whenever infinite_count > max_infinite_retention_buckets.then (breach): route_remediation (io.kestra.plugin.core.flow.Switch on auto_remediate) either considers remediation ("true", gated again by dry_run through check_dry_run) or only logs that remediation is disabled ("false"). When both gates allow it, bound_bucket_retention (io.kestra.plugin.core.flow.Loop) runs patch_bucket_retention (io.kestra.plugin.core.http.Request, PATCH /api/v2/buckets/{id}) for each flagged bucket, setting retentionRules to remediation_retention_days. alert_retention_risk always fires to Slack regardless of which path ran.else (compliant): log_retention_healthy records a clean check.log_audit_complete always runs last, printing the headline numbers regardless of which branch fired.errors block alerts Slack separately if the flow itself fails - an unreachable instance or an invalid token must not read as "no breach".buckets() function, not inferred from dashboards or configuration files.auto_remediate, dry_run) between "breach detected" and "retention actually bounded".FluxQuery against Flux's own introspection functions, beyond writing and reading measurement data.buckets() is a live, read-only snapshot; running it by hand in the InfluxDB UI answers one moment in time and fixes nothing. Kestra supplies the schedule, the risk classification as a first-class branch, two independent authorization gates before anything is patched, and an execution history that shows exactly when a bucket was created with infinite retention and whether it was bounded.
Local testing:
docker run -d --name influxdb-retention-sentinel -p 8087:8086 influxdb:2
docker network connect YOUR_KESTRA_NETWORK influxdb-retention-sentinel (only needed if the Kestra Worker runs in a separate Docker network than this container; set INFLUXDB_URL to http://influxdb-retention-sentinel:8086 from inside that network, or http://localhost:8087 from the host). Complete the container's first-run setup (org, bucket, token) via influx setup or the UI before running this flow; a freshly-created bucket with no retention flag set is exactly the infinite-retention case this blueprint audits.
INFLUXDB_URL: InfluxDB base URL, matching this plugin's own documented connection pattern (see influxdb-load-query-data.yaml).INFLUXDB_TOKEN: InfluxDB API token used both by FluxQuery and, if remediation runs, the REST API patch - must have read access to buckets and, for remediation, write/admin access.SLACK_WEBHOOK_URL: Slack incoming webhook used by alert_retention_risk and the errors block.SECRET_, base64-encoded, and read back in flows with {{ secret('NAME') }} - for example SECRET_INFLUXDB_TOKEN=$(echo -n '<your-influxdb-token>' | 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.influxdb_org (STRING, default my-org): organization whose buckets are audited.max_infinite_retention_buckets (INT, default 0): breach threshold; 0 means any infinite-retention bucket at all breaches.remediation_retention_days (INT, default 90): bounded retention applied when remediation runs.auto_remediate (SELECT: "false", "true"; default "false"): must be "true" for the patch to even be considered.dry_run (SELECT: "true", "false"; default "true"): must be explicitly "false", together with auto_remediate: "true", for the bucket to actually be patched.outputs.audit_bucket_retention.uri: the raw stored buckets() result for every run.outputs.evaluate_retention_risk.vars.infinite_count / .infinite_buckets: the computed risk result for every run.INFLUXDB_URL, INFLUXDB_TOKEN, and SLACK_WEBHOOK_URL secrets.auto_remediate: "false") and confirm alert_retention_risk fires naming the expected bucket, and that log_remediation_disabled logs without patching anything.auto_remediate: "true" and dry_run: "true" and confirm log_dry_run_remediation describes the patch without applying it.auto_remediate: "true" and dry_run: "false" and confirm via the InfluxDB UI or GET /api/v2/buckets/{id} that the bucket's retentionRules now shows everySeconds matching remediation_retention_days * 86400.periodic_retention_check once you trust the check; it always runs in the safe auto_remediate: "false" / dry_run: "true" mode regardless of what you leave the flow's own defaults set to.influxdb_org values with io.kestra.plugin.core.flow.Loop (ForEach is deprecated) to sweep a multi-org instance in one run.evaluate_retention_risk to also flag buckets above a maximum retention ceiling, not just infinite ones, for organizations with an upper-bound compliance policy instead of (or in addition to) a lower bound.Pause approval task instead of (or alongside) the static auto_remediate input, for a human-reviewed patch on production organizations._monitoring, _tasks) from the audit by filtering on name in evaluate_retention_risk, if your organization's policy only targets user-created buckets.FluxQuery, InfluxQLQuery, Load, Write (plus a FluxTrigger trigger) - none expose bucket retention as a settable property. Remediation calls InfluxDB's own documented PATCH /api/v2/buckets/{id} REST endpoint directly through the core io.kestra.plugin.core.http.Request task instead.Authorization: Token <token>, not Bearer. Verified from InfluxDB's own API authentication documentation; using Bearer here would authenticate against the wrong scheme and fail.FluxQuery's STORE output was not confirmed against a live instance. evaluate_retention_risk's script defensively handles both a bare row list and a {"rows": [...]}-wrapped shape, but this has not been exercised against a running InfluxDB server in this environment.retentionPeriod == 0 is InfluxDB's own documented meaning for infinite retention, confirmed from the InfluxDB v2 API reference's equivalent everySeconds field ("0 represents infinite retention") - this is not an assumption invented for this blueprint.auto_remediate and dry_run are independent gates, not a single boolean. Both must be "true"/"false" respectively for the patch Loop to run; setting only one leaves the other still blocking.Switch case keys "true"/"false" are quoted strings. auto_remediate renders as the literal string "true" or "false"; unquoted true:/false: YAML map keys would parse as booleans instead and would not match.