List icon
OutputValues icon
If icon
SlackIncomingWebhook icon
Loop icon
Delete icon
Fail icon
Log icon
Schedule icon

Huawei OBS Stale Object Retention Sentinel

Scan a Huawei OBS prefix for objects past retention, alert Slack with reclaimable bytes, and optionally delete and verify the stale ones.

Categories
CloudInfrastructure

Temporary exports, staging landing zones and old job output tend to accumulate in object storage because nothing ever looks back at them. Huawei OBS has lifecycle rules, but they are bucket-wide or prefix-wide console configuration with no review step and no record of what they actually deleted on a given day. This blueprint does the same job as a flow: list what's under a prefix, decide what's stale from lastModified, alert on what it found, and, only when you ask it to, delete exactly those objects and prove they are gone.

This blueprint was created by Mohit Jeswani.

How it works

  1. list_stale_candidates (io.kestra.plugin.huawei.obs.List) lists every object under prefix in bucket, optionally narrowed further by regexp. Read-only.
  2. evaluate (io.kestra.plugin.core.output.OutputValues) compares each object's lastModified date against now() - retention_days and produces the stale object list, their count, their total size in bytes, and a severity.
  3. route (io.kestra.plugin.core.flow.If):
    • compliant: logs that nothing is past retention.
    • alert: posts the stale count and reclaimable bytes to Slack.
      • remediate_gate runs only when auto_cleanup is true and dry_run is false.
      • cleanup (io.kestra.plugin.core.flow.Loop, concurrencyLimit: 1) calls io.kestra.plugin.huawei.obs.Delete once per stale key, never the whole prefix, so an object that is not actually stale is never touched.
      • reread lists the prefix again, and verify_result fails the flow if any object past retention_days is still there.
  4. summary logs the stale count, reclaimable bytes and severity, closing the governance cycle.
  5. errors alerts Slack if the flow itself fails, for example on an expired AK/SK.

What you get

  • A Slack alert with a number, not a guess, the exact count and byte total of what is sitting past retention under a prefix.
  • Deletion that only ever removes the objects the same run identified as stale, never a prefix-wide wipe.
  • A verified record, in the execution's own logs, that cleanup actually emptied out what it claimed to.

Who it's for

  • Platform and data teams who land temporary exports or staging files in Huawei OBS and have no process catching the ones nobody cleaned up.
  • Teams evaluating the Huawei Cloud plugin who want a worked example of obs.List and obs.Delete used together safely.
  • FinOps-minded teams who want object storage cost creep visible before the monthly bill, not after.

Why orchestrate this with Kestra

An OBS lifecycle rule is silent: it runs in the background with no alert, no count of what it removed, and no easy way to preview the impact before enabling it. Kestra keeps retention_days and the prefix as flow inputs, reports what it found before anything is deleted, requires two separate flags to actually delete, and leaves a full execution history of every run, compliant or not, remediated or not.

Prerequisites

  • A Huawei Cloud account with OBS enabled and a bucket already created.
  • An AK/SK pair (IAM access key and secret key) with OBS read permission, and delete permission on the bucket if auto_cleanup is ever enabled.
  • A Slack incoming webhook URL.

This flow calls the Huawei Cloud OBS API directly over HTTPS; there is no official local Huawei Cloud emulator. OBS is S3-API compatible, so List and Delete can be pointed at a local MinIO container via endpointOverride and pathStyleAccess: true for a dry run of the logic, but the actual lastModified ages used to prove retention_days need real aged objects, which is easiest against a real trial-tier OBS bucket.

Secrets

  • HUAWEI_AK: the IAM access key used by every OBS task in this flow. In Kestra OSS, provide it as the base64-encoded environment variable SECRET_HUAWEI_AK.
  • HUAWEI_SK: the IAM secret key paired with HUAWEI_AK. In Kestra OSS, provide it as the base64-encoded environment variable SECRET_HUAWEI_SK.
  • SLACK_WEBHOOK_URL: used by alert and the errors block. In Kestra OSS, provide it as the base64-encoded environment variable SECRET_SLACK_WEBHOOK_URL.

Inputs

Input Type Default Purpose
region STRING eu-west-101 Huawei Cloud region used to sign OBS requests
bucket STRING <your-obs-bucket> Bucket to scan
prefix STRING tmp/ Only objects under this prefix are scanned
regexp STRING empty Optional extra key filter, applied after the prefix
retention_days INT 30 Age past which an object is reported stale
auto_cleanup BOOL false Allow deleting the stale objects found this run
dry_run BOOL true Must be false for Delete to run

Outputs

  • {{ outputs.list_stale_candidates.objects }}: every object under the prefix, each with key, size, lastModified, etag, owner.
  • {{ outputs.evaluate.values.stale_count }} / {{ outputs.evaluate.values.stale_size_bytes }}: how many objects are past retention and their combined size.
  • {{ outputs.evaluate.values.severity }}: OK or STALE_OBJECTS_FOUND.
  • {{ outputs.reread.objects }}: only present after a cleanup run, the post-delete listing used to verify.

Pitfalls

  • prefix is the entire blast radius for auto_cleanup. A prefix of "" scans and can delete the whole bucket; scope it narrowly.
  • Staleness is judged by lastModified, the last write time, not by when an object was created or first accessed. An object rewritten in place resets its own clock.
  • List iterates every page under the prefix into memory before evaluate runs; a prefix with millions of keys should be narrowed further or should set maxResults on list_stale_candidates directly.
  • The AK/SK pair needs OBS delete permission only if auto_cleanup is ever turned on; keep it read-only otherwise.
  • OBS versioned buckets do not free space on delete without a versionId: Delete places a delete marker instead of removing the object. Pass a lifecycle rule or a separate purge for versioned buckets.

Quick start

  1. Add the HUAWEI_AK, HUAWEI_SK and SLACK_WEBHOOK_URL secrets.
  2. Set bucket and prefix to a real location you expect to accumulate temporary objects.
  3. Run the flow once with the defaults and read the stale count in summary.
  4. Set auto_cleanup: true and dry_run: false on a non-production prefix first, confirm verify_result logs remediated, then apply the same change to production.
  5. Enable the schedule_daily_at_0230 trigger, which always runs in safe mode until you change its mapped inputs.

How to extend

  • Narrow by owner or by a key pattern in regexp to scope cleanup to one team's exports.
  • Replace Delete in the cleanup loop with a copy-then-delete into a cheaper storage class if Huawei OBS exposes one for your bucket, instead of removing the object outright.
  • Track stale_size_bytes over time by logging it to a table with io.kestra.plugin.core.output.OutputValues on every scheduled run, compliant or not.
  • Point this at several prefixes with io.kestra.plugin.core.flow.Loop around the whole flow to cover a fleet of staging locations in one schedule.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.