Skip to content

AWS.AutoScaling reference

Source: src/AWS/AutoScaling/AutoScalingGroup.ts

An EC2 Auto Scaling Group that manages a fleet of instances from a launch template and can register that fleet with one or more load balancer target groups.

Pair with ScalingPolicy for target-tracking scaling, ScheduledAction for time-based capacity changes, and consumeLifecycleActions to run a Lambda handler while instances pause during launch/terminate transitions.

AutoScalingGroup: Creating an Auto Scaling Group

Section titled “AutoScalingGroup: Creating an Auto Scaling Group”

Fleet from a Launch Template

import { AutoScalingGroup, LaunchTemplate } from "alchemy/AWS/AutoScaling";
import { Subnet, Vpc } from "alchemy/AWS/EC2";
const vpc = yield* Vpc("Vpc", { cidrBlock: "10.0.0.0/16" });
const subnet = yield* Subnet("Subnet", {
vpcId: vpc.vpcId,
cidrBlock: "10.0.1.0/24",
});
const template = yield* LaunchTemplate("Template", {
imageId: "ami-0abcdef1234567890",
instanceType: "t3.micro",
});
const group = yield* AutoScalingGroup("Fleet", {
launchTemplate: template,
subnetIds: [subnet.subnetId],
minSize: 1,
maxSize: 3,
});

Reference an existing Launch Template by name

const group = yield* AutoScalingGroup("Fleet", {
launchTemplate: { launchTemplateName: "my-template", version: 2 },
subnetIds: [subnet.subnetId],
minSize: 0,
maxSize: 0,
desiredCapacity: 0,
});
const group = yield* AutoScalingGroup("WebFleet", {
launchTemplate: template,
subnetIds: [subnetA.subnetId, subnetB.subnetId],
minSize: 2,
maxSize: 6,
targetGroupArns: [targetGroup.targetGroupArn],
// healthCheckType defaults to "ELB" when target groups are attached
healthCheckGracePeriod: "5 minutes",
});
import { ScalingPolicy } from "alchemy/AWS/AutoScaling";
yield* ScalingPolicy("CpuPolicy", {
autoScalingGroup: group,
predefinedMetricType: "ASGAverageCPUUtilization",
targetValue: 60,
});

Source: src/AWS/AutoScaling/CompleteLifecycleAction.ts

A write binding that lets a Function/Instance complete or heartbeat paused lifecycle actions on an Auto Scaling Group. Grants autoscaling:CompleteLifecycleAction and autoscaling:RecordLifecycleActionHeartbeat scoped to the group ARN.

CompleteLifecycleAction: Completing Lifecycle Actions

Section titled “CompleteLifecycleAction: Completing Lifecycle Actions”

Signal CONTINUE from a lifecycle handler

const lifecycle = yield* CompleteLifecycleAction(group);
yield* lifecycle.complete({
LifecycleHookName: event.detail.LifecycleHookName,
LifecycleActionToken: event.detail.LifecycleActionToken,
LifecycleActionResult: "CONTINUE",
});

Drain launching instances from a Lambda Function

import * as AWS from "alchemy/AWS";
import {
CompleteLifecycleAction,
CompleteLifecycleActionHttp,
consumeLifecycleActions,
} from "alchemy/AWS/AutoScaling";
export class LifecycleFunction extends AWS.Lambda.Function<AWS.Lambda.Function>()(
"LifecycleFunction",
) {}
export default LifecycleFunction.make(
{ main: import.meta.url },
Effect.gen(function* () {
const lifecycle = yield* CompleteLifecycleAction(group);
yield* consumeLifecycleActions(
group,
{ lifecycleTransition: "LAUNCHING", heartbeatTimeout: "300 seconds" },
(events) =>
Stream.runForEach(events, (event) =>
lifecycle
.complete({
LifecycleHookName: event.detail.LifecycleHookName,
LifecycleActionToken: event.detail.LifecycleActionToken,
LifecycleActionResult: "CONTINUE",
})
.pipe(Effect.orDie),
),
);
return {};
}).pipe(
Effect.provide(
Layer.mergeAll(AWS.Lambda.EventSource, CompleteLifecycleActionHttp),
),
),
);

