From 274630bd9c238a32f18e3a7e7ca6ce8291e6a668 Mon Sep 17 00:00:00 2001 From: David Zanetti Date: Tue, 24 Nov 2015 14:23:19 +1300 Subject: [PATCH] Support adding tags to AMI and snapshots created by amazon-import - Tags follows the same approach as the amazon-ebs builder - Clean up some debug messages - Improve readability by pulling out AMI id into seperate variable Note: this duplicates the tag creation code in builder/amazon/common/step_create_tags.go. Maybe this should be a multistep post-processor instead, and we re-use steps from the builder. --- .../amazon-import/post-processor.go | 69 +++++++++++++++++-- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/post-processor/amazon-import/post-processor.go b/post-processor/amazon-import/post-processor.go index 1794b7bf8..45ff58e5d 100644 --- a/post-processor/amazon-import/post-processor.go +++ b/post-processor/amazon-import/post-processor.go @@ -6,6 +6,7 @@ import ( "os" "log" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/s3/s3manager" @@ -38,6 +39,7 @@ type Config struct { SkipClean bool `mapstructure:"skip_clean"` ImportTaskDesc string `mapstructure:"import_task_desc"` ImportDiskDesc string `mapstructure:"import_disk_desc"` + Tags map[string]string `mapstructure:"tags"` ctx interpolate.Context } @@ -106,7 +108,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac return nil, false, fmt.Errorf("Artifact type %s is not supported by this post-processor", artifact.BuilderId()) } - log.Println("Looking for OVA in artifact...") + log.Println("Looking for OVA in artifact") // Locate the files output from the builder source := "" for _, path := range artifact.Files() { @@ -122,11 +124,11 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac } // Set up the AWS session - log.Println("Creating AWS session...") + log.Println("Creating AWS session") session := session.New(config) // open the source file - log.Printf("Opening file %s to upload...", source) + log.Printf("Opening file %s to upload", source) file, err := os.Open(source) if err != nil { return nil, false, fmt.Errorf("Failed to open %s: %s", source, err) @@ -200,11 +202,68 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac ui.Message(fmt.Sprintf("Import task %s complete", *import_start.ImportTaskId)) + createdami := *import_result.ImportImageTasks[0].ImageId + + // If we have tags, then apply them now to both the AMI and snaps + // created by the import + if len(p.config.Tags) > 0 { + var ec2Tags []*ec2.Tag; + + log.Printf("Repacking tags into AWS format") + + for key, value := range p.config.Tags { + ui.Message(fmt.Sprintf("Adding tag \"%s\": \"%s\"", key, value)) + ec2Tags = append(ec2Tags, &ec2.Tag{ + Key: aws.String(key), + Value: aws.String(value), + }) + } + + resourceIds := []*string{&createdami} + + log.Printf("Getting details of %s", createdami) + + imageResp, err := ec2conn.DescribeImages(&ec2.DescribeImagesInput{ + ImageIds: resourceIds, + }) + + if err != nil { + return nil, false, fmt.Errorf("Failed to retrieve details for AMI %s: %s", createdami, err) + } + + if len(imageResp.Images) == 0 { + return nil, false, fmt.Errorf("AMI %s has no images", createdami) + } + + image := imageResp.Images[0] + + log.Printf("Walking block device mappings for %s to find snapshots", createdami) + + for _, device := range image.BlockDeviceMappings { + if device.Ebs != nil && device.Ebs.SnapshotId != nil { + ui.Message(fmt.Sprintf("Tagging snapshot %s", *device.Ebs.SnapshotId)) + resourceIds = append(resourceIds, device.Ebs.SnapshotId) + } + } + + ui.Message(fmt.Sprintf("Tagging AMI %s", createdami)) + + _, err = ec2conn.CreateTags(&ec2.CreateTagsInput{ + Resources: resourceIds, + Tags: ec2Tags, + }) + + if err != nil { + return nil, false, fmt.Errorf("Failed to add tags to resources %#v: %s", resourceIds, err) + } + + } + // Add the reported AMI ID to the artifact list - log.Printf("Adding created AMI ID %s in region %s to output artifacts", *import_result.ImportImageTasks[0].ImageId, *config.Region) + log.Printf("Adding created AMI ID %s in region %s to output artifacts", createdami, *config.Region) artifact = &awscommon.Artifact{ Amis: map[string]string{ - *config.Region: *import_result.ImportImageTasks[0].ImageId, + *config.Region: createdami, }, BuilderIdValue: BuilderId, Conn: ec2conn,