From cd210b3152a63424e5a51bc8402dcb5d2139f473 Mon Sep 17 00:00:00 2001 From: Joel Speed Date: Tue, 17 Mar 2020 16:36:03 +0000 Subject: [PATCH] Set SpotMarketOptions in launchInstance --- pkg/actuators/machine/instances.go | 47 +++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/pkg/actuators/machine/instances.go b/pkg/actuators/machine/instances.go index 64d3b4ebad..f460013db6 100644 --- a/pkg/actuators/machine/instances.go +++ b/pkg/actuators/machine/instances.go @@ -305,14 +305,15 @@ func launchInstance(machine *machinev1.Machine, machineProviderConfig *awsprovid ImageId: amiID, InstanceType: aws.String(machineProviderConfig.InstanceType), // Only a single instance of the AWS instance allowed - MinCount: aws.Int64(1), - MaxCount: aws.Int64(1), - KeyName: machineProviderConfig.KeyName, - IamInstanceProfile: iamInstanceProfile, - TagSpecifications: []*ec2.TagSpecification{tagInstance, tagVolume}, - NetworkInterfaces: networkInterfaces, - UserData: &userDataEnc, - Placement: placement, + MinCount: aws.Int64(1), + MaxCount: aws.Int64(1), + KeyName: machineProviderConfig.KeyName, + IamInstanceProfile: iamInstanceProfile, + TagSpecifications: []*ec2.TagSpecification{tagInstance, tagVolume}, + NetworkInterfaces: networkInterfaces, + UserData: &userDataEnc, + Placement: placement, + InstanceMarketOptions: getInstanceMarketOptionsRequest(machineProviderConfig), } if len(blockDeviceMappings) > 0 { @@ -374,3 +375,33 @@ func (il instanceList) Less(i, j int) bool { func sortInstances(instances []*ec2.Instance) { sort.Sort(instanceList(instances)) } + +func getInstanceMarketOptionsRequest(providerConfig *awsproviderv1.AWSMachineProviderConfig) *ec2.InstanceMarketOptionsRequest { + if providerConfig.SpotMarketOptions == nil { + // Instance is not a Spot instance + return nil + } + + // Set required values for Spot instances + spotOptions := &ec2.SpotMarketOptions{} + // The following two options ensure that: + // - If an instance is interrupted, it is terminated rather than hibernating or stopping + // - No replacement instance will be created if the instance is interrupted + // - If the spot request cannot immediately be fulfilled, it will not be created + // This behaviour should satisfy the 1:1 mapping of Machines to Instances as + // assumed by the machine API. + spotOptions.SetInstanceInterruptionBehavior(ec2.InstanceInterruptionBehaviorTerminate) + spotOptions.SetSpotInstanceType(ec2.SpotInstanceTypeOneTime) + + // Set the MaxPrice if specified by the providerConfig + maxPrice := providerConfig.SpotMarketOptions.MaxPrice + if maxPrice != nil && *maxPrice != "" { + spotOptions.SetMaxPrice(*maxPrice) + } + + instanceMarketOptionsRequest := &ec2.InstanceMarketOptionsRequest{} + instanceMarketOptionsRequest.SetMarketType(ec2.MarketTypeSpot) + instanceMarketOptionsRequest.SetSpotOptions(spotOptions) + + return instanceMarketOptionsRequest +}