Buy more time with a heartbeat

// reset the heartbeat timeout while a long drain is still in progress
yield* lifecycle.heartbeat({
LifecycleHookName: event.detail.LifecycleHookName,
LifecycleActionToken: event.detail.LifecycleActionToken,
});

Source: src/AWS/AutoScaling/DescribeAutoScalingGroup.ts

Runtime binding for the DescribeAutoScalingGroups operation scoped to one group (IAM action autoscaling:DescribeAutoScalingGroups; EC2 Auto Scaling Describe* actions do not support resource-level permissions, so the grant is on *).

Returns the bound group’s live description — capacity, instances and their lifecycle states, suspended processes — or undefined if the group no longer exists. Provide the implementation with Effect.provide(AWS.AutoScaling.DescribeAutoScalingGroupHttp).

DescribeAutoScalingGroup: Observing the Fleet

Section titled “DescribeAutoScalingGroup: Observing the Fleet”
// init — bind the operation to the group
const describeGroup = yield* AWS.AutoScaling.DescribeAutoScalingGroup(group);
// runtime — read the group's live state
const live = yield* describeGroup();
const inService = (live?.Instances ?? []).filter(
(i) => i.LifecycleState === "InService",
);

Source: src/AWS/AutoScaling/DescribeScalingActivities.ts

Runtime binding for the DescribeScalingActivities operation (IAM action autoscaling:DescribeScalingActivities; EC2 Auto Scaling Describe* actions do not support resource-level permissions, so the grant is on *).

Returns the bound group’s recent scaling activities — what scaled, when, why, and whether it succeeded. Provide the implementation with Effect.provide(AWS.AutoScaling.DescribeScalingActivitiesHttp).

DescribeScalingActivities: Observing Scaling Activity

Section titled “DescribeScalingActivities: Observing Scaling Activity”
// init — bind the operation to the group
const describeScalingActivities =
yield* AWS.AutoScaling.DescribeScalingActivities(group);
// runtime — page through the group's recent activities
const page = yield* describeScalingActivities({ MaxRecords: 50 });
for (const activity of page.Activities ?? []) {
yield* Effect.log(`${activity.StatusCode}: ${activity.Cause}`);
}

Source: src/AWS/AutoScaling/ExecutePolicy.ts

Runtime binding for the ExecutePolicy operation (IAM action autoscaling:ExecutePolicy scoped to the group ARN).

Executes a step or simple scaling policy on the bound group — useful for testing a policy’s design or driving scaling from application logic. Target-tracking policies cannot be executed manually. Provide the implementation with Effect.provide(AWS.AutoScaling.ExecutePolicyHttp).

// init — bind the operation to the group
const executePolicy = yield* AWS.AutoScaling.ExecutePolicy(group);
// runtime — trigger the policy with a synthetic metric breach
yield* executePolicy({
PolicyName: "scale-out-on-cpu",
MetricValue: 85,
BreachThreshold: 80,
});

Source: src/AWS/AutoScaling/InstanceRefresh.ts

Runtime binding for the instance refresh operations — StartInstanceRefresh, CancelInstanceRefresh, RollbackInstanceRefresh (IAM actions scoped to the group ARN) and DescribeInstanceRefreshes (granted on *; EC2 Auto Scaling Describe* actions do not support resource-level permissions).

Lets a deploy pipeline Lambda roll the fleet onto a new launch template version, watch progress, and cancel or roll back a bad deploy. Provide the implementation with Effect.provide(AWS.AutoScaling.InstanceRefreshHttp).

Roll the fleet and watch progress

// init — bind the operations to the group
const refresh = yield* AWS.AutoScaling.InstanceRefresh(group);
// runtime — start a rolling replacement with auto-rollback
const { InstanceRefreshId } = yield* refresh.start({
Preferences: { MinHealthyPercentage: 90, AutoRollback: true },
});
// runtime — check on it
const page = yield* refresh.describe({
InstanceRefreshIds: [InstanceRefreshId!],
});

Cancel a bad deploy

