The aws:ec2/spotFleetRequest:SpotFleetRequest resource, part of the Pulumi AWS provider, defines a Spot Fleet request that provisions multiple Spot instances across instance types, availability zones, and price points. This guide focuses on three capabilities: launch specifications vs launch templates, allocation strategies, and multi-subnet placement.
Spot Fleet requests require IAM fleet roles, reference VPC subnets, and use AMIs that exist in your region. AWS strongly discourages this legacy API; consider EC2 Fleet or Auto Scaling Groups for new projects. The examples are intentionally small. Combine them with your own IAM roles, VPC infrastructure, and capacity planning.
Request capacity across instance types and markets
Spot Fleet requests let you define multiple launch specifications, each targeting different instance types, zones, or price points.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
// Request a Spot fleet
const cheapCompute = new aws.ec2.SpotFleetRequest("cheap_compute", {
iamFleetRole: "arn:aws:iam::12345678:role/spot-fleet",
spotPrice: "0.03",
allocationStrategy: "diversified",
targetCapacity: 6,
validUntil: "2019-11-04T20:44:20Z",
launchSpecifications: [
{
instanceType: "m4.10xlarge",
ami: "ami-1234",
spotPrice: "2.793",
placementTenancy: "dedicated",
iamInstanceProfileArn: example.arn,
},
{
instanceType: "m4.4xlarge",
ami: "ami-5678",
keyName: "my-key",
spotPrice: "1.117",
iamInstanceProfileArn: example.arn,
availabilityZone: "us-west-1a",
subnetId: "subnet-1234",
weightedCapacity: "35",
rootBlockDevices: [{
volumeSize: 300,
volumeType: "gp2",
}],
tags: {
Name: "spot-fleet-example",
},
},
],
});
import pulumi
import pulumi_aws as aws
# Request a Spot fleet
cheap_compute = aws.ec2.SpotFleetRequest("cheap_compute",
iam_fleet_role="arn:aws:iam::12345678:role/spot-fleet",
spot_price="0.03",
allocation_strategy="diversified",
target_capacity=6,
valid_until="2019-11-04T20:44:20Z",
launch_specifications=[
{
"instance_type": "m4.10xlarge",
"ami": "ami-1234",
"spot_price": "2.793",
"placement_tenancy": "dedicated",
"iam_instance_profile_arn": example["arn"],
},
{
"instance_type": "m4.4xlarge",
"ami": "ami-5678",
"key_name": "my-key",
"spot_price": "1.117",
"iam_instance_profile_arn": example["arn"],
"availability_zone": "us-west-1a",
"subnet_id": "subnet-1234",
"weighted_capacity": "35",
"root_block_devices": [{
"volume_size": 300,
"volume_type": "gp2",
}],
"tags": {
"Name": "spot-fleet-example",
},
},
])
package main
import (
"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 {
// Request a Spot fleet
_, err := ec2.NewSpotFleetRequest(ctx, "cheap_compute", &ec2.SpotFleetRequestArgs{
IamFleetRole: pulumi.String("arn:aws:iam::12345678:role/spot-fleet"),
SpotPrice: pulumi.String("0.03"),
AllocationStrategy: pulumi.String("diversified"),
TargetCapacity: pulumi.Int(6),
ValidUntil: pulumi.String("2019-11-04T20:44:20Z"),
LaunchSpecifications: ec2.SpotFleetRequestLaunchSpecificationArray{
&ec2.SpotFleetRequestLaunchSpecificationArgs{
InstanceType: pulumi.String("m4.10xlarge"),
Ami: pulumi.String("ami-1234"),
SpotPrice: pulumi.String("2.793"),
PlacementTenancy: pulumi.String("dedicated"),
IamInstanceProfileArn: pulumi.Any(example.Arn),
},
&ec2.SpotFleetRequestLaunchSpecificationArgs{
InstanceType: pulumi.String("m4.4xlarge"),
Ami: pulumi.String("ami-5678"),
KeyName: pulumi.String("my-key"),
SpotPrice: pulumi.String("1.117"),
IamInstanceProfileArn: pulumi.Any(example.Arn),
AvailabilityZone: pulumi.String("us-west-1a"),
SubnetId: pulumi.String("subnet-1234"),
WeightedCapacity: pulumi.String("35"),
RootBlockDevices: ec2.SpotFleetRequestLaunchSpecificationRootBlockDeviceArray{
&ec2.SpotFleetRequestLaunchSpecificationRootBlockDeviceArgs{
VolumeSize: pulumi.Int(300),
VolumeType: pulumi.String("gp2"),
},
},
Tags: pulumi.StringMap{
"Name": pulumi.String("spot-fleet-example"),
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
// Request a Spot fleet
var cheapCompute = new Aws.Ec2.SpotFleetRequest("cheap_compute", new()
{
IamFleetRole = "arn:aws:iam::12345678:role/spot-fleet",
SpotPrice = "0.03",
AllocationStrategy = "diversified",
TargetCapacity = 6,
ValidUntil = "2019-11-04T20:44:20Z",
LaunchSpecifications = new[]
{
new Aws.Ec2.Inputs.SpotFleetRequestLaunchSpecificationArgs
{
InstanceType = "m4.10xlarge",
Ami = "ami-1234",
SpotPrice = "2.793",
PlacementTenancy = "dedicated",
IamInstanceProfileArn = example.Arn,
},
new Aws.Ec2.Inputs.SpotFleetRequestLaunchSpecificationArgs
{
InstanceType = "m4.4xlarge",
Ami = "ami-5678",
KeyName = "my-key",
SpotPrice = "1.117",
IamInstanceProfileArn = example.Arn,
AvailabilityZone = "us-west-1a",
SubnetId = "subnet-1234",
WeightedCapacity = "35",
RootBlockDevices = new[]
{
new Aws.Ec2.Inputs.SpotFleetRequestLaunchSpecificationRootBlockDeviceArgs
{
VolumeSize = 300,
VolumeType = "gp2",
},
},
Tags =
{
{ "Name", "spot-fleet-example" },
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.ec2.SpotFleetRequest;
import com.pulumi.aws.ec2.SpotFleetRequestArgs;
import com.pulumi.aws.ec2.inputs.SpotFleetRequestLaunchSpecificationArgs;
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) {
// Request a Spot fleet
var cheapCompute = new SpotFleetRequest("cheapCompute", SpotFleetRequestArgs.builder()
.iamFleetRole("arn:aws:iam::12345678:role/spot-fleet")
.spotPrice("0.03")
.allocationStrategy("diversified")
.targetCapacity(6)
.validUntil("2019-11-04T20:44:20Z")
.launchSpecifications(
SpotFleetRequestLaunchSpecificationArgs.builder()
.instanceType("m4.10xlarge")
.ami("ami-1234")
.spotPrice("2.793")
.placementTenancy("dedicated")
.iamInstanceProfileArn(example.arn())
.build(),
SpotFleetRequestLaunchSpecificationArgs.builder()
.instanceType("m4.4xlarge")
.ami("ami-5678")
.keyName("my-key")
.spotPrice("1.117")
.iamInstanceProfileArn(example.arn())
.availabilityZone("us-west-1a")
.subnetId("subnet-1234")
.weightedCapacity("35")
.rootBlockDevices(SpotFleetRequestLaunchSpecificationRootBlockDeviceArgs.builder()
.volumeSize(300)
.volumeType("gp2")
.build())
.tags(Map.of("Name", "spot-fleet-example"))
.build())
.build());
}
}
resources:
# Request a Spot fleet
cheapCompute:
type: aws:ec2:SpotFleetRequest
name: cheap_compute
properties:
iamFleetRole: arn:aws:iam::12345678:role/spot-fleet
spotPrice: '0.03'
allocationStrategy: diversified
targetCapacity: 6
validUntil: 2019-11-04T20:44:20Z
launchSpecifications:
- instanceType: m4.10xlarge
ami: ami-1234
spotPrice: '2.793'
placementTenancy: dedicated
iamInstanceProfileArn: ${example.arn}
- instanceType: m4.4xlarge
ami: ami-5678
keyName: my-key
spotPrice: '1.117'
iamInstanceProfileArn: ${example.arn}
availabilityZone: us-west-1a
subnetId: subnet-1234
weightedCapacity: 35
rootBlockDevices:
- volumeSize: '300'
volumeType: gp2
tags:
Name: spot-fleet-example
The launchSpecifications array defines each configuration option: instance type, AMI, spot price, and placement. The allocationStrategy property controls how the fleet distributes your targetCapacity across these options. The “diversified” strategy spreads capacity to reduce interruption risk. The iamFleetRole grants permissions to launch and terminate instances on your behalf.
Use launch templates for standardized configuration
Launch templates centralize instance configuration that can be versioned and reused across fleets.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const foo = new aws.ec2.LaunchTemplate("foo", {
name: "launch-template",
imageId: "ami-516b9131",
instanceType: "m1.small",
keyName: "some-key",
});
const fooSpotFleetRequest = new aws.ec2.SpotFleetRequest("foo", {
iamFleetRole: "arn:aws:iam::12345678:role/spot-fleet",
spotPrice: "0.005",
targetCapacity: 2,
validUntil: "2019-11-04T20:44:20Z",
launchTemplateConfigs: [{
launchTemplateSpecification: {
id: foo.id,
version: foo.latestVersion,
},
}],
}, {
dependsOn: [test_attach],
});
import pulumi
import pulumi_aws as aws
foo = aws.ec2.LaunchTemplate("foo",
name="launch-template",
image_id="ami-516b9131",
instance_type="m1.small",
key_name="some-key")
foo_spot_fleet_request = aws.ec2.SpotFleetRequest("foo",
iam_fleet_role="arn:aws:iam::12345678:role/spot-fleet",
spot_price="0.005",
target_capacity=2,
valid_until="2019-11-04T20:44:20Z",
launch_template_configs=[{
"launch_template_specification": {
"id": foo.id,
"version": foo.latest_version,
},
}],
opts = pulumi.ResourceOptions(depends_on=[test_attach]))
package main
import (
"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 {
foo, err := ec2.NewLaunchTemplate(ctx, "foo", &ec2.LaunchTemplateArgs{
Name: pulumi.String("launch-template"),
ImageId: pulumi.String("ami-516b9131"),
InstanceType: pulumi.String("m1.small"),
KeyName: pulumi.String("some-key"),
})
if err != nil {
return err
}
_, err = ec2.NewSpotFleetRequest(ctx, "foo", &ec2.SpotFleetRequestArgs{
IamFleetRole: pulumi.String("arn:aws:iam::12345678:role/spot-fleet"),
SpotPrice: pulumi.String("0.005"),
TargetCapacity: pulumi.Int(2),
ValidUntil: pulumi.String("2019-11-04T20:44:20Z"),
LaunchTemplateConfigs: ec2.SpotFleetRequestLaunchTemplateConfigArray{
&ec2.SpotFleetRequestLaunchTemplateConfigArgs{
LaunchTemplateSpecification: &ec2.SpotFleetRequestLaunchTemplateConfigLaunchTemplateSpecificationArgs{
Id: foo.ID(),
Version: foo.LatestVersion,
},
},
},
}, pulumi.DependsOn([]pulumi.Resource{
test_attach,
}))
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 foo = new Aws.Ec2.LaunchTemplate("foo", new()
{
Name = "launch-template",
ImageId = "ami-516b9131",
InstanceType = "m1.small",
KeyName = "some-key",
});
var fooSpotFleetRequest = new Aws.Ec2.SpotFleetRequest("foo", new()
{
IamFleetRole = "arn:aws:iam::12345678:role/spot-fleet",
SpotPrice = "0.005",
TargetCapacity = 2,
ValidUntil = "2019-11-04T20:44:20Z",
LaunchTemplateConfigs = new[]
{
new Aws.Ec2.Inputs.SpotFleetRequestLaunchTemplateConfigArgs
{
LaunchTemplateSpecification = new Aws.Ec2.Inputs.SpotFleetRequestLaunchTemplateConfigLaunchTemplateSpecificationArgs
{
Id = foo.Id,
Version = foo.LatestVersion,
},
},
},
}, new CustomResourceOptions
{
DependsOn =
{
test_attach,
},
});
});
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.ec2.SpotFleetRequest;
import com.pulumi.aws.ec2.SpotFleetRequestArgs;
import com.pulumi.aws.ec2.inputs.SpotFleetRequestLaunchTemplateConfigArgs;
import com.pulumi.aws.ec2.inputs.SpotFleetRequestLaunchTemplateConfigLaunchTemplateSpecificationArgs;
import com.pulumi.resources.CustomResourceOptions;
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 foo = new LaunchTemplate("foo", LaunchTemplateArgs.builder()
.name("launch-template")
.imageId("ami-516b9131")
.instanceType("m1.small")
.keyName("some-key")
.build());
var fooSpotFleetRequest = new SpotFleetRequest("fooSpotFleetRequest", SpotFleetRequestArgs.builder()
.iamFleetRole("arn:aws:iam::12345678:role/spot-fleet")
.spotPrice("0.005")
.targetCapacity(2)
.validUntil("2019-11-04T20:44:20Z")
.launchTemplateConfigs(SpotFleetRequestLaunchTemplateConfigArgs.builder()
.launchTemplateSpecification(SpotFleetRequestLaunchTemplateConfigLaunchTemplateSpecificationArgs.builder()
.id(foo.id())
.version(foo.latestVersion())
.build())
.build())
.build(), CustomResourceOptions.builder()
.dependsOn(test_attach)
.build());
}
}
resources:
foo:
type: aws:ec2:LaunchTemplate
properties:
name: launch-template
imageId: ami-516b9131
instanceType: m1.small
keyName: some-key
fooSpotFleetRequest:
type: aws:ec2:SpotFleetRequest
name: foo
properties:
iamFleetRole: arn:aws:iam::12345678:role/spot-fleet
spotPrice: '0.005'
targetCapacity: 2
validUntil: 2019-11-04T20:44:20Z
launchTemplateConfigs:
- launchTemplateSpecification:
id: ${foo.id}
version: ${foo.latestVersion}
options:
dependsOn:
- ${["test-attach"]}
The launchTemplateConfigs property references a launch template by id and version. This separates instance configuration (AMI, instance type, key pairs) from fleet-level settings (capacity, allocation strategy). Launch templates support versioning, making it easier to roll out configuration changes.
Distribute capacity across multiple subnets
When you need instances spread across availability zones, launch template overrides let you specify different subnets for each portion of your fleet.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = aws.ec2.getSubnets({
filters: [{
name: "vpc-id",
values: [vpcId],
}],
});
const foo = new aws.ec2.LaunchTemplate("foo", {
name: "launch-template",
imageId: "ami-516b9131",
instanceType: "m1.small",
keyName: "some-key",
});
const fooSpotFleetRequest = new aws.ec2.SpotFleetRequest("foo", {
iamFleetRole: "arn:aws:iam::12345678:role/spot-fleet",
spotPrice: "0.005",
targetCapacity: 2,
validUntil: "2019-11-04T20:44:20Z",
launchTemplateConfigs: [{
launchTemplateSpecification: {
id: foo.id,
version: foo.latestVersion,
},
overrides: [
{
subnetId: example.then(example => example.ids?.[0]),
},
{
subnetId: example.then(example => example.ids?.[1]),
},
{
subnetId: example.then(example => example.ids?.[2]),
},
],
}],
}, {
dependsOn: [test_attach],
});
import pulumi
import pulumi_aws as aws
example = aws.ec2.get_subnets(filters=[{
"name": "vpc-id",
"values": [vpc_id],
}])
foo = aws.ec2.LaunchTemplate("foo",
name="launch-template",
image_id="ami-516b9131",
instance_type="m1.small",
key_name="some-key")
foo_spot_fleet_request = aws.ec2.SpotFleetRequest("foo",
iam_fleet_role="arn:aws:iam::12345678:role/spot-fleet",
spot_price="0.005",
target_capacity=2,
valid_until="2019-11-04T20:44:20Z",
launch_template_configs=[{
"launch_template_specification": {
"id": foo.id,
"version": foo.latest_version,
},
"overrides": [
{
"subnet_id": example.ids[0],
},
{
"subnet_id": example.ids[1],
},
{
"subnet_id": example.ids[2],
},
],
}],
opts = pulumi.ResourceOptions(depends_on=[test_attach]))
package main
import (
"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.GetSubnets(ctx, &ec2.GetSubnetsArgs{
Filters: []ec2.GetSubnetsFilter{
{
Name: "vpc-id",
Values: interface{}{
vpcId,
},
},
},
}, nil);
if err != nil {
return err
}
foo, err := ec2.NewLaunchTemplate(ctx, "foo", &ec2.LaunchTemplateArgs{
Name: pulumi.String("launch-template"),
ImageId: pulumi.String("ami-516b9131"),
InstanceType: pulumi.String("m1.small"),
KeyName: pulumi.String("some-key"),
})
if err != nil {
return err
}
_, err = ec2.NewSpotFleetRequest(ctx, "foo", &ec2.SpotFleetRequestArgs{
IamFleetRole: pulumi.String("arn:aws:iam::12345678:role/spot-fleet"),
SpotPrice: pulumi.String("0.005"),
TargetCapacity: pulumi.Int(2),
ValidUntil: pulumi.String("2019-11-04T20:44:20Z"),
LaunchTemplateConfigs: ec2.SpotFleetRequestLaunchTemplateConfigArray{
&ec2.SpotFleetRequestLaunchTemplateConfigArgs{
LaunchTemplateSpecification: &ec2.SpotFleetRequestLaunchTemplateConfigLaunchTemplateSpecificationArgs{
Id: foo.ID(),
Version: foo.LatestVersion,
},
Overrides: ec2.SpotFleetRequestLaunchTemplateConfigOverrideArray{
&ec2.SpotFleetRequestLaunchTemplateConfigOverrideArgs{
SubnetId: pulumi.String(example.Ids[0]),
},
&ec2.SpotFleetRequestLaunchTemplateConfigOverrideArgs{
SubnetId: pulumi.String(example.Ids[1]),
},
&ec2.SpotFleetRequestLaunchTemplateConfigOverrideArgs{
SubnetId: pulumi.String(example.Ids[2]),
},
},
},
},
}, pulumi.DependsOn([]pulumi.Resource{
test_attach,
}))
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.GetSubnets.Invoke(new()
{
Filters = new[]
{
new Aws.Ec2.Inputs.GetSubnetsFilterInputArgs
{
Name = "vpc-id",
Values = new[]
{
vpcId,
},
},
},
});
var foo = new Aws.Ec2.LaunchTemplate("foo", new()
{
Name = "launch-template",
ImageId = "ami-516b9131",
InstanceType = "m1.small",
KeyName = "some-key",
});
var fooSpotFleetRequest = new Aws.Ec2.SpotFleetRequest("foo", new()
{
IamFleetRole = "arn:aws:iam::12345678:role/spot-fleet",
SpotPrice = "0.005",
TargetCapacity = 2,
ValidUntil = "2019-11-04T20:44:20Z",
LaunchTemplateConfigs = new[]
{
new Aws.Ec2.Inputs.SpotFleetRequestLaunchTemplateConfigArgs
{
LaunchTemplateSpecification = new Aws.Ec2.Inputs.SpotFleetRequestLaunchTemplateConfigLaunchTemplateSpecificationArgs
{
Id = foo.Id,
Version = foo.LatestVersion,
},
Overrides = new[]
{
new Aws.Ec2.Inputs.SpotFleetRequestLaunchTemplateConfigOverrideArgs
{
SubnetId = example.Apply(getSubnetsResult => getSubnetsResult.Ids[0]),
},
new Aws.Ec2.Inputs.SpotFleetRequestLaunchTemplateConfigOverrideArgs
{
SubnetId = example.Apply(getSubnetsResult => getSubnetsResult.Ids[1]),
},
new Aws.Ec2.Inputs.SpotFleetRequestLaunchTemplateConfigOverrideArgs
{
SubnetId = example.Apply(getSubnetsResult => getSubnetsResult.Ids[2]),
},
},
},
},
}, new CustomResourceOptions
{
DependsOn =
{
test_attach,
},
});
});
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.GetSubnetsArgs;
import com.pulumi.aws.ec2.LaunchTemplate;
import com.pulumi.aws.ec2.LaunchTemplateArgs;
import com.pulumi.aws.ec2.SpotFleetRequest;
import com.pulumi.aws.ec2.SpotFleetRequestArgs;
import com.pulumi.aws.ec2.inputs.SpotFleetRequestLaunchTemplateConfigArgs;
import com.pulumi.aws.ec2.inputs.SpotFleetRequestLaunchTemplateConfigLaunchTemplateSpecificationArgs;
import com.pulumi.resources.CustomResourceOptions;
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.getSubnets(GetSubnetsArgs.builder()
.filters(GetSubnetsFilterArgs.builder()
.name("vpc-id")
.values(vpcId)
.build())
.build());
var foo = new LaunchTemplate("foo", LaunchTemplateArgs.builder()
.name("launch-template")
.imageId("ami-516b9131")
.instanceType("m1.small")
.keyName("some-key")
.build());
var fooSpotFleetRequest = new SpotFleetRequest("fooSpotFleetRequest", SpotFleetRequestArgs.builder()
.iamFleetRole("arn:aws:iam::12345678:role/spot-fleet")
.spotPrice("0.005")
.targetCapacity(2)
.validUntil("2019-11-04T20:44:20Z")
.launchTemplateConfigs(SpotFleetRequestLaunchTemplateConfigArgs.builder()
.launchTemplateSpecification(SpotFleetRequestLaunchTemplateConfigLaunchTemplateSpecificationArgs.builder()
.id(foo.id())
.version(foo.latestVersion())
.build())
.overrides(
SpotFleetRequestLaunchTemplateConfigOverrideArgs.builder()
.subnetId(example.ids()[0])
.build(),
SpotFleetRequestLaunchTemplateConfigOverrideArgs.builder()
.subnetId(example.ids()[1])
.build(),
SpotFleetRequestLaunchTemplateConfigOverrideArgs.builder()
.subnetId(example.ids()[2])
.build())
.build())
.build(), CustomResourceOptions.builder()
.dependsOn(test_attach)
.build());
}
}
resources:
foo:
type: aws:ec2:LaunchTemplate
properties:
name: launch-template
imageId: ami-516b9131
instanceType: m1.small
keyName: some-key
fooSpotFleetRequest:
type: aws:ec2:SpotFleetRequest
name: foo
properties:
iamFleetRole: arn:aws:iam::12345678:role/spot-fleet
spotPrice: '0.005'
targetCapacity: 2
validUntil: 2019-11-04T20:44:20Z
launchTemplateConfigs:
- launchTemplateSpecification:
id: ${foo.id}
version: ${foo.latestVersion}
overrides:
- subnetId: ${example.ids[0]}
- subnetId: ${example.ids[1]}
- subnetId: ${example.ids[2]}
options:
dependsOn:
- ${["test-attach"]}
variables:
example:
fn::invoke:
function: aws:ec2:getSubnets
arguments:
filters:
- name: vpc-id
values:
- ${vpcId}
The overrides array within launchTemplateConfigs specifies a subnetId for each portion of capacity. The fleet distributes instances across these subnets, improving availability. This example queries subnets dynamically using getSubnets, then creates one override per subnet.
Beyond these examples
These snippets focus on specific Spot Fleet features: launch specifications and launch templates, allocation strategies and capacity distribution, and subnet overrides for multi-AZ placement. They’re intentionally minimal rather than full fleet deployments.
The examples rely on pre-existing infrastructure such as IAM fleet roles and instance profiles, VPC subnets and availability zones, and AMIs valid for the target region. They focus on fleet configuration rather than provisioning the surrounding infrastructure.
To keep things focused, common fleet patterns are omitted, including:
- On-Demand capacity mixing (onDemandTargetCapacity)
- Load balancer integration (loadBalancers, targetGroupArns)
- Instance health replacement (replaceUnhealthyInstances)
- Capacity rebalancing (spotMaintenanceStrategies)
These omissions are intentional: the goal is to illustrate how each fleet feature is wired, not provide drop-in capacity modules. See the Spot Fleet Request resource reference for all available configuration options.
Let's create AWS EC2 Spot Fleet Requests
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Resource Deprecation & Alternatives
Launch Configuration
launchSpecifications or launchTemplateConfigs, not both. At least one is required. Launch templates are generally recommended for newer deployments.launchSpecifications takes similar but not identical inputs to aws.ec2.Instance. Check the AWS API reference for supported inputs, as there are limitations on what you can specify.iamInstanceProfileArn with the ARN from aws.iam.InstanceProfile, not the profile name. Launch specifications require the ARN attribute as input.Networking & Multi-AZ Deployment
subnetId or availabilityZone parameters in the same launch configuration block are not supported. Use separate launch configuration blocks or launch template overrides, one per subnet.subnetId values, as shown in the multiple launch configurations example.Capacity & Allocation
lowestPrice (default), diversified, capacityOptimized, capacityOptimizedPrioritized, and priceCapacityOptimized. This property is immutable after creation.targetCapacity is the number of units to request. You can set capacity in terms of instances or performance characteristics like vCPUs, memory, or I/O.Instance Lifecycle & Termination
terminateInstancesWithExpiration (for expiration) and terminateInstancesOnDelete (for deletion). If terminateInstancesOnDelete isn’t specified, it defaults to the value of terminateInstancesWithExpiration.instanceInterruptionBehaviour property controls this. Default is terminate, but you can set it to stop the instance instead. This property is immutable.replaceUnhealthyInstances is false. You must explicitly enable this if you want automatic replacement.Fulfillment & Timeouts
waitForFulfillment is set, Pulumi waits for the request to be fulfilled and throws an error if the 10-minute timeout is reached.Immutability & Updates
iamFleetRole, loadBalancers, targetGroupArns, allocationStrategy, context, fleetType, instanceInterruptionBehaviour, instancePoolsToUseCount, launchSpecifications, launchTemplateConfigs, onDemandAllocationStrategy, onDemandMaxTotalPrice, replaceUnhealthyInstances, spotPrice, targetCapacityUnitType, terminateInstancesWithExpiration, validFrom, and validUntil.