From 3dbf1cb371b3eddfe752ce444e6d14f72723009f Mon Sep 17 00:00:00 2001 From: Mark Meyer Date: Thu, 12 Oct 2017 23:33:01 +0200 Subject: [PATCH] Enable tagging of spot requests This adds a new parameter to the EBS builders named `spot_tags'. This parameter accepts a map of tags, much like `tags'. These tags will be applied to a spot request that is created. Improve visibility. --- builder/amazon/common/run_config.go | 5 ++++ .../amazon/common/step_run_spot_instance.go | 28 +++++++++++++++++++ builder/amazon/ebs/builder.go | 2 ++ builder/amazon/ebssurrogate/builder.go | 2 ++ builder/amazon/ebsvolume/builder.go | 2 ++ builder/amazon/instance/builder.go | 2 ++ 6 files changed, 41 insertions(+) diff --git a/builder/amazon/common/run_config.go b/builder/amazon/common/run_config.go index 129d4d541..b6e13dcc0 100644 --- a/builder/amazon/common/run_config.go +++ b/builder/amazon/common/run_config.go @@ -43,6 +43,7 @@ type RunConfig struct { SourceAmiFilter AmiFilterOptions `mapstructure:"source_ami_filter"` SpotPrice string `mapstructure:"spot_price"` SpotPriceAutoProduct string `mapstructure:"spot_price_auto_product"` + SpotTags map[string]string `mapstructure:"spot_tags"` SubnetId string `mapstructure:"subnet_id"` TemporaryKeyPairName string `mapstructure:"temporary_key_pair_name"` TemporarySGSourceCidr string `mapstructure:"temporary_security_group_source_cidr"` @@ -76,6 +77,10 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { c.RunTags = make(map[string]string) } + if c.SpotTags == nil { + c.SpotTags = make(map[string]string) + } + // Validation errs := c.Comm.Prepare(ctx) diff --git a/builder/amazon/common/step_run_spot_instance.go b/builder/amazon/common/step_run_spot_instance.go index 8c7cbf74a..7b96544bb 100644 --- a/builder/amazon/common/step_run_spot_instance.go +++ b/builder/amazon/common/step_run_spot_instance.go @@ -32,6 +32,7 @@ type StepRunSpotInstance struct { SourceAMI string SpotPrice string SpotPriceProduct string + SpotTags TagMap SubnetId string Tags TagMap VolumeTags TagMap @@ -227,6 +228,33 @@ func (s *StepRunSpotInstance) Run(ctx context.Context, state multistep.StateBag) } instanceId = *spotResp.SpotInstanceRequests[0].InstanceId + // Tag spot instance request + spotTags, err := s.SpotTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) + if err != nil { + err := fmt.Errorf("Error tagging spot request: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + spotTags.Report(ui) + + if len(spotTags) > 0 && s.SpotTags.IsSet() { + // Retry creating tags for about 2.5 minutes + err = retry.Retry(0.2, 30, 11, func(_ uint) (bool, error) { + _, err := ec2conn.CreateTags(&ec2.CreateTagsInput{ + Tags: spotTags, + Resources: []*string{spotRequestId}, + }) + return true, err + }) + if err != nil { + err := fmt.Errorf("Error tagging spot request: %s", err) + state.Put("error", err) + ui.Error(err.Error()) + return multistep.ActionHalt + } + } + // Set the instance ID so that the cleanup works properly s.instanceId = instanceId diff --git a/builder/amazon/ebs/builder.go b/builder/amazon/ebs/builder.go index 665bf8098..bd10ad36a 100644 --- a/builder/amazon/ebs/builder.go +++ b/builder/amazon/ebs/builder.go @@ -48,6 +48,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { "ami_description", "run_tags", "run_volume_tags", + "spot_tags", "snapshot_tags", "tags", }, @@ -134,6 +135,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SourceAMI: b.config.SourceAmi, SpotPrice: b.config.SpotPrice, SpotPriceProduct: b.config.SpotPriceAutoProduct, + SpotTags: b.config.SpotTags, SubnetId: b.config.SubnetId, Tags: b.config.RunTags, UserData: b.config.UserData, diff --git a/builder/amazon/ebssurrogate/builder.go b/builder/amazon/ebssurrogate/builder.go index 52a151b22..9642c1a83 100644 --- a/builder/amazon/ebssurrogate/builder.go +++ b/builder/amazon/ebssurrogate/builder.go @@ -48,6 +48,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { "run_tags", "run_volume_tags", "snapshot_tags", + "spot_tags", "tags", }, }, @@ -148,6 +149,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SourceAMI: b.config.SourceAmi, SpotPrice: b.config.SpotPrice, SpotPriceProduct: b.config.SpotPriceAutoProduct, + SpotTags: b.config.SpotTags, SubnetId: b.config.SubnetId, Tags: b.config.RunTags, UserData: b.config.UserData, diff --git a/builder/amazon/ebsvolume/builder.go b/builder/amazon/ebsvolume/builder.go index 1a79b964e..222febc56 100644 --- a/builder/amazon/ebsvolume/builder.go +++ b/builder/amazon/ebsvolume/builder.go @@ -44,6 +44,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { InterpolateFilter: &interpolate.RenderFilter{ Exclude: []string{ "run_tags", + "spot_tags", "ebs_volumes", }, }, @@ -132,6 +133,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SourceAMI: b.config.SourceAmi, SpotPrice: b.config.SpotPrice, SpotPriceProduct: b.config.SpotPriceAutoProduct, + SpotTags: b.config.SpotTags, SubnetId: b.config.SubnetId, Tags: b.config.RunTags, UserData: b.config.UserData, diff --git a/builder/amazon/instance/builder.go b/builder/amazon/instance/builder.go index c197cadeb..fb59fff95 100644 --- a/builder/amazon/instance/builder.go +++ b/builder/amazon/instance/builder.go @@ -69,6 +69,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { "run_volume_tags", "snapshot_tags", "tags", + "spot_tags", }, }, }, configs...) @@ -219,6 +220,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe SpotPriceProduct: b.config.SpotPriceAutoProduct, SubnetId: b.config.SubnetId, Tags: b.config.RunTags, + SpotTags: b.config.SpotTags, UserData: b.config.UserData, UserDataFile: b.config.UserDataFile, }