yield* refresh.cancel().pipe(
Effect.catchTag("ActiveInstanceRefreshNotFoundFault", () => Effect.void),
);

Source: src/AWS/AutoScaling/LaunchTemplate.ts

A launch template that preserves the Host authoring model used by AWS.EC2.Instance, but packages that host configuration for use with an Auto Scaling Group.

LaunchTemplate: Creating a Launch Template

Section titled “LaunchTemplate: Creating a Launch Template”

Basic Launch Template

import { LaunchTemplate } from "alchemy/AWS/AutoScaling";
const template = yield* LaunchTemplate("Template", {
imageId: "ami-0abcdef1234567890",
instanceType: "t3.micro",
});

Launch a fleet from the template

import { AutoScalingGroup } from "alchemy/AWS/AutoScaling";
const group = yield* AutoScalingGroup("Fleet", {
launchTemplate: template,
subnetIds: [subnet.subnetId],
minSize: 1,
maxSize: 3,
});
const template = yield* Effect.gen(function* () {
yield* Http.serve(HttpServerResponse.json({ ok: true }));
return {
main: import.meta.url,
imageId,
instanceType: "t3.small",
securityGroupIds: [securityGroup.groupId],
port: 3000,
};
}).pipe(
Effect.provide(AWS.EC2.HttpServer),
AWS.AutoScaling.LaunchTemplate("ApiTemplate"),
);

Source: src/AWS/AutoScaling/LifecycleHook.ts

A lifecycle hook that pauses an Auto Scaling instance in a wait state on launch or termination so a handler can drain connections, snapshot state, or warm caches before the transition completes. Pair with consumeLifecycleActions to receive the transition events and CompleteLifecycleAction to signal CONTINUE / ABANDON.

Drain before termination (EventBridge target)

const hook = yield* LifecycleHook("Drain", {
autoScalingGroup: group,
lifecycleTransition: "TERMINATING",
heartbeatTimeout: "300 seconds",
defaultResult: "CONTINUE",
});

Warm caches before an instance enters service

const hook = yield* LifecycleHook("Warm", {
autoScalingGroup: group,
lifecycleTransition: "LAUNCHING",
heartbeatTimeout: "2 minutes",
});

Source: src/AWS/AutoScaling/ScalingPolicy.ts

A target-tracking scaling policy for an Auto Scaling Group. EC2 Auto Scaling creates and manages the CloudWatch alarms that keep the tracked metric at targetValue by adjusting the group’s desired capacity.

Track average CPU utilization

import { AutoScalingGroup, ScalingPolicy } from "alchemy/AWS/AutoScaling";
const group = yield* AutoScalingGroup("Fleet", {
launchTemplate: template,
subnetIds: [subnet.subnetId],
minSize: 1,
maxSize: 4,
});
const policy = yield* ScalingPolicy("CpuPolicy", {
autoScalingGroup: group,
predefinedMetricType: "ASGAverageCPUUtilization",
targetValue: 60,
});

Scale on ALB requests per target without scale-in

const policy = yield* ScalingPolicy("RequestPolicy", {
autoScalingGroup: group,
predefinedMetricType: "ALBRequestCountPerTarget",
targetValue: 1000,
disableScaleIn: true,
estimatedInstanceWarmup: "3 minutes",
});

Source: src/AWS/AutoScaling/ScheduledAction.ts

A scheduled scaling action that changes an Auto Scaling Group’s capacity on a recurring cron schedule or at a single future time.

ScheduledAction: Creating a Scheduled Action

Section titled “ScheduledAction: Creating a Scheduled Action”

Scale up every weekday morning

const action = yield* ScheduledAction("MorningScaleUp", {
autoScalingGroup: group,
recurrence: "0 9 * * MON-FRI",
timeZone: "America/New_York",
minSize: 2,
maxSize: 10,
desiredCapacity: 4,
});

One-time capacity change

const action = yield* ScheduledAction("BlackFriday", {
autoScalingGroup: group,
startTime: "2026-11-27T00:00:00Z",
desiredCapacity: 20,
});

Source: src/AWS/AutoScaling/SetDesiredCapacity.ts

