From 65f10b7c979152b575324658283f8f597699fe7d Mon Sep 17 00:00:00 2001 From: Xu Fan Date: Fri, 18 Dec 2015 15:12:54 +0800 Subject: [PATCH] provider/aws: tag the spot instance. --- .../aws/resource_aws_spot_instance_request.go | 28 +++++++++- builtin/providers/aws/tags.go | 56 +++++++++++++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/builtin/providers/aws/resource_aws_spot_instance_request.go b/builtin/providers/aws/resource_aws_spot_instance_request.go index 256730cfdc3d..8574f2029c7d 100644 --- a/builtin/providers/aws/resource_aws_spot_instance_request.go +++ b/builtin/providers/aws/resource_aws_spot_instance_request.go @@ -140,11 +140,35 @@ func resourceAwsSpotInstanceRequestCreate(d *schema.ResourceData, meta interface } log.Printf("[DEBUG] waiting for spot bid to resolve... this may take several minutes.") - _, err = spotStateConf.WaitForState() + result, err := spotStateConf.WaitForState() if err != nil { return fmt.Errorf("Error while waiting for spot request (%s) to resolve: %s", sir, err) } + + sir = *result.(*ec2.SpotInstanceRequest) + d.Set("spot_instance_id", sir.InstanceId) + + // Wait for the spot instance running + log.Printf( + "[DEBUG] Waiting for instance (%s) to become running", + *sir.InstanceId) + + stateConf := &resource.StateChangeConf{ + Pending: []string{"pending"}, + Target: "running", + Refresh: InstanceStateRefreshFunc(conn, *sir.InstanceId), + Timeout: 10 * time.Minute, + Delay: 10 * time.Second, + MinTimeout: 3 * time.Second, + } + + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf( + "Error waiting for instance (%s) to become ready: %s", + *sir.InstanceId, err) + } } return resourceAwsSpotInstanceRequestUpdate(d, meta) @@ -254,7 +278,7 @@ func resourceAwsSpotInstanceRequestUpdate(d *schema.ResourceData, meta interface conn := meta.(*AWSClient).ec2conn d.Partial(true) - if err := setTags(conn, d); err != nil { + if err := setTagsSpotRequest(conn, d); err != nil { return err } else { d.SetPartial("tags") diff --git a/builtin/providers/aws/tags.go b/builtin/providers/aws/tags.go index df5d9e2a720d..a71c9a902360 100644 --- a/builtin/providers/aws/tags.go +++ b/builtin/providers/aws/tags.go @@ -52,6 +52,62 @@ func setTags(conn *ec2.EC2, d *schema.ResourceData) error { return nil } +// setTagsSpotRequest also set the tags to the spot instance. +func setTagsSpotRequest(conn *ec2.EC2, d *schema.ResourceData) error { + if d.HasChange("tags") { + oraw, nraw := d.GetChange("tags") + o := oraw.(map[string]interface{}) + n := nraw.(map[string]interface{}) + create, remove := diffTags(tagsFromMap(o), tagsFromMap(n)) + + // Set tags + if len(remove) > 0 { + log.Printf("[DEBUG] Removing tags: %#v from %s", remove, d.Id()) + _, err := conn.DeleteTags(&ec2.DeleteTagsInput{ + Resources: []*string{aws.String(d.Id())}, + Tags: remove, + }) + if err != nil { + return err + } + + if instanceId := d.Get("spot_instance_id").(string); instanceId != "" { + log.Printf("[DEBUG] Removing tags: %#v from %s", remove, instanceId) + _, err := conn.DeleteTags(&ec2.DeleteTagsInput{ + Resources: []*string{aws.String(instanceId)}, + Tags: remove, + }) + if err != nil { + return err + } + } + } + if len(create) > 0 { + log.Printf("[DEBUG] Creating tags: %s for %s", create, d.Id()) + _, err := conn.CreateTags(&ec2.CreateTagsInput{ + Resources: []*string{aws.String(d.Id())}, + Tags: create, + }) + if err != nil { + return err + } + + if instanceId := d.Get("spot_instance_id").(string); instanceId != "" { + log.Printf("[DEBUG] Creating tags: %s for %s", create, instanceId) + _, err := conn.CreateTags(&ec2.CreateTagsInput{ + Resources: []*string{aws.String(instanceId)}, + Tags: create, + }) + if err != nil { + return err + } + } + } + } + + return nil +} + // diffTags takes our tags locally and the ones remotely and returns // the set of tags that must be created, and the set of tags that must // be destroyed.