From bcaa5e49f1f06979a52410c7697eefc5406dac2e Mon Sep 17 00:00:00 2001 From: Mark Meyer Date: Fri, 13 Oct 2017 08:45:46 +0200 Subject: [PATCH 1/3] Document the `spot_tags` parameter --- website/source/docs/builders/amazon-ebs.html.md | 4 ++++ website/source/docs/builders/amazon-ebssurrogate.html.md | 4 ++++ website/source/docs/builders/amazon-ebsvolume.html.md | 4 ++++ website/source/docs/builders/amazon-instance.html.md | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index f8d75ebd0..2db8c6d9f 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -343,6 +343,10 @@ builder. best spot price. This must be one of: `Linux/UNIX`, `SUSE Linux`, `Windows`, `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)`, `Windows (Amazon VPC)` +- `spot_tags` (object of key/value strings) - Requires `spot_price` to + be set. This tells Packer to aplly tags to the spot request that is + issued. + - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) on HVM-compatible AMIs. If true, add `ec2:ModifyInstanceAttribute` to your AWS IAM policy. Note: you must make sure enhanced networking is enabled on your instance. See [Amazon's diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index eb21c1525..f29eb6507 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -336,6 +336,10 @@ builder. best spot price. This must be one of: `Linux/UNIX`, `SUSE Linux`, `Windows`, `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)`, `Windows (Amazon VPC)` +- `spot_tags` (object of key/value strings) - Requires `spot_price` to + be set. This tells Packer to aplly tags to the spot request that is + issued. + - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) on HVM-compatible AMIs. If true, add `ec2:ModifyInstanceAttribute` to your AWS IAM policy. Note: you must make sure enhanced networking is enabled on your instance. See [Amazon's diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index acfa33e84..880d8b49f 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -264,6 +264,10 @@ builder. best spot price. This must be one of: `Linux/UNIX`, `SUSE Linux`, `Windows`, `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)` or `Windows (Amazon VPC)` +- `spot_tags` (object of key/value strings) - Requires `spot_price` to + be set. This tells Packer to aplly tags to the spot request that is + issued. + - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) on HVM-compatible AMIs. If true, add `ec2:ModifyInstanceAttribute` to your AWS IAM policy. Note: you must make sure enhanced networking is enabled on your instance. See [Amazon's diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index 52686aeec..c3f3d76b8 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -339,6 +339,10 @@ builder. best spot price. This must be one of: `Linux/UNIX`, `SUSE Linux`, `Windows`, `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)`, `Windows (Amazon VPC)` +- `spot_tags` (object of key/value strings) - Requires `spot_price` to + be set. This tells Packer to aplly tags to the spot request that is + issued. + - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) on HVM-compatible AMIs. If true, add `ec2:ModifyInstanceAttribute` to your AWS IAM policy. Note: you must make sure enhanced networking is enabled on your instance. See [Amazon's From 3dbf1cb371b3eddfe752ce444e6d14f72723009f Mon Sep 17 00:00:00 2001 From: Mark Meyer Date: Thu, 12 Oct 2017 23:33:01 +0200 Subject: [PATCH 2/3] 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, } From 2fec76ea8703ded3ad819db2eb37356016244fd2 Mon Sep 17 00:00:00 2001 From: Mark Meyer Date: Fri, 13 Oct 2017 08:22:15 +0200 Subject: [PATCH 3/3] Check if spot price is empty, when spot_tags is set --- builder/amazon/common/run_config.go | 11 +++++++---- website/source/docs/builders/amazon-ebs.html.md | 2 +- .../source/docs/builders/amazon-ebssurrogate.html.md | 2 +- website/source/docs/builders/amazon-ebsvolume.html.md | 2 +- website/source/docs/builders/amazon-instance.html.md | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/builder/amazon/common/run_config.go b/builder/amazon/common/run_config.go index b6e13dcc0..9467d42bd 100644 --- a/builder/amazon/common/run_config.go +++ b/builder/amazon/common/run_config.go @@ -77,10 +77,6 @@ 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) @@ -123,6 +119,13 @@ func (c *RunConfig) Prepare(ctx *interpolate.Context) []error { } } + if c.SpotTags != nil { + if c.SpotPrice == "" || c.SpotPrice == "0" { + errs = append(errs, fmt.Errorf( + "spot_tags should not be set when not requesting a spot instance")) + } + } + if c.UserData != "" && c.UserDataFile != "" { errs = append(errs, fmt.Errorf("Only one of user_data or user_data_file can be specified.")) } else if c.UserDataFile != "" { diff --git a/website/source/docs/builders/amazon-ebs.html.md b/website/source/docs/builders/amazon-ebs.html.md index 2db8c6d9f..c09591768 100644 --- a/website/source/docs/builders/amazon-ebs.html.md +++ b/website/source/docs/builders/amazon-ebs.html.md @@ -344,7 +344,7 @@ builder. `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)`, `Windows (Amazon VPC)` - `spot_tags` (object of key/value strings) - Requires `spot_price` to - be set. This tells Packer to aplly tags to the spot request that is + be set. This tells Packer to apply tags to the spot request that is issued. - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) diff --git a/website/source/docs/builders/amazon-ebssurrogate.html.md b/website/source/docs/builders/amazon-ebssurrogate.html.md index f29eb6507..881cce45e 100644 --- a/website/source/docs/builders/amazon-ebssurrogate.html.md +++ b/website/source/docs/builders/amazon-ebssurrogate.html.md @@ -337,7 +337,7 @@ builder. `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)`, `Windows (Amazon VPC)` - `spot_tags` (object of key/value strings) - Requires `spot_price` to - be set. This tells Packer to aplly tags to the spot request that is + be set. This tells Packer to apply tags to the spot request that is issued. - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) diff --git a/website/source/docs/builders/amazon-ebsvolume.html.md b/website/source/docs/builders/amazon-ebsvolume.html.md index 880d8b49f..a3ff74785 100644 --- a/website/source/docs/builders/amazon-ebsvolume.html.md +++ b/website/source/docs/builders/amazon-ebsvolume.html.md @@ -265,7 +265,7 @@ builder. `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)` or `Windows (Amazon VPC)` - `spot_tags` (object of key/value strings) - Requires `spot_price` to - be set. This tells Packer to aplly tags to the spot request that is + be set. This tells Packer to apply tags to the spot request that is issued. - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA) diff --git a/website/source/docs/builders/amazon-instance.html.md b/website/source/docs/builders/amazon-instance.html.md index c3f3d76b8..00700dfb5 100644 --- a/website/source/docs/builders/amazon-instance.html.md +++ b/website/source/docs/builders/amazon-instance.html.md @@ -340,7 +340,7 @@ builder. `Linux/UNIX (Amazon VPC)`, `SUSE Linux (Amazon VPC)`, `Windows (Amazon VPC)` - `spot_tags` (object of key/value strings) - Requires `spot_price` to - be set. This tells Packer to aplly tags to the spot request that is + be set. This tells Packer to apply tags to the spot request that is issued. - `sriov_support` (boolean) - Enable enhanced networking (SriovNetSupport but not ENA)