Runtime binding for the SetDesiredCapacity operation (IAM action autoscaling:SetDesiredCapacity scoped to the group ARN).

Manually sets the size of the bound Auto Scaling Group — e.g. a Lambda that scales a fleet up ahead of a known traffic spike or down to zero overnight. Provide the implementation with Effect.provide(AWS.AutoScaling.SetDesiredCapacityHttp).

// init — bind the operation to the group
const setDesiredCapacity = yield* AWS.AutoScaling.SetDesiredCapacity(group);
// runtime — set the fleet size, honoring the group's cooldown
yield* setDesiredCapacity({ DesiredCapacity: 4, HonorCooldown: true });

Source: src/AWS/AutoScaling/SetInstanceHealth.ts

Runtime binding for the SetInstanceHealth operation (IAM action autoscaling:SetInstanceHealth scoped to the group ARN).

Reports an instance’s health to EC2 Auto Scaling — the backbone of custom health checks: a watchdog Lambda (or the instance itself) flags an instance Unhealthy and the group replaces it. Provide the implementation with Effect.provide(AWS.AutoScaling.SetInstanceHealthHttp).

// init — bind the operation to the group
const setInstanceHealth = yield* AWS.AutoScaling.SetInstanceHealth(group);
// runtime — mark the instance unhealthy so the group replaces it
yield* setInstanceHealth({
InstanceId: instanceId,
HealthStatus: "Unhealthy",
});

Source: src/AWS/AutoScaling/SetInstanceProtection.ts

Runtime binding for the SetInstanceProtection operation (IAM action autoscaling:SetInstanceProtection scoped to the group ARN).

Toggles scale-in protection on instances — e.g. a worker protects itself while it processes a long-running job, then removes protection when idle so the group may reclaim it. Provide the implementation with Effect.provide(AWS.AutoScaling.SetInstanceProtectionHttp).

SetInstanceProtection: Scale-In Protection

Section titled “SetInstanceProtection: Scale-In Protection”
// init — bind the operation to the group
const setInstanceProtection =
yield* AWS.AutoScaling.SetInstanceProtection(group);
// runtime — protect while working, release when idle
yield* setInstanceProtection({
InstanceIds: [instanceId],
ProtectedFromScaleIn: true,
});

Source: src/AWS/AutoScaling/Standby.ts

Runtime binding for the EnterStandby / ExitStandby operations (IAM actions autoscaling:EnterStandby and autoscaling:ExitStandby scoped to the group ARN).

Temporarily pulls instances out of service — to debug a misbehaving instance, apply a patch, or drain it during maintenance — and puts them back afterwards. Provide the implementation with Effect.provide(AWS.AutoScaling.StandbyHttp).

// init — bind the operations to the group
const standby = yield* AWS.AutoScaling.Standby(group);
// runtime — take the instance out of rotation
yield* standby.enter({
InstanceIds: [instanceId],
ShouldDecrementDesiredCapacity: true,
});
// ... perform maintenance ...
// runtime — put it back in service
yield* standby.exit({ InstanceIds: [instanceId] });

Source: src/AWS/AutoScaling/TerminateInstanceInAutoScalingGroup.ts

Runtime binding for the TerminateInstanceInAutoScalingGroup operation (IAM action autoscaling:TerminateInstanceInAutoScalingGroup scoped to the group ARN).

Requests termination of a specific instance, optionally decrementing the desired capacity — e.g. recycling a wedged worker (the group launches a replacement) or retiring the instance it runs on. Provide the implementation with Effect.provide(AWS.AutoScaling.TerminateInstanceInAutoScalingGroupHttp).

TerminateInstanceInAutoScalingGroup: Manual Scaling

Section titled “TerminateInstanceInAutoScalingGroup: Manual Scaling”
// init — bind the operation to the group
const terminateInstance =
yield* AWS.AutoScaling.TerminateInstanceInAutoScalingGroup(group);
// runtime — terminate and let the group launch a replacement
const { Activity } = yield* terminateInstance({
InstanceId: instanceId,
ShouldDecrementDesiredCapacity: false,
});