Auto Scaling Groups running with zero scaling policies
What does ZopNight detect here?
Min, max and desired capacity alone do not make a group scale. Without at least 1 scaling policy, an ASG holds whatever capacity it was last set to. ZopNight fires only when AWS DescribePolicies confirms a count of exactly 0, and skips ECS capacity-provider and fixed-size groups.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-ASC-001 |
| Category | compliance |
| Severity | medium |
| Metric | none — pure configuration read |
| Source | asg_no_scaling_policy.go |
Where it applies
The gap between “has autoscaling” and “will autoscale”
Creating an Auto Scaling Group sets a min, a max and a desired count, none of which reacts to anything. Reaction comes from scaling policies: Target Tracking, Step or Simple. A group with a max of 10 and zero policies will sit at its desired count through every traffic spike and every quiet weekend, exactly like a fixed fleet, while the console says autoscaling is on.
Two shapes it knows to leave alone
Not every policy-less group is a mistake, and the rule skips two architectures where the absence is intentional:
- ECS capacity-provider groups. When ECS manages an ASG through a capacity provider (the AmazonECSManaged tag), ECS itself decides capacity. An ASG-level scaling policy there would fight the orchestrator.
- Fixed-size groups. When min equals max, the group is pinned by definition. A policy could never move it, so recommending one is meaningless.
Stopped groups are also excluded.
Confirm the count from your terminal
aws autoscaling describe-policies \ --auto-scaling-group-name my-asg \ --query 'length(ScalingPolicies)'A result of 0 on a group that is supposed to track demand is this finding, reproduced.
Why a missing answer is not a zero
The policy count comes from the discovery pass calling DescribePolicies (the
autoscaling:DescribePolicies read, part of the AWS-managed ReadOnlyAccess grant).
That enrichment is best-effort: on a throttle or a 403 the count is simply absent.
The rule treats absent as unknown, not as zero, and abstains. It fires only on a
confirmed count of exactly 0, never on missing evidence.
What to attach
The recommendation ships with a concrete default: a Target Tracking policy on average CPU at 70%, read from the CPUUtilization series EC2 publishes to CloudWatch. Target Tracking is the right first policy for most groups because it handles both scale-out and scale-in from one setting; Step policies earn their complexity only when different alarm thresholds need different responses. There is no dollar figure on this finding. It is a resilience gap, not a direct saving, so its cost fields are all zero.