Configure AWS Auto Scaling Policies

The aws:autoscaling/policy:Policy resource, part of the Pulumi AWS provider, defines scaling policies that control when and how Auto Scaling groups add or remove instances. This guide focuses on three capabilities: simple fixed-adjustment scaling, target tracking with metric math, and predictive scaling with ML forecasting.

Scaling policies attach to existing Auto Scaling groups and may reference CloudWatch alarms, SQS queues, or load balancers as metric sources. The examples are intentionally small. Combine them with your own Auto Scaling groups, alarms, and monitoring infrastructure.

Scale by a fixed number of instances

Simple scaling policies add or remove a fixed number of instances when triggered, providing straightforward capacity adjustments.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const bar = new aws.autoscaling.Group("bar", {
    availabilityZones: ["us-east-1a"],
    name: "foobar3-test",
    maxSize: 5,
    minSize: 2,
    healthCheckGracePeriod: 300,
    healthCheckType: "ELB",
    forceDelete: true,
    launchConfiguration: foo.name,
});
const bat = new aws.autoscaling.Policy("bat", {
    name: "foobar3-test",
    scalingAdjustment: 4,
    adjustmentType: "ChangeInCapacity",
    cooldown: 300,
    autoscalingGroupName: bar.name,
});
import pulumi
import pulumi_aws as aws

bar = aws.autoscaling.Group("bar",
    availability_zones=["us-east-1a"],
    name="foobar3-test",
    max_size=5,
    min_size=2,
    health_check_grace_period=300,
    health_check_type="ELB",
    force_delete=True,
    launch_configuration=foo["name"])
bat = aws.autoscaling.Policy("bat",
    name="foobar3-test",
    scaling_adjustment=4,
    adjustment_type="ChangeInCapacity",
    cooldown=300,
    autoscaling_group_name=bar.name)
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/autoscaling"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ec2"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		bar, err := autoscaling.NewGroup(ctx, "bar", &autoscaling.GroupArgs{
			AvailabilityZones: pulumi.StringArray{
				pulumi.String("us-east-1a"),
			},
			Name:                   pulumi.String("foobar3-test"),
			MaxSize:                pulumi.Int(5),
			MinSize:                pulumi.Int(2),
			HealthCheckGracePeriod: pulumi.Int(300),
			HealthCheckType:        pulumi.String("ELB"),
			ForceDelete:            pulumi.Bool(true),
			LaunchConfiguration:    pulumi.Any(foo.Name),
		})
		if err != nil {
			return err
		}
		_, err = autoscaling.NewPolicy(ctx, "bat", &autoscaling.PolicyArgs{
			Name:                 pulumi.String("foobar3-test"),
			ScalingAdjustment:    pulumi.Int(4),
			AdjustmentType:       pulumi.String("ChangeInCapacity"),
			Cooldown:             pulumi.Int(300),
			AutoscalingGroupName: bar.Name,
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var bar = new Aws.AutoScaling.Group("bar", new()
    {
        AvailabilityZones = new[]
        {
            "us-east-1a",
        },
        Name = "foobar3-test",
        MaxSize = 5,
        MinSize = 2,
        HealthCheckGracePeriod = 300,
        HealthCheckType = "ELB",
        ForceDelete = true,
        LaunchConfiguration = foo.Name,
    });

    var bat = new Aws.AutoScaling.Policy("bat", new()
    {
        Name = "foobar3-test",
        ScalingAdjustment = 4,
        AdjustmentType = "ChangeInCapacity",
        Cooldown = 300,
        AutoscalingGroupName = bar.Name,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.autoscaling.Group;
import com.pulumi.aws.autoscaling.GroupArgs;
import com.pulumi.aws.autoscaling.Policy;
import com.pulumi.aws.autoscaling.PolicyArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var bar = new Group("bar", GroupArgs.builder()
            .availabilityZones("us-east-1a")
            .name("foobar3-test")
            .maxSize(5)
            .minSize(2)
            .healthCheckGracePeriod(300)
            .healthCheckType("ELB")
            .forceDelete(true)
            .launchConfiguration(foo.name())
            .build());

        var bat = new Policy("bat", PolicyArgs.builder()
            .name("foobar3-test")
            .scalingAdjustment(4)
            .adjustmentType("ChangeInCapacity")
            .cooldown(300)
            .autoscalingGroupName(bar.name())
            .build());

    }
}
resources:
  bat:
    type: aws:autoscaling:Policy
    properties:
      name: foobar3-test
      scalingAdjustment: 4
      adjustmentType: ChangeInCapacity
      cooldown: 300
      autoscalingGroupName: ${bar.name}
  bar:
    type: aws:autoscaling:Group
    properties:
      availabilityZones:
        - us-east-1a
      name: foobar3-test
      maxSize: 5
      minSize: 2
      healthCheckGracePeriod: 300
      healthCheckType: ELB
      forceDelete: true
      launchConfiguration: ${foo.name}

When the policy executes, it adds the number of instances specified in scalingAdjustment. The adjustmentType of “ChangeInCapacity” means the value is an absolute count, not a percentage. The cooldown period prevents rapid successive scaling actions, giving new instances time to start handling load before the next evaluation.

Maintain target metrics with calculated ratios

Target tracking policies automatically adjust capacity to maintain a metric at a target value. When monitoring a calculated ratio like messages per instance, you use metric math to combine CloudWatch data sources.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.autoscaling.Policy("example", {
    autoscalingGroupName: "my-test-asg",
    name: "foo",
    policyType: "TargetTrackingScaling",
    targetTrackingConfiguration: {
        targetValue: 100,
        customizedMetricSpecification: {
            metrics: [
                {
                    label: "Get the queue size (the number of messages waiting to be processed)",
                    id: "m1",
                    metricStat: {
                        metric: {
                            namespace: "AWS/SQS",
                            metricName: "ApproximateNumberOfMessagesVisible",
                            dimensions: [{
                                name: "QueueName",
                                value: "my-queue",
                            }],
                        },
                        stat: "Sum",
                        period: 10,
                    },
                    returnData: false,
                },
                {
                    label: "Get the group size (the number of InService instances)",
                    id: "m2",
                    metricStat: {
                        metric: {
                            namespace: "AWS/AutoScaling",
                            metricName: "GroupInServiceInstances",
                            dimensions: [{
                                name: "AutoScalingGroupName",
                                value: "my-asg",
                            }],
                        },
                        stat: "Average",
                        period: 10,
                    },
                    returnData: false,
                },
                {
                    label: "Calculate the backlog per instance",
                    id: "e1",
                    expression: "m1 / m2",
                    returnData: true,
                },
            ],
        },
    },
});
import pulumi
import pulumi_aws as aws

example = aws.autoscaling.Policy("example",
    autoscaling_group_name="my-test-asg",
    name="foo",
    policy_type="TargetTrackingScaling",
    target_tracking_configuration={
        "target_value": 100,
        "customized_metric_specification": {
            "metrics": [
                {
                    "label": "Get the queue size (the number of messages waiting to be processed)",
                    "id": "m1",
                    "metric_stat": {
                        "metric": {
                            "namespace": "AWS/SQS",
                            "metric_name": "ApproximateNumberOfMessagesVisible",
                            "dimensions": [{
                                "name": "QueueName",
                                "value": "my-queue",
                            }],
                        },
                        "stat": "Sum",
                        "period": 10,
                    },
                    "return_data": False,
                },
                {
                    "label": "Get the group size (the number of InService instances)",
                    "id": "m2",
                    "metric_stat": {
                        "metric": {
                            "namespace": "AWS/AutoScaling",
                            "metric_name": "GroupInServiceInstances",
                            "dimensions": [{
                                "name": "AutoScalingGroupName",
                                "value": "my-asg",
                            }],
                        },
                        "stat": "Average",
                        "period": 10,
                    },
                    "return_data": False,
                },
                {
                    "label": "Calculate the backlog per instance",
                    "id": "e1",
                    "expression": "m1 / m2",
                    "return_data": True,
                },
            ],
        },
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/autoscaling"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := autoscaling.NewPolicy(ctx, "example", &autoscaling.PolicyArgs{
			AutoscalingGroupName: pulumi.String("my-test-asg"),
			Name:                 pulumi.String("foo"),
			PolicyType:           pulumi.String("TargetTrackingScaling"),
			TargetTrackingConfiguration: &autoscaling.PolicyTargetTrackingConfigurationArgs{
				TargetValue: pulumi.Float64(100),
				CustomizedMetricSpecification: &autoscaling.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationArgs{
					Metrics: autoscaling.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricArray{
						&autoscaling.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricArgs{
							Label: pulumi.String("Get the queue size (the number of messages waiting to be processed)"),
							Id:    pulumi.String("m1"),
							MetricStat: &autoscaling.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatArgs{
								Metric: &autoscaling.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatMetricArgs{
									Namespace:  pulumi.String("AWS/SQS"),
									MetricName: pulumi.String("ApproximateNumberOfMessagesVisible"),
									Dimensions: autoscaling.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatMetricDimensionArray{
										&autoscaling.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatMetricDimensionArgs{
											Name:  pulumi.String("QueueName"),
											Value: pulumi.String("my-queue"),
										},
									},
								},
								Stat:   pulumi.String("Sum"),
								Period: pulumi.Int(10),
							},
							ReturnData: pulumi.Bool(false),
						},
						&autoscaling.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricArgs{
							Label: pulumi.String("Get the group size (the number of InService instances)"),
							Id:    pulumi.String("m2"),
							MetricStat: &autoscaling.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatArgs{
								Metric: &autoscaling.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatMetricArgs{
									Namespace:  pulumi.String("AWS/AutoScaling"),
									MetricName: pulumi.String("GroupInServiceInstances"),
									Dimensions: autoscaling.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatMetricDimensionArray{
										&autoscaling.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatMetricDimensionArgs{
											Name:  pulumi.String("AutoScalingGroupName"),
											Value: pulumi.String("my-asg"),
										},
									},
								},
								Stat:   pulumi.String("Average"),
								Period: pulumi.Int(10),
							},
							ReturnData: pulumi.Bool(false),
						},
						&autoscaling.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricArgs{
							Label:      pulumi.String("Calculate the backlog per instance"),
							Id:         pulumi.String("e1"),
							Expression: pulumi.String("m1 / m2"),
							ReturnData: pulumi.Bool(true),
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.AutoScaling.Policy("example", new()
    {
        AutoscalingGroupName = "my-test-asg",
        Name = "foo",
        PolicyType = "TargetTrackingScaling",
        TargetTrackingConfiguration = new Aws.AutoScaling.Inputs.PolicyTargetTrackingConfigurationArgs
        {
            TargetValue = 100,
            CustomizedMetricSpecification = new Aws.AutoScaling.Inputs.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationArgs
            {
                Metrics = new[]
                {
                    new Aws.AutoScaling.Inputs.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricArgs
                    {
                        Label = "Get the queue size (the number of messages waiting to be processed)",
                        Id = "m1",
                        MetricStat = new Aws.AutoScaling.Inputs.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatArgs
                        {
                            Metric = new Aws.AutoScaling.Inputs.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatMetricArgs
                            {
                                Namespace = "AWS/SQS",
                                MetricName = "ApproximateNumberOfMessagesVisible",
                                Dimensions = new[]
                                {
                                    new Aws.AutoScaling.Inputs.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatMetricDimensionArgs
                                    {
                                        Name = "QueueName",
                                        Value = "my-queue",
                                    },
                                },
                            },
                            Stat = "Sum",
                            Period = 10,
                        },
                        ReturnData = false,
                    },
                    new Aws.AutoScaling.Inputs.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricArgs
                    {
                        Label = "Get the group size (the number of InService instances)",
                        Id = "m2",
                        MetricStat = new Aws.AutoScaling.Inputs.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatArgs
                        {
                            Metric = new Aws.AutoScaling.Inputs.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatMetricArgs
                            {
                                Namespace = "AWS/AutoScaling",
                                MetricName = "GroupInServiceInstances",
                                Dimensions = new[]
                                {
                                    new Aws.AutoScaling.Inputs.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatMetricDimensionArgs
                                    {
                                        Name = "AutoScalingGroupName",
                                        Value = "my-asg",
                                    },
                                },
                            },
                            Stat = "Average",
                            Period = 10,
                        },
                        ReturnData = false,
                    },
                    new Aws.AutoScaling.Inputs.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricArgs
                    {
                        Label = "Calculate the backlog per instance",
                        Id = "e1",
                        Expression = "m1 / m2",
                        ReturnData = true,
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.autoscaling.Policy;
import com.pulumi.aws.autoscaling.PolicyArgs;
import com.pulumi.aws.autoscaling.inputs.PolicyTargetTrackingConfigurationArgs;
import com.pulumi.aws.autoscaling.inputs.PolicyTargetTrackingConfigurationCustomizedMetricSpecificationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new Policy("example", PolicyArgs.builder()
            .autoscalingGroupName("my-test-asg")
            .name("foo")
            .policyType("TargetTrackingScaling")
            .targetTrackingConfiguration(PolicyTargetTrackingConfigurationArgs.builder()
                .targetValue(100.0)
                .customizedMetricSpecification(PolicyTargetTrackingConfigurationCustomizedMetricSpecificationArgs.builder()
                    .metrics(                    
                        PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricArgs.builder()
                            .label("Get the queue size (the number of messages waiting to be processed)")
                            .id("m1")
                            .metricStat(PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatArgs.builder()
                                .metric(PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatMetricArgs.builder()
                                    .namespace("AWS/SQS")
                                    .metricName("ApproximateNumberOfMessagesVisible")
                                    .dimensions(PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatMetricDimensionArgs.builder()
                                        .name("QueueName")
                                        .value("my-queue")
                                        .build())
                                    .build())
                                .stat("Sum")
                                .period(10)
                                .build())
                            .returnData(false)
                            .build(),
                        PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricArgs.builder()
                            .label("Get the group size (the number of InService instances)")
                            .id("m2")
                            .metricStat(PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatArgs.builder()
                                .metric(PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatMetricArgs.builder()
                                    .namespace("AWS/AutoScaling")
                                    .metricName("GroupInServiceInstances")
                                    .dimensions(PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricMetricStatMetricDimensionArgs.builder()
                                        .name("AutoScalingGroupName")
                                        .value("my-asg")
                                        .build())
                                    .build())
                                .stat("Average")
                                .period(10)
                                .build())
                            .returnData(false)
                            .build(),
                        PolicyTargetTrackingConfigurationCustomizedMetricSpecificationMetricArgs.builder()
                            .label("Calculate the backlog per instance")
                            .id("e1")
                            .expression("m1 / m2")
                            .returnData(true)
                            .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:autoscaling:Policy
    properties:
      autoscalingGroupName: my-test-asg
      name: foo
      policyType: TargetTrackingScaling
      targetTrackingConfiguration:
        targetValue: 100
        customizedMetricSpecification:
          metrics:
            - label: Get the queue size (the number of messages waiting to be processed)
              id: m1
              metricStat:
                metric:
                  namespace: AWS/SQS
                  metricName: ApproximateNumberOfMessagesVisible
                  dimensions:
                    - name: QueueName
                      value: my-queue
                stat: Sum
                period: 10
              returnData: false
            - label: Get the group size (the number of InService instances)
              id: m2
              metricStat:
                metric:
                  namespace: AWS/AutoScaling
                  metricName: GroupInServiceInstances
                  dimensions:
                    - name: AutoScalingGroupName
                      value: my-asg
                stat: Average
                period: 10
              returnData: false
            - label: Calculate the backlog per instance
              id: e1
              expression: m1 / m2
              returnData: true

The policy calculates backlog per instance by dividing queue size by group size, then scales to keep that ratio at 100. The metricQueries array defines two input metrics (m1 for queue size, m2 for instance count) and one expression (e1) that divides them. Only the expression has returnData set to true, making it the value the policy tracks. AWS automatically scales in or out to maintain the target.

Forecast capacity with predictive scaling

Predictive scaling uses machine learning to forecast future load and scale proactively rather than waiting for metrics to breach thresholds.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.autoscaling.Policy("example", {
    autoscalingGroupName: "my-test-asg",
    name: "foo",
    policyType: "PredictiveScaling",
    predictiveScalingConfiguration: {
        metricSpecification: {
            targetValue: 10,
            customizedLoadMetricSpecification: {
                metricDataQueries: [{
                    id: "load_sum",
                    expression: "SUM(SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName=\"CPUUtilization\" my-test-asg', 'Sum', 3600))",
                }],
            },
            customizedCapacityMetricSpecification: {
                metricDataQueries: [{
                    id: "capacity_sum",
                    expression: "SUM(SEARCH('{AWS/AutoScaling,AutoScalingGroupName} MetricName=\"GroupInServiceIntances\" my-test-asg', 'Average', 300))",
                }],
            },
            customizedScalingMetricSpecification: {
                metricDataQueries: [
                    {
                        id: "capacity_sum",
                        expression: "SUM(SEARCH('{AWS/AutoScaling,AutoScalingGroupName} MetricName=\"GroupInServiceIntances\" my-test-asg', 'Average', 300))",
                        returnData: false,
                    },
                    {
                        id: "load_sum",
                        expression: "SUM(SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName=\"CPUUtilization\" my-test-asg', 'Sum', 300))",
                        returnData: false,
                    },
                    {
                        id: "weighted_average",
                        expression: "load_sum / (capacity_sum * PERIOD(capacity_sum) / 60)",
                    },
                ],
            },
        },
    },
});
import pulumi
import pulumi_aws as aws

example = aws.autoscaling.Policy("example",
    autoscaling_group_name="my-test-asg",
    name="foo",
    policy_type="PredictiveScaling",
    predictive_scaling_configuration={
        "metric_specification": {
            "target_value": 10,
            "customized_load_metric_specification": {
                "metric_data_queries": [{
                    "id": "load_sum",
                    "expression": "SUM(SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName=\"CPUUtilization\" my-test-asg', 'Sum', 3600))",
                }],
            },
            "customized_capacity_metric_specification": {
                "metric_data_queries": [{
                    "id": "capacity_sum",
                    "expression": "SUM(SEARCH('{AWS/AutoScaling,AutoScalingGroupName} MetricName=\"GroupInServiceIntances\" my-test-asg', 'Average', 300))",
                }],
            },
            "customized_scaling_metric_specification": {
                "metric_data_queries": [
                    {
                        "id": "capacity_sum",
                        "expression": "SUM(SEARCH('{AWS/AutoScaling,AutoScalingGroupName} MetricName=\"GroupInServiceIntances\" my-test-asg', 'Average', 300))",
                        "return_data": False,
                    },
                    {
                        "id": "load_sum",
                        "expression": "SUM(SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName=\"CPUUtilization\" my-test-asg', 'Sum', 300))",
                        "return_data": False,
                    },
                    {
                        "id": "weighted_average",
                        "expression": "load_sum / (capacity_sum * PERIOD(capacity_sum) / 60)",
                    },
                ],
            },
        },
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/autoscaling"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := autoscaling.NewPolicy(ctx, "example", &autoscaling.PolicyArgs{
			AutoscalingGroupName: pulumi.String("my-test-asg"),
			Name:                 pulumi.String("foo"),
			PolicyType:           pulumi.String("PredictiveScaling"),
			PredictiveScalingConfiguration: &autoscaling.PolicyPredictiveScalingConfigurationArgs{
				MetricSpecification: &autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationArgs{
					TargetValue: pulumi.Float64(10),
					CustomizedLoadMetricSpecification: &autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedLoadMetricSpecificationArgs{
						MetricDataQueries: autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedLoadMetricSpecificationMetricDataQueryArray{
							&autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedLoadMetricSpecificationMetricDataQueryArgs{
								Id:         pulumi.String("load_sum"),
								Expression: pulumi.String("SUM(SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName=\"CPUUtilization\" my-test-asg', 'Sum', 3600))"),
							},
						},
					},
					CustomizedCapacityMetricSpecification: &autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedCapacityMetricSpecificationArgs{
						MetricDataQueries: autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedCapacityMetricSpecificationMetricDataQueryArray{
							&autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedCapacityMetricSpecificationMetricDataQueryArgs{
								Id:         pulumi.String("capacity_sum"),
								Expression: pulumi.String("SUM(SEARCH('{AWS/AutoScaling,AutoScalingGroupName} MetricName=\"GroupInServiceIntances\" my-test-asg', 'Average', 300))"),
							},
						},
					},
					CustomizedScalingMetricSpecification: &autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationArgs{
						MetricDataQueries: autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryArray{
							&autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryArgs{
								Id:         pulumi.String("capacity_sum"),
								Expression: pulumi.String("SUM(SEARCH('{AWS/AutoScaling,AutoScalingGroupName} MetricName=\"GroupInServiceIntances\" my-test-asg', 'Average', 300))"),
								ReturnData: pulumi.Bool(false),
							},
							&autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryArgs{
								Id:         pulumi.String("load_sum"),
								Expression: pulumi.String("SUM(SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName=\"CPUUtilization\" my-test-asg', 'Sum', 300))"),
								ReturnData: pulumi.Bool(false),
							},
							&autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryArgs{
								Id:         pulumi.String("weighted_average"),
								Expression: pulumi.String("load_sum / (capacity_sum * PERIOD(capacity_sum) / 60)"),
							},
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.AutoScaling.Policy("example", new()
    {
        AutoscalingGroupName = "my-test-asg",
        Name = "foo",
        PolicyType = "PredictiveScaling",
        PredictiveScalingConfiguration = new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationArgs
        {
            MetricSpecification = new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationArgs
            {
                TargetValue = 10,
                CustomizedLoadMetricSpecification = new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedLoadMetricSpecificationArgs
                {
                    MetricDataQueries = new[]
                    {
                        new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedLoadMetricSpecificationMetricDataQueryArgs
                        {
                            Id = "load_sum",
                            Expression = "SUM(SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName=\"CPUUtilization\" my-test-asg', 'Sum', 3600))",
                        },
                    },
                },
                CustomizedCapacityMetricSpecification = new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedCapacityMetricSpecificationArgs
                {
                    MetricDataQueries = new[]
                    {
                        new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedCapacityMetricSpecificationMetricDataQueryArgs
                        {
                            Id = "capacity_sum",
                            Expression = "SUM(SEARCH('{AWS/AutoScaling,AutoScalingGroupName} MetricName=\"GroupInServiceIntances\" my-test-asg', 'Average', 300))",
                        },
                    },
                },
                CustomizedScalingMetricSpecification = new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationArgs
                {
                    MetricDataQueries = new[]
                    {
                        new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryArgs
                        {
                            Id = "capacity_sum",
                            Expression = "SUM(SEARCH('{AWS/AutoScaling,AutoScalingGroupName} MetricName=\"GroupInServiceIntances\" my-test-asg', 'Average', 300))",
                            ReturnData = false,
                        },
                        new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryArgs
                        {
                            Id = "load_sum",
                            Expression = "SUM(SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName=\"CPUUtilization\" my-test-asg', 'Sum', 300))",
                            ReturnData = false,
                        },
                        new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryArgs
                        {
                            Id = "weighted_average",
                            Expression = "load_sum / (capacity_sum * PERIOD(capacity_sum) / 60)",
                        },
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.autoscaling.Policy;
import com.pulumi.aws.autoscaling.PolicyArgs;
import com.pulumi.aws.autoscaling.inputs.PolicyPredictiveScalingConfigurationArgs;
import com.pulumi.aws.autoscaling.inputs.PolicyPredictiveScalingConfigurationMetricSpecificationArgs;
import com.pulumi.aws.autoscaling.inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedLoadMetricSpecificationArgs;
import com.pulumi.aws.autoscaling.inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedCapacityMetricSpecificationArgs;
import com.pulumi.aws.autoscaling.inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new Policy("example", PolicyArgs.builder()
            .autoscalingGroupName("my-test-asg")
            .name("foo")
            .policyType("PredictiveScaling")
            .predictiveScalingConfiguration(PolicyPredictiveScalingConfigurationArgs.builder()
                .metricSpecification(PolicyPredictiveScalingConfigurationMetricSpecificationArgs.builder()
                    .targetValue(10.0)
                    .customizedLoadMetricSpecification(PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedLoadMetricSpecificationArgs.builder()
                        .metricDataQueries(PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedLoadMetricSpecificationMetricDataQueryArgs.builder()
                            .id("load_sum")
                            .expression("SUM(SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName=\"CPUUtilization\" my-test-asg', 'Sum', 3600))")
                            .build())
                        .build())
                    .customizedCapacityMetricSpecification(PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedCapacityMetricSpecificationArgs.builder()
                        .metricDataQueries(PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedCapacityMetricSpecificationMetricDataQueryArgs.builder()
                            .id("capacity_sum")
                            .expression("SUM(SEARCH('{AWS/AutoScaling,AutoScalingGroupName} MetricName=\"GroupInServiceIntances\" my-test-asg', 'Average', 300))")
                            .build())
                        .build())
                    .customizedScalingMetricSpecification(PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationArgs.builder()
                        .metricDataQueries(                        
                            PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryArgs.builder()
                                .id("capacity_sum")
                                .expression("SUM(SEARCH('{AWS/AutoScaling,AutoScalingGroupName} MetricName=\"GroupInServiceIntances\" my-test-asg', 'Average', 300))")
                                .returnData(false)
                                .build(),
                            PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryArgs.builder()
                                .id("load_sum")
                                .expression("SUM(SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName=\"CPUUtilization\" my-test-asg', 'Sum', 300))")
                                .returnData(false)
                                .build(),
                            PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryArgs.builder()
                                .id("weighted_average")
                                .expression("load_sum / (capacity_sum * PERIOD(capacity_sum) / 60)")
                                .build())
                        .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:autoscaling:Policy
    properties:
      autoscalingGroupName: my-test-asg
      name: foo
      policyType: PredictiveScaling
      predictiveScalingConfiguration:
        metricSpecification:
          targetValue: 10
          customizedLoadMetricSpecification:
            metricDataQueries:
              - id: load_sum
                expression: SUM(SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName="CPUUtilization" my-test-asg', 'Sum', 3600))
          customizedCapacityMetricSpecification:
            metricDataQueries:
              - id: capacity_sum
                expression: SUM(SEARCH('{AWS/AutoScaling,AutoScalingGroupName} MetricName="GroupInServiceIntances" my-test-asg', 'Average', 300))
          customizedScalingMetricSpecification:
            metricDataQueries:
              - id: capacity_sum
                expression: SUM(SEARCH('{AWS/AutoScaling,AutoScalingGroupName} MetricName="GroupInServiceIntances" my-test-asg', 'Average', 300))
                returnData: false
              - id: load_sum
                expression: SUM(SEARCH('{AWS/EC2,AutoScalingGroupName} MetricName="CPUUtilization" my-test-asg', 'Sum', 300))
                returnData: false
              - id: weighted_average
                expression: load_sum / (capacity_sum * PERIOD(capacity_sum) / 60)

The policy defines three metric specifications: load (CPU utilization), capacity (in-service instances), and scaling (weighted average). Each uses CloudWatch Metrics Insights SEARCH queries to aggregate historical data. The ML model learns daily and weekly patterns from this data, then scales ahead of predicted demand. The targetValue sets the desired scaling metric level.

Combine predefined load metrics with custom scaling

Predictive scaling can use AWS-provided metrics for load forecasting while applying custom metric math for scaling decisions.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.autoscaling.Policy("example", {
    autoscalingGroupName: "my-test-asg",
    name: "foo",
    policyType: "PredictiveScaling",
    predictiveScalingConfiguration: {
        metricSpecification: {
            targetValue: 10,
            predefinedLoadMetricSpecification: {
                predefinedMetricType: "ASGTotalCPUUtilization",
                resourceLabel: "app/my-alb/778d41231b141a0f/targetgroup/my-alb-target-group/943f017f100becff",
            },
            customizedScalingMetricSpecification: {
                metricDataQueries: [{
                    id: "scaling",
                    metricStat: {
                        metric: {
                            metricName: "CPUUtilization",
                            namespace: "AWS/EC2",
                            dimensions: [{
                                name: "AutoScalingGroupName",
                                value: "my-test-asg",
                            }],
                        },
                        stat: "Average",
                    },
                }],
            },
        },
    },
});
import pulumi
import pulumi_aws as aws

example = aws.autoscaling.Policy("example",
    autoscaling_group_name="my-test-asg",
    name="foo",
    policy_type="PredictiveScaling",
    predictive_scaling_configuration={
        "metric_specification": {
            "target_value": 10,
            "predefined_load_metric_specification": {
                "predefined_metric_type": "ASGTotalCPUUtilization",
                "resource_label": "app/my-alb/778d41231b141a0f/targetgroup/my-alb-target-group/943f017f100becff",
            },
            "customized_scaling_metric_specification": {
                "metric_data_queries": [{
                    "id": "scaling",
                    "metric_stat": {
                        "metric": {
                            "metric_name": "CPUUtilization",
                            "namespace": "AWS/EC2",
                            "dimensions": [{
                                "name": "AutoScalingGroupName",
                                "value": "my-test-asg",
                            }],
                        },
                        "stat": "Average",
                    },
                }],
            },
        },
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/autoscaling"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := autoscaling.NewPolicy(ctx, "example", &autoscaling.PolicyArgs{
			AutoscalingGroupName: pulumi.String("my-test-asg"),
			Name:                 pulumi.String("foo"),
			PolicyType:           pulumi.String("PredictiveScaling"),
			PredictiveScalingConfiguration: &autoscaling.PolicyPredictiveScalingConfigurationArgs{
				MetricSpecification: &autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationArgs{
					TargetValue: pulumi.Float64(10),
					PredefinedLoadMetricSpecification: &autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationPredefinedLoadMetricSpecificationArgs{
						PredefinedMetricType: pulumi.String("ASGTotalCPUUtilization"),
						ResourceLabel:        pulumi.String("app/my-alb/778d41231b141a0f/targetgroup/my-alb-target-group/943f017f100becff"),
					},
					CustomizedScalingMetricSpecification: &autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationArgs{
						MetricDataQueries: autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryArray{
							&autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryArgs{
								Id: pulumi.String("scaling"),
								MetricStat: &autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryMetricStatArgs{
									Metric: &autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryMetricStatMetricArgs{
										MetricName: pulumi.String("CPUUtilization"),
										Namespace:  pulumi.String("AWS/EC2"),
										Dimensions: autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryMetricStatMetricDimensionArray{
											&autoscaling.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryMetricStatMetricDimensionArgs{
												Name:  pulumi.String("AutoScalingGroupName"),
												Value: pulumi.String("my-test-asg"),
											},
										},
									},
									Stat: pulumi.String("Average"),
								},
							},
						},
					},
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.AutoScaling.Policy("example", new()
    {
        AutoscalingGroupName = "my-test-asg",
        Name = "foo",
        PolicyType = "PredictiveScaling",
        PredictiveScalingConfiguration = new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationArgs
        {
            MetricSpecification = new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationArgs
            {
                TargetValue = 10,
                PredefinedLoadMetricSpecification = new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationPredefinedLoadMetricSpecificationArgs
                {
                    PredefinedMetricType = "ASGTotalCPUUtilization",
                    ResourceLabel = "app/my-alb/778d41231b141a0f/targetgroup/my-alb-target-group/943f017f100becff",
                },
                CustomizedScalingMetricSpecification = new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationArgs
                {
                    MetricDataQueries = new[]
                    {
                        new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryArgs
                        {
                            Id = "scaling",
                            MetricStat = new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryMetricStatArgs
                            {
                                Metric = new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryMetricStatMetricArgs
                                {
                                    MetricName = "CPUUtilization",
                                    Namespace = "AWS/EC2",
                                    Dimensions = new[]
                                    {
                                        new Aws.AutoScaling.Inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryMetricStatMetricDimensionArgs
                                        {
                                            Name = "AutoScalingGroupName",
                                            Value = "my-test-asg",
                                        },
                                    },
                                },
                                Stat = "Average",
                            },
                        },
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.autoscaling.Policy;
import com.pulumi.aws.autoscaling.PolicyArgs;
import com.pulumi.aws.autoscaling.inputs.PolicyPredictiveScalingConfigurationArgs;
import com.pulumi.aws.autoscaling.inputs.PolicyPredictiveScalingConfigurationMetricSpecificationArgs;
import com.pulumi.aws.autoscaling.inputs.PolicyPredictiveScalingConfigurationMetricSpecificationPredefinedLoadMetricSpecificationArgs;
import com.pulumi.aws.autoscaling.inputs.PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new Policy("example", PolicyArgs.builder()
            .autoscalingGroupName("my-test-asg")
            .name("foo")
            .policyType("PredictiveScaling")
            .predictiveScalingConfiguration(PolicyPredictiveScalingConfigurationArgs.builder()
                .metricSpecification(PolicyPredictiveScalingConfigurationMetricSpecificationArgs.builder()
                    .targetValue(10.0)
                    .predefinedLoadMetricSpecification(PolicyPredictiveScalingConfigurationMetricSpecificationPredefinedLoadMetricSpecificationArgs.builder()
                        .predefinedMetricType("ASGTotalCPUUtilization")
                        .resourceLabel("app/my-alb/778d41231b141a0f/targetgroup/my-alb-target-group/943f017f100becff")
                        .build())
                    .customizedScalingMetricSpecification(PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationArgs.builder()
                        .metricDataQueries(PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryArgs.builder()
                            .id("scaling")
                            .metricStat(PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryMetricStatArgs.builder()
                                .metric(PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryMetricStatMetricArgs.builder()
                                    .metricName("CPUUtilization")
                                    .namespace("AWS/EC2")
                                    .dimensions(PolicyPredictiveScalingConfigurationMetricSpecificationCustomizedScalingMetricSpecificationMetricDataQueryMetricStatMetricDimensionArgs.builder()
                                        .name("AutoScalingGroupName")
                                        .value("my-test-asg")
                                        .build())
                                    .build())
                                .stat("Average")
                                .build())
                            .build())
                        .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:autoscaling:Policy
    properties:
      autoscalingGroupName: my-test-asg
      name: foo
      policyType: PredictiveScaling
      predictiveScalingConfiguration:
        metricSpecification:
          targetValue: 10
          predefinedLoadMetricSpecification:
            predefinedMetricType: ASGTotalCPUUtilization
            resourceLabel: app/my-alb/778d41231b141a0f/targetgroup/my-alb-target-group/943f017f100becff
          customizedScalingMetricSpecification:
            metricDataQueries:
              - id: scaling
                metricStat:
                  metric:
                    metricName: CPUUtilization
                    namespace: AWS/EC2
                    dimensions:
                      - name: AutoScalingGroupName
                        value: my-test-asg
                  stat: Average

The predefinedLoadMetricSpecification uses AWS’s built-in CPU utilization metric for forecasting, simplifying configuration. The customizedScalingMetricSpecification still uses custom metric math to define how scaling decisions are made. This hybrid approach works well when AWS metrics match your load patterns but you need custom scaling logic.

Beyond these examples

These snippets focus on specific policy-level features: simple and target tracking scaling, metric math and Metrics Insights queries, and predictive scaling with ML forecasting. They’re intentionally minimal rather than full Auto Scaling deployments.

The examples reference pre-existing infrastructure such as Auto Scaling groups, CloudWatch alarms (for simple scaling), and SQS queues or load balancers (for metric sources). They focus on configuring the policy rather than provisioning the surrounding infrastructure.

To keep things focused, common policy patterns are omitted, including:

  • Step scaling with multiple threshold ranges
  • Warmup periods and cooldown tuning
  • Scaling policy disablement (enabled property)
  • CloudWatch alarm integration details

These omissions are intentional: the goal is to illustrate how each policy type is wired, not provide drop-in scaling modules. See the AutoScaling Policy resource reference for all available configuration options.

Let's configure AWS Auto Scaling Policies

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration & Best Practices
Should I set `desiredCapacity` on my Auto Scaling Group when using scaling policies?
You should omit desiredCapacity from the aws.autoscaling.Group when using autoscaling policies. It’s good practice to choose either manual scaling (with desiredCapacity) or dynamic policy-based scaling, but not both, to avoid conflicts.
What policy types are available and what's the default?
Four policy types are available: SimpleScaling, StepScaling, TargetTrackingScaling, and PredictiveScaling. If you don’t specify policyType, AWS defaults to SimpleScaling.
What does `adjustmentType` control?
adjustmentType determines whether the scaling adjustment is an absolute number or a percentage of current capacity. Valid values are ChangeInCapacity, ExactCapacity, and PercentChangeInCapacity.
Scaling Adjustments & Timing
What's the difference between `cooldown` and `estimatedInstanceWarmup`?
cooldown is the time in seconds after a scaling activity completes before the next scaling activity can start. estimatedInstanceWarmup is the estimated time until a newly launched instance contributes CloudWatch metrics. If you don’t specify estimatedInstanceWarmup, AWS defaults to the group’s cooldown period.
How do I scale up vs scale down with `scalingAdjustment`?
Use a positive value for scalingAdjustment to scale up and a negative value to scale down. This property is only available for SimpleScaling type policies.
How do I configure step scaling with multiple thresholds?
Use the stepAdjustments array with objects containing scalingAdjustment, metricIntervalLowerBound, and metricIntervalUpperBound for each threshold range. Each step defines how much to scale when metrics fall within that interval.
Policy Types & Advanced Features
How do I scale based on SQS queue backlog per instance?
Use TargetTrackingScaling with customizedMetricSpecification and metric math. Create metrics for queue size (ApproximateNumberOfMessagesVisible) and group size (GroupInServiceInstances), then use an expression like m1 / m2 to calculate backlog per instance.
Can I use predictive scaling with custom metrics?
Yes, configure predictiveScalingConfiguration with customizedLoadMetricSpecification, customizedCapacityMetricSpecification, and customizedScalingMetricSpecification using CloudWatch metric queries or expressions.
Can I mix predefined and custom metrics in predictive scaling?
Yes, you can use predefinedLoadMetricSpecification (like ASGTotalCPUUtilization) alongside customizedScalingMetricSpecification or other customized metric specifications.
How do I create a target tracking policy for CPU utilization?
Set policyType to TargetTrackingScaling and configure targetTrackingConfiguration with predefinedMetricSpecification using ASGAverageCPUUtilization as the predefinedMetricType, then specify your desired targetValue.
Resource Management
What properties can't I change after creating the policy?
Both autoscalingGroupName and name are immutable. Changing either property will force replacement of the policy resource.
Can I temporarily disable a scaling policy without deleting it?
Yes, set enabled to false to disable the policy. The default value is true.

Using a different cloud?

Explore compute guides for other cloud providers: