Create AWS Auto Scaling Groups

The aws:autoscaling/group:Group resource, part of the Pulumi AWS provider, defines an Auto Scaling group that manages EC2 instance capacity: launch configuration, size constraints, and scaling behavior. This guide focuses on four capabilities: launch template integration, mixed instances policies with spot and on-demand, instance refresh for configuration rollouts, and warm pools for faster scaling.

Auto Scaling groups require launch templates or launch configurations, run in VPC subnets or availability zones, and often integrate with load balancers and CloudWatch alarms. The examples are intentionally small. Combine them with your own networking, health checks, and scaling policies.

Launch instances from a template version

Most deployments start by defining a launch template that specifies the AMI and instance type, then referencing that template in the Auto Scaling group.

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

const foobar = new aws.ec2.LaunchTemplate("foobar", {
    namePrefix: "foobar",
    imageId: "ami-1a2b3c",
    instanceType: "t2.micro",
});
const bar = new aws.autoscaling.Group("bar", {
    availabilityZones: ["us-east-1a"],
    desiredCapacity: 1,
    maxSize: 1,
    minSize: 1,
    launchTemplate: {
        id: foobar.id,
        version: "$Latest",
    },
});
import pulumi
import pulumi_aws as aws

foobar = aws.ec2.LaunchTemplate("foobar",
    name_prefix="foobar",
    image_id="ami-1a2b3c",
    instance_type="t2.micro")
