Skip to content
Cloud Native Pulse
Release v0.9.53.0 2 October 2026 · 8 min read

The Roomba for Your Cloud Learns New Floors

Cloud Custodian · release

Cloud Custodian logo

Cloud Custodian 0.9.53.0 just gave your cloud a much bigger broom. If you have never met the project: Cloud Custodian is an open-source rules engine that lets you write simple YAML policies that find, tag, clean up, and enforce rules on your cloud resources across AWS, Azure, and GCP. Think of it as a Roomba for your cloud bill and your security posture: you write the rules once, and it quietly wanders around your accounts deleting forgotten junk, slapping tags on unlabeled servers, and flagging anything that breaks policy. Platform teams, security folks, and anyone who has ever opened a cloud console and muttered “who left this here?” use it daily.

This release matters because Custodian can now govern a whole lot more of your world: every custom resource (CRD) in your Kubernetes clusters, your growing pile of AI services, the new S3 lakehouse formats, and even Google Workspace users who skipped MFA.

What’s New in 0.9.53.0

The short version: Custodian grew 23 new resource types and a stack of new filters and actions, spread across AWS, Azure, GCP, and Kubernetes. The long version is better. Here are the four stories worth your time.

Kubernetes: Policies for Any Custom Resource, No Plugin Required

This is the headline. Custodian’s Kubernetes support historically knew about a fixed list of resource types: if your platform ran on custom resources, the engine was blind to them until someone wrote support upstream.

The new k8s custom-resource type changes that: it discovers any installed CRD at scan time and lists that CRD’s instances too. Neither the definition nor the instances need to be declared ahead of time.

Why care? Because platform teams run their real infrastructure on CRDs: databases, cert-manager certificates, Argo applications, internal abstractions. Policy-as-code could not touch any of it without bespoke plugin work.

Now a single generic resource type covers all of them, today and for every CRD you install next year. Your governance rules finally speak your platform’s language.

Building it turned up a real bug: on CRDs with many objects, listing silently stopped after the first page of results. The fix (PR #11081) ships in this release too, verified against a real cluster by the custom-resource author (PR #11083).

The exact identifier is k8s.custom-resource. Every discovered CRD’s instances land under that single resource type, each tagged with the identity of the CRD it came from — crd_group, crd_version, crd_plural, crd_scope — so you scope by CRD identity in a plain value filter (the project’s own test suite uses Karpenter NodePools as the worked example):

code
policies:
  - name: audit-karpenter-nodepools
    resource: k8s.custom-resource
    filters:
      - type: value
        key: crd_group
        value: karpenter.sh

A filters: block is optional — with none, you simply get every custom resource in the cluster. Implementation and tests: PR #11083.

AI Sprawl Gets a Custodian Policy

Your company’s AI footprint grew this year. Its governance did not. 0.9.53.0 quietly closes that gap with a batch of AI-surface resources: five Q Business resource types (application, index, plugin, data accessor, data source), an AIOps investigation group resource, and a new deployments filter for Bedrock custom models that finds Active models older than 14 days that are serving exactly nothing:

code
policies:
  - name: bedrock-undeployed-custom-models
    resource: aws.bedrock-custom-model
    filters:
      - type: value
        key: modelStatus
        value: Active
      - type: value
        key: creationTime
        op: gt
        value_type: age
        value: 14
      - type: deployments
        status: Active
        value: absent

That is a policy for custom models that are billing you for storage while doing absolutely nothing. The filter queries ListCustomModelDeployments for each model and can require a deployment to be present or absent, optionally scoped by deployment status. The Q Business resources ship with a cross-account filter on applications and universal tagging on everything. See PR #10944 for the Bedrock filter and PR #10990 for Q Business.

S3 Tables and S3 Files: The Lakehouse Joins the Party

AWS’s newer storage formats now have first-class support. S3 Tables (the Iceberg-native table store) get two resources: aws.s3-table-bucket and aws.s3-table, with cross-account filters that evaluate table bucket and table policies, plus has-statement and replication filters, and tag, remove-tag, and mark-for-op (tag a resource now for a delayed action later) actions. S3 Files adds three more: aws.s3files-file-system, aws.s3files-mount-target, and aws.s3files-access-point, with cross-account and has-statement on file systems, plus subnet, security-group, and network-location filters on mount targets.

Every filter and action here is the standard Custodian set, pointed at the new lakehouse types — for example, flag S3 Tables shared outside your org:

code
policies:
  - name: s3tables-shared-outside-org
    resource: aws.s3-table
    filters:
      - type: cross-account
        whitelist_org_ids:
          - o-your-org-id

Both new types carry the full filter and action set listed above, so inventory and remediation work the same as on any other Custodian resource.

If your data platform team just discovered that “temporary” analytics buckets live forever, these are for you. The work landed in PR #10973 (Tables) and PR #10972 (Files).

Google Workspace MFA Reporting

A first for the project: gcp.workspace-user lets policies report Google Workspace users who have not enrolled in two-step verification. This is enabling work for the CIS GCP Benchmark control that requires MFA for all non-service accounts, and it matters technically because Workspace users are not GCP resources at all: they live in Cloud Identity, are read through the Admin SDK Directory API, and are authorized by domain-wide delegation rather than GCP IAM. Custodian’s session layer had to learn all of that. The policy is exactly as simple as you hope:

code
policies:
  - name: gcp-workspace-users-without-mfa
    resource: gcp.workspace-user
    filters:
      - type: value
        key: isEnrolledIn2Sv
        value: false
      - type: value
        key: suspended
        value: false

Full details, including the operational prerequisites — domain-wide delegation with an impersonated Workspace admin, GOOGLE_WORKSPACE_SUBJECT, and customer scoping via GOOGLE_WORKSPACE_CUSTOMER (defaulting to my_customer) — in PR #10950. A follow-up will add auditing of security-key usage.

Also worth a look: an API Gateway v2 route resource, a Vertex AI metadata-store artifact resource, IoT expansion (certificates, OTA updates, policies — PR #11098), SSM tagging everywhere (tag, remove-tag, mark-for-op on SSM-managed instances — the hybrid mi-* kind; EC2 i-* instances already tag via EC2 — plus ops items, patch baselines, maintenance windows, and associations — PR #11093), rds-global-cluster and event-connection resources, surfacing notifications and a filter expression on AWS Budgets (PR #11116), Azure ML archive and cancel actions, an Azure NSG remove-rules action, a GCP KMS cryptokey update action, and parent-scoped dimensions in the Azure metric filter.

The Quiet Core Upgrades

Two core changes did not get their own story above but deserve a look. --vars-file (PR #10939) lets you inject variables at custodian run time without editing your policy files — the same mechanism c7n-org (Custodian’s multi-account runner) uses for account vars, finally available in the main CLI. Your vars-file entries are expanded first, then the standard framework variables (like account_id and region) are layered on top, so built-ins always win:

code
custodian run -s out policy.yml --vars-file vars.yml

vars.yml is plain key-value YAML — the PR author’s own use case was a source_region for notification queues that live in a different region than the one being scanned:

code
# vars.yml
source_region: us-east-1

Reference it anywhere in the policy with the standard placeholder syntax, {source_region}, exactly like the built-ins — and on a name collision the framework built-ins ({account_id}, {region}) win:

code
policies:
  - name: cross-region-notify
    resource: aws.ec2
    actions:
      - type: notify
        to: [ops@example.com]
        transport:
          type: sns
          topic: alarms-{source_region}

And dynamic tagging (PR #10968) is now standardized across providers: the “give this tag a default value only if it is not already set” authoring pattern, previously AWS-only, now works the same way on Azure and GCP, and aws.asg tag actions got fixed to share the same resolution logic.

Correctness Fixes Worth Knowing About

No security advisories in this release, but three fixes address silent wrongness in a tool whose whole job is complete, correct inventory:

  • Kube listing dropped resources past page one. The pagination fix above (PR #11081) means policies on large clusters no longer silently skip everything after the first page.
  • The resolver served cached responses across different request headers. The URI cache key now includes request headers (PR #11148), so an uri filter keyed on headers gets fresh answers.
  • The kube resource cache ignored the resource type. Cache keys now include it (PR #11168), preventing cross-type cache collisions.

Upgrade Notes

Nothing here is a fire drill, but four changes alter what your existing policies can see or touch:

  • CloudWatch dashboards lost an action. The rename-tag action is gone from aws.cloudwatch-dashboard, replaced by native CloudWatch tagging, so audit any policies that still reference it. PR #11090
  • KMS and Route53 now skip AWS-managed resources. Actions no longer fire on resources AWS owns and you cannot really manage. PR #11050
  • Tagging tolerates mid-run deletions. Resources deleted between inventory and the tag action no longer cause hard failures. PR #11089
  • SSM compliance filters honor defaults. ec2 ssm-compliance now respects advertised state defaults instead of requiring explicit values. PR #10883

Closing

Upgrade, point a policy at your messiest CRD, and let the Roomba finally reach the corners.

Learn More

Also on the podcast 1 · Cloud Native Pulse: Episode 1 ▶ Play 00:17:01