Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix disabling spot instances when using launch templates #10198

Merged
merged 2 commits into from
Nov 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion pkg/model/awsmodel/autoscalinggroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ func (b *AutoscalingGroupModelBuilder) buildLaunchTemplateTask(c *fi.ModelBuilde
// You cannot use a launch template that is set to request Spot Instances (InstanceMarketOptions)
// when you configure an Auto Scaling group with a mixed instances policy.
if ig.Spec.MixedInstancesPolicy == nil {
lt.SpotPrice = lc.SpotPrice
lt.SpotPrice = fi.String(lc.SpotPrice)
} else {
lt.SpotPrice = fi.String("")
}
if ig.Spec.SpotDurationInMinutes != nil {
lt.SpotDurationInMinutes = ig.Spec.SpotDurationInMinutes
Expand Down
4 changes: 2 additions & 2 deletions upup/pkg/fi/cloudup/awstasks/autoscalinggroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,8 +456,8 @@ func (v *AutoscalingGroup) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Autos

if changes.LaunchTemplate != nil {
spec := &autoscaling.LaunchTemplateSpecification{
LaunchTemplateId: changes.LaunchTemplate.ID,
Version: &launchTemplateVersion,
LaunchTemplateName: changes.LaunchTemplate.ID,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just curious, why is this change necessary?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is some strange mix in the current code as you can see in other sections of the file:

LaunchTemplateName: e.LaunchTemplate.ID,

This will be changed in #10151 where I tested the fix initially and this is why the current "mismatch".

Version: &launchTemplateVersion,
}
if e.UseMixedInstancesPolicy() {
setup(request).LaunchTemplate = &autoscaling.LaunchTemplate{LaunchTemplateSpecification: spec}
Expand Down
2 changes: 1 addition & 1 deletion upup/pkg/fi/cloudup/awstasks/launchtemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ type LaunchTemplate struct {
// SecurityGroups is a list of security group associated
SecurityGroups []*SecurityGroup
// SpotPrice is set to the spot-price bid if this is a spot pricing request
SpotPrice string
SpotPrice *string
// SpotDurationInMinutes is set for requesting spot blocks
SpotDurationInMinutes *int64
// Tags are the keypairs to apply to the instance and volume on launch as well as the launch template itself.
Expand Down
15 changes: 10 additions & 5 deletions upup/pkg/fi/cloudup/awstasks/launchtemplate_target_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@ func (t *LaunchTemplate) RenderAWS(c *awsup.AWSAPITarget, a, ep, changes *Launch
lc.UserData = aws.String(base64.StdEncoding.EncodeToString(d))
}
// @step: add market options
if t.SpotPrice != "" {
if fi.StringValue(t.SpotPrice) != "" {
s := &ec2.LaunchTemplateSpotMarketOptionsRequest{
BlockDurationMinutes: t.SpotDurationInMinutes,
InstanceInterruptionBehavior: t.InstanceInterruptionBehavior,
MaxPrice: fi.String(t.SpotPrice),
MaxPrice: t.SpotPrice,
}
lc.InstanceMarketOptions = &ec2.LaunchTemplateInstanceMarketOptionsRequest{
MarketType: fi.String("spot"),
Expand Down Expand Up @@ -213,9 +213,14 @@ func (t *LaunchTemplate) Find(c *fi.Context) (*LaunchTemplate, error) {
if lt.LaunchTemplateData.IamInstanceProfile != nil {
actual.IAMInstanceProfile = &IAMInstanceProfile{Name: lt.LaunchTemplateData.IamInstanceProfile.Name}
}
// @step: add instanceInterruptionBehavior if there is one
if lt.LaunchTemplateData.InstanceMarketOptions != nil && lt.LaunchTemplateData.InstanceMarketOptions.SpotOptions != nil {
actual.InstanceInterruptionBehavior = lt.LaunchTemplateData.InstanceMarketOptions.SpotOptions.InstanceInterruptionBehavior
// @step: add InstanceMarketOptions if there are any
imo := lt.LaunchTemplateData.InstanceMarketOptions
if imo != nil && imo.SpotOptions != nil && aws.StringValue(imo.SpotOptions.MaxPrice) != "" {
actual.SpotPrice = imo.SpotOptions.MaxPrice
actual.SpotDurationInMinutes = imo.SpotOptions.BlockDurationMinutes
actual.InstanceInterruptionBehavior = imo.SpotOptions.InstanceInterruptionBehavior
} else {
actual.SpotPrice = aws.String("")
}

// @step: get the image is order to find out the root device name as using the index
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ func (t *LaunchTemplate) RenderCloudformation(target *cloudformation.Cloudformat
},
}

if e.SpotPrice != "" {
marketSpotOptions := cloudformationLaunchTemplateMarketOptionsSpotOptions{MaxPrice: fi.String(e.SpotPrice)}
if fi.StringValue(e.SpotPrice) != "" {
marketSpotOptions := cloudformationLaunchTemplateMarketOptionsSpotOptions{MaxPrice: e.SpotPrice}
if e.SpotDurationInMinutes != nil {
marketSpotOptions.BlockDurationMinutes = e.SpotDurationInMinutes
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestLaunchTemplateCloudformationRender(t *testing.T) {
RootVolumeOptimization: fi.Bool(true),
RootVolumeIops: fi.Int64(100),
RootVolumeSize: fi.Int64(64),
SpotPrice: "10",
SpotPrice: fi.String("10"),
SpotDurationInMinutes: fi.Int64(120),
InstanceInterruptionBehavior: fi.String("hibernate"),
SSHKey: &SSHKey{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@ func (t *LaunchTemplate) RenderTerraform(target *terraform.TerraformTarget, a, e
},
}

if e.SpotPrice != "" {
marketSpotOptions := terraformLaunchTemplateMarketOptionsSpotOptions{MaxPrice: fi.String(e.SpotPrice)}
if fi.StringValue(e.SpotPrice) != "" {
marketSpotOptions := terraformLaunchTemplateMarketOptionsSpotOptions{MaxPrice: e.SpotPrice}
if e.SpotDurationInMinutes != nil {
marketSpotOptions.BlockDurationMinutes = e.SpotDurationInMinutes
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestLaunchTemplateTerraformRender(t *testing.T) {
ID: fi.String("test-11"),
InstanceMonitoring: fi.Bool(true),
InstanceType: fi.String("t2.medium"),
SpotPrice: "0.1",
SpotPrice: fi.String("0.1"),
SpotDurationInMinutes: fi.Int64(60),
InstanceInterruptionBehavior: fi.String("hibernate"),
RootVolumeOptimization: fi.Bool(true),
Expand Down