Skip to content

Commit 2ce11b0

Browse files
committed
Spot instances
1 parent f65064f commit 2ce11b0

File tree

4 files changed

+100
-25
lines changed

4 files changed

+100
-25
lines changed

iterative/aws/provider.go

Lines changed: 64 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"sort"
7+
"strconv"
78
"time"
89

910
"github.com/aws/aws-sdk-go/aws"
@@ -23,6 +24,8 @@ func ResourceMachineCreate(ctx context.Context, d *schema.ResourceData, m interf
2324
ami := d.Get("image").(string)
2425
keyPublic := d.Get("ssh_public").(string)
2526
securityGroup := d.Get("aws_security_group").(string)
27+
spot := d.Get("spot").(bool)
28+
spotPrice := d.Get("spotPrice").(float64)
2629
if ami == "" {
2730
ami = "iterative-cml"
2831
}
@@ -139,35 +142,71 @@ func ResourceMachineCreate(ctx context.Context, d *schema.ResourceData, m interf
139142
return errors.New("no subnets found")
140143
}
141144

142-
//launch instance
143-
runResult, err := svc.RunInstancesWithContext(ctx, &ec2.RunInstancesInput{
144-
UserData: aws.String(userData),
145-
ImageId: aws.String(instanceAmi),
146-
KeyName: aws.String(pairName),
147-
InstanceType: aws.String(instanceType),
148-
MinCount: aws.Int64(1),
149-
MaxCount: aws.Int64(1),
150-
SecurityGroupIds: []*string{aws.String(sgID)},
151-
SubnetId: aws.String(*subDesc.Subnets[0].SubnetId),
152-
BlockDeviceMappings: []*ec2.BlockDeviceMapping{
153-
{
154-
//VirtualName: aws.String("Root"),
155-
DeviceName: aws.String("/dev/sda1"),
156-
Ebs: &ec2.EbsBlockDevice{
157-
DeleteOnTermination: aws.Bool(true),
158-
Encrypted: aws.Bool(false),
159-
//Iops: aws.Int64(0),
160-
VolumeSize: aws.Int64(int64(hddSize)),
161-
VolumeType: aws.String("gp2"),
162-
},
145+
blockDeviceMappings := []*ec2.BlockDeviceMapping{
146+
{
147+
DeviceName: aws.String("/dev/sda1"),
148+
Ebs: &ec2.EbsBlockDevice{
149+
DeleteOnTermination: aws.Bool(true),
150+
Encrypted: aws.Bool(false),
151+
VolumeSize: aws.Int64(int64(hddSize)),
152+
VolumeType: aws.String("gp2"),
163153
},
164154
},
165-
})
166-
if err != nil {
167-
return err
168155
}
169156

170-
instanceID := *runResult.Instances[0].InstanceId
157+
//launch instance
158+
var instanceID string
159+
if spot {
160+
spotInstanceRequest, err := svc.RequestSpotInstances(&ec2.RequestSpotInstancesInput{
161+
LaunchSpecification: &ec2.RequestSpotLaunchSpecification{
162+
UserData: aws.String(userData),
163+
ImageId: aws.String(instanceAmi),
164+
KeyName: aws.String(pairName),
165+
InstanceType: aws.String(instanceType),
166+
SecurityGroupIds: []*string{aws.String(sgID)},
167+
SubnetId: aws.String(*subDesc.Subnets[0].SubnetId),
168+
BlockDeviceMappings: blockDeviceMappings,
169+
},
170+
InstanceCount: aws.Int64(1),
171+
SpotPrice: aws.String(strconv.FormatFloat(spotPrice, 'f', 5, 64)),
172+
})
173+
if err != nil {
174+
return err
175+
}
176+
177+
spotInstanceRequestID := *spotInstanceRequest.SpotInstanceRequests[0].SpotInstanceRequestId
178+
err = svc.WaitUntilSpotInstanceRequestFulfilled(&ec2.DescribeSpotInstanceRequestsInput{
179+
SpotInstanceRequestIds: []*string{aws.String(spotInstanceRequestID)},
180+
})
181+
if err != nil {
182+
return err
183+
}
184+
resolvedSpotInstance, err := svc.DescribeSpotInstanceRequests(&ec2.DescribeSpotInstanceRequestsInput{
185+
SpotInstanceRequestIds: []*string{aws.String(spotInstanceRequestID)},
186+
})
187+
if err != nil {
188+
return err
189+
}
190+
191+
instanceID = *resolvedSpotInstance.SpotInstanceRequests[0].InstanceId
192+
} else {
193+
runResult, err := svc.RunInstancesWithContext(ctx, &ec2.RunInstancesInput{
194+
UserData: aws.String(userData),
195+
ImageId: aws.String(instanceAmi),
196+
KeyName: aws.String(pairName),
197+
InstanceType: aws.String(instanceType),
198+
MinCount: aws.Int64(1),
199+
MaxCount: aws.Int64(1),
200+
SecurityGroupIds: []*string{aws.String(sgID)},
201+
SubnetId: aws.String(*subDesc.Subnets[0].SubnetId),
202+
BlockDeviceMappings: blockDeviceMappings,
203+
})
204+
if err != nil {
205+
return err
206+
}
207+
208+
instanceID = *runResult.Instances[0].InstanceId
209+
}
171210

172211
// Add name to the created instance
173212
_, err = svc.CreateTags(&ec2.CreateTagsInput{

iterative/azure/provider.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ func ResourceMachineCreate(ctx context.Context, d *schema.ResourceData, m interf
2727
instanceType := getInstanceType(d.Get("instance_type").(string), d.Get("instance_gpu").(string))
2828
keyPublic := d.Get("ssh_public").(string)
2929
hddSize := int32(d.Get("instance_hdd_size").(int))
30+
spot := d.Get("spot").(bool)
31+
spotPrice := d.Get("spotPrice").(float64)
32+
vmPriority := compute.Regular
33+
if spot {
34+
vmPriority = compute.Spot
35+
}
3036

3137
image := d.Get("image").(string)
3238
if image == "" {
@@ -186,8 +192,14 @@ func ResourceMachineCreate(ctx context.Context, d *schema.ResourceData, m interf
186192
gpName,
187193
vmName,
188194
compute.VirtualMachine{
195+
189196
Location: to.StringPtr(region),
190197
VirtualMachineProperties: &compute.VirtualMachineProperties{
198+
EvictionPolicy: compute.Delete,
199+
Priority: vmPriority,
200+
BillingProfile: &compute.BillingProfile{
201+
MaxPrice: to.Float64Ptr(spotPrice),
202+
},
191203
HardwareProfile: &compute.HardwareProfile{
192204
VMSize: compute.VirtualMachineSizeTypes(instanceType),
193205
},

iterative/resource_machine.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ func machineSchema() *map[string]*schema.Schema {
4848
Optional: true,
4949
Default: "",
5050
},
51+
"spot": &schema.Schema{
52+
Type: schema.TypeBool,
53+
ForceNew: true,
54+
Optional: true,
55+
Default: false,
56+
},
57+
"spotPrice": &schema.Schema{
58+
Type: schema.TypeFloat,
59+
ForceNew: true,
60+
Optional: true,
61+
Default: -1,
62+
},
5163
"instance_type": &schema.Schema{
5264
Type: schema.TypeString,
5365
ForceNew: true,

iterative/resource_runner.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,18 @@ func resourceRunner() *schema.Resource {
7272
Type: schema.TypeString,
7373
Computed: true,
7474
},
75+
"spot": &schema.Schema{
76+
Type: schema.TypeBool,
77+
ForceNew: true,
78+
Optional: true,
79+
Default: false,
80+
},
81+
"spotPrice": &schema.Schema{
82+
Type: schema.TypeFloat,
83+
ForceNew: true,
84+
Optional: true,
85+
Default: -1,
86+
},
7587
"instance_type": &schema.Schema{
7688
Type: schema.TypeString,
7789
ForceNew: true,

0 commit comments

Comments
 (0)