Overcast is alpha — behaviour and APIs may change between releases. Pin your version and read the changelog before upgrading.

overcast

Auto Scaling — AWS Auto Scaling

Quick start, how a group converges on desired capacity, which scaling policies and lifecycle hooks run for real, and the configurations refused with 501.

Auto Scaling groups converge: a reconciler launches and terminates EC2 instances until each group matches its DesiredCapacity, running the lifecycle state machine and recording an activity for everything it does.

Status: ⚠️ Partial

Quick start

export AWS_ENDPOINT_URL=http://localhost:4566
aws autoscaling create-launch-configuration --launch-configuration-name web \
  --image-id ami-12345678 --instance-type t3.micro
aws autoscaling create-auto-scaling-group --auto-scaling-group-name web \
  --launch-configuration-name web --availability-zones us-east-1a \
  --min-size 1 --max-size 3 --desired-capacity 2

aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name web \
  --query 'AutoScalingGroups[0].Instances[].[InstanceId,LifecycleState]'

Any credentials work; with none configured, run eval "$(overcast env)" first — see Using AWS SDKs and CLI.

The reconciler is woken by every change, so the instances are usually there by the time the next call lands. A one-second tick bounds the transitions nothing pokes — a lifecycle heartbeat expiring, a cooldown ending.

What works

AreaBehaviour
ConvergenceCreateAutoScalingGroup, UpdateAutoScalingGroup, SetDesiredCapacity, ExecutePolicy and alarm-driven policies all move DesiredCapacity; the reconciler then calls EC2 RunInstances / TerminateInstances to close the gap, clamped to MinSize and MaxSize
Launch sourceEither a launch configuration or an EC2 LaunchTemplate, by ID or name and at a version including $Latest and $Default. The template is resolved through EC2 when the group is configured, so one that does not exist is a ValidationError rather than a group that never converges. DescribeAutoScalingGroups reports it, as does each instance launched from it
Instance statePending → InService and Terminating → gone, reported with LifecycleState, HealthStatus, AvailabilityZone, InstanceType and ProtectedFromScaleIn
PlacementEvery group names at least one of AvailabilityZones and VPCZoneIdentifier; a group with neither is refused. Launches round-robin across VPCZoneIdentifier’s subnets, each instance landing in its own subnet’s zone, or across AvailabilityZones for a group with no subnets. A group given only subnets takes its zones from them
Instance tagsTags marked PropagateAtLaunch are applied to each instance, alongside aws:autoscaling:groupName
Scaling policiesSimpleScaling and StepScaling execute, honouring ChangeInCapacity, ExactCapacity, PercentChangeInCapacity, MinAdjustmentMagnitude and the group’s cooldown
CloudWatch alarmsA policy ARN in an alarm’s AlarmActions works end to end. For a step policy, the breach is the alarm’s most recent datapoint minus its threshold — the number AWS compares against the metric interval bounds
Lifecycle hooksThe instance really parks in Pending:Wait or Terminating:Wait, an EC2 Instance-launch Lifecycle Action event carrying the LifecycleActionToken is published to the default EventBridge bus, and it stays there until CompleteLifecycleAction or HeartbeatTimeout applies the hook’s DefaultResult. RecordLifecycleActionHeartbeat extends the window
ActivitiesEvery launch and termination writes a DescribeScalingActivities entry with AWS’s StatusCode, Progress, Description and Cause wording, capped at the 200 most recent per group. A launch EC2 refuses is recorded as a Failed activity carrying EC2’s own error, never silently dropped

Refused, not ignored

A configuration the reconciler cannot converge is refused at the configuring operation rather than stored and quietly disregarded.

ConfigurationOperationResult
MixedInstancesPolicyCreateAutoScalingGroup / UpdateAutoScalingGroup501 — there is no instance-type fleet or spot allocation to distribute over
InstanceIdCreateAutoScalingGroup501 — launch parameters cannot be derived from a running instance
No launch source at allCreateAutoScalingGroup400 ValidationError, as on AWS
Neither AvailabilityZones nor VPCZoneIdentifierCreateAutoScalingGroup, and any UpdateAutoScalingGroup that would leave a group with neither400 ValidationError, as on AWS — At least one Availability Zone or VPC Subnet is required. A group with no placement has nowhere to launch
VPCZoneIdentifier subnets outside AvailabilityZonesCreateAutoScalingGroup / UpdateAutoScalingGroup400 ValidationError, as on AWS — the two must name the same zones
PolicyType=TargetTrackingScalingPutScalingPolicy501 — nothing tracks a target metric value
PolicyType=PredictiveScalingPutScalingPolicy501 — there is no forecasting model over historical metrics
Warm pools, instance refresh, scheduled actions, notification configurations—Not registered; a protocol-correct 501

Differences from AWS

AreaOn AWSOvercast
Termination policyDefault — balance across AZs, then the documented tie-breaksOldestInstance, skipping instances protected from scale-in — the same answer Default gives for a single-AZ or uniform group
TerminationPoliciesChooses which instance goesStored and echoed; it does not change the choice
HealthCheckType=ELBLoad-balancer target health marks an instance unhealthyAccepted and echoed, as is HealthCheckGracePeriod; only SetInstanceHealth marks an instance unhealthy
Lifecycle hooksEvery hook watching a transition runsThe instance parks on the first matching hook by name
RegionGroups are regionalGroups are global to the emulator; the reconciler launches into the configured default region
InstancesReal computeMetadata — the group converges on records, not on running compute. See EC2

Operations

All 25 listed operations are implemented. Per-operation status, notes and AWS API links: Auto Scaling operations.