Skip to main content

Expose number of managed Resources in plan policy

It would be nice to have the count of managed resources to build advanced policies:

In this run x%/Resources will be destroyed, we need to confirm that.

Workaround
Problem
Status: 🗑️ Archived1 comment

Log in to comment and vote

Comments1

  • Violet Highlighter

    •

    Aug 28

    Hey Felix,
    If you wanted to start using a policy like this now - we created an example you can implement.
    This is achievable using a custom plan policy input pattern from our docs.
    We put together a working setup that uses a custom plan policy + an after_plan hook that can be attached to the stack.

    Setup:
    An after_plan stack hook (Stack → Settings → Hooks → After planning):

    terraform show -json spacelift.plan | jq -c '.configuration' > configuration.custom.spacelift.json

    And a Plan policy:

    package spacelift
    
    import rego.v1
    
    warn_threshold := 25
    deny_threshold := 50
    
    all_resources := input.terraform.resource_changes
    
    destroyed_resources contains resource if {
        some resource in all_resources
        "delete" in resource.change.actions
    }
    
    destroyed := count(destroyed_resources)
    remaining := count(input.third_party_metadata.custom.configuration.root_module.resources)
    total := remaining + destroyed
    
    destroy_percentage := pct if {
        total > 0
        pct := (destroyed * 100) / total
    } else := 0
    
    warn contains msg if {
        destroy_percentage > warn_threshold
        destroy_percentage <= deny_threshold
        msg := sprintf(
            "This run will destroy %d of %d managed resources (%v%%). Review carefully.",
            [destroyed, total, destroy_percentage],
        )
    }
    
    deny contains msg if {
        destroy_percentage > deny_threshold
        msg := sprintf(
            "Blocked: this run would destroy %d of %d managed resources (%v%%), exceeding the %d%% limit.",
            [destroyed, total, destroy_percentage, deny_threshold],
        )
    }
    
    warn contains msg if {
        msg := sprintf(
            "Plan summary: %d/%d resources to destroy (%v%%).",
            [destroyed, total, destroy_percentage],
        )
    }
    
    sample := true

    How it works:

    • The after_plan hook dumps the Terraform config to configuration.custom.spacelift.json, which should merge into the policy input under input.third_party_metadata.custom.configuration - doc reference.

    • The policy counts resources defined in configuration (remaining) plus resources being deleted (destroyed) to derive the total, then calculates the destroy percentage.

    • Warn threshold is 25%, deny is 50% - which can be tuned to your liking.

    Tip: if you want to roll this out across multiple stacks without configuring each one individually, you can put the after_plan hook into a context with an autoattachment label, and attach the same autoattachment label to the policy. Any stack tagged with that label will pick up both the hook and the policy automatically.

    A couple of notes:

    • This is specific to Terraform stacks - the terraform show -json command and the .configuration structure are Terraform-specific.

    • Before rolling this out, I'd recommend testing the policy against previous plan policy inputs using the policy workbench - you can grab past inputs from stacks that already have plan policies attached and validate the logic in the simulation panel before enforcing it on live runs.