Configure AWS Auto Scaling Policies

The aws:autoscaling/policy:Policy resource, part of the Pulumi AWS provider, defines Auto Scaling policies that adjust group capacity based on metrics, thresholds, or forecasts. This guide focuses on three capabilities: simple scaling with fixed adjustments, target tracking with calculated metrics, and predictive scaling with custom and predefined metrics.

Policies attach to existing Auto Scaling groups and may reference CloudWatch alarms, SQS queues, or ALB target groups as metric sources. The examples are intentionally small. Combine them with your own Auto Scaling groups, alarms, and metric sources.

Scale by a fixed amount on demand

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 a CloudWatch alarm fires, the policy adds the number of instances specified in scalingAdjustment. The adjustmentType of “ChangeInCapacity” means the value is added directly to current capacity. The cooldown period prevents rapid successive scaling actions.

Maintain target value using calculated metrics

Target tracking policies automatically adjust capacity to keep a metric at a specified target, calculating the right scaling actions based on current state.

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 SQS queue size by the number of running instances, then scales to maintain 100 messages per instance. The targetTrackingConfiguration defines the target value and metric calculation. Each metric query in the metrics array either fetches data (returnData: false) or computes a derived value (returnData: true). The expression “m1 / m2” divides queue size by instance count.

Forecast capacity needs with custom metrics

Predictive scaling analyzes historical patterns to forecast future load and pre-scale capacity before demand arrives.

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 predictiveScalingConfiguration uses three metric specifications: customizedLoadMetricSpecification tracks incoming demand, customizedCapacityMetricSpecification measures current capacity, and customizedScalingMetricSpecification calculates the ratio that drives scaling decisions. Each uses CloudWatch Metrics Insights queries (SEARCH expressions) to aggregate metrics across the Auto Scaling group. The policy forecasts load patterns and scales proactively.

Combine predefined and custom metrics for forecasting

Predictive policies can mix AWS-provided load metrics with custom scaling metrics, simplifying configuration when standard load patterns apply.

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 ALB request count metric, identified by the resourceLabel pointing to your target group. The customizedScalingMetricSpecification defines how to calculate the scaling metric from EC2 CPU utilization. This hybrid approach reduces configuration complexity when standard load metrics fit your use case.

Beyond these examples

These snippets focus on specific policy-level features: simple, target tracking, and predictive scaling; metric math and custom metric specifications; and predefined and customized metric combinations. They’re intentionally minimal rather than full Auto Scaling solutions.

The examples reference pre-existing infrastructure such as Auto Scaling groups, CloudWatch alarms (for simple scaling), and SQS queues or ALB target groups (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 adjustment thresholds
  • Warmup periods and cooldown tuning (estimatedInstanceWarmup)
  • Policy enable/disable controls (enabled property)
  • Minimum adjustment magnitude for percentage-based scaling

These omissions are intentional: the goal is to illustrate how each policy type is wired, not provide drop-in scaling modules. See the Auto Scaling 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

Policy Types & Configuration
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 are the different adjustment types?
Three adjustment types control how scaling occurs: ChangeInCapacity adds or subtracts instances, ExactCapacity sets the group to a specific size, and PercentChangeInCapacity scales by a percentage of current capacity.
Should I omit desiredCapacity from my Auto Scaling Group when using policies?
Yes, it’s good practice to omit desiredCapacity from the aws.autoscaling.Group when using autoscaling policies. Mixing manual scaling (via desiredCapacity) with dynamic policy-based scaling can cause conflicts.
How do I enable or disable a scaling policy?
Use the enabled property, which accepts a boolean value and defaults to true. Set it to false to disable the policy without deleting it.
Scaling Behavior & 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 time until a newly launched instance contributes CloudWatch metrics. If you don’t specify estimatedInstanceWarmup, AWS uses the group’s cooldown period.
What happens if I don't specify metricAggregationType?
AWS defaults to Average aggregation. Valid values are Minimum, Maximum, and Average.
Advanced Features
How do I create a target tracking scaling policy?
Set policyType to TargetTrackingScaling and configure targetTrackingConfiguration with either a predefinedMetricSpecification (like ASGAverageCPUUtilization) or a customizedMetricSpecification for custom metrics.
How do I use metric math in a target tracking policy?
Define multiple metrics in customizedMetricSpecification.metrics, each with a unique id. Use the expression field to combine metrics mathematically (e.g., m1 / m2 for backlog per instance). Set returnData: true on the final calculated metric and false on input metrics.
How do I configure step scaling adjustments?
Use the stepAdjustments array with objects containing scalingAdjustment, metricIntervalLowerBound, and metricIntervalUpperBound. Each step defines a different scaling action based on metric threshold ranges.
How do I create a predictive scaling policy?
Set policyType to PredictiveScaling and configure predictiveScalingConfiguration.metricSpecification with load, capacity, and scaling metrics. You can use predefined metrics (like ASGTotalCPUUtilization) or customized metric specifications with CloudWatch metric queries.
Common Issues & Limitations
What properties are immutable after creation?
Both autoscalingGroupName and name are immutable. Changing either requires replacing the policy resource.
When is minAdjustmentMagnitude used?
minAdjustmentMagnitude sets the minimum number of instances to scale when adjustmentType is PercentChangeInCapacity. This ensures small percentage changes still scale by at least this many instances.

Using a different cloud?

Explore compute guides for other cloud providers: