diff --git a/builder/amazon/common/interpolate_build_info.go b/builder/amazon/common/interpolate_build_info.go index a279a2f72..b141bc9d4 100644 --- a/builder/amazon/common/interpolate_build_info.go +++ b/builder/amazon/common/interpolate_build_info.go @@ -1,6 +1,36 @@ package common +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" +) + type BuildInfoTemplate struct { - SourceAMI string - BuildRegion string + BuildRegion string + SourceAMI string + SourceAMIName string + SourceAMITags map[string]string +} + +func extractBuildInfo(region string, state multistep.StateBag) *BuildInfoTemplate { + rawSourceAMI, hasSourceAMI := state.GetOk("source_image") + if !hasSourceAMI { + return &BuildInfoTemplate{ + BuildRegion: region, + } + } + + sourceAMI := rawSourceAMI.(*ec2.Image) + sourceAMITags := make(map[string]string, len(sourceAMI.Tags)) + for _, tag := range sourceAMI.Tags { + sourceAMITags[aws.StringValue(tag.Key)] = aws.StringValue(tag.Value) + } + + return &BuildInfoTemplate{ + BuildRegion: region, + SourceAMI: aws.StringValue(sourceAMI.ImageId), + SourceAMIName: aws.StringValue(sourceAMI.Name), + SourceAMITags: sourceAMITags, + } } diff --git a/builder/amazon/common/step_create_tags.go b/builder/amazon/common/step_create_tags.go index 96177c8a8..95a736a6b 100644 --- a/builder/amazon/common/step_create_tags.go +++ b/builder/amazon/common/step_create_tags.go @@ -26,13 +26,6 @@ func (s *StepCreateTags) Run(_ context.Context, state multistep.StateBag) multis ui := state.Get("ui").(packer.Ui) amis := state.Get("amis").(map[string]string) - var sourceAMI string - if rawSourceAMI, hasSourceAMI := state.GetOk("source_image"); hasSourceAMI { - sourceAMI = *rawSourceAMI.(*ec2.Image).ImageId - } else { - sourceAMI = "" - } - if !s.Tags.IsSet() && !s.SnapshotTags.IsSet() { return multistep.ActionContinue } @@ -79,7 +72,7 @@ func (s *StepCreateTags) Run(_ context.Context, state multistep.StateBag) multis // Convert tags to ec2.Tag format ui.Say("Creating AMI tags") - amiTags, err := s.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, sourceAMI) + amiTags, err := s.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { state.Put("error", err) ui.Error(err.Error()) @@ -88,7 +81,7 @@ func (s *StepCreateTags) Run(_ context.Context, state multistep.StateBag) multis amiTags.Report(ui) ui.Say("Creating snapshot tags") - snapshotTags, err := s.SnapshotTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, sourceAMI) + snapshotTags, err := s.SnapshotTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { state.Put("error", err) ui.Error(err.Error()) diff --git a/builder/amazon/common/step_modify_ami_attributes.go b/builder/amazon/common/step_modify_ami_attributes.go index 26ab31986..234e1762a 100644 --- a/builder/amazon/common/step_modify_ami_attributes.go +++ b/builder/amazon/common/step_modify_ami_attributes.go @@ -27,13 +27,6 @@ func (s *StepModifyAMIAttributes) Run(_ context.Context, state multistep.StateBa session := state.Get("awsSession").(*session.Session) ui := state.Get("ui").(packer.Ui) amis := state.Get("amis").(map[string]string) - - var sourceAMI string - if rawSourceAMI, hasSourceAMI := state.GetOk("source_image"); hasSourceAMI { - sourceAMI = *rawSourceAMI.(*ec2.Image).ImageId - } else { - sourceAMI = "" - } snapshots := state.Get("snapshots").(map[string][]string) // Determine if there is any work to do. @@ -50,10 +43,7 @@ func (s *StepModifyAMIAttributes) Run(_ context.Context, state multistep.StateBa } var err error - s.Ctx.Data = &BuildInfoTemplate{ - SourceAMI: sourceAMI, - BuildRegion: *ec2conn.Config.Region, - } + s.Ctx.Data = extractBuildInfo(*ec2conn.Config.Region, state) s.Description, err = interpolate.Render(s.Description, &s.Ctx) if err != nil { err = fmt.Errorf("Error interpolating AMI description: %s", err) diff --git a/builder/amazon/common/step_run_source_instance.go b/builder/amazon/common/step_run_source_instance.go index 761e6f09c..8542e9387 100644 --- a/builder/amazon/common/step_run_source_instance.go +++ b/builder/amazon/common/step_run_source_instance.go @@ -88,7 +88,7 @@ func (s *StepRunSourceInstance) Run(_ context.Context, state multistep.StateBag) s.Tags["Name"] = "Packer Builder" } - ec2Tags, err := s.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, s.SourceAMI) + ec2Tags, err := s.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { err := fmt.Errorf("Error tagging source instance: %s", err) state.Put("error", err) @@ -96,7 +96,7 @@ func (s *StepRunSourceInstance) Run(_ context.Context, state multistep.StateBag) return multistep.ActionHalt } - volTags, err := s.VolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, s.SourceAMI) + volTags, err := s.VolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { err := fmt.Errorf("Error tagging volumes: %s", err) state.Put("error", err) @@ -259,7 +259,7 @@ func (s *StepRunSourceInstance) Run(_ context.Context, state multistep.StateBag) if len(volumeIds) > 0 && s.VolumeTags.IsSet() { ui.Say("Adding tags to source EBS Volumes") - volumeTags, err := s.VolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, s.SourceAMI) + volumeTags, err := s.VolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { err := fmt.Errorf("Error tagging source EBS Volumes on %s: %s", *instance.InstanceId, err) state.Put("error", err) diff --git a/builder/amazon/common/step_run_spot_instance.go b/builder/amazon/common/step_run_spot_instance.go index 0f08ea90b..d90dd391a 100644 --- a/builder/amazon/common/step_run_spot_instance.go +++ b/builder/amazon/common/step_run_spot_instance.go @@ -143,7 +143,7 @@ func (s *StepRunSpotInstance) Run(_ context.Context, state multistep.StateBag) m s.Tags["Name"] = "Packer Builder" } - ec2Tags, err := s.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, s.SourceAMI) + ec2Tags, err := s.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { err := fmt.Errorf("Error tagging source instance: %s", err) state.Put("error", err) @@ -287,7 +287,7 @@ func (s *StepRunSpotInstance) Run(_ context.Context, state multistep.StateBag) m if len(volumeIds) > 0 && s.VolumeTags.IsSet() { ui.Say("Adding tags to source EBS Volumes") - volumeTags, err := s.VolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, s.SourceAMI) + volumeTags, err := s.VolumeTags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { err := fmt.Errorf("Error tagging source EBS Volumes on %s: %s", *instance.InstanceId, err) state.Put("error", err) diff --git a/builder/amazon/common/tags.go b/builder/amazon/common/tags.go index 3c257e10f..918269f91 100644 --- a/builder/amazon/common/tags.go +++ b/builder/amazon/common/tags.go @@ -5,6 +5,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/packer/helper/multistep" "github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/template/interpolate" ) @@ -23,12 +24,10 @@ func (t TagMap) IsSet() bool { return len(t) > 0 } -func (t TagMap) EC2Tags(ctx interpolate.Context, region, sourceAMIID string) (EC2Tags, error) { +func (t TagMap) EC2Tags(ctx interpolate.Context, region string, state multistep.StateBag) (EC2Tags, error) { var ec2Tags []*ec2.Tag - ctx.Data = &BuildInfoTemplate{ - SourceAMI: sourceAMIID, - BuildRegion: region, - } + ctx.Data = extractBuildInfo(region, state) + for key, value := range t { interpolatedKey, err := interpolate.Render(key, &ctx) if err != nil { diff --git a/builder/amazon/ebsvolume/step_tag_ebs_volumes.go b/builder/amazon/ebsvolume/step_tag_ebs_volumes.go index 31e6799b1..62a84146c 100644 --- a/builder/amazon/ebsvolume/step_tag_ebs_volumes.go +++ b/builder/amazon/ebsvolume/step_tag_ebs_volumes.go @@ -18,7 +18,6 @@ type stepTagEBSVolumes struct { func (s *stepTagEBSVolumes) Run(_ context.Context, state multistep.StateBag) multistep.StepAction { ec2conn := state.Get("ec2").(*ec2.EC2) instance := state.Get("instance").(*ec2.Instance) - sourceAMI := state.Get("source_image").(*ec2.Image) ui := state.Get("ui").(packer.Ui) volumes := make(EbsVolumes) @@ -43,7 +42,7 @@ func (s *stepTagEBSVolumes) Run(_ context.Context, state multistep.StateBag) mul continue } - tags, err := mapping.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, *sourceAMI.ImageId) + tags, err := mapping.Tags.EC2Tags(s.Ctx, *ec2conn.Config.Region, state) if err != nil { err := fmt.Errorf("Error tagging device %s with %s", mapping.DeviceName, err) state.Put("error", err)