The aws:ec2/spotFleetRequest:SpotFleetRequest resource, part of the Pulumi AWS provider, requests a fleet of Spot instances across multiple instance types, availability zones, and pricing pools. AWS strongly discourages this legacy API; consider using EC2 Fleet or Auto Scaling Groups instead. This guide focuses on three capabilities: launch specifications vs launch templates, allocation strategies, and multi-subnet distribution.
Spot Fleet requests require IAM fleet roles with spot-fleet permissions, IAM instance profiles for launched instances, and reference existing VPC infrastructure. The examples are intentionally small. Combine them with your own IAM roles, AMIs, and network configuration.
Request Spot capacity with launch specifications
Teams seeking cost savings request Spot Fleet capacity by defining multiple launch specifications that bid across different instance types and availability zones.
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 multiple bids, each with its own instance type, AMI, and spot price. The allocationStrategy determines how the fleet distributes capacity: “diversified” spreads instances across all pools, while “lowestPrice” concentrates on the cheapest options. The targetCapacity sets the total number of units to request, and the iamFleetRole grants permissions to launch and terminate instances.
Use launch templates for centralized configuration
Launch templates centralize instance configuration and can be versioned independently from the fleet request.
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 capacity settings (target capacity, allocation strategy). Launch templates conflict with launch specifications; use one approach or the other.
Distribute capacity across multiple subnets
Applications requiring high availability spread capacity across multiple subnets using launch template overrides.
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 different subnet IDs for each instance. The fleet distributes capacity across these subnets, improving fault tolerance. The getSubnets data source dynamically discovers subnets in your VPC, avoiding hardcoded IDs.
Beyond these examples
These snippets focus on specific Spot Fleet features: launch specifications and launch templates, allocation strategies and capacity distribution, and subnet-level placement with overrides. They’re intentionally minimal rather than full fleet deployments.
The examples reference pre-existing infrastructure such as IAM fleet roles with spot-fleet permissions, IAM instance profiles for EC2 instances, VPC subnets for placement, and AMIs and launch templates. They focus on configuring the fleet request rather than provisioning everything around it.
To keep things focused, common Spot Fleet patterns are omitted, including:
- On-Demand capacity mixing (onDemandTargetCapacity)
- Load balancer integration (loadBalancers, targetGroupArns)
- Instance interruption handling (instanceInterruptionBehaviour)
- Capacity replacement strategies (replaceUnhealthyInstances)
- Time-bound requests (validFrom, validUntil)
These omissions are intentional: the goal is to illustrate how each Spot 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
Deprecation & Alternatives
Launch Configuration
launchSpecifications or launchTemplateConfigs (at least one is required). Launch specifications have limitations compared to normal aws.ec2.Instance parameters; refer to the AWS API reference for supported inputs.iamInstanceProfileArn parameter, which takes the arn attribute from aws.iam.InstanceProfile (not the instance profile name).subnetId or availabilityZone parameters in the same launch configuration block. Use separate launch configuration blocks or launch template overrides, one per subnet.Capacity & Allocation
lowestPrice (default), diversified, capacityOptimized, capacityOptimizedPrioritized, and priceCapacityOptimized.fleetType is maintain, which requests target capacity and attempts to maintain it. The alternative is request, which only requests capacity without maintaining it.maintain. You can specify a target capacity of 0 and add capacity later.Instance Lifecycle & Termination
terminateInstancesOnDelete. If not specified, it defaults to the value of terminateInstancesWithExpiration.instanceInterruptionBehaviour.replaceUnhealthyInstances is false. You must explicitly enable this behavior.Timeouts & Fulfillment
waitForFulfillment is set, Pulumi waits up to 10 minutes for the Spot Request to be fulfilled. An error is thrown if the timeout is reached.Immutability & Updates
iamFleetRole, loadBalancers, targetGroupArns, allocationStrategy, fleetType, instanceInterruptionBehaviour, instancePoolsToUseCount, launchSpecifications, launchTemplateConfigs, onDemandAllocationStrategy, onDemandMaxTotalPrice, replaceUnhealthyInstances, spotPrice, targetCapacityUnitType, terminateInstancesWithExpiration, validFrom, validUntil, and context. Changes to these properties force resource replacement.targetCapacity and onDemandTargetCapacity are mutable and can be updated without replacing the resource.