bar = aws.autoscaling.Group("bar",
    availability_zones=["us-east-1a"],
    desired_capacity=1,
    max_size=1,
    min_size=1,
    launch_template={
        "id": foobar.id,
        "version": "$Latest",
    })
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 {
		foobar, err := ec2.NewLaunchTemplate(ctx, "foobar", &ec2.LaunchTemplateArgs{
			NamePrefix:   pulumi.String("foobar"),
			ImageId:      pulumi.String("ami-1a2b3c"),
			InstanceType: pulumi.String("t2.micro"),
		})
		if err != nil {
			return err
		}
		_, err = autoscaling.NewGroup(ctx, "bar", &autoscaling.GroupArgs{
			AvailabilityZones: pulumi.StringArray{
				pulumi.String("us-east-1a"),
			},
			DesiredCapacity: pulumi.Int(1),
			MaxSize:         pulumi.Int(1),
			MinSize:         pulumi.Int(1),
			LaunchTemplate: &autoscaling.GroupLaunchTemplateArgs{
				Id:      foobar.ID(),
				Version: pulumi.String("$Latest"),
			},
		})
		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 foobar = new Aws.Ec2.LaunchTemplate("foobar", new()
    {
        NamePrefix = "foobar",
        ImageId = "ami-1a2b3c",
        InstanceType = "t2.micro",
    });

    var bar = new Aws.AutoScaling.Group("bar", new()
    {
        AvailabilityZones = new[]
        {
            "us-east-1a",
        },
        DesiredCapacity = 1,
        MaxSize = 1,
        MinSize = 1,
        LaunchTemplate = new Aws.AutoScaling.Inputs.GroupLaunchTemplateArgs
        {
            Id = foobar.Id,
            Version = "$Latest",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ec2.LaunchTemplate;
import com.pulumi.aws.ec2.LaunchTemplateArgs;
import com.pulumi.aws.autoscaling.Group;
import com.pulumi.aws.autoscaling.GroupArgs;
import com.pulumi.aws.autoscaling.inputs.GroupLaunchTemplateArgs;
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 foobar = new LaunchTemplate("foobar", LaunchTemplateArgs.builder()
            .namePrefix("foobar")
            .imageId("ami-1a2b3c")
            .instanceType("t2.micro")
            .build());

        var bar = new Group("bar", GroupArgs.builder()
            .availabilityZones("us-east-1a")
            .desiredCapacity(1)
            .maxSize(1)
            .minSize(1)
            .launchTemplate(GroupLaunchTemplateArgs.builder()
                .id(foobar.id())
                .version("$Latest")
                .build())
            .build());

    }
}
resources:
  foobar:
    type: aws:ec2:LaunchTemplate
    properties:
      namePrefix: foobar
      imageId: ami-1a2b3c
      instanceType: t2.micro
  bar:
    type: aws:autoscaling:Group
    properties:
      availabilityZones:
        - us-east-1a
      desiredCapacity: 1
      maxSize: 1
      minSize: 1
      launchTemplate:
        id: ${foobar.id}
        version: $Latest

The launchTemplate block points to your template by ID and specifies which version to use. The $Latest version ensures new instances always use the most recent template configuration. The capacity properties (minSize, maxSize, desiredCapacity) control how many instances Auto Scaling maintains.

Mix instance types with weighted capacity

Applications that can run on different instance types benefit from mixed instances policies, which let Auto Scaling choose from multiple types to optimize cost and availability.

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

const example = new aws.ec2.LaunchTemplate("example", {
    namePrefix: "example",
    imageId: exampleAwsAmi.id,
    instanceType: "c5.large",
});
const exampleGroup = new aws.autoscaling.Group("example", {
    availabilityZones: ["us-east-1a"],
    desiredCapacity: 1,
    maxSize: 1,
    minSize: 1,
    mixedInstancesPolicy: {
        launchTemplate: {
            launchTemplateSpecification: {
                launchTemplateId: example.id,
            },
            overrides: [
                {
                    instanceType: "c4.large",
                    weightedCapacity: "3",
                },
                {
                    instanceType: "c3.large",
                    weightedCapacity: "2",
                },
            ],
        },
    },
});
import pulumi
import pulumi_aws as aws

example = aws.ec2.LaunchTemplate("example",
    name_prefix="example",
    image_id=example_aws_ami["id"],
    instance_type="c5.large")
example_group = aws.autoscaling.Group("example",
    availability_zones=["us-east-1a"],
    desired_capacity=1,
    max_size=1,
    min_size=1,
    mixed_instances_policy={
        "launch_template": {
            "launch_template_specification": {
                "launch_template_id": example.id,
            },
            "overrides": [
                {
                    "instance_type": "c4.large",
                    "weighted_capacity": "3",
                },
                {
                    "instance_type": "c3.large",
                    "weighted_capacity": "2",
                },
            ],
        },
    })
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 {
		example, err := ec2.NewLaunchTemplate(ctx, "example", &ec2.LaunchTemplateArgs{
			NamePrefix:   pulumi.String("example"),
			ImageId:      pulumi.Any(exampleAwsAmi.Id),
			InstanceType: pulumi.String("c5.large"),
		})
		if err != nil {
			return err
		}
		_, err = autoscaling.NewGroup(ctx, "example", &autoscaling.GroupArgs{
			AvailabilityZones: pulumi.StringArray{
				pulumi.String("us-east-1a"),
			},
			DesiredCapacity: pulumi.Int(1),
			MaxSize:         pulumi.Int(1),
			MinSize:         pulumi.Int(1),
			MixedInstancesPolicy: &autoscaling.GroupMixedInstancesPolicyArgs{
				LaunchTemplate: &autoscaling.GroupMixedInstancesPolicyLaunchTemplateArgs{
					LaunchTemplateSpecification: &autoscaling.GroupMixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationArgs{
						LaunchTemplateId: example.ID(),
					},
					Overrides: autoscaling.GroupMixedInstancesPolicyLaunchTemplateOverrideArray{
						&autoscaling.GroupMixedInstancesPolicyLaunchTemplateOverrideArgs{
							InstanceType:     pulumi.String("c4.large"),
							WeightedCapacity: pulumi.String("3"),
						},
						&autoscaling.GroupMixedInstancesPolicyLaunchTemplateOverrideArgs{
							InstanceType:     pulumi.String("c3.large"),
							WeightedCapacity: pulumi.String("2"),
						},
					},
				},
			},
		})
		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.Ec2.LaunchTemplate("example", new()
    {
        NamePrefix = "example",
        ImageId = exampleAwsAmi.Id,
        InstanceType = "c5.large",
    });

    var exampleGroup = new Aws.AutoScaling.Group("example", new()
    {
        AvailabilityZones = new[]
        {
            "us-east-1a",
        },
        DesiredCapacity = 1,
        MaxSize = 1,
        MinSize = 1,
        MixedInstancesPolicy = new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyArgs
        {
            LaunchTemplate = new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyLaunchTemplateArgs
            {
                LaunchTemplateSpecification = new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationArgs
                {
                    LaunchTemplateId = example.Id,
                },
                Overrides = new[]
                {
                    new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyLaunchTemplateOverrideArgs
                    {
                        InstanceType = "c4.large",
                        WeightedCapacity = "3",
                    },
                    new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyLaunchTemplateOverrideArgs
                    {
                        InstanceType = "c3.large",
                        WeightedCapacity = "2",
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ec2.LaunchTemplate;
import com.pulumi.aws.ec2.LaunchTemplateArgs;
import com.pulumi.aws.autoscaling.Group;
import com.pulumi.aws.autoscaling.GroupArgs;
import com.pulumi.aws.autoscaling.inputs.GroupMixedInstancesPolicyArgs;
import com.pulumi.aws.autoscaling.inputs.GroupMixedInstancesPolicyLaunchTemplateArgs;
import com.pulumi.aws.autoscaling.inputs.GroupMixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationArgs;
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 LaunchTemplate("example", LaunchTemplateArgs.builder()
            .namePrefix("example")
            .imageId(exampleAwsAmi.id())
            .instanceType("c5.large")
            .build());

        var exampleGroup = new Group("exampleGroup", GroupArgs.builder()
            .availabilityZones("us-east-1a")
            .desiredCapacity(1)
            .maxSize(1)
            .minSize(1)
            .mixedInstancesPolicy(GroupMixedInstancesPolicyArgs.builder()
                .launchTemplate(GroupMixedInstancesPolicyLaunchTemplateArgs.builder()
                    .launchTemplateSpecification(GroupMixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationArgs.builder()
                        .launchTemplateId(example.id())
                        .build())
                    .overrides(                    
                        GroupMixedInstancesPolicyLaunchTemplateOverrideArgs.builder()
                            .instanceType("c4.large")
                            .weightedCapacity("3")
                            .build(),
                        GroupMixedInstancesPolicyLaunchTemplateOverrideArgs.builder()
                            .instanceType("c3.large")
                            .weightedCapacity("2")
                            .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:ec2:LaunchTemplate
    properties:
      namePrefix: example
      imageId: ${exampleAwsAmi.id}
      instanceType: c5.large
  exampleGroup:
    type: aws:autoscaling:Group
    name: example
    properties:
      availabilityZones:
        - us-east-1a
      desiredCapacity: 1
      maxSize: 1
      minSize: 1
      mixedInstancesPolicy:
        launchTemplate:
          launchTemplateSpecification:
            launchTemplateId: ${example.id}
          overrides:
            - instanceType: c4.large
              weightedCapacity: '3'
            - instanceType: c3.large
              weightedCapacity: '2'

The mixedInstancesPolicy defines a base launch template and a list of instance type overrides. Each override specifies an instance type and weighted capacity, which tells Auto Scaling how much capacity that instance type provides. A c4.large with weight 3 counts as three units of capacity, while a c3.large with weight 2 counts as two units.

Optimize costs with spot instances and rebalancing

Workloads that tolerate interruption can reduce costs by mixing on-demand and spot instances, with capacity rebalancing to proactively replace at-risk spot instances.

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

const example = new aws.ec2.LaunchTemplate("example", {
    namePrefix: "example",
    imageId: exampleAwsAmi.id,
    instanceType: "c5.large",
});
const exampleGroup = new aws.autoscaling.Group("example", {
    capacityRebalance: true,
    desiredCapacity: 12,
    maxSize: 15,
    minSize: 12,
    vpcZoneIdentifiers: [
        example1.id,
        example2.id,
    ],
    mixedInstancesPolicy: {
        instancesDistribution: {
            onDemandBaseCapacity: 0,
            onDemandPercentageAboveBaseCapacity: 25,
            spotAllocationStrategy: "capacity-optimized",
        },
        launchTemplate: {
            launchTemplateSpecification: {
                launchTemplateId: example.id,
            },
            overrides: [
                {
                    instanceType: "c4.large",
                    weightedCapacity: "3",
                },
                {
                    instanceType: "c3.large",
                    weightedCapacity: "2",
                },
            ],
        },
    },
});
import pulumi
import pulumi_aws as aws

example = aws.ec2.LaunchTemplate("example",
    name_prefix="example",
    image_id=example_aws_ami["id"],
    instance_type="c5.large")
example_group = aws.autoscaling.Group("example",
    capacity_rebalance=True,
    desired_capacity=12,
    max_size=15,
    min_size=12,
    vpc_zone_identifiers=[
        example1["id"],
        example2["id"],
    ],
    mixed_instances_policy={
        "instances_distribution": {
            "on_demand_base_capacity": 0,
            "on_demand_percentage_above_base_capacity": 25,
            "spot_allocation_strategy": "capacity-optimized",
        },
        "launch_template": {
            "launch_template_specification": {
                "launch_template_id": example.id,
            },
            "overrides": [
                {
                    "instance_type": "c4.large",
                    "weighted_capacity": "3",
                },
                {
                    "instance_type": "c3.large",
                    "weighted_capacity": "2",
                },
            ],
        },
    })
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 {
		example, err := ec2.NewLaunchTemplate(ctx, "example", &ec2.LaunchTemplateArgs{
			NamePrefix:   pulumi.String("example"),
			ImageId:      pulumi.Any(exampleAwsAmi.Id),
			InstanceType: pulumi.String("c5.large"),
		})
		if err != nil {
			return err
		}
		_, err = autoscaling.NewGroup(ctx, "example", &autoscaling.GroupArgs{
			CapacityRebalance: pulumi.Bool(true),
			DesiredCapacity:   pulumi.Int(12),
			MaxSize:           pulumi.Int(15),
			MinSize:           pulumi.Int(12),
			VpcZoneIdentifiers: pulumi.StringArray{
				example1.Id,
				example2.Id,
			},
			MixedInstancesPolicy: &autoscaling.GroupMixedInstancesPolicyArgs{
				InstancesDistribution: &autoscaling.GroupMixedInstancesPolicyInstancesDistributionArgs{
					OnDemandBaseCapacity:                pulumi.Int(0),
					OnDemandPercentageAboveBaseCapacity: pulumi.Int(25),
					SpotAllocationStrategy:              pulumi.String("capacity-optimized"),
				},
				LaunchTemplate: &autoscaling.GroupMixedInstancesPolicyLaunchTemplateArgs{
					LaunchTemplateSpecification: &autoscaling.GroupMixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationArgs{
						LaunchTemplateId: example.ID(),
					},
					Overrides: autoscaling.GroupMixedInstancesPolicyLaunchTemplateOverrideArray{
						&autoscaling.GroupMixedInstancesPolicyLaunchTemplateOverrideArgs{
							InstanceType:     pulumi.String("c4.large"),
							WeightedCapacity: pulumi.String("3"),
						},
						&autoscaling.GroupMixedInstancesPolicyLaunchTemplateOverrideArgs{
							InstanceType:     pulumi.String("c3.large"),
							WeightedCapacity: pulumi.String("2"),
						},
					},
				},
			},
		})
		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.Ec2.LaunchTemplate("example", new()
    {
        NamePrefix = "example",
        ImageId = exampleAwsAmi.Id,
        InstanceType = "c5.large",
    });

    var exampleGroup = new Aws.AutoScaling.Group("example", new()
    {
        CapacityRebalance = true,
        DesiredCapacity = 12,
        MaxSize = 15,
        MinSize = 12,
        VpcZoneIdentifiers = new[]
        {
            example1.Id,
            example2.Id,
        },
        MixedInstancesPolicy = new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyArgs
        {
            InstancesDistribution = new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyInstancesDistributionArgs
            {
                OnDemandBaseCapacity = 0,
                OnDemandPercentageAboveBaseCapacity = 25,
                SpotAllocationStrategy = "capacity-optimized",
            },
            LaunchTemplate = new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyLaunchTemplateArgs
            {
                LaunchTemplateSpecification = new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationArgs
                {
                    LaunchTemplateId = example.Id,
                },
                Overrides = new[]
                {
                    new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyLaunchTemplateOverrideArgs
                    {
                        InstanceType = "c4.large",
                        WeightedCapacity = "3",
                    },
                    new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyLaunchTemplateOverrideArgs
                    {
                        InstanceType = "c3.large",
                        WeightedCapacity = "2",
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ec2.LaunchTemplate;
import com.pulumi.aws.ec2.LaunchTemplateArgs;
import com.pulumi.aws.autoscaling.Group;
import com.pulumi.aws.autoscaling.GroupArgs;
import com.pulumi.aws.autoscaling.inputs.GroupMixedInstancesPolicyArgs;
import com.pulumi.aws.autoscaling.inputs.GroupMixedInstancesPolicyInstancesDistributionArgs;
import com.pulumi.aws.autoscaling.inputs.GroupMixedInstancesPolicyLaunchTemplateArgs;
import com.pulumi.aws.autoscaling.inputs.GroupMixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationArgs;
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 LaunchTemplate("example", LaunchTemplateArgs.builder()
            .namePrefix("example")
            .imageId(exampleAwsAmi.id())
            .instanceType("c5.large")
            .build());

        var exampleGroup = new Group("exampleGroup", GroupArgs.builder()
            .capacityRebalance(true)
            .desiredCapacity(12)
            .maxSize(15)
            .minSize(12)
            .vpcZoneIdentifiers(            
                example1.id(),
                example2.id())
            .mixedInstancesPolicy(GroupMixedInstancesPolicyArgs.builder()
                .instancesDistribution(GroupMixedInstancesPolicyInstancesDistributionArgs.builder()
                    .onDemandBaseCapacity(0)
                    .onDemandPercentageAboveBaseCapacity(25)
                    .spotAllocationStrategy("capacity-optimized")
                    .build())
                .launchTemplate(GroupMixedInstancesPolicyLaunchTemplateArgs.builder()
                    .launchTemplateSpecification(GroupMixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationArgs.builder()
                        .launchTemplateId(example.id())
                        .build())
                    .overrides(                    
                        GroupMixedInstancesPolicyLaunchTemplateOverrideArgs.builder()
                            .instanceType("c4.large")
                            .weightedCapacity("3")
                            .build(),
                        GroupMixedInstancesPolicyLaunchTemplateOverrideArgs.builder()
                            .instanceType("c3.large")
                            .weightedCapacity("2")
                            .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:ec2:LaunchTemplate
    properties:
      namePrefix: example
      imageId: ${exampleAwsAmi.id}
      instanceType: c5.large
  exampleGroup:
    type: aws:autoscaling:Group
    name: example
    properties:
      capacityRebalance: true
      desiredCapacity: 12
      maxSize: 15
      minSize: 12
      vpcZoneIdentifiers:
        - ${example1.id}
        - ${example2.id}
      mixedInstancesPolicy:
        instancesDistribution:
          onDemandBaseCapacity: 0
          onDemandPercentageAboveBaseCapacity: 25
          spotAllocationStrategy: capacity-optimized
        launchTemplate:
          launchTemplateSpecification:
            launchTemplateId: ${example.id}
          overrides:
            - instanceType: c4.large
              weightedCapacity: '3'
            - instanceType: c3.large
              weightedCapacity: '2'

The instancesDistribution block controls the on-demand and spot mix. Setting onDemandBaseCapacity to 0 and onDemandPercentageAboveBaseCapacity to 25 means 25% of capacity runs on-demand, 75% on spot. The capacityRebalance property enables proactive replacement of spot instances that are at elevated risk of interruption.

Select instances by compute requirements

Instead of manually listing instance types, you can specify compute requirements like minimum memory and vCPU count, letting Auto Scaling choose compatible instances.

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

const example = new aws.ec2.LaunchTemplate("example", {
    namePrefix: "example",
    imageId: exampleAwsAmi.id,
    instanceType: "c5.large",
});
const exampleGroup = new aws.autoscaling.Group("example", {
    availabilityZones: ["us-east-1a"],
    desiredCapacity: 1,
    maxSize: 1,
    minSize: 1,
    mixedInstancesPolicy: {
        launchTemplate: {
            launchTemplateSpecification: {
                launchTemplateId: example.id,
            },
            overrides: [{
                instanceRequirements: {
                    memoryMib: {
                        min: 1000,
                    },
                    vcpuCount: {
                        min: 4,
                    },
                },
            }],
        },
    },
});
import pulumi
import pulumi_aws as aws

example = aws.ec2.LaunchTemplate("example",
    name_prefix="example",
    image_id=example_aws_ami["id"],
    instance_type="c5.large")
example_group = aws.autoscaling.Group("example",
    availability_zones=["us-east-1a"],
    desired_capacity=1,
    max_size=1,
    min_size=1,
    mixed_instances_policy={
        "launch_template": {
            "launch_template_specification": {
                "launch_template_id": example.id,
            },
            "overrides": [{
                "instance_requirements": {
                    "memory_mib": {
                        "min": 1000,
                    },
                    "vcpu_count": {
                        "min": 4,
                    },
                },
            }],
        },
    })
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 {
		example, err := ec2.NewLaunchTemplate(ctx, "example", &ec2.LaunchTemplateArgs{
			NamePrefix:   pulumi.String("example"),
			ImageId:      pulumi.Any(exampleAwsAmi.Id),
			InstanceType: pulumi.String("c5.large"),
		})
		if err != nil {
			return err
		}
		_, err = autoscaling.NewGroup(ctx, "example", &autoscaling.GroupArgs{
			AvailabilityZones: pulumi.StringArray{
				pulumi.String("us-east-1a"),
			},
			DesiredCapacity: pulumi.Int(1),
			MaxSize:         pulumi.Int(1),
			MinSize:         pulumi.Int(1),
			MixedInstancesPolicy: &autoscaling.GroupMixedInstancesPolicyArgs{
				LaunchTemplate: &autoscaling.GroupMixedInstancesPolicyLaunchTemplateArgs{
					LaunchTemplateSpecification: &autoscaling.GroupMixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationArgs{
						LaunchTemplateId: example.ID(),
					},
					Overrides: autoscaling.GroupMixedInstancesPolicyLaunchTemplateOverrideArray{
						&autoscaling.GroupMixedInstancesPolicyLaunchTemplateOverrideArgs{
							InstanceRequirements: &autoscaling.GroupMixedInstancesPolicyLaunchTemplateOverrideInstanceRequirementsArgs{
								MemoryMib: &autoscaling.GroupMixedInstancesPolicyLaunchTemplateOverrideInstanceRequirementsMemoryMibArgs{
									Min: pulumi.Int(1000),
								},
								VcpuCount: &autoscaling.GroupMixedInstancesPolicyLaunchTemplateOverrideInstanceRequirementsVcpuCountArgs{
									Min: pulumi.Int(4),
								},
							},
						},
					},
				},
			},
		})
		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.Ec2.LaunchTemplate("example", new()
    {
        NamePrefix = "example",
        ImageId = exampleAwsAmi.Id,
        InstanceType = "c5.large",
    });

    var exampleGroup = new Aws.AutoScaling.Group("example", new()
    {
        AvailabilityZones = new[]
        {
            "us-east-1a",
        },
        DesiredCapacity = 1,
        MaxSize = 1,
        MinSize = 1,
        MixedInstancesPolicy = new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyArgs
        {
            LaunchTemplate = new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyLaunchTemplateArgs
            {
                LaunchTemplateSpecification = new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationArgs
                {
                    LaunchTemplateId = example.Id,
                },
                Overrides = new[]
                {
                    new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyLaunchTemplateOverrideArgs
                    {
                        InstanceRequirements = new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyLaunchTemplateOverrideInstanceRequirementsArgs
                        {
                            MemoryMib = new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyLaunchTemplateOverrideInstanceRequirementsMemoryMibArgs
                            {
                                Min = 1000,
                            },
                            VcpuCount = new Aws.AutoScaling.Inputs.GroupMixedInstancesPolicyLaunchTemplateOverrideInstanceRequirementsVcpuCountArgs
                            {
                                Min = 4,
                            },
                        },
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ec2.LaunchTemplate;
import com.pulumi.aws.ec2.LaunchTemplateArgs;
import com.pulumi.aws.autoscaling.Group;
import com.pulumi.aws.autoscaling.GroupArgs;
import com.pulumi.aws.autoscaling.inputs.GroupMixedInstancesPolicyArgs;
import com.pulumi.aws.autoscaling.inputs.GroupMixedInstancesPolicyLaunchTemplateArgs;
import com.pulumi.aws.autoscaling.inputs.GroupMixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationArgs;
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 LaunchTemplate("example", LaunchTemplateArgs.builder()
            .namePrefix("example")
            .imageId(exampleAwsAmi.id())
            .instanceType("c5.large")
            .build());

        var exampleGroup = new Group("exampleGroup", GroupArgs.builder()
            .availabilityZones("us-east-1a")
            .desiredCapacity(1)
            .maxSize(1)
            .minSize(1)
            .mixedInstancesPolicy(GroupMixedInstancesPolicyArgs.builder()
                .launchTemplate(GroupMixedInstancesPolicyLaunchTemplateArgs.builder()
                    .launchTemplateSpecification(GroupMixedInstancesPolicyLaunchTemplateLaunchTemplateSpecificationArgs.builder()
                        .launchTemplateId(example.id())
                        .build())
                    .overrides(GroupMixedInstancesPolicyLaunchTemplateOverrideArgs.builder()
                        .instanceRequirements(GroupMixedInstancesPolicyLaunchTemplateOverrideInstanceRequirementsArgs.builder()
                            .memoryMib(GroupMixedInstancesPolicyLaunchTemplateOverrideInstanceRequirementsMemoryMibArgs.builder()
                                .min(1000)
                                .build())
                            .vcpuCount(GroupMixedInstancesPolicyLaunchTemplateOverrideInstanceRequirementsVcpuCountArgs.builder()
                                .min(4)
                                .build())
                            .build())
                        .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:ec2:LaunchTemplate
    properties:
      namePrefix: example
      imageId: ${exampleAwsAmi.id}
      instanceType: c5.large
  exampleGroup:
    type: aws:autoscaling:Group
    name: example
    properties:
      availabilityZones:
        - us-east-1a
      desiredCapacity: 1
      maxSize: 1
      minSize: 1
      mixedInstancesPolicy:
        launchTemplate:
          launchTemplateSpecification:
            launchTemplateId: ${example.id}
          overrides:
            - instanceRequirements:
                memoryMib:
                  min: 1000
                vcpuCount:
                  min: 4

The instanceRequirements block defines minimum memory and vCPU constraints. Auto Scaling selects instance types that meet these requirements, automatically adapting to availability and pricing across the instance catalog. This approach simplifies configuration when you care about compute capacity rather than specific instance families.

Roll out template changes with instance refresh

When you update a launch template, existing instances continue running the old configuration. Instance refresh automates the rollout by gradually replacing instances.

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

const example = aws.ec2.getAmi({
    mostRecent: true,
    owners: ["amazon"],
    filters: [{
        name: "name",
        values: ["amzn-ami-hvm-*-x86_64-gp2"],
    }],
});
const exampleLaunchTemplate = new aws.ec2.LaunchTemplate("example", {
    imageId: example.then(example => example.id),
    instanceType: "t3.nano",
});
const exampleGroup = new aws.autoscaling.Group("example", {
    availabilityZones: ["us-east-1a"],
    desiredCapacity: 1,
    maxSize: 2,
    minSize: 1,
    launchTemplate: {
        id: exampleLaunchTemplate.id,
        version: exampleLaunchTemplate.latestVersion,
    },
    tags: [{
        key: "Key",
        value: "Value",
        propagateAtLaunch: true,
    }],
    instanceRefresh: {
        strategy: "Rolling",
        preferences: {
            minHealthyPercentage: 50,
        },
        triggers: ["tag"],
    },
});
import pulumi
import pulumi_aws as aws

example = aws.ec2.get_ami(most_recent=True,
    owners=["amazon"],
    filters=[{
        "name": "name",
        "values": ["amzn-ami-hvm-*-x86_64-gp2"],
    }])
example_launch_template = aws.ec2.LaunchTemplate("example",
    image_id=example.id,
    instance_type="t3.nano")
example_group = aws.autoscaling.Group("example",
    availability_zones=["us-east-1a"],
    desired_capacity=1,
    max_size=2,
    min_size=1,
    launch_template={
        "id": example_launch_template.id,
        "version": example_launch_template.latest_version,
    },
    tags=[{
        "key": "Key",
        "value": "Value",
        "propagate_at_launch": True,
    }],
    instance_refresh={
        "strategy": "Rolling",
        "preferences": {
            "min_healthy_percentage": 50,
        },
        "triggers": ["tag"],
    })
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 {
		example, err := ec2.LookupAmi(ctx, &ec2.LookupAmiArgs{
			MostRecent: pulumi.BoolRef(true),
			Owners: []string{
				"amazon",
			},
			Filters: []ec2.GetAmiFilter{
				{
					Name: "name",
					Values: []string{
						"amzn-ami-hvm-*-x86_64-gp2",
					},
				},
			},
		}, nil)
		if err != nil {
			return err
		}
		exampleLaunchTemplate, err := ec2.NewLaunchTemplate(ctx, "example", &ec2.LaunchTemplateArgs{
			ImageId:      pulumi.String(example.Id),
			InstanceType: pulumi.String("t3.nano"),
		})
		if err != nil {
			return err
		}
		_, err = autoscaling.NewGroup(ctx, "example", &autoscaling.GroupArgs{
			AvailabilityZones: pulumi.StringArray{
				pulumi.String("us-east-1a"),
			},
			DesiredCapacity: pulumi.Int(1),
			MaxSize:         pulumi.Int(2),
			MinSize:         pulumi.Int(1),
			LaunchTemplate: &autoscaling.GroupLaunchTemplateArgs{
				Id:      exampleLaunchTemplate.ID(),
				Version: exampleLaunchTemplate.LatestVersion,
			},
			Tags: autoscaling.GroupTagArray{
				&autoscaling.GroupTagArgs{
					Key:               pulumi.String("Key"),
					Value:             pulumi.String("Value"),
					PropagateAtLaunch: pulumi.Bool(true),
				},
			},
			InstanceRefresh: &autoscaling.GroupInstanceRefreshArgs{
				Strategy: pulumi.String("Rolling"),
				Preferences: &autoscaling.GroupInstanceRefreshPreferencesArgs{
					MinHealthyPercentage: pulumi.Int(50),
				},
				Triggers: pulumi.StringArray{
					pulumi.String("tag"),
				},
			},
		})
		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 = Aws.Ec2.GetAmi.Invoke(new()
    {
        MostRecent = true,
        Owners = new[]
        {
            "amazon",
        },
        Filters = new[]
        {
            new Aws.Ec2.Inputs.GetAmiFilterInputArgs
            {
                Name = "name",
                Values = new[]
                {
                    "amzn-ami-hvm-*-x86_64-gp2",
                },
            },
        },
    });

    var exampleLaunchTemplate = new Aws.Ec2.LaunchTemplate("example", new()
    {
        ImageId = example.Apply(getAmiResult => getAmiResult.Id),
        InstanceType = "t3.nano",
    });

    var exampleGroup = new Aws.AutoScaling.Group("example", new()
    {
        AvailabilityZones = new[]
        {
            "us-east-1a",
        },
        DesiredCapacity = 1,
        MaxSize = 2,
        MinSize = 1,
        LaunchTemplate = new Aws.AutoScaling.Inputs.GroupLaunchTemplateArgs
        {
            Id = exampleLaunchTemplate.Id,
            Version = exampleLaunchTemplate.LatestVersion,
        },
        Tags = new[]
        {
            new Aws.AutoScaling.Inputs.GroupTagArgs
            {
                Key = "Key",
                Value = "Value",
                PropagateAtLaunch = true,
            },
        },
        InstanceRefresh = new Aws.AutoScaling.Inputs.GroupInstanceRefreshArgs
        {
            Strategy = "Rolling",
            Preferences = new Aws.AutoScaling.Inputs.GroupInstanceRefreshPreferencesArgs
            {
                MinHealthyPercentage = 50,
            },
            Triggers = new[]
            {
                "tag",
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ec2.Ec2Functions;
import com.pulumi.aws.ec2.inputs.GetAmiArgs;
import com.pulumi.aws.ec2.LaunchTemplate;
import com.pulumi.aws.ec2.LaunchTemplateArgs;
import com.pulumi.aws.autoscaling.Group;
import com.pulumi.aws.autoscaling.GroupArgs;
import com.pulumi.aws.autoscaling.inputs.GroupLaunchTemplateArgs;
import com.pulumi.aws.autoscaling.inputs.GroupTagArgs;
import com.pulumi.aws.autoscaling.inputs.GroupInstanceRefreshArgs;
import com.pulumi.aws.autoscaling.inputs.GroupInstanceRefreshPreferencesArgs;
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) {
        final var example = Ec2Functions.getAmi(GetAmiArgs.builder()
            .mostRecent(true)
            .owners("amazon")
            .filters(GetAmiFilterArgs.builder()
                .name("name")
                .values("amzn-ami-hvm-*-x86_64-gp2")
                .build())
            .build());

        var exampleLaunchTemplate = new LaunchTemplate("exampleLaunchTemplate", LaunchTemplateArgs.builder()
            .imageId(example.id())
            .instanceType("t3.nano")
            .build());

        var exampleGroup = new Group("exampleGroup", GroupArgs.builder()
            .availabilityZones("us-east-1a")
            .desiredCapacity(1)
            .maxSize(2)
            .minSize(1)
            .launchTemplate(GroupLaunchTemplateArgs.builder()
                .id(exampleLaunchTemplate.id())
                .version(exampleLaunchTemplate.latestVersion())
                .build())
            .tags(GroupTagArgs.builder()
                .key("Key")
                .value("Value")
                .propagateAtLaunch(true)
                .build())
            .instanceRefresh(GroupInstanceRefreshArgs.builder()
                .strategy("Rolling")
                .preferences(GroupInstanceRefreshPreferencesArgs.builder()
                    .minHealthyPercentage(50)
                    .build())
                .triggers("tag")
                .build())
            .build());

    }
}
resources:
  exampleGroup:
    type: aws:autoscaling:Group
    name: example
    properties:
      availabilityZones:
        - us-east-1a
      desiredCapacity: 1
      maxSize: 2
      minSize: 1
      launchTemplate:
        id: ${exampleLaunchTemplate.id}
        version: ${exampleLaunchTemplate.latestVersion}
      tags:
        - key: Key
          value: Value
          propagateAtLaunch: true
      instanceRefresh:
        strategy: Rolling
        preferences:
          minHealthyPercentage: 50
        triggers:
          - tag
  exampleLaunchTemplate:
    type: aws:ec2:LaunchTemplate
    name: example
    properties:
      imageId: ${example.id}
      instanceType: t3.nano
variables:
  example:
    fn::invoke:
      function: aws:ec2:getAmi
      arguments:
        mostRecent: true
        owners:
          - amazon
        filters:
          - name: name
            values:
              - amzn-ami-hvm-*-x86_64-gp2

The instanceRefresh block defines how updates roll out. The Rolling strategy replaces instances in batches, maintaining at least minHealthyPercentage of capacity throughout the refresh. The triggers property lists which changes should start a refresh; here, tag changes trigger automatic rollouts.

Pre-initialize instances in a warm pool

Applications with slow startup times can maintain a pool of pre-initialized instances that are ready to enter service quickly when scaling events occur.

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

const example = new aws.ec2.LaunchTemplate("example", {
    namePrefix: "example",
    imageId: exampleAwsAmi.id,
    instanceType: "c5.large",
});
const exampleGroup = new aws.autoscaling.Group("example", {
    availabilityZones: ["us-east-1a"],
    desiredCapacity: 1,
    maxSize: 5,
    minSize: 1,
    warmPool: {
        poolState: "Hibernated",
        minSize: 1,
        maxGroupPreparedCapacity: 10,
        instanceReusePolicy: {
            reuseOnScaleIn: true,
        },
    },
});
import pulumi
import pulumi_aws as aws

example = aws.ec2.LaunchTemplate("example",
    name_prefix="example",
    image_id=example_aws_ami["id"],
    instance_type="c5.large")
example_group = aws.autoscaling.Group("example",
    availability_zones=["us-east-1a"],
    desired_capacity=1,
    max_size=5,
    min_size=1,
    warm_pool={
        "pool_state": "Hibernated",
        "min_size": 1,
        "max_group_prepared_capacity": 10,
        "instance_reuse_policy": {
            "reuse_on_scale_in": True,
        },
    })
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 {
		_, err := ec2.NewLaunchTemplate(ctx, "example", &ec2.LaunchTemplateArgs{
			NamePrefix:   pulumi.String("example"),
			ImageId:      pulumi.Any(exampleAwsAmi.Id),
			InstanceType: pulumi.String("c5.large"),
		})
		if err != nil {
			return err
		}
		_, err = autoscaling.NewGroup(ctx, "example", &autoscaling.GroupArgs{
			AvailabilityZones: pulumi.StringArray{
				pulumi.String("us-east-1a"),
			},
			DesiredCapacity: pulumi.Int(1),
			MaxSize:         pulumi.Int(5),
			MinSize:         pulumi.Int(1),
			WarmPool: &autoscaling.GroupWarmPoolArgs{
				PoolState:                pulumi.String("Hibernated"),
				MinSize:                  pulumi.Int(1),
				MaxGroupPreparedCapacity: pulumi.Int(10),
				InstanceReusePolicy: &autoscaling.GroupWarmPoolInstanceReusePolicyArgs{
					ReuseOnScaleIn: 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.Ec2.LaunchTemplate("example", new()
    {
        NamePrefix = "example",
        ImageId = exampleAwsAmi.Id,
        InstanceType = "c5.large",
    });

    var exampleGroup = new Aws.AutoScaling.Group("example", new()
    {
        AvailabilityZones = new[]
        {
            "us-east-1a",
        },
        DesiredCapacity = 1,
        MaxSize = 5,
        MinSize = 1,
        WarmPool = new Aws.AutoScaling.Inputs.GroupWarmPoolArgs
        {
            PoolState = "Hibernated",
            MinSize = 1,
            MaxGroupPreparedCapacity = 10,
            InstanceReusePolicy = new Aws.AutoScaling.Inputs.GroupWarmPoolInstanceReusePolicyArgs
            {
                ReuseOnScaleIn = true,
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ec2.LaunchTemplate;
import com.pulumi.aws.ec2.LaunchTemplateArgs;
import com.pulumi.aws.autoscaling.Group;
import com.pulumi.aws.autoscaling.GroupArgs;
import com.pulumi.aws.autoscaling.inputs.GroupWarmPoolArgs;
import com.pulumi.aws.autoscaling.inputs.GroupWarmPoolInstanceReusePolicyArgs;
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 LaunchTemplate("example", LaunchTemplateArgs.builder()
            .namePrefix("example")
            .imageId(exampleAwsAmi.id())
            .instanceType("c5.large")
            .build());

        var exampleGroup = new Group("exampleGroup", GroupArgs.builder()
            .availabilityZones("us-east-1a")
            .desiredCapacity(1)
            .maxSize(5)
            .minSize(1)
            .warmPool(GroupWarmPoolArgs.builder()
                .poolState("Hibernated")
                .minSize(1)
                .maxGroupPreparedCapacity(10)
                .instanceReusePolicy(GroupWarmPoolInstanceReusePolicyArgs.builder()
                    .reuseOnScaleIn(true)
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:ec2:LaunchTemplate
    properties:
      namePrefix: example
      imageId: ${exampleAwsAmi.id}
      instanceType: c5.large
  exampleGroup:
    type: aws:autoscaling:Group
    name: example
    properties:
      availabilityZones:
        - us-east-1a
      desiredCapacity: 1
      maxSize: 5
      minSize: 1
      warmPool:
        poolState: Hibernated
        minSize: 1
        maxGroupPreparedCapacity: 10
        instanceReusePolicy:
          reuseOnScaleIn: true

The warmPool block configures a pool of instances that are stopped or hibernated until needed. The poolState determines whether instances are stopped or hibernated. The instanceReusePolicy controls whether instances return to the warm pool when scaling in, reducing initialization overhead for future scale-out events.

Beyond these examples

These snippets focus on specific Auto Scaling group features: launch templates and mixed instances policies, spot instances and capacity rebalancing, and instance refresh and warm pools. They’re intentionally minimal rather than full scaling solutions.

The examples may reference pre-existing infrastructure such as launch templates with AMI and instance configuration, VPC subnets for instance placement, and IAM roles for lifecycle hooks. They focus on configuring the Auto Scaling group rather than provisioning everything around it.

To keep things focused, common Auto Scaling patterns are omitted, including:

  • Load balancer integration (loadBalancers, targetGroupArns)
  • Health check configuration (healthCheckType, healthCheckGracePeriod)
  • Scaling policies and CloudWatch alarms
  • Lifecycle hooks for custom instance initialization
  • Placement groups and availability zone distribution
  • Termination policies and instance protection

These omissions are intentional: the goal is to illustrate how each Auto Scaling feature is wired, not provide drop-in scaling modules. See the Auto Scaling Group resource reference for all available configuration options.

Let's create AWS Auto Scaling Groups

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Launch Configuration & Instance Types
What are my options for launching instances in an Auto Scaling Group?
You must specify exactly one of three options: launchConfiguration (legacy), launchTemplate (recommended), or mixedInstancesPolicy (for mixing spot and on-demand instances).
How do I use the latest version of a launch template?
Set launchTemplate.version to $Latest to automatically use the most recent version.
How do I mix spot and on-demand instances?
Use mixedInstancesPolicy with instancesDistribution to configure the spot allocation strategy and on-demand percentage. Enable capacityRebalance to handle spot interruptions gracefully.
Can I use attribute-based instance type selection instead of specifying exact types?
Yes, configure mixedInstancesPolicy.launchTemplate.overrides with instanceRequirements to specify memory and vCPU constraints rather than exact instance types.
Networking & Availability Zones
Should I use availabilityZones or vpcZoneIdentifiers?
These properties conflict with each other. Use availabilityZones to launch into default VPC subnets, or vpcZoneIdentifiers to specify exact subnet IDs (recommended for most use cases).
Capacity & Scaling
How does Pulumi wait for Auto Scaling Group capacity?
By default, Pulumi waits for minSize (or desiredCapacity if specified) healthy instances before continuing. Instances are considered healthy when they report HealthStatus: "Healthy" and LifecycleState: "InService". Set waitForCapacityTimeout to “0” to skip this waiting behavior.
How do I wait for instances to be healthy in load balancers?
Use minElbCapacity to wait for a minimum number of healthy instances in ELBs on creation only, or waitForElbCapacity to wait for an exact number on both create and update operations. waitForElbCapacity takes precedence over minElbCapacity.
How do I automatically refresh instances when the Auto Scaling Group updates?
Configure instanceRefresh with a strategy like “Rolling” and specify triggers (e.g., “tag”) to automatically refresh instances when certain properties change.
Load Balancer Integration
Why am I getting conflicts with load balancer attachments?
Using the same traffic source in both the ASG resource (loadBalancers, targetGroupArns, trafficSource) and standalone Attachment resources causes conflicts. Choose one approach: manage attachments inline with the ASG or use standalone resources, not both.
Lifecycle & Maintenance
Why don't my initialLifecycleHooks work on updates?
initialLifecycleHooks only works when creating a new Auto Scaling Group. For updates or other use cases, use the standalone aws.autoscaling.LifecycleHook resource instead.
Can suspending processes break my Auto Scaling Group?
Yes, suspending the Launch or Terminate process types can prevent your Auto Scaling Group from functioning properly. Only suspend these processes if absolutely necessary.
What happens when I delete an Auto Scaling Group?
By default, Pulumi drains all instances before deleting the group. Set forceDelete to true to bypass this behavior and delete immediately, though this may leave resources dangling.

Using a different cloud?

Explore compute guides for other cloud providers: