From fb0e0aa8468db9c92143fd61aa84f45d38e48e43 Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Fri, 15 Jun 2018 08:30:35 +1000 Subject: [PATCH 01/67] added launch templates and ondemand capacity --- aws/resource_aws_spot_fleet_request.go | 216 ++++++++++++++++++++++++- aws/structure.go | 25 +++ 2 files changed, 233 insertions(+), 8 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 4f33c33e88ef..6b9635357caa 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "strconv" + "strings" "time" "github.com/aws/aws-sdk-go/aws" @@ -53,9 +54,10 @@ func resourceAwsSpotFleetRequest() *schema.Resource { // http://docs.aws.amazon.com/sdk-for-go/api/service/ec2.html#type-SpotFleetLaunchSpecification // http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_SpotFleetLaunchSpecification.html "launch_specification": { - Type: schema.TypeSet, - Required: true, - ForceNew: true, + Type: schema.TypeSet, + Optional: true, + ConflictsWith: []string{"launch_template_configs"}, + ForceNew: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "vpc_security_group_ids": { @@ -311,12 +313,88 @@ func resourceAwsSpotFleetRequest() *schema.Resource { }, Set: hashLaunchSpecification, }, + "launch_template_configs": { + Type: schema.TypeSet, + Optional: true, + ConflictsWith: []string{"launch_specification"}, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "launch_template_specification": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"launch_template_configs.0.launch_template_specification.0.name"}, + ValidateFunc: validateLaunchTemplateId, + }, + "name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"launch_template_configs.0.launch_template_specification.0.id"}, + ValidateFunc: validateLaunchTemplateName, + }, + "version": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(1, 255), + }, + }, + }, + }, + "overrides": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "availability_zone": { + Type: schema.TypeString, + Optional: true, + //ValidateFunc: validateLaunchTemplateId, + }, + "instance_type": { + Type: schema.TypeString, + Optional: true, + //ValidateFunc: validateLaunchTemplateName, + }, + "spot_price": { + Type: schema.TypeString, + Optional: true, + //ValidateFunc: validation.StringLenBetween(1, 255), + }, + "subnet_id": { + Type: schema.TypeString, + Optional: true, + //ValidateFunc: validation.StringLenBetween(1, 255), + }, + "weighted_capacity": { + Type: schema.TypeFloat, + Optional: true, + //ValidateFunc: validation.StringLenBetween(1, 255), + }, + }, + }, + }, + }, + }, + }, // Everything on a spot fleet is ForceNew except target_capacity "target_capacity": { Type: schema.TypeInt, Required: true, ForceNew: false, }, + "on_demand_target_capacity": { + Type: schema.TypeInt, + ConflictsWith: []string{"launch_specification"}, + Optional: true, + ForceNew: false, + }, "allocation_strategy": { Type: schema.TypeString, Optional: true, @@ -418,6 +496,14 @@ func resourceAwsSpotFleetRequest() *schema.Resource { }, "tags": tagsSchema(), }, + CustomizeDiff: customdiff.Sequence( + customdiff.ComputedIf("launch_template_configs.0.launch_template_specification.0.id", func(diff *schema.ResourceDiff, meta interface{}) bool { + return diff.HasChange("launch_template_configs.0.launch_template_specification.0.name") + }), + customdiff.ComputedIf("launch_template_configs.0.launch_template_specification.0.name", func(diff *schema.ResourceDiff, meta interface{}) bool { + return diff.HasChange("launch_template_configs.0.launch_template_specification.0.id") + }), + ), } } @@ -676,19 +762,101 @@ func buildAwsSpotFleetLaunchSpecifications( return specs, nil } +func buildLaunchTemplateConfigs(d *schema.ResourceData, meta interface{}) ([]*ec2.LaunchTemplateConfig, error) { + launch_template_cfgs := d.Get("launch_template_configs").(*schema.Set).List() + cfgs := make([]*ec2.LaunchTemplateConfig, len(launch_template_cfgs)) + log.Printf("[DEBUG] cfgs: %#v", cfgs) + + for _, launch_template_cfg := range launch_template_cfgs { + + ltc := &ec2.LaunchTemplateConfig{} + + ltc_map := launch_template_cfg.(map[string]interface{}) + + //launch template spec + if v, ok := ltc_map["launch_template_specification"]; ok { + //panic: interface conversion: interface {} is []interface {}, not *schema.Set + vL := v.([]interface{}) + //vL := v.(*schema.Set).List() + //log.Printf("[DEBUG] vL(672): %#v", vL) + //for _, v := range vL { + //panic: interface conversion: interface {} is []interface {}, not map[string]interface {} + lts := vL[0].(map[string]interface{}) + log.Printf("[DEBUG] lts(676): %#v", vL) + flts := &ec2.FleetLaunchTemplateSpecification{} + log.Printf("[DEBUG] flts(678): %#v", flts) + if v, ok := lts["id"].(string); ok && v != "" { + flts.LaunchTemplateId = aws.String(v) + } + + if v, ok := lts["name"].(string); ok && v != "" { + flts.LaunchTemplateName = aws.String(v) + } + + if v, ok := lts["version"].(string); ok && v != "" { + flts.Version = aws.String(v) + } + log.Printf("[DEBUG] flts(691): %#v", flts) + + ltc.LaunchTemplateSpecification = flts + //} + } + + //now the overrides + overrides := make([]*ec2.LaunchTemplateOverrides, 0) + // for each override + if v, ok := ltc_map["overrides"]; ok { + vL := v.(*schema.Set).List() + for _, v := range vL { + ors := v.(map[string]interface{}) + lto := &ec2.LaunchTemplateOverrides{} + + if v, ok := ors["availability_zone"].(string); ok && v != "" { + lto.AvailabilityZone = aws.String(v) + } + + if v, ok := ors["instance_type"].(string); ok && v != "" { + lto.InstanceType = aws.String(v) + } + + if v, ok := ors["spot_price"].(string); ok && v != "" { + lto.SpotPrice = aws.String(v) + } + + if v, ok := ors["subnet_id"].(string); ok && v != "" { + lto.SubnetId = aws.String(v) + } + + if v, ok := ors["weighted_capacity"].(float64); ok && v > 0 { + lto.WeightedCapacity = aws.Float64(float64(v)) + } + + overrides = append(overrides, lto) + + } + } + ltc.Overrides = overrides + + cfgs = append(cfgs, ltc) + } + + return cfgs, nil +} + func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) error { // http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RequestSpotFleet.html conn := meta.(*AWSClient).ec2conn - launch_specs, err := buildAwsSpotFleetLaunchSpecifications(d, meta) - if err != nil { - return err + _, launchSpecificationOk := d.GetOk("launch_specification") + _, launchTemplateConfigsOk := d.GetOk("launch_template_configs") + + if !launchSpecificationOk && !launchTemplateConfigsOk { + return fmt.Errorf("One of `launch_specification` or `launch_template` must be set for an a fleet request") } // http://docs.aws.amazon.com/sdk-for-go/api/service/ec2.html#type-SpotFleetRequestConfigData spotFleetConfig := &ec2.SpotFleetRequestConfigData{ IamFleetRole: aws.String(d.Get("iam_fleet_role").(string)), - LaunchSpecifications: launch_specs, TargetCapacity: aws.Int64(int64(d.Get("target_capacity").(int))), ClientToken: aws.String(resource.UniqueId()), TerminateInstancesWithExpiration: aws.Bool(d.Get("terminate_instances_with_expiration").(bool)), @@ -698,6 +866,32 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) TagSpecifications: ec2TagSpecificationsFromMap(d.Get("tags").(map[string]interface{}), ec2.ResourceTypeSpotFleetRequest), } + var err error + + if launchSpecificationOk { + launch_specs, err := buildAwsSpotFleetLaunchSpecifications(d, meta) + if err != nil { + return err + } + spotFleetConfig.LaunchSpecifications = launch_specs + } + + // Need to suppport multiples + if launchTemplateConfigsOk { + // launch_template_cfg, err := buildLaunchTemplateConfig(d, meta) + // if err != nil { + // return err + // } + spotFleetConfig.LaunchTemplateConfigs, err = buildLaunchTemplateConfigs(d, meta) + if err != nil { + return err + } + } + + if v, ok := d.GetOk("on_demand_target_capacity"); ok { + spotFleetConfig.OnDemandTargetCapacity = aws.Int64(int64(v.(int))) + } + if v, ok := d.GetOk("excess_capacity_termination_policy"); ok { spotFleetConfig.ExcessCapacityTerminationPolicy = aws.String(v.(string)) } @@ -804,7 +998,7 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) Pending: []string{ec2.BatchStateSubmitted}, Target: []string{ec2.BatchStateActive}, Refresh: resourceAwsSpotFleetRequestStateRefreshFunc(d, meta), - Timeout: 10 * time.Minute, + Timeout: d.Timeout(schema.TimeoutCreate), //10 * time.Minute, MinTimeout: 10 * time.Second, Delay: 30 * time.Second, } @@ -1019,6 +1213,12 @@ func resourceAwsSpotFleetRequestRead(d *schema.ResourceData, meta interface{}) e return fmt.Errorf("error setting tags: %s", err) } + if config.LaunchTemplateConfigs[0] != nil { + d.Set("launch_template_configs.0.launch_template_specification.0.id", flattenFleetLaunchTemplateSpecification(config.LaunchTemplateConfigs[0].LaunchTemplateSpecification)) + } else { + d.Set("launch_template_configs.0.launch_template_specification.0.id", nil) + } + return nil } diff --git a/aws/structure.go b/aws/structure.go index 6a733e9fbb2d..c95d9b95eb44 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -4684,6 +4684,31 @@ func flattenLaunchTemplateSpecification(lt *autoscaling.LaunchTemplateSpecificat return result } +func flattenFleetLaunchTemplateSpecification(flt *ec2.FleetLaunchTemplateSpecification) []map[string]interface{} { + attrs := map[string]interface{}{} + result := make([]map[string]interface{}, 0) + + // unlike autoscaling.LaunchTemplateConfiguration, FleetLaunchTemplateSpecs only return what was set + if flt.LaunchTemplateId != nil { + attrs["id"] = *flt.LaunchTemplateId + } + + if flt.LaunchTemplateName != nil { + attrs["name"] = *flt.LaunchTemplateName + } + + // version is returned only if it was previously set + if flt.Version != nil { + attrs["version"] = *flt.Version + } else { + attrs["version"] = nil + } + + result = append(result, attrs) + + return result +} + func flattenVpcPeeringConnectionOptions(options *ec2.VpcPeeringConnectionOptionsDescription) []interface{} { // When the VPC Peering Connection is pending acceptance, // the details about accepter and/or requester peering From 077cb40d76360161ae70ba6664953110598398c4 Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Mon, 18 Jun 2018 20:05:09 +1000 Subject: [PATCH 02/67] Added tests with incorrect subresource ids --- aws/resource_aws_spot_fleet_request_test.go | 726 ++++++++++++++++---- 1 file changed, 596 insertions(+), 130 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 01e334e3b662..ef66a0dcf1b3 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -1,59 +1,59 @@ package aws import ( - "errors" - "fmt" - "log" - "regexp" - "testing" - "time" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/ec2" - "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "errors" + "fmt" + "log" + "regexp" + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" ) func init() { - resource.AddTestSweepers("aws_spot_fleet_request", &resource.Sweeper{ - Name: "aws_spot_fleet_request", - F: testSweepSpotFleetRequests, - }) + resource.AddTestSweepers("aws_spot_fleet_request", &resource.Sweeper{ + Name: "aws_spot_fleet_request", + F: testSweepSpotFleetRequests, + }) } func testSweepSpotFleetRequests(region string) error { - client, err := sharedClientForRegion(region) - if err != nil { - return fmt.Errorf("error getting client: %s", err) - } - conn := client.(*AWSClient).ec2conn + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*AWSClient).ec2conn - err = conn.DescribeSpotFleetRequestsPages(&ec2.DescribeSpotFleetRequestsInput{}, func(page *ec2.DescribeSpotFleetRequestsOutput, isLast bool) bool { - if len(page.SpotFleetRequestConfigs) == 0 { - log.Print("[DEBUG] No Spot Fleet Requests to sweep") - return false - } + err = conn.DescribeSpotFleetRequestsPages(&ec2.DescribeSpotFleetRequestsInput{}, func(page *ec2.DescribeSpotFleetRequestsOutput, isLast bool) bool { + if len(page.SpotFleetRequestConfigs) == 0 { + log.Print("[DEBUG] No Spot Fleet Requests to sweep") + return false + } - for _, config := range page.SpotFleetRequestConfigs { - id := aws.StringValue(config.SpotFleetRequestId) + for _, config := range page.SpotFleetRequestConfigs { + id := aws.StringValue(config.SpotFleetRequestId) - log.Printf("[INFO] Deleting Spot Fleet Request: %s", id) - err := deleteSpotFleetRequest(id, true, 5*time.Minute, conn) - if err != nil { - log.Printf("[ERROR] Failed to delete Spot Fleet Request (%s): %s", id, err) - } - } - return !isLast - }) - if err != nil { - if testSweepSkipSweepError(err) { - log.Printf("[WARN] Skipping EC2 Spot Fleet Requests sweep for %s: %s", region, err) - return nil - } - return fmt.Errorf("Error retrieving EC2 Spot Fleet Requests: %s", err) - } - return nil + log.Printf("[INFO] Deleting Spot Fleet Request: %s", id) + err := deleteSpotFleetRequest(id, true, 5*time.Minute, conn) + if err != nil { + log.Printf("[ERROR] Failed to delete Spot Fleet Request (%s): %s", id, err) + } + } + return !isLast + }) + if err != nil { + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping EC2 Spot Fleet Requests sweep for %s: %s", region, err) + return nil + } + return fmt.Errorf("Error retrieving EC2 Spot Fleet Requests: %s", err) + } + return nil } func TestAccAWSSpotFleetRequest_basic(t *testing.T) { @@ -148,6 +148,206 @@ func TestAccAWSSpotFleetRequest_associatePublicIpAddress(t *testing.T) { }) } +func TestAccAWSSpotFleetRequest_launchTemplate(t *testing.T) { + var sfr ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestLaunchTemplateConfig(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &sfr), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_specification.#", "0"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), + ), + }, + }, + }) +} + +//On-Demand capacity requires launch template defined spot fleet, so can't test without it. +func TestAccAWSSpotFleetRequest_launchTemplateWithOnDemandCapacity(t *testing.T) { + var sfr ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &sfr), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_specification.#", "0"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "on_demand_target_capacity", "2"), + ), + }, + }, + }) +} + +func TestAccAWSSpotFleetRequest_launchTemplateWithOverrides(t *testing.T) { + var sfr ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestLaunchTemplateConfigWithOverrides(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &sfr), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_specification.#", "0"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.3492852471.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.3492852471.overrides.#", "2"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.3492852471.overrides.#", "2"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.3492852471.overrides.3113255372.instance_type", "t1.micro"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.3492852471.overrides.3113255372.weighted_capacity", "2"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.3492852471.overrides.1994766569.instance_type", "m3.medium"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.3492852471.overrides.1994766569.spot_price", "0.26"), + ), + }, + }, + }) +} + +func TestAccAWSSpotFleetRequest_launchTemplateToLaunchSpec(t *testing.T) { + var before, after ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestLaunchTemplateConfig(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &before), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_specification.#", "0"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), + ), + }, + { + Config: testAccAWSSpotFleetRequestConfig(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &after), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_price", "0.005"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_specification.#", "1"), + // resource.TestCheckResourceAttr( + // "aws_spot_fleet_request.foo", "launch_template_configs.#", "0"), + testAccCheckAWSSpotFleetRequestConfigRecreated(t, &before, &after), + ), + }, + }, + }) +} + +func TestAccAWSSpotFleetRequest_launchSpecToLaunchTemplate(t *testing.T) { + var before, after ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestConfig(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &before), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_price", "0.005"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_specification.#", "1"), + // resource.TestCheckResourceAttr( + // "aws_spot_fleet_request.foo", "launch_template_configs.#", "0"), + ), + }, + { + Config: testAccAWSSpotFleetRequestLaunchTemplateConfig(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &after), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_specification.#", "0"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), + testAccCheckAWSSpotFleetRequestConfigRecreated(t, &before, &after), + ), + }, + }, + }) +} + func TestAccAWSSpotFleetRequest_instanceInterruptionBehavior(t *testing.T) { var sfr ec2.SpotFleetRequestConfig rName := acctest.RandString(10) @@ -562,19 +762,19 @@ func TestAccAWSSpotFleetRequest_withWeightedCapacity(t *testing.T) { validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) resourceName := "aws_spot_fleet_request.test" - fulfillSleep := func() resource.TestCheckFunc { - // sleep so that EC2 can fuflill the request. We do this to guard against a - // regression and possible leak where we'll destroy the request and the - // associated IAM role before anything is actually provisioned and running, - // thus leaking when those newly started instances are attempted to be - // destroyed - // See https://github.com/hashicorp/terraform/pull/8938 - return func(s *terraform.State) error { - log.Print("[DEBUG] Test: Sleep to allow EC2 to actually begin fulfilling TestAccAWSSpotFleetRequest_withWeightedCapacity request") - time.Sleep(1 * time.Minute) - return nil - } - } + fulfillSleep := func() resource.TestCheckFunc { + // sleep so that EC2 can fuflill the request. We do this to guard against a + // regression and possible leak where we'll destroy the request and the + // associated IAM role before anything is actually provisioned and running, + // thus leaking when those newly started instances are attempted to be + // destroyed + // See https://github.com/hashicorp/terraform/pull/8938 + return func(s *terraform.State) error { + log.Print("[DEBUG] Test: Sleep to allow EC2 to actually begin fulfilling TestAccAWSSpotFleetRequest_withWeightedCapacity request") + time.Sleep(1 * time.Minute) + return nil + } + } resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSEc2SpotFleetRequest(t) }, @@ -745,7 +945,6 @@ func TestAccAWSSpotFleetRequest_WithTargetGroups(t *testing.T) { rInt := acctest.RandInt() validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) resourceName := "aws_spot_fleet_request.test" - resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSEc2SpotFleetRequest(t) }, Providers: testAccProviders, @@ -784,46 +983,46 @@ func TestAccAWSSpotFleetRequest_WithInstanceStoreAmi(t *testing.T) { } func testAccCheckAWSSpotFleetRequestConfigRecreated(t *testing.T, - before, after *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { - return func(s *terraform.State) error { - if before.SpotFleetRequestId == after.SpotFleetRequestId { - t.Fatalf("Expected change of Spot Fleet Request IDs, but both were %v", before.SpotFleetRequestId) - } - return nil - } + before, after *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { + return func(s *terraform.State) error { + if before.SpotFleetRequestId == after.SpotFleetRequestId { + t.Fatalf("Expected change of Spot Fleet Request IDs, but both were %v", before.SpotFleetRequestId) + } + return nil + } } func testAccCheckAWSSpotFleetRequestExists( - n string, sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("Not found: %s", n) - } + n string, sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } - if rs.Primary.ID == "" { - return errors.New("No Spot fleet request with that id exists") - } + if rs.Primary.ID == "" { + return errors.New("No Spot fleet request with that id exists") + } - conn := testAccProvider.Meta().(*AWSClient).ec2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn - params := &ec2.DescribeSpotFleetRequestsInput{ - SpotFleetRequestIds: []*string{&rs.Primary.ID}, - } - resp, err := conn.DescribeSpotFleetRequests(params) + params := &ec2.DescribeSpotFleetRequestsInput{ + SpotFleetRequestIds: []*string{&rs.Primary.ID}, + } + resp, err := conn.DescribeSpotFleetRequests(params) - if err != nil { - return err - } + if err != nil { + return err + } - if v := len(resp.SpotFleetRequestConfigs); v != 1 { - return fmt.Errorf("Expected 1 request returned, got %d", v) - } + if v := len(resp.SpotFleetRequestConfigs); v != 1 { + return fmt.Errorf("Expected 1 request returned, got %d", v) + } - *sfr = *resp.SpotFleetRequestConfigs[0] + *sfr = *resp.SpotFleetRequestConfigs[0] - return nil - } + return nil + } } func testAccCheckAWSSpotFleetRequestDestroy(s *terraform.State) error { @@ -848,28 +1047,28 @@ func testAccCheckAWSSpotFleetRequestDestroy(s *terraform.State) error { } func testAccCheckAWSSpotFleetRequest_EBSAttributes( - sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { - return func(s *terraform.State) error { - if len(sfr.SpotFleetRequestConfig.LaunchSpecifications) == 0 { - return errors.New("Missing launch specification") - } + sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { + return func(s *terraform.State) error { + if len(sfr.SpotFleetRequestConfig.LaunchSpecifications) == 0 { + return errors.New("Missing launch specification") + } - spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] + spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] - ebs := spec.BlockDeviceMappings - if len(ebs) < 2 { - return fmt.Errorf("Expected %d block device mappings, got %d", 2, len(ebs)) - } + ebs := spec.BlockDeviceMappings + if len(ebs) < 2 { + return fmt.Errorf("Expected %d block device mappings, got %d", 2, len(ebs)) + } - if *ebs[0].DeviceName != "/dev/xvda" { - return fmt.Errorf("Expected device 0's name to be %s, got %s", "/dev/xvda", *ebs[0].DeviceName) - } - if *ebs[1].DeviceName != "/dev/xvdcz" { - return fmt.Errorf("Expected device 1's name to be %s, got %s", "/dev/xvdcz", *ebs[1].DeviceName) - } + if *ebs[0].DeviceName != "/dev/xvda" { + return fmt.Errorf("Expected device 0's name to be %s, got %s", "/dev/xvda", *ebs[0].DeviceName) + } + if *ebs[1].DeviceName != "/dev/xvdcz" { + return fmt.Errorf("Expected device 1's name to be %s, got %s", "/dev/xvdcz", *ebs[1].DeviceName) + } - return nil - } + return nil + } } func testAccCheckAWSSpotFleetRequest_PlacementAttributes( @@ -879,7 +1078,7 @@ func testAccCheckAWSSpotFleetRequest_PlacementAttributes( return errors.New("Missing launch specification") } - spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] + spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] placement := spec.Placement if placement == nil { @@ -897,26 +1096,26 @@ func testAccCheckAWSSpotFleetRequest_PlacementAttributes( } func testAccCheckAWSSpotFleetRequest_IamInstanceProfileArn( - sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { - return func(s *terraform.State) error { - if len(sfr.SpotFleetRequestConfig.LaunchSpecifications) == 0 { - return errors.New("Missing launch specification") - } + sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { + return func(s *terraform.State) error { + if len(sfr.SpotFleetRequestConfig.LaunchSpecifications) == 0 { + return errors.New("Missing launch specification") + } - spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] + spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] - profile := spec.IamInstanceProfile - if profile == nil { - return fmt.Errorf("Expected IamInstanceProfile to be set, got nil") - } - //Validate the string whether it is ARN - re := regexp.MustCompile(`arn:aws:iam::\d{12}:instance-profile/?[a-zA-Z0-9+=,.@-_].*`) - if !re.MatchString(*profile.Arn) { - return fmt.Errorf("Expected IamInstanceProfile input as ARN, got %s", *profile.Arn) - } + profile := spec.IamInstanceProfile + if profile == nil { + return fmt.Errorf("Expected IamInstanceProfile to be set, got nil") + } + //Validate the string whether it is ARN + re := regexp.MustCompile(`arn:aws:iam::\d{12}:instance-profile/?[a-zA-Z0-9+=,.@-_].*`) + if !re.MatchString(*profile.Arn) { + return fmt.Errorf("Expected IamInstanceProfile input as ARN, got %s", *profile.Arn) + } - return nil - } + return nil + } } func testAccPreCheckAWSEc2SpotFleetRequest(t *testing.T) { @@ -1112,6 +1311,273 @@ resource "aws_spot_fleet_request" "test" { `, validUntil) } +func testAccAWSSpotFleetRequestLaunchTemplateConfig(rName string, rInt int) string { + return fmt.Sprintf(` +resource "aws_key_pair" "debugging" { + key_name = "tmp-key-%s" + public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com" +} + +resource "aws_iam_policy" "test-policy" { + name = "test-policy-%d" + path = "/" + description = "Spot Fleet Request ACCTest Policy" + policy = < Date: Mon, 18 Jun 2018 21:06:16 +1000 Subject: [PATCH 03/67] Added documentation --- .../docs/r/spot_fleet_request.html.markdown | 109 +++++++++++++++++- 1 file changed, 106 insertions(+), 3 deletions(-) diff --git a/website/docs/r/spot_fleet_request.html.markdown b/website/docs/r/spot_fleet_request.html.markdown index 0870878734cd..be5d9668047e 100644 --- a/website/docs/r/spot_fleet_request.html.markdown +++ b/website/docs/r/spot_fleet_request.html.markdown @@ -13,6 +13,8 @@ instances to be requested on the Spot market. ## Example Usage +Using launch specifications: + ```hcl # Request a Spot fleet resource "aws_spot_fleet_request" "cheap_compute" { @@ -52,10 +54,41 @@ resource "aws_spot_fleet_request" "cheap_compute" { } ``` +Using launch templates: + +``` +resource "aws_launch_template" "foo" { + name = "test-launch-template" + image_id = "${var.ami}" + instance_type = "${var.instance_type}" + key_name = "${var.key_name}" + spot_price = "0.05" +} + +resource "aws_spot_fleet_request" "foo" { + iam_fleet_role = "arn:aws:iam::12345678:role/spot-fleet" + spot_price = "0.005" + target_capacity = 2 + valid_until = "2019-11-04T20:44:20Z" + + launch_template_configs { + launch_template_specification { + id = "${aws_launch_template.foo.id}" + version = "${aws_launch_template.foo.latest_version}" + } + } + + depends_on = ["aws_iam_policy_attachment.test-attach"] +} +``` + ~> **NOTE:** Terraform does not support the functionality where multiple `subnet_id` or `availability_zone` parameters can be specified in the same -launch configuration block. If you want to specify multiple values, then separate launch configuration blocks should be used: +launch configuration block. If you want to specify multiple values, then separate launch configuration blocks should be used or launch template overrides should be configured, one per subnet: ```hcl +# +# Launch Specification Method +# resource "aws_spot_fleet_request" "foo" { iam_fleet_role = "arn:aws:iam::12345678:role/spot-fleet" spot_price = "0.005" @@ -76,6 +109,47 @@ resource "aws_spot_fleet_request" "foo" { availability_zone = "us-west-2a" } } + +# +# Launch Template Method +# + +data "aws_subnet_ids" "example" { + vpc_id = "${var.vpc_id}" +} + +resource "aws_launch_template" "foo" { + name = "test-launch-template" + image_id = "${var.ami}" + instance_type = "${var.instance_type}" + key_name = "${var.key_name}" + spot_price = "0.05" +} + +resource "aws_spot_fleet_request" "foo" { + iam_fleet_role = "arn:aws:iam::12345678:role/spot-fleet" + spot_price = "0.005" + target_capacity = 2 + valid_until = "2019-11-04T20:44:20Z" + + launch_template_configs { + launch_template_specification { + id = "${aws_launch_template.foo.id}" + version = "${aws_launch_template.foo.latest_version}" + } + overrides { + subnet_id = "${data.aws_subnets.example.ids[0]}" + } + overrides { + subnet_id = "${data.aws_subnets.example.ids[1]}" + } + overrides { + subnet_id = "${data.aws_subnets.example.ids[2]}" + } + } + + depends_on = ["aws_iam_policy_attachment.test-attach"] +} ``` ## Argument Reference @@ -88,9 +162,9 @@ Most of these arguments directly correspond to the CancelSpotFleetRequests or when the Spot fleet request expires, if you set terminateInstancesWithExpiration. * `replace_unhealthy_instances` - (Optional) Indicates whether Spot fleet should replace unhealthy instances. Default `false`. -* `launch_specification` - Used to define the launch configuration of the +* `launch_specification` - (Optional) Used to define the launch configuration of the spot-fleet request. Can be specified multiple times to define different bids -across different markets and instance types. +across different markets and instance types. Conflicts with `launch_template_configs`. At least one of `launch_specification` or `launch_template_configs` is required. **Note:** This takes in similar but not identical inputs as [`aws_instance`](instance.html). There are limitations on @@ -98,6 +172,7 @@ across different markets and instance types. [reference documentation](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_SpotFleetLaunchSpecification.html). Any normal [`aws_instance`](instance.html) parameter that corresponds to those inputs may be used and it have a additional parameter `iam_instance_profile_arn` takes `aws_iam_instance_profile` attribute `arn` as input. +* `launch_template_configs` - (Optional) Launch template configuration block. See [Launch Template Configs](#launch-template-configs) below for more details. Conflicts with `launch_specification`. At least one of `launch_specification` or `launch_template_configs` is required. * `spot_price` - (Optional; Default: On-demand price) The maximum bid price per unit hour. * `wait_for_fulfillment` - (Optional; Default: false) If set, Terraform will wait for the Spot Request to be fulfilled, and will throw an error if the @@ -105,6 +180,7 @@ across different markets and instance types. * `target_capacity` - The number of units to request. You can choose to set the target capacity in terms of instances or a performance characteristic that is important to your application workload, such as vCPUs, memory, or I/O. +* `on_demand_target_capacity` - (Optional) Allows specification of a minimum value of the `target_capacity` to be filled by full price on-demand instance to ensure a minimum capacity of the fleet no matter spot instance availability. Not supported by `launch_specification`, must be used with `launch_template_configs`. * `allocation_strategy` - Indicates how to allocate the target capacity across the Spot pools specified by the Spot fleet request. The default is `lowestPrice`. @@ -129,6 +205,33 @@ across different markets and instance types. * `target_group_arns` (Optional) A list of `aws_alb_target_group` ARNs, for use with Application Load Balancing. * `tags` - (Optional) A map of tags to assign to the resource. +### Launch Template Configs + +The `launch_template_configs` block supports the following: + +* `launch_template_specification` - (Required) Launch template specification. See [Launch Template Specification](#launch-template-specification) below for more details. +* `overrides` - (Optional) One or more overide configurations. See [Overrides](#overrides) below for more details. + +### Launch Template Specification + +* `id` - The ID of the launch template. Conflicts with `name`. +* `name` - The name of the launch template. Conflicts with `id`. +* `version` - (Optional) Template version. Unlike the autoscaling equivalent, does not support `$Latest` or `$Default`, so use the launch_template resource's attribute, e.g. `"${aws_launch_template.foo.latest_version}"`. Wil use default version if omitted. + + **Note:** The specified launch template can specify only a subset of the + inputs of [`aws_launch_template`](launch_template.html). There are limitations on + what you can specify as spot fleet does not support all the attributes that are supported by autoscaling groups. [AWS documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-launch-templates.html#launch-templates-spot-fleet) is currently sparse, but at least `instance_initiated_shutdown_behavior` is confirmed unsupported. + +### Overrides + +* `instance_type` - (Optional) The type of instance to request. +* `availability_zone` - (Optional) The availability zone in which to place the request. +* `spot_price` - (Optional) The maximum spot bid for this override request. +* `weighted_capacity` - (Optional) The capacity added to the fleet by a fulfilled request. +* `subnet_id` - (Optional) The subnet in which to launch the requested instance. + + **Note:** Instead of statically defining these override blocks they can be passed in as a list of maps containing the above keys and their values. This allows dynamic, programmatic generation of overrides based on variable or environment data. + ### Timeouts The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: From 56a7c2eedf03bda823b8ba01f68922ad28bef647 Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Mon, 25 Jun 2018 20:58:39 +1000 Subject: [PATCH 04/67] added forceNews, ondemand active instance handling on delete and better resource reading --- aws/resource_aws_spot_fleet_request.go | 118 +++++++++++++++++++++---- 1 file changed, 99 insertions(+), 19 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 6b9635357caa..21b6e26c534f 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -316,6 +316,7 @@ func resourceAwsSpotFleetRequest() *schema.Resource { "launch_template_configs": { Type: schema.TypeSet, Optional: true, + ForceNew: true, ConflictsWith: []string{"launch_specification"}, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -329,6 +330,7 @@ func resourceAwsSpotFleetRequest() *schema.Resource { Type: schema.TypeString, Optional: true, Computed: true, + ForceNew: true, ConflictsWith: []string{"launch_template_configs.0.launch_template_specification.0.name"}, ValidateFunc: validateLaunchTemplateId, }, @@ -336,12 +338,15 @@ func resourceAwsSpotFleetRequest() *schema.Resource { Type: schema.TypeString, Optional: true, Computed: true, + ForceNew: true, ConflictsWith: []string{"launch_template_configs.0.launch_template_specification.0.id"}, ValidateFunc: validateLaunchTemplateName, }, "version": { Type: schema.TypeString, Optional: true, + Computed: true, + ForceNew: true, ValidateFunc: validation.StringLenBetween(1, 255), }, }, @@ -350,35 +355,45 @@ func resourceAwsSpotFleetRequest() *schema.Resource { "overrides": { Type: schema.TypeSet, Optional: true, + ForceNew: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "availability_zone": { Type: schema.TypeString, Optional: true, + ForceNew: true, //ValidateFunc: validateLaunchTemplateId, }, "instance_type": { Type: schema.TypeString, Optional: true, + ForceNew: true, //ValidateFunc: validateLaunchTemplateName, }, "spot_price": { Type: schema.TypeString, Optional: true, + Computed: true, + ForceNew: true, //ValidateFunc: validation.StringLenBetween(1, 255), }, "subnet_id": { Type: schema.TypeString, Optional: true, + Computed: true, + ForceNew: true, //ValidateFunc: validation.StringLenBetween(1, 255), }, "weighted_capacity": { Type: schema.TypeFloat, Optional: true, + Computed: true, + ForceNew: true, //ValidateFunc: validation.StringLenBetween(1, 255), }, }, }, + Set: hashLaunchTemplateOverrides, }, }, }, @@ -765,7 +780,6 @@ func buildAwsSpotFleetLaunchSpecifications( func buildLaunchTemplateConfigs(d *schema.ResourceData, meta interface{}) ([]*ec2.LaunchTemplateConfig, error) { launch_template_cfgs := d.Get("launch_template_configs").(*schema.Set).List() cfgs := make([]*ec2.LaunchTemplateConfig, len(launch_template_cfgs)) - log.Printf("[DEBUG] cfgs: %#v", cfgs) for _, launch_template_cfg := range launch_template_cfgs { @@ -775,16 +789,11 @@ func buildLaunchTemplateConfigs(d *schema.ResourceData, meta interface{}) ([]*ec //launch template spec if v, ok := ltc_map["launch_template_specification"]; ok { - //panic: interface conversion: interface {} is []interface {}, not *schema.Set vL := v.([]interface{}) - //vL := v.(*schema.Set).List() - //log.Printf("[DEBUG] vL(672): %#v", vL) - //for _, v := range vL { - //panic: interface conversion: interface {} is []interface {}, not map[string]interface {} lts := vL[0].(map[string]interface{}) - log.Printf("[DEBUG] lts(676): %#v", vL) + flts := &ec2.FleetLaunchTemplateSpecification{} - log.Printf("[DEBUG] flts(678): %#v", flts) + if v, ok := lts["id"].(string); ok && v != "" { flts.LaunchTemplateId = aws.String(v) } @@ -796,15 +805,13 @@ func buildLaunchTemplateConfigs(d *schema.ResourceData, meta interface{}) ([]*ec if v, ok := lts["version"].(string); ok && v != "" { flts.Version = aws.String(v) } - log.Printf("[DEBUG] flts(691): %#v", flts) ltc.LaunchTemplateSpecification = flts - //} + } - //now the overrides overrides := make([]*ec2.LaunchTemplateOverrides, 0) - // for each override + if v, ok := ltc_map["overrides"]; ok { vL := v.(*schema.Set).List() for _, v := range vL { @@ -1214,14 +1221,48 @@ func resourceAwsSpotFleetRequestRead(d *schema.ResourceData, meta interface{}) e } if config.LaunchTemplateConfigs[0] != nil { - d.Set("launch_template_configs.0.launch_template_specification.0.id", flattenFleetLaunchTemplateSpecification(config.LaunchTemplateConfigs[0].LaunchTemplateSpecification)) + d.Set("launch_template_configs.0.launch_template_specification.0", flattenFleetLaunchTemplateSpecification(config.LaunchTemplateConfigs[0].LaunchTemplateSpecification)) + d.Set("launch_template_configs.0.overrides", setLaunchTemplateOverrides(config.LaunchTemplateConfigs[0].Overrides)) } else { - d.Set("launch_template_configs.0.launch_template_specification.0.id", nil) + d.Set("launch_template_configs.0.launch_template_specification.0", nil) } return nil } +func setLaunchTemplateOverrides(overrides []*ec2.LaunchTemplateOverrides) *schema.Set { + overrideSet := &schema.Set{F: hashLaunchTemplateOverrides} + for _, override := range overrides { + overrideSet.Add(overrideToMap(override)) + } + return overrideSet +} + +func overrideToMap(override *ec2.LaunchTemplateOverrides) map[string]interface{} { + m := make(map[string]interface{}) + + if override.AvailabilityZone != nil { + m["availability_zone"] = aws.StringValue(override.AvailabilityZone) + } + if override.InstanceType != nil { + m["instance_type"] = aws.StringValue(override.InstanceType) + } + + if override.SpotPrice != nil { + m["spot_price"] = aws.StringValue(override.SpotPrice) + } + + if override.SubnetId != nil { + m["subnet_id"] = aws.StringValue(override.SubnetId) + } + + if override.WeightedCapacity != nil { + m["weighted_capacity"] = aws.Float64Value(override.WeightedCapacity) //strconv.FormatFloat(*override.WeightedCapacity, 'f', 0, 64) + } + + return m +} + func launchSpecsToSet(launchSpecs []*ec2.SpotFleetLaunchSpecification, conn *ec2.EC2) (*schema.Set, error) { specSet := &schema.Set{F: hashLaunchSpecification} for _, spec := range launchSpecs { @@ -1500,20 +1541,20 @@ func deleteSpotFleetRequest(spotFleetRequestID string, terminateInstances bool, return nil } - activeInstances := func(fleetRequestID string) (int, error) { + activeInstances := func(fleetRequestID string) (int, []*ec2.ActiveInstance, error) { resp, err := conn.DescribeSpotFleetInstances(&ec2.DescribeSpotFleetInstancesInput{ SpotFleetRequestId: aws.String(fleetRequestID), }) if err != nil || resp == nil { - return 0, fmt.Errorf("error reading Spot Fleet Instances (%s): %s", spotFleetRequestID, err) + return 0, nil,fmt.Errorf("error reading Spot Fleet Instances (%s): %s", spotFleetRequestID, err) } - return len(resp.ActiveInstances), nil + return len(resp.ActiveInstances),resp.ActiveInstances, nil } err = resource.Retry(timeout, func() *resource.RetryError { - n, err := activeInstances(spotFleetRequestID) + n, activeInsts, err := activeInstances(spotFleetRequestID) if err != nil { return resource.NonRetryableError(err) } @@ -1523,12 +1564,30 @@ func deleteSpotFleetRequest(spotFleetRequestID string, terminateInstances bool, return resource.RetryableError(fmt.Errorf("fleet still has (%d) running instances", n)) } + instances := []*string{} + for _, instMap := range activeInsts { + instances = append(instances, aws.String(*instMap.InstanceId)) + } + iresp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ + InstanceIds: instances, + }) + if err != nil { + return resource.RetryableError( + fmt.Errorf("Error while trying to determine fleet status for fleet (%s): %s", spotFleetRequestID, err)) + } + if len(iresp.Reservations) == 0 { + log.Printf("[DEBUG] Active instance count is %d for Spot Fleet Request (%s), but instances have terminated, removing", n, spotFleetRequestID) + return nil + } else { + log.Printf("[DEBUG] Active instance count is %d for Spot Fleet Request (%s), and %d instances are still running", n, spotFleetRequestID, len(iresp.Reservations)) + } + log.Printf("[DEBUG] Active instance count is 0 for Spot Fleet Request (%s), removing", spotFleetRequestID) return nil }) if isResourceTimeoutError(err) { - n, err := activeInstances(spotFleetRequestID) + n, _, err := activeInstances(spotFleetRequestID) if err != nil { return err } @@ -1574,6 +1633,27 @@ func hashLaunchSpecification(v interface{}) int { return hashcode.String(buf.String()) } +func hashLaunchTemplateOverrides(v interface{}) int { + var buf bytes.Buffer + m := v.(map[string]interface{}) + if m["availability_zone"] != nil { + buf.WriteString(fmt.Sprintf("%s-", m["availability_zone"].(string))) + } + if m["subnet_id"] != nil { + buf.WriteString(fmt.Sprintf("%s-", m["subnet_id"].(string))) + } + if m["spot_price"] != nil { + buf.WriteString(fmt.Sprintf("%s-", m["spot_price"].(string))) + } + if m["instance_type"] != nil { + buf.WriteString(fmt.Sprintf("%s-", m["instance_type"].(string))) + } + if m["weighted_capacity"] != nil { + buf.WriteString(fmt.Sprintf("%f-", m["weighted_capacity"].(float64))) + } + return hashcode.String(buf.String()) +} + func hashEbsBlockDevice(v interface{}) int { var buf bytes.Buffer m := v.(map[string]interface{}) From 4ba60abf4cade175f6325ee05fce160f349c3e47 Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Thu, 28 Jun 2018 20:53:56 +1000 Subject: [PATCH 05/67] Fixed test failure and added better debugging, added tests --- aws/resource_aws_spot_fleet_request.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 21b6e26c534f..629602534bf5 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -1220,7 +1220,7 @@ func resourceAwsSpotFleetRequestRead(d *schema.ResourceData, meta interface{}) e return fmt.Errorf("error setting tags: %s", err) } - if config.LaunchTemplateConfigs[0] != nil { + if len(config.LaunchTemplateConfigs) > 0 { d.Set("launch_template_configs.0.launch_template_specification.0", flattenFleetLaunchTemplateSpecification(config.LaunchTemplateConfigs[0].LaunchTemplateSpecification)) d.Set("launch_template_configs.0.overrides", setLaunchTemplateOverrides(config.LaunchTemplateConfigs[0].Overrides)) } else { @@ -1579,7 +1579,7 @@ func deleteSpotFleetRequest(spotFleetRequestID string, terminateInstances bool, log.Printf("[DEBUG] Active instance count is %d for Spot Fleet Request (%s), but instances have terminated, removing", n, spotFleetRequestID) return nil } else { - log.Printf("[DEBUG] Active instance count is %d for Spot Fleet Request (%s), and %d instances are still running", n, spotFleetRequestID, len(iresp.Reservations)) + log.Printf("[DEBUG] Active instance count is %d for Spot Fleet Request (%s), and at least 1 instance is still running", n, spotFleetRequestID) } log.Printf("[DEBUG] Active instance count is 0 for Spot Fleet Request (%s), removing", spotFleetRequestID) From f3d2ec33df37a29c371cb8003b32afd9418c9b21 Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Sat, 20 Oct 2018 19:57:28 +1100 Subject: [PATCH 06/67] remove unnecessary float64 conversion causing lint failure --- aws/resource_aws_spot_fleet_request.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 629602534bf5..9c71c74144b4 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -835,7 +835,7 @@ func buildLaunchTemplateConfigs(d *schema.ResourceData, meta interface{}) ([]*ec } if v, ok := ors["weighted_capacity"].(float64); ok && v > 0 { - lto.WeightedCapacity = aws.Float64(float64(v)) + lto.WeightedCapacity = aws.Float64(v) } overrides = append(overrides, lto) From 42d717f4f004fa0060e5cd556880fcf8f00d606b Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Sun, 11 Nov 2018 14:20:16 +1100 Subject: [PATCH 07/67] remove commented validatefuncs --- aws/resource_aws_spot_fleet_request.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 9c71c74144b4..d9ba963bd14c 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -362,34 +362,29 @@ func resourceAwsSpotFleetRequest() *schema.Resource { Type: schema.TypeString, Optional: true, ForceNew: true, - //ValidateFunc: validateLaunchTemplateId, }, "instance_type": { Type: schema.TypeString, Optional: true, ForceNew: true, - //ValidateFunc: validateLaunchTemplateName, }, "spot_price": { Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - //ValidateFunc: validation.StringLenBetween(1, 255), }, "subnet_id": { Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, - //ValidateFunc: validation.StringLenBetween(1, 255), }, "weighted_capacity": { Type: schema.TypeFloat, Optional: true, Computed: true, ForceNew: true, - //ValidateFunc: validation.StringLenBetween(1, 255), }, }, }, @@ -398,7 +393,8 @@ func resourceAwsSpotFleetRequest() *schema.Resource { }, }, }, - // Everything on a spot fleet is ForceNew except target_capacity + // Everything on a spot fleet is ForceNew except target_capacity and excess_capacity_termination_policy, + // see https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#ModifySpotFleetRequestInput "target_capacity": { Type: schema.TypeInt, Required: true, @@ -408,7 +404,7 @@ func resourceAwsSpotFleetRequest() *schema.Resource { Type: schema.TypeInt, ConflictsWith: []string{"launch_specification"}, Optional: true, - ForceNew: false, + ForceNew: true, }, "allocation_strategy": { Type: schema.TypeString, From 0f4144c946dd7c58713584855a2e9b8b209ca566 Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Sun, 11 Nov 2018 14:36:18 +1100 Subject: [PATCH 08/67] comment customdiff --- aws/resource_aws_spot_fleet_request.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index d9ba963bd14c..72e3e091be45 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -507,6 +507,9 @@ func resourceAwsSpotFleetRequest() *schema.Resource { }, "tags": tagsSchema(), }, + // A launch template can be created with an id or a name, but once created will have both even though we specify only one. + // If either changes, this makes sure the other (which was specified) will register as changed in order to correctly determine diffs. + // This was taken from the original implementation of launch templates in resource_aws_autoscaling_group.go CustomizeDiff: customdiff.Sequence( customdiff.ComputedIf("launch_template_configs.0.launch_template_specification.0.id", func(diff *schema.ResourceDiff, meta interface{}) bool { return diff.HasChange("launch_template_configs.0.launch_template_specification.0.name") From 99cca2739798429bceacbf7e1f862add08d1ff42 Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Sun, 11 Nov 2018 14:41:02 +1100 Subject: [PATCH 09/67] fix commenting and logic of template to config assignment --- aws/resource_aws_spot_fleet_request.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 72e3e091be45..5a619abb3e47 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -857,7 +857,7 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) _, launchTemplateConfigsOk := d.GetOk("launch_template_configs") if !launchSpecificationOk && !launchTemplateConfigsOk { - return fmt.Errorf("One of `launch_specification` or `launch_template` must be set for an a fleet request") + return fmt.Errorf("One of `launch_specification` or `launch_template` must be set for a fleet request") } // http://docs.aws.amazon.com/sdk-for-go/api/service/ec2.html#type-SpotFleetRequestConfigData @@ -882,16 +882,12 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) spotFleetConfig.LaunchSpecifications = launch_specs } - // Need to suppport multiples if launchTemplateConfigsOk { - // launch_template_cfg, err := buildLaunchTemplateConfig(d, meta) - // if err != nil { - // return err - // } - spotFleetConfig.LaunchTemplateConfigs, err = buildLaunchTemplateConfigs(d, meta) + launch_templates, err := buildLaunchTemplateConfigs(d, meta) if err != nil { return err } + spotFleetConfig.LaunchTemplateConfigs = launch_templates } if v, ok := d.GetOk("on_demand_target_capacity"); ok { From 785ab9ebd209cf997659024ea920394341b26f46 Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Sun, 11 Nov 2018 14:45:46 +1100 Subject: [PATCH 10/67] comment nonretryable error --- aws/resource_aws_spot_fleet_request.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 5a619abb3e47..208b399d7669 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -978,6 +978,12 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) if isAWSErr(err, "InvalidSpotFleetRequestConfig", "") { return resource.RetryableError(fmt.Errorf("Error creating Spot fleet request, retrying: %s", err)) } + if isAWSErr(err, "InvalidSpotFleetRequestConfig", "LaunchTemplateSpecification") { + return resource.NonRetryableError(err) + } + if isAWSErr(err, "InvalidSpotFleetRequestConfig", "IamFleetRole") { + return resource.RetryableError(fmt.Errorf("Error creating Spot fleet request, retrying: %s", err)) + } if err != nil { return resource.NonRetryableError(err) } From 2599b36de6ee2ff3862fa300ea8e8654b67b62ac Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Sun, 11 Nov 2018 17:42:29 +1100 Subject: [PATCH 11/67] clean up commented test --- aws/resource_aws_spot_fleet_request_test.go | 88 ++++++++++----------- 1 file changed, 42 insertions(+), 46 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index ef66a0dcf1b3..5dc873949231 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -292,13 +292,11 @@ func TestAccAWSSpotFleetRequest_launchTemplateToLaunchSpec(t *testing.T) { "aws_spot_fleet_request.foo", "spot_price", "0.005"), resource.TestCheckResourceAttr( "aws_spot_fleet_request.foo", "launch_specification.#", "1"), - // resource.TestCheckResourceAttr( - // "aws_spot_fleet_request.foo", "launch_template_configs.#", "0"), testAccCheckAWSSpotFleetRequestConfigRecreated(t, &before, &after), - ), - }, - }, - }) + ), + }, + }, + }) } func TestAccAWSSpotFleetRequest_launchSpecToLaunchTemplate(t *testing.T) { @@ -306,46 +304,44 @@ func TestAccAWSSpotFleetRequest_launchSpecToLaunchTemplate(t *testing.T) { rName := acctest.RandString(10) rInt := acctest.RandInt() - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSSpotFleetRequestConfig(rName, rInt), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &before), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_price", "0.005"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_specification.#", "1"), - // resource.TestCheckResourceAttr( - // "aws_spot_fleet_request.foo", "launch_template_configs.#", "0"), - ), - }, - { - Config: testAccAWSSpotFleetRequestLaunchTemplateConfig(rName, rInt), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &after), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_specification.#", "0"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), - testAccCheckAWSSpotFleetRequestConfigRecreated(t, &before, &after), - ), - }, - }, - }) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestConfig(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &before), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_price", "0.005"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_specification.#", "1"), + ), + }, + { + Config: testAccAWSSpotFleetRequestLaunchTemplateConfig(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &after), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_specification.#", "0"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), + testAccCheckAWSSpotFleetRequestConfigRecreated(t, &before, &after), + ), + }, + }, + }) } func TestAccAWSSpotFleetRequest_instanceInterruptionBehavior(t *testing.T) { From 08f3d6c17e627c58ac7b577f8b7b0df85b8b019f Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Sat, 8 Dec 2018 20:00:20 +1100 Subject: [PATCH 12/67] attempt to fix documentation as per review request --- website/docs/r/spot_fleet_request.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/r/spot_fleet_request.html.markdown b/website/docs/r/spot_fleet_request.html.markdown index be5d9668047e..b762ed2b692f 100644 --- a/website/docs/r/spot_fleet_request.html.markdown +++ b/website/docs/r/spot_fleet_request.html.markdown @@ -180,7 +180,7 @@ across different markets and instance types. Conflicts with `launch_template_con * `target_capacity` - The number of units to request. You can choose to set the target capacity in terms of instances or a performance characteristic that is important to your application workload, such as vCPUs, memory, or I/O. -* `on_demand_target_capacity` - (Optional) Allows specification of a minimum value of the `target_capacity` to be filled by full price on-demand instance to ensure a minimum capacity of the fleet no matter spot instance availability. Not supported by `launch_specification`, must be used with `launch_template_configs`. +* `on_demand_target_capacity` - (Optional) The number of full-price On-Demand units to request in addition to the spot instance capacity. Use this to guarantee a minimum capacity of the fleet even in the event that the spot requests cannot be filled. Capacity is defined in the same units as configured in target_capacity such as vCPUs, memory, or I/O. Not supported by launch_specification, must be used with launch_template_configs. * `allocation_strategy` - Indicates how to allocate the target capacity across the Spot pools specified by the Spot fleet request. The default is `lowestPrice`. @@ -216,7 +216,7 @@ The `launch_template_configs` block supports the following: * `id` - The ID of the launch template. Conflicts with `name`. * `name` - The name of the launch template. Conflicts with `id`. -* `version` - (Optional) Template version. Unlike the autoscaling equivalent, does not support `$Latest` or `$Default`, so use the launch_template resource's attribute, e.g. `"${aws_launch_template.foo.latest_version}"`. Wil use default version if omitted. +* `version` - (Optional) Template version. Unlike the autoscaling equivalent, does not support `$Latest` or `$Default`, so use the launch_template resource's attribute, e.g. `"${aws_launch_template.foo.latest_version}"`. Will use default version if omitted. **Note:** The specified launch template can specify only a subset of the inputs of [`aws_launch_template`](launch_template.html). There are limitations on From 87fb70ba56bc98a1ebae746a72a042b058211cfb Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Sat, 8 Dec 2018 20:15:32 +1100 Subject: [PATCH 13/67] removed on-demand spot instance feature due to moving to a different PR --- aws/resource_aws_spot_fleet_request.go | 10 ---------- aws/resource_aws_spot_fleet_request_test.go | 3 +++ website/docs/r/spot_fleet_request.html.markdown | 1 - 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 208b399d7669..7e5740fa5117 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -400,12 +400,6 @@ func resourceAwsSpotFleetRequest() *schema.Resource { Required: true, ForceNew: false, }, - "on_demand_target_capacity": { - Type: schema.TypeInt, - ConflictsWith: []string{"launch_specification"}, - Optional: true, - ForceNew: true, - }, "allocation_strategy": { Type: schema.TypeString, Optional: true, @@ -890,10 +884,6 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) spotFleetConfig.LaunchTemplateConfigs = launch_templates } - if v, ok := d.GetOk("on_demand_target_capacity"); ok { - spotFleetConfig.OnDemandTargetCapacity = aws.Int64(int64(v.(int))) - } - if v, ok := d.GetOk("excess_capacity_termination_policy"); ok { spotFleetConfig.ExcessCapacityTerminationPolicy = aws.String(v.(string)) } diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 5dc873949231..7e8bcefda4f4 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -1393,6 +1393,7 @@ resource "aws_spot_fleet_request" "foo" { `, rName, rInt, rInt, rName) } +<<<<<<< HEAD func testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName string, rInt int) string { return fmt.Sprintf(` resource "aws_key_pair" "debugging" { @@ -1479,6 +1480,8 @@ resource "aws_spot_fleet_request" "foo" { `, rName, rInt, rInt, rName) } +======= +>>>>>>> removed on-demand spot instance feature due to moving to a different PR func testAccAWSSpotFleetRequestLaunchTemplateConfigWithOverrides(rName string, rInt int) string { return fmt.Sprintf(` resource "aws_key_pair" "debugging" { diff --git a/website/docs/r/spot_fleet_request.html.markdown b/website/docs/r/spot_fleet_request.html.markdown index b762ed2b692f..25d36b457e51 100644 --- a/website/docs/r/spot_fleet_request.html.markdown +++ b/website/docs/r/spot_fleet_request.html.markdown @@ -180,7 +180,6 @@ across different markets and instance types. Conflicts with `launch_template_con * `target_capacity` - The number of units to request. You can choose to set the target capacity in terms of instances or a performance characteristic that is important to your application workload, such as vCPUs, memory, or I/O. -* `on_demand_target_capacity` - (Optional) The number of full-price On-Demand units to request in addition to the spot instance capacity. Use this to guarantee a minimum capacity of the fleet even in the event that the spot requests cannot be filled. Capacity is defined in the same units as configured in target_capacity such as vCPUs, memory, or I/O. Not supported by launch_specification, must be used with launch_template_configs. * `allocation_strategy` - Indicates how to allocate the target capacity across the Spot pools specified by the Spot fleet request. The default is `lowestPrice`. From 277770f900b1891cb19fbbcd5ec63821ea297b3b Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Sat, 8 Dec 2018 20:18:35 +1100 Subject: [PATCH 14/67] rename overrideToMap to flattenSpotFleetRequestLaunchTemplateOverrides --- aws/resource_aws_spot_fleet_request.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 7e5740fa5117..2e1e9462e789 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -1224,12 +1224,12 @@ func resourceAwsSpotFleetRequestRead(d *schema.ResourceData, meta interface{}) e func setLaunchTemplateOverrides(overrides []*ec2.LaunchTemplateOverrides) *schema.Set { overrideSet := &schema.Set{F: hashLaunchTemplateOverrides} for _, override := range overrides { - overrideSet.Add(overrideToMap(override)) + overrideSet.Add(flattenSpotFleetRequestLaunchTemplateOverrides(override)) } return overrideSet } -func overrideToMap(override *ec2.LaunchTemplateOverrides) map[string]interface{} { +func flattenSpotFleetRequestLaunchTemplateOverrides(override *ec2.LaunchTemplateOverrides) map[string]interface{} { m := make(map[string]interface{}) if override.AvailabilityZone != nil { From 4e250151e0ab0441934c47775ec099c3ce1ea307 Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Sat, 8 Dec 2018 20:26:41 +1100 Subject: [PATCH 15/67] remove comment cruft --- aws/resource_aws_spot_fleet_request.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 2e1e9462e789..c09d13eade44 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -1248,7 +1248,7 @@ func flattenSpotFleetRequestLaunchTemplateOverrides(override *ec2.LaunchTemplate } if override.WeightedCapacity != nil { - m["weighted_capacity"] = aws.Float64Value(override.WeightedCapacity) //strconv.FormatFloat(*override.WeightedCapacity, 'f', 0, 64) + m["weighted_capacity"] = aws.Float64Value(override.WeightedCapacity) } return m From eca0782278b6b08b82fa9e6647c3271873f339f2 Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Sat, 8 Dec 2018 21:31:02 +1100 Subject: [PATCH 16/67] added launch template conflict with launch specification test --- aws/resource_aws_spot_fleet_request_test.go | 77 +++++++++------------ 1 file changed, 31 insertions(+), 46 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 7e8bcefda4f4..f98278705ab8 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -213,6 +213,22 @@ func TestAccAWSSpotFleetRequest_launchTemplateWithOnDemandCapacity(t *testing.T) }) } +func TestAccAWSSpotFleetRequest_launchTemplateConflictLaunchSpecification(t *testing.T) { + rName := acctest.RandString(10) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName), + ExpectError: regexp.MustCompile(`"launch_template_configs": conflicts with launch_specification`), + }, + }, + }) +} + func TestAccAWSSpotFleetRequest_launchTemplateWithOverrides(t *testing.T) { var sfr ec2.SpotFleetRequestConfig rName := acctest.RandString(10) @@ -1393,43 +1409,8 @@ resource "aws_spot_fleet_request" "foo" { `, rName, rInt, rInt, rName) } -<<<<<<< HEAD -func testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName string, rInt int) string { +func testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName string) string { return fmt.Sprintf(` -resource "aws_key_pair" "debugging" { - key_name = "tmp-key-%s" - public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com" -} - -resource "aws_iam_policy" "test-policy" { - name = "test-policy-%d" - path = "/" - description = "Spot Fleet Request ACCTest Policy" - policy = <>>>>>> removed on-demand spot instance feature due to moving to a different PR func testAccAWSSpotFleetRequestLaunchTemplateConfigWithOverrides(rName string, rInt int) string { return fmt.Sprintf(` resource "aws_key_pair" "debugging" { From 2d31a1211dbd0e136985f6367ee12393a1dc385d Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Sat, 8 Dec 2018 22:07:12 +1100 Subject: [PATCH 17/67] fixed lint errors, readded somehow missing tests --- aws/resource_aws_spot_fleet_request.go | 4 +- aws/resource_aws_spot_fleet_request_test.go | 169 ++++++++++++++++++++ 2 files changed, 171 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index c09d13eade44..d811f6dc314a 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -770,7 +770,7 @@ func buildAwsSpotFleetLaunchSpecifications( return specs, nil } -func buildLaunchTemplateConfigs(d *schema.ResourceData, meta interface{}) ([]*ec2.LaunchTemplateConfig, error) { +func buildLaunchTemplateConfigs(d *schema.ResourceData) ([]*ec2.LaunchTemplateConfig, error) { launch_template_cfgs := d.Get("launch_template_configs").(*schema.Set).List() cfgs := make([]*ec2.LaunchTemplateConfig, len(launch_template_cfgs)) @@ -877,7 +877,7 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) } if launchTemplateConfigsOk { - launch_templates, err := buildLaunchTemplateConfigs(d, meta) + launch_templates, err := buildLaunchTemplateConfigs(d) if err != nil { return err } diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index f98278705ab8..f553128461a6 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -148,6 +148,55 @@ func TestAccAWSSpotFleetRequest_associatePublicIpAddress(t *testing.T) { }) } +func TestAccAWSSpotFleetRequest_fleetType(t *testing.T) { + var sfr ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestConfigFleetType(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &sfr), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "fleet_type", "request"), + ), + }, + }, + }) +} + +func TestAccAWSSpotFleetRequest_iamInstanceProfileArn(t *testing.T) { + var sfr ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestConfigIamInstanceProfileArn(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &sfr), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + testAccCheckAWSSpotFleetRequest_IamInstanceProfileArn(&sfr), + ), + }, + }, + }) +} + func TestAccAWSSpotFleetRequest_launchTemplate(t *testing.T) { var sfr ec2.SpotFleetRequestConfig rName := acctest.RandString(10) @@ -229,6 +278,40 @@ func TestAccAWSSpotFleetRequest_launchTemplateConflictLaunchSpecification(t *tes }) } +//On-Demand capacity requires launch template defined spot fleet, so can't test without it. +func TestAccAWSSpotFleetRequest_launchTemplateWithOnDemandCapacity(t *testing.T) { + var sfr ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &sfr), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_specification.#", "0"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "on_demand_target_capacity", "2"), + ), + }, + }, + }) +} + func TestAccAWSSpotFleetRequest_launchTemplateWithOverrides(t *testing.T) { var sfr ec2.SpotFleetRequestConfig rName := acctest.RandString(10) @@ -1467,6 +1550,92 @@ resource "aws_spot_fleet_request" "foo" { `, rName, rName) } +func testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName string, rInt int) string { + return fmt.Sprintf(` +resource "aws_key_pair" "debugging" { + key_name = "tmp-key-%s" + public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com" +} + +resource "aws_iam_policy" "test-policy" { + name = "test-policy-%d" + path = "/" + description = "Spot Fleet Request ACCTest Policy" + policy = < Date: Sat, 8 Dec 2018 22:28:45 +1100 Subject: [PATCH 18/67] fix missing tests retry --- aws/resource_aws_spot_fleet_request_test.go | 165 +++++++++++--------- 1 file changed, 94 insertions(+), 71 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index f553128461a6..177463470ef2 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -149,52 +149,52 @@ func TestAccAWSSpotFleetRequest_associatePublicIpAddress(t *testing.T) { } func TestAccAWSSpotFleetRequest_fleetType(t *testing.T) { - var sfr ec2.SpotFleetRequestConfig - rName := acctest.RandString(10) - rInt := acctest.RandInt() + var sfr ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSSpotFleetRequestConfigFleetType(rName, rInt), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &sfr), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "fleet_type", "request"), - ), - }, - }, - }) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestConfigFleetType(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &sfr), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "fleet_type", "request"), + ), + }, + }, + }) } func TestAccAWSSpotFleetRequest_iamInstanceProfileArn(t *testing.T) { - var sfr ec2.SpotFleetRequestConfig - rName := acctest.RandString(10) - rInt := acctest.RandInt() + var sfr ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSSpotFleetRequestConfigIamInstanceProfileArn(rName, rInt), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &sfr), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - testAccCheckAWSSpotFleetRequest_IamInstanceProfileArn(&sfr), - ), - }, - }, - }) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestConfigIamInstanceProfileArn(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &sfr), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + testAccCheckAWSSpotFleetRequest_IamInstanceProfileArn(&sfr), + ), + }, + }, + }) } func TestAccAWSSpotFleetRequest_launchTemplate(t *testing.T) { @@ -280,36 +280,36 @@ func TestAccAWSSpotFleetRequest_launchTemplateConflictLaunchSpecification(t *tes //On-Demand capacity requires launch template defined spot fleet, so can't test without it. func TestAccAWSSpotFleetRequest_launchTemplateWithOnDemandCapacity(t *testing.T) { - var sfr ec2.SpotFleetRequestConfig - rName := acctest.RandString(10) - rInt := acctest.RandInt() + var sfr ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName, rInt), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &sfr), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_specification.#", "0"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "on_demand_target_capacity", "2"), - ), - }, - }, - }) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &sfr), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_specification.#", "0"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "on_demand_target_capacity", "2"), + ), + }, + }, + }) } func TestAccAWSSpotFleetRequest_launchTemplateWithOverrides(t *testing.T) { @@ -722,6 +722,29 @@ func TestAccAWSSpotFleetRequest_multipleInstanceTypesInSameAz(t *testing.T) { }) } +func testAccCheckAWSSpotFleetRequest_IamInstanceProfileArn( + sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { + return func(s *terraform.State) error { + if len(sfr.SpotFleetRequestConfig.LaunchSpecifications) == 0 { + return errors.New("Missing launch specification") + } + + spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] + + profile := spec.IamInstanceProfile + if profile == nil { + return fmt.Errorf("Expected IamInstanceProfile to be set, got nil") + } + //Validate the string whether it is ARN + re := regexp.MustCompile("arn:aws:iam::\\d{12}:instance-profile/?[a-zA-Z0-9+=,.@-_].*") + if !re.MatchString(*profile.Arn) { + return fmt.Errorf("Expected IamInstanceProfile input as ARN, got %s", *profile.Arn) + } + + return nil + } +} + func TestAccAWSSpotFleetRequest_multipleInstanceTypesInSameSubnet(t *testing.T) { var sfr ec2.SpotFleetRequestConfig rName := acctest.RandString(10) @@ -1551,7 +1574,7 @@ resource "aws_spot_fleet_request" "foo" { } func testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName string, rInt int) string { - return fmt.Sprintf(` + return fmt.Sprintf(` resource "aws_key_pair" "debugging" { key_name = "tmp-key-%s" public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com" From aaea7ca614d06d141cc5a2b3d65fd4716a5c3789 Mon Sep 17 00:00:00 2001 From: Circle Date: Thu, 28 Feb 2019 22:46:08 +1100 Subject: [PATCH 19/67] fmt --- aws/resource_aws_spot_fleet_request_test.go | 754 +++++++++++--------- 1 file changed, 410 insertions(+), 344 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 177463470ef2..2c9a7f4332b1 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -1,59 +1,59 @@ package aws import ( - "errors" - "fmt" - "log" - "regexp" - "testing" - "time" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/ec2" - "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "errors" + "fmt" + "log" + "regexp" + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" ) func init() { - resource.AddTestSweepers("aws_spot_fleet_request", &resource.Sweeper{ - Name: "aws_spot_fleet_request", - F: testSweepSpotFleetRequests, - }) + resource.AddTestSweepers("aws_spot_fleet_request", &resource.Sweeper{ + Name: "aws_spot_fleet_request", + F: testSweepSpotFleetRequests, + }) } func testSweepSpotFleetRequests(region string) error { - client, err := sharedClientForRegion(region) - if err != nil { - return fmt.Errorf("error getting client: %s", err) - } - conn := client.(*AWSClient).ec2conn + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*AWSClient).ec2conn - err = conn.DescribeSpotFleetRequestsPages(&ec2.DescribeSpotFleetRequestsInput{}, func(page *ec2.DescribeSpotFleetRequestsOutput, isLast bool) bool { - if len(page.SpotFleetRequestConfigs) == 0 { - log.Print("[DEBUG] No Spot Fleet Requests to sweep") - return false - } + err = conn.DescribeSpotFleetRequestsPages(&ec2.DescribeSpotFleetRequestsInput{}, func(page *ec2.DescribeSpotFleetRequestsOutput, isLast bool) bool { + if len(page.SpotFleetRequestConfigs) == 0 { + log.Print("[DEBUG] No Spot Fleet Requests to sweep") + return false + } - for _, config := range page.SpotFleetRequestConfigs { - id := aws.StringValue(config.SpotFleetRequestId) + for _, config := range page.SpotFleetRequestConfigs { + id := aws.StringValue(config.SpotFleetRequestId) - log.Printf("[INFO] Deleting Spot Fleet Request: %s", id) - err := deleteSpotFleetRequest(id, true, 5*time.Minute, conn) - if err != nil { - log.Printf("[ERROR] Failed to delete Spot Fleet Request (%s): %s", id, err) - } - } - return !isLast - }) - if err != nil { - if testSweepSkipSweepError(err) { - log.Printf("[WARN] Skipping EC2 Spot Fleet Requests sweep for %s: %s", region, err) - return nil - } - return fmt.Errorf("Error retrieving EC2 Spot Fleet Requests: %s", err) - } - return nil + log.Printf("[INFO] Deleting Spot Fleet Request: %s", id) + err := deleteSpotFleetRequest(id, true, 5*time.Minute, conn) + if err != nil { + log.Printf("[ERROR] Failed to delete Spot Fleet Request (%s): %s", id, err) + } + } + return !isLast + }) + if err != nil { + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping EC2 Spot Fleet Requests sweep for %s: %s", region, err) + return nil + } + return fmt.Errorf("Error retrieving EC2 Spot Fleet Requests: %s", err) + } + return nil } func TestAccAWSSpotFleetRequest_basic(t *testing.T) { @@ -138,10 +138,14 @@ func TestAccAWSSpotFleetRequest_associatePublicIpAddress(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigAssociatePublicIpAddress(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.24370212.associate_public_ip_address", "true"), + testAccCheckAWSSpotFleetRequestExists( + resourceName, &sfr), + resource.TestCheckResourceAttr( + resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.#", "1"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.24370212.associate_public_ip_address", "true"), ), }, }, @@ -149,52 +153,52 @@ func TestAccAWSSpotFleetRequest_associatePublicIpAddress(t *testing.T) { } func TestAccAWSSpotFleetRequest_fleetType(t *testing.T) { - var sfr ec2.SpotFleetRequestConfig - rName := acctest.RandString(10) - rInt := acctest.RandInt() - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSSpotFleetRequestConfigFleetType(rName, rInt), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &sfr), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "fleet_type", "request"), - ), - }, - }, - }) + var sfr ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestConfigFleetType(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &sfr), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "fleet_type", "request"), + ), + }, + }, + }) } func TestAccAWSSpotFleetRequest_iamInstanceProfileArn(t *testing.T) { - var sfr ec2.SpotFleetRequestConfig - rName := acctest.RandString(10) - rInt := acctest.RandInt() - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSSpotFleetRequestConfigIamInstanceProfileArn(rName, rInt), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &sfr), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - testAccCheckAWSSpotFleetRequest_IamInstanceProfileArn(&sfr), - ), - }, - }, - }) + var sfr ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestConfigIamInstanceProfileArn(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &sfr), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + testAccCheckAWSSpotFleetRequest_IamInstanceProfileArn(&sfr), + ), + }, + }, + }) } func TestAccAWSSpotFleetRequest_launchTemplate(t *testing.T) { @@ -263,53 +267,53 @@ func TestAccAWSSpotFleetRequest_launchTemplateWithOnDemandCapacity(t *testing.T) } func TestAccAWSSpotFleetRequest_launchTemplateConflictLaunchSpecification(t *testing.T) { - rName := acctest.RandString(10) + rName := acctest.RandString(10) - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName), - ExpectError: regexp.MustCompile(`"launch_template_configs": conflicts with launch_specification`), - }, - }, - }) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName), + ExpectError: regexp.MustCompile(`"launch_template_configs": conflicts with launch_specification`), + }, + }, + }) } //On-Demand capacity requires launch template defined spot fleet, so can't test without it. func TestAccAWSSpotFleetRequest_launchTemplateWithOnDemandCapacity(t *testing.T) { - var sfr ec2.SpotFleetRequestConfig - rName := acctest.RandString(10) - rInt := acctest.RandInt() - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName, rInt), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &sfr), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_specification.#", "0"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "on_demand_target_capacity", "2"), - ), - }, - }, - }) + var sfr ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &sfr), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_specification.#", "0"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "on_demand_target_capacity", "2"), + ), + }, + }, + }) } func TestAccAWSSpotFleetRequest_launchTemplateWithOverrides(t *testing.T) { @@ -392,10 +396,10 @@ func TestAccAWSSpotFleetRequest_launchTemplateToLaunchSpec(t *testing.T) { resource.TestCheckResourceAttr( "aws_spot_fleet_request.foo", "launch_specification.#", "1"), testAccCheckAWSSpotFleetRequestConfigRecreated(t, &before, &after), - ), - }, - }, - }) + ), + }, + }, + }) } func TestAccAWSSpotFleetRequest_launchSpecToLaunchTemplate(t *testing.T) { @@ -403,44 +407,44 @@ func TestAccAWSSpotFleetRequest_launchSpecToLaunchTemplate(t *testing.T) { rName := acctest.RandString(10) rInt := acctest.RandInt() - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSSpotFleetRequestConfig(rName, rInt), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &before), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_price", "0.005"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_specification.#", "1"), - ), - }, - { - Config: testAccAWSSpotFleetRequestLaunchTemplateConfig(rName, rInt), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &after), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_specification.#", "0"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), - testAccCheckAWSSpotFleetRequestConfigRecreated(t, &before, &after), - ), - }, - }, - }) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestConfig(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &before), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_price", "0.005"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_specification.#", "1"), + ), + }, + { + Config: testAccAWSSpotFleetRequestLaunchTemplateConfig(rName, rInt), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists( + "aws_spot_fleet_request.foo", &after), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "spot_request_state", "active"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_specification.#", "0"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr( + "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), + testAccCheckAWSSpotFleetRequestConfigRecreated(t, &before, &after), + ), + }, + }, + }) } func TestAccAWSSpotFleetRequest_instanceInterruptionBehavior(t *testing.T) { @@ -482,8 +486,10 @@ func TestAccAWSSpotFleetRequest_fleetType(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigFleetType(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + testAccCheckAWSSpotFleetRequestExists( + resourceName, &sfr), + resource.TestCheckResourceAttr( + resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "fleet_type", "request"), ), }, @@ -493,7 +499,7 @@ func TestAccAWSSpotFleetRequest_fleetType(t *testing.T) { func TestAccAWSSpotFleetRequest_iamInstanceProfileArn(t *testing.T) { var sfr ec2.SpotFleetRequestConfig - rName := acctest.RandString(10) + rName := acctest.RandString(10) rInt := acctest.RandInt() validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) resourceName := "aws_spot_fleet_request.test" @@ -530,19 +536,27 @@ func TestAccAWSSpotFleetRequest_changePriceForcesNewRequest(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfig(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &before), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr(resourceName, "spot_price", "0.005"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "1"), + testAccCheckAWSSpotFleetRequestExists( + resourceName, &before), + resource.TestCheckResourceAttr( + resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr( + resourceName, "spot_price", "0.005"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.#", "1"), ), }, { Config: testAccAWSSpotFleetRequestConfigChangeSpotBidPrice(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &after), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spot_price", "0.01"), + testAccCheckAWSSpotFleetRequestExists( + resourceName, &after), + resource.TestCheckResourceAttr( + resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.#", "1"), + resource.TestCheckResourceAttr( + resourceName, "spot_price", "0.01"), testAccCheckAWSSpotFleetRequestConfigRecreated(t, &before, &after), ), }, @@ -635,9 +649,12 @@ func TestAccAWSSpotFleetRequest_lowestPriceAzOrSubnetInRegion(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfig(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "1"), + testAccCheckAWSSpotFleetRequestExists( + resourceName, &sfr), + resource.TestCheckResourceAttr( + resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.#", "1"), ), }, }, @@ -659,11 +676,16 @@ func TestAccAWSSpotFleetRequest_lowestPriceAzInGivenList(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigWithAzs(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "2"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.1991689378.availability_zone", "us-west-2a"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.19404370.availability_zone", "us-west-2b"), + testAccCheckAWSSpotFleetRequestExists( + resourceName, &sfr), + resource.TestCheckResourceAttr( + resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.#", "2"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.1991689378.availability_zone", "us-west-2a"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.19404370.availability_zone", "us-west-2b"), ), }, }, @@ -685,9 +707,12 @@ func TestAccAWSSpotFleetRequest_lowestPriceSubnetInGivenList(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigWithSubnet(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "2"), + testAccCheckAWSSpotFleetRequestExists( + resourceName, &sfr), + resource.TestCheckResourceAttr( + resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.#", "2"), ), }, }, @@ -709,13 +734,20 @@ func TestAccAWSSpotFleetRequest_multipleInstanceTypesInSameAz(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigMultipleInstanceTypesinSameAz(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "2"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.1991689378.instance_type", "m1.small"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.1991689378.availability_zone", "us-west-2a"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.590403189.instance_type", "m3.large"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.590403189.availability_zone", "us-west-2a"), + testAccCheckAWSSpotFleetRequestExists( + resourceName, &sfr), + resource.TestCheckResourceAttr( + resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.#", "2"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.1991689378.instance_type", "m1.small"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.1991689378.availability_zone", "us-west-2a"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.590403189.instance_type", "m3.large"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.590403189.availability_zone", "us-west-2a"), ), }, }, @@ -723,26 +755,26 @@ func TestAccAWSSpotFleetRequest_multipleInstanceTypesInSameAz(t *testing.T) { } func testAccCheckAWSSpotFleetRequest_IamInstanceProfileArn( - sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { - return func(s *terraform.State) error { - if len(sfr.SpotFleetRequestConfig.LaunchSpecifications) == 0 { - return errors.New("Missing launch specification") - } + sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { + return func(s *terraform.State) error { + if len(sfr.SpotFleetRequestConfig.LaunchSpecifications) == 0 { + return errors.New("Missing launch specification") + } - spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] + spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] - profile := spec.IamInstanceProfile - if profile == nil { - return fmt.Errorf("Expected IamInstanceProfile to be set, got nil") - } - //Validate the string whether it is ARN - re := regexp.MustCompile("arn:aws:iam::\\d{12}:instance-profile/?[a-zA-Z0-9+=,.@-_].*") - if !re.MatchString(*profile.Arn) { - return fmt.Errorf("Expected IamInstanceProfile input as ARN, got %s", *profile.Arn) - } + profile := spec.IamInstanceProfile + if profile == nil { + return fmt.Errorf("Expected IamInstanceProfile to be set, got nil") + } + //Validate the string whether it is ARN + re := regexp.MustCompile("arn:aws:iam::\\d{12}:instance-profile/?[a-zA-Z0-9+=,.@-_].*") + if !re.MatchString(*profile.Arn) { + return fmt.Errorf("Expected IamInstanceProfile input as ARN, got %s", *profile.Arn) + } - return nil - } + return nil + } } func TestAccAWSSpotFleetRequest_multipleInstanceTypesInSameSubnet(t *testing.T) { @@ -760,9 +792,12 @@ func TestAccAWSSpotFleetRequest_multipleInstanceTypesInSameSubnet(t *testing.T) { Config: testAccAWSSpotFleetRequestConfigMultipleInstanceTypesinSameSubnet(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "2"), + testAccCheckAWSSpotFleetRequestExists( + resourceName, &sfr), + resource.TestCheckResourceAttr( + resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.#", "2"), ), }, }, @@ -784,14 +819,22 @@ func TestAccAWSSpotFleetRequest_overriddingSpotPrice(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigOverridingSpotPrice(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr(resourceName, "spot_price", "0.035"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "2"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.4143232216.spot_price", "0.01"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.4143232216.instance_type", "m3.large"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.1991689378.spot_price", ""), //there will not be a value here since it's not overriding - resource.TestCheckResourceAttr(resourceName, "launch_specification.1991689378.instance_type", "m1.small"), + testAccCheckAWSSpotFleetRequestExists( + resourceName, &sfr), + resource.TestCheckResourceAttr( + resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr( + resourceName, "spot_price", "0.035"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.#", "2"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.4143232216.spot_price", "0.01"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.4143232216.instance_type", "m3.large"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.1991689378.spot_price", ""), //there will not be a value here since it's not overriding + resource.TestCheckResourceAttr( + resourceName, "launch_specification.1991689378.instance_type", "m1.small"), ), }, }, @@ -813,9 +856,12 @@ func TestAccAWSSpotFleetRequest_withoutSpotPrice(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigWithoutSpotPrice(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "2"), + testAccCheckAWSSpotFleetRequestExists( + resourceName, &sfr), + resource.TestCheckResourceAttr( + resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.#", "2"), ), }, }, @@ -837,10 +883,14 @@ func TestAccAWSSpotFleetRequest_diversifiedAllocation(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigDiversifiedAllocation(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "3"), - resource.TestCheckResourceAttr(resourceName, "allocation_strategy", "diversified"), + testAccCheckAWSSpotFleetRequestExists( + resourceName, &sfr), + resource.TestCheckResourceAttr( + resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.#", "3"), + resource.TestCheckResourceAttr( + resourceName, "allocation_strategy", "diversified"), ), }, }, @@ -862,11 +912,16 @@ func TestAccAWSSpotFleetRequest_multipleInstancePools(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigMultipleInstancePools(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "3"), - resource.TestCheckResourceAttr(resourceName, "allocation_strategy", "lowestPrice"), - resource.TestCheckResourceAttr(resourceName, "instance_pools_to_use_count", "2"), + testAccCheckAWSSpotFleetRequestExists( + resourceName, &sfr), + resource.TestCheckResourceAttr( + resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.#", "3"), + resource.TestCheckResourceAttr( + resourceName, "allocation_strategy", "lowestPrice"), + resource.TestCheckResourceAttr( + resourceName, "instance_pools_to_use_count", "2"), ), }, }, @@ -880,19 +935,19 @@ func TestAccAWSSpotFleetRequest_withWeightedCapacity(t *testing.T) { validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) resourceName := "aws_spot_fleet_request.test" - fulfillSleep := func() resource.TestCheckFunc { - // sleep so that EC2 can fuflill the request. We do this to guard against a - // regression and possible leak where we'll destroy the request and the - // associated IAM role before anything is actually provisioned and running, - // thus leaking when those newly started instances are attempted to be - // destroyed - // See https://github.com/hashicorp/terraform/pull/8938 - return func(s *terraform.State) error { - log.Print("[DEBUG] Test: Sleep to allow EC2 to actually begin fulfilling TestAccAWSSpotFleetRequest_withWeightedCapacity request") - time.Sleep(1 * time.Minute) - return nil - } - } + fulfillSleep := func() resource.TestCheckFunc { + // sleep so that EC2 can fuflill the request. We do this to guard against a + // regression and possible leak where we'll destroy the request and the + // associated IAM role before anything is actually provisioned and running, + // thus leaking when those newly started instances are attempted to be + // destroyed + // See https://github.com/hashicorp/terraform/pull/8938 + return func(s *terraform.State) error { + log.Print("[DEBUG] Test: Sleep to allow EC2 to actually begin fulfilling TestAccAWSSpotFleetRequest_withWeightedCapacity request") + time.Sleep(1 * time.Minute) + return nil + } + } resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSEc2SpotFleetRequest(t) }, @@ -903,13 +958,20 @@ func TestAccAWSSpotFleetRequest_withWeightedCapacity(t *testing.T) { Config: testAccAWSSpotFleetRequestConfigWithWeightedCapacity(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( fulfillSleep(), - testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "2"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.4120185872.weighted_capacity", "3"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.4120185872.instance_type", "r3.large"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.590403189.weighted_capacity", "6"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.590403189.instance_type", "m3.large"), + testAccCheckAWSSpotFleetRequestExists( + resourceName, &sfr), + resource.TestCheckResourceAttr( + resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.#", "2"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.4120185872.weighted_capacity", "3"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.4120185872.instance_type", "r3.large"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.590403189.weighted_capacity", "6"), + resource.TestCheckResourceAttr( + resourceName, "launch_specification.590403189.instance_type", "m3.large"), ), }, }, @@ -942,7 +1004,7 @@ func TestAccAWSSpotFleetRequest_withEBSDisk(t *testing.T) { func TestAccAWSSpotFleetRequest_LaunchSpecification_EbsBlockDevice_KmsKeyId(t *testing.T) { var config ec2.SpotFleetRequestConfig rName := acctest.RandString(10) - rInt := acctest.RandInt() + rInt := acctest.RandInt() validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) resourceName := "aws_spot_fleet_request.test" @@ -955,7 +1017,7 @@ func TestAccAWSSpotFleetRequest_LaunchSpecification_EbsBlockDevice_KmsKeyId(t *t Config: testAccAWSSpotFleetRequestLaunchSpecificationEbsBlockDeviceKmsKeyId(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckAWSSpotFleetRequestExists(resourceName, &config), - ), + ), }, }, }) @@ -971,12 +1033,12 @@ func TestAccAWSSpotFleetRequest_LaunchSpecification_RootBlockDevice_KmsKeyId(t * resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSEc2SpotFleetRequest(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, Steps: []resource.TestStep{ { Config: testAccAWSSpotFleetRequestLaunchSpecificationRootBlockDeviceKmsKeyId(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &config), + testAccCheckAWSSpotFleetRequestExists(resourceName,&config), ), }, }, @@ -1061,7 +1123,7 @@ func TestAccAWSSpotFleetRequest_WithTargetGroups(t *testing.T) { var sfr ec2.SpotFleetRequestConfig rName := acctest.RandString(10) rInt := acctest.RandInt() - validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) +validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) resourceName := "aws_spot_fleet_request.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSEc2SpotFleetRequest(t) }, @@ -1071,8 +1133,10 @@ func TestAccAWSSpotFleetRequest_WithTargetGroups(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigWithTargetGroups(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + testAccCheckAWSSpotFleetRequestExists( + resourceName, &sfr), + resource.TestCheckResourceAttr( + resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "1"), resource.TestCheckResourceAttr(resourceName, "target_group_arns.#", "1"), ), @@ -1101,46 +1165,46 @@ func TestAccAWSSpotFleetRequest_WithInstanceStoreAmi(t *testing.T) { } func testAccCheckAWSSpotFleetRequestConfigRecreated(t *testing.T, - before, after *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { - return func(s *terraform.State) error { - if before.SpotFleetRequestId == after.SpotFleetRequestId { - t.Fatalf("Expected change of Spot Fleet Request IDs, but both were %v", before.SpotFleetRequestId) - } - return nil - } + before, after *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { + return func(s *terraform.State) error { + if before.SpotFleetRequestId == after.SpotFleetRequestId { + t.Fatalf("Expected change of Spot Fleet Request IDs, but both were %v", before.SpotFleetRequestId) + } + return nil + } } func testAccCheckAWSSpotFleetRequestExists( - n string, sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("Not found: %s", n) - } + n string, sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } - if rs.Primary.ID == "" { - return errors.New("No Spot fleet request with that id exists") - } + if rs.Primary.ID == "" { + return errors.New("No Spot fleet request with that id exists") + } - conn := testAccProvider.Meta().(*AWSClient).ec2conn + conn := testAccProvider.Meta().(*AWSClient).ec2conn - params := &ec2.DescribeSpotFleetRequestsInput{ - SpotFleetRequestIds: []*string{&rs.Primary.ID}, - } - resp, err := conn.DescribeSpotFleetRequests(params) + params := &ec2.DescribeSpotFleetRequestsInput{ + SpotFleetRequestIds: []*string{&rs.Primary.ID}, + } + resp, err := conn.DescribeSpotFleetRequests(params) - if err != nil { - return err - } + if err != nil { + return err + } - if v := len(resp.SpotFleetRequestConfigs); v != 1 { - return fmt.Errorf("Expected 1 request returned, got %d", v) - } + if v := len(resp.SpotFleetRequestConfigs); v != 1 { + return fmt.Errorf("Expected 1 request returned, got %d", v) + } - *sfr = *resp.SpotFleetRequestConfigs[0] + *sfr = *resp.SpotFleetRequestConfigs[0] - return nil - } + return nil + } } func testAccCheckAWSSpotFleetRequestDestroy(s *terraform.State) error { @@ -1165,28 +1229,28 @@ func testAccCheckAWSSpotFleetRequestDestroy(s *terraform.State) error { } func testAccCheckAWSSpotFleetRequest_EBSAttributes( - sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { - return func(s *terraform.State) error { - if len(sfr.SpotFleetRequestConfig.LaunchSpecifications) == 0 { - return errors.New("Missing launch specification") - } + sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { + return func(s *terraform.State) error { + if len(sfr.SpotFleetRequestConfig.LaunchSpecifications) == 0 { + return errors.New("Missing launch specification") + } - spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] + spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] - ebs := spec.BlockDeviceMappings - if len(ebs) < 2 { - return fmt.Errorf("Expected %d block device mappings, got %d", 2, len(ebs)) - } + ebs := spec.BlockDeviceMappings + if len(ebs) < 2 { + return fmt.Errorf("Expected %d block device mappings, got %d", 2, len(ebs)) + } - if *ebs[0].DeviceName != "/dev/xvda" { - return fmt.Errorf("Expected device 0's name to be %s, got %s", "/dev/xvda", *ebs[0].DeviceName) - } - if *ebs[1].DeviceName != "/dev/xvdcz" { - return fmt.Errorf("Expected device 1's name to be %s, got %s", "/dev/xvdcz", *ebs[1].DeviceName) - } + if *ebs[0].DeviceName != "/dev/xvda" { + return fmt.Errorf("Expected device 0's name to be %s, got %s", "/dev/xvda", *ebs[0].DeviceName) + } + if *ebs[1].DeviceName != "/dev/xvdcz" { + return fmt.Errorf("Expected device 1's name to be %s, got %s", "/dev/xvdcz", *ebs[1].DeviceName) + } - return nil - } + return nil + } } func testAccCheckAWSSpotFleetRequest_PlacementAttributes( @@ -1196,7 +1260,7 @@ func testAccCheckAWSSpotFleetRequest_PlacementAttributes( return errors.New("Missing launch specification") } - spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] + spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] placement := spec.Placement if placement == nil { @@ -1205,35 +1269,38 @@ func testAccCheckAWSSpotFleetRequest_PlacementAttributes( if *placement.Tenancy != "dedicated" { return fmt.Errorf("Expected placement tenancy to be %q, got %q", "dedicated", *placement.Tenancy) } + + if aws.StringValue(placement.GroupName) != fmt.Sprintf("test-pg-%s", rName) { return fmt.Errorf("Expected placement group to be %q, got %q", fmt.Sprintf("test-pg-%s", rName), aws.StringValue(placement.GroupName)) - } - - return nil } + + return nil +} + } func testAccCheckAWSSpotFleetRequest_IamInstanceProfileArn( - sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { - return func(s *terraform.State) error { - if len(sfr.SpotFleetRequestConfig.LaunchSpecifications) == 0 { - return errors.New("Missing launch specification") - } + sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { + return func(s *terraform.State) error { + if len(sfr.SpotFleetRequestConfig.LaunchSpecifications) == 0 { + return errors.New("Missing launch specification") + } - spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] + spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] - profile := spec.IamInstanceProfile - if profile == nil { - return fmt.Errorf("Expected IamInstanceProfile to be set, got nil") - } - //Validate the string whether it is ARN - re := regexp.MustCompile(`arn:aws:iam::\d{12}:instance-profile/?[a-zA-Z0-9+=,.@-_].*`) - if !re.MatchString(*profile.Arn) { - return fmt.Errorf("Expected IamInstanceProfile input as ARN, got %s", *profile.Arn) - } + profile := spec.IamInstanceProfile + if profile == nil { + return fmt.Errorf("Expected IamInstanceProfile to be set, got nil") + } + //Validate the string whether it is ARN + re := regexp.MustCompile(`arn:aws:iam::\d{12}:instance-profile/?[a-zA-Z0-9+=,.@-_].*`) + if !re.MatchString(*profile.Arn) { + return fmt.Errorf("Expected IamInstanceProfile input as ARN, got %s", *profile.Arn) + } - return nil - } + return nil + } } func testAccPreCheckAWSEc2SpotFleetRequest(t *testing.T) { @@ -1243,8 +1310,8 @@ func testAccPreCheckAWSEc2SpotFleetRequest(t *testing.T) { _, err := conn.DescribeSpotFleetRequests(input) - if testAccPreCheckSkipError(err) { - t.Skipf("skipping acceptance testing: %s", err) + if testAccPreCheckSkipError(err) { + t.Skipf("skipping acceptance testing: %s", err) } if err != nil { @@ -1262,7 +1329,6 @@ data "aws_availability_zones" "available" { values = ["opt-in-not-required"] } } - resource "aws_key_pair" "debugging" { key_name = "tmp-key-%[1]s" public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com" @@ -1574,7 +1640,7 @@ resource "aws_spot_fleet_request" "foo" { } func testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName string, rInt int) string { - return fmt.Sprintf(` + return fmt.Sprintf(` resource "aws_key_pair" "debugging" { key_name = "tmp-key-%s" public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com" From 0d2fe425ae3d5e1b7c574d34f50fcd5f6eea108e Mon Sep 17 00:00:00 2001 From: Circle Date: Thu, 28 Feb 2019 22:50:43 +1100 Subject: [PATCH 20/67] remove duplicate test --- aws/resource_aws_spot_fleet_request_test.go | 23 --------------------- 1 file changed, 23 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 2c9a7f4332b1..9f1463d237eb 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -1280,29 +1280,6 @@ func testAccCheckAWSSpotFleetRequest_PlacementAttributes( } -func testAccCheckAWSSpotFleetRequest_IamInstanceProfileArn( - sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { - return func(s *terraform.State) error { - if len(sfr.SpotFleetRequestConfig.LaunchSpecifications) == 0 { - return errors.New("Missing launch specification") - } - - spec := *sfr.SpotFleetRequestConfig.LaunchSpecifications[0] - - profile := spec.IamInstanceProfile - if profile == nil { - return fmt.Errorf("Expected IamInstanceProfile to be set, got nil") - } - //Validate the string whether it is ARN - re := regexp.MustCompile(`arn:aws:iam::\d{12}:instance-profile/?[a-zA-Z0-9+=,.@-_].*`) - if !re.MatchString(*profile.Arn) { - return fmt.Errorf("Expected IamInstanceProfile input as ARN, got %s", *profile.Arn) - } - - return nil - } -} - func testAccPreCheckAWSEc2SpotFleetRequest(t *testing.T) { conn := testAccProvider.Meta().(*AWSClient).ec2conn From a24cdea89fe48f5ec8eef9cd661106e8ad3d81bd Mon Sep 17 00:00:00 2001 From: Circle Date: Thu, 28 Feb 2019 23:03:54 +1100 Subject: [PATCH 21/67] fix arn check regex --- aws/resource_aws_spot_fleet_request_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 9f1463d237eb..d2e19a0139e4 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -768,7 +768,7 @@ func testAccCheckAWSSpotFleetRequest_IamInstanceProfileArn( return fmt.Errorf("Expected IamInstanceProfile to be set, got nil") } //Validate the string whether it is ARN - re := regexp.MustCompile("arn:aws:iam::\\d{12}:instance-profile/?[a-zA-Z0-9+=,.@-_].*") + re := regexp.MustCompile(`arn:aws:iam::\d{12}:instance-profile/?[a-zA-Z0-9+=,.@-_].*`) if !re.MatchString(*profile.Arn) { return fmt.Errorf("Expected IamInstanceProfile input as ARN, got %s", *profile.Arn) } From 366d5a000602e0f2c4f450c076e840002343e2b1 Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Sun, 25 Aug 2019 22:16:55 +1000 Subject: [PATCH 22/67] Update website/docs/r/spot_fleet_request.html.markdown Co-Authored-By: Gauthier Wallet --- website/docs/r/spot_fleet_request.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/spot_fleet_request.html.markdown b/website/docs/r/spot_fleet_request.html.markdown index 25d36b457e51..80ed28f29758 100644 --- a/website/docs/r/spot_fleet_request.html.markdown +++ b/website/docs/r/spot_fleet_request.html.markdown @@ -13,7 +13,7 @@ instances to be requested on the Spot market. ## Example Usage -Using launch specifications: +### Using launch specifications: ```hcl # Request a Spot fleet From 0a9d8f6765c30ee2e3195516cc0cb06a82ace1ce Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Sun, 25 Aug 2019 22:17:13 +1000 Subject: [PATCH 23/67] Update website/docs/r/spot_fleet_request.html.markdown Co-Authored-By: Gauthier Wallet --- website/docs/r/spot_fleet_request.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/spot_fleet_request.html.markdown b/website/docs/r/spot_fleet_request.html.markdown index 80ed28f29758..7b9f57caa91b 100644 --- a/website/docs/r/spot_fleet_request.html.markdown +++ b/website/docs/r/spot_fleet_request.html.markdown @@ -54,7 +54,7 @@ resource "aws_spot_fleet_request" "cheap_compute" { } ``` -Using launch templates: +### Using launch templates: ``` resource "aws_launch_template" "foo" { From 9e7361bc519d6b87fffaa0d6015c7fb6f64c270b Mon Sep 17 00:00:00 2001 From: Stephen Hallett Date: Sun, 25 Aug 2019 22:18:33 +1000 Subject: [PATCH 24/67] Update website/docs/r/spot_fleet_request.html.markdown Co-Authored-By: Gauthier Wallet --- website/docs/r/spot_fleet_request.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/spot_fleet_request.html.markdown b/website/docs/r/spot_fleet_request.html.markdown index 7b9f57caa91b..d414bcc3c8fa 100644 --- a/website/docs/r/spot_fleet_request.html.markdown +++ b/website/docs/r/spot_fleet_request.html.markdown @@ -215,7 +215,7 @@ The `launch_template_configs` block supports the following: * `id` - The ID of the launch template. Conflicts with `name`. * `name` - The name of the launch template. Conflicts with `id`. -* `version` - (Optional) Template version. Unlike the autoscaling equivalent, does not support `$Latest` or `$Default`, so use the launch_template resource's attribute, e.g. `"${aws_launch_template.foo.latest_version}"`. Will use default version if omitted. +* `version` - (Optional) Template version. Unlike the autoscaling equivalent, does not support `$Latest` or `$Default`, so use the launch_template resource's attribute, e.g. `"${aws_launch_template.foo.latest_version}"`. It will use the default version if omitted. **Note:** The specified launch template can specify only a subset of the inputs of [`aws_launch_template`](launch_template.html). There are limitations on From 268f2280babb7b9a74303709042c3567a48e7e39 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Wed, 8 Apr 2020 21:39:45 +0300 Subject: [PATCH 25/67] foramtting changes --- aws/resource_aws_spot_fleet_request.go | 2 +- aws/resource_aws_spot_fleet_request_test.go | 506 +++++--------------- 2 files changed, 109 insertions(+), 399 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index d811f6dc314a..ca6ffaccd26b 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -5,11 +5,11 @@ import ( "fmt" "log" "strconv" - "strings" "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform-plugin-sdk/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/helper/hashcode" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index d2e19a0139e4..e6d56b8c7d53 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -138,63 +138,10 @@ func TestAccAWSSpotFleetRequest_associatePublicIpAddress(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigAssociatePublicIpAddress(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - resourceName, &sfr), - resource.TestCheckResourceAttr( - resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.#", "1"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.24370212.associate_public_ip_address", "true"), - ), - }, - }, - }) -} - -func TestAccAWSSpotFleetRequest_fleetType(t *testing.T) { - var sfr ec2.SpotFleetRequestConfig - rName := acctest.RandString(10) - rInt := acctest.RandInt() - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSSpotFleetRequestConfigFleetType(rName, rInt), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &sfr), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "fleet_type", "request"), - ), - }, - }, - }) -} - -func TestAccAWSSpotFleetRequest_iamInstanceProfileArn(t *testing.T) { - var sfr ec2.SpotFleetRequestConfig - rName := acctest.RandString(10) - rInt := acctest.RandInt() - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSSpotFleetRequestConfigIamInstanceProfileArn(rName, rInt), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &sfr), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - testAccCheckAWSSpotFleetRequest_IamInstanceProfileArn(&sfr), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.24370212.associate_public_ip_address", "true"), ), }, }, @@ -205,6 +152,8 @@ func TestAccAWSSpotFleetRequest_launchTemplate(t *testing.T) { var sfr ec2.SpotFleetRequestConfig rName := acctest.RandString(10) rInt := acctest.RandInt() + validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) + resourceName := "aws_spot_fleet_request.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -212,20 +161,14 @@ func TestAccAWSSpotFleetRequest_launchTemplate(t *testing.T) { CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSSpotFleetRequestLaunchTemplateConfig(rName, rInt), + Config: testAccAWSSpotFleetRequestLaunchTemplateConfig(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &sfr), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_specification.#", "0"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.overrides.#", "0"), ), }, }, @@ -237,6 +180,8 @@ func TestAccAWSSpotFleetRequest_launchTemplateWithOnDemandCapacity(t *testing.T) var sfr ec2.SpotFleetRequestConfig rName := acctest.RandString(10) rInt := acctest.RandInt() + validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) + resourceName := "aws_spot_fleet_request.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -244,22 +189,15 @@ func TestAccAWSSpotFleetRequest_launchTemplateWithOnDemandCapacity(t *testing.T) CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName, rInt), + Config: testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &sfr), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_specification.#", "0"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "on_demand_target_capacity", "2"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.overrides.#", "0"), + resource.TestCheckResourceAttr(resourceName, "on_demand_target_capacity", "2"), ), }, }, @@ -282,44 +220,12 @@ func TestAccAWSSpotFleetRequest_launchTemplateConflictLaunchSpecification(t *tes }) } -//On-Demand capacity requires launch template defined spot fleet, so can't test without it. -func TestAccAWSSpotFleetRequest_launchTemplateWithOnDemandCapacity(t *testing.T) { - var sfr ec2.SpotFleetRequestConfig - rName := acctest.RandString(10) - rInt := acctest.RandInt() - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName, rInt), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &sfr), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_specification.#", "0"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "on_demand_target_capacity", "2"), - ), - }, - }, - }) -} - func TestAccAWSSpotFleetRequest_launchTemplateWithOverrides(t *testing.T) { var sfr ec2.SpotFleetRequestConfig rName := acctest.RandString(10) rInt := acctest.RandInt() + validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) + resourceName := "aws_spot_fleet_request.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -327,30 +233,19 @@ func TestAccAWSSpotFleetRequest_launchTemplateWithOverrides(t *testing.T) { CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSSpotFleetRequestLaunchTemplateConfigWithOverrides(rName, rInt), + Config: testAccAWSSpotFleetRequestLaunchTemplateConfigWithOverrides(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &sfr), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_specification.#", "0"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.3492852471.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.3492852471.overrides.#", "2"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.3492852471.overrides.#", "2"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.3492852471.overrides.3113255372.instance_type", "t1.micro"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.3492852471.overrides.3113255372.weighted_capacity", "2"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.3492852471.overrides.1994766569.instance_type", "m3.medium"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.3492852471.overrides.1994766569.spot_price", "0.26"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.3492852471.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.3492852471.overrides.#", "2"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.3492852471.overrides.#", "2"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.3492852471.overrides.3113255372.instance_type", "t1.micro"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.3492852471.overrides.3113255372.weighted_capacity", "2"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.3492852471.overrides.1994766569.instance_type", "m3.medium"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.3492852471.overrides.1994766569.spot_price", "0.26"), ), }, }, @@ -361,6 +256,8 @@ func TestAccAWSSpotFleetRequest_launchTemplateToLaunchSpec(t *testing.T) { var before, after ec2.SpotFleetRequestConfig rName := acctest.RandString(10) rInt := acctest.RandInt() + validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) + resourceName := "aws_spot_fleet_request.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -368,33 +265,23 @@ func TestAccAWSSpotFleetRequest_launchTemplateToLaunchSpec(t *testing.T) { CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSSpotFleetRequestLaunchTemplateConfig(rName, rInt), + Config: testAccAWSSpotFleetRequestLaunchTemplateConfig(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &before), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_specification.#", "0"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &before), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.overrides.#", "0"), ), }, { - Config: testAccAWSSpotFleetRequestConfig(rName, rInt), + Config: testAccAWSSpotFleetRequestConfig(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &after), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_price", "0.005"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_specification.#", "1"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &after), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "spot_price", "0.005"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "1"), testAccCheckAWSSpotFleetRequestConfigRecreated(t, &before, &after), ), }, @@ -406,6 +293,8 @@ func TestAccAWSSpotFleetRequest_launchSpecToLaunchTemplate(t *testing.T) { var before, after ec2.SpotFleetRequestConfig rName := acctest.RandString(10) rInt := acctest.RandInt() + validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) + resourceName := "aws_spot_fleet_request.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -413,33 +302,23 @@ func TestAccAWSSpotFleetRequest_launchSpecToLaunchTemplate(t *testing.T) { CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSSpotFleetRequestConfig(rName, rInt), + Config: testAccAWSSpotFleetRequestConfig(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &before), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_price", "0.005"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_specification.#", "1"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &before), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "spot_price", "0.005"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "1"), ), }, { - Config: testAccAWSSpotFleetRequestLaunchTemplateConfig(rName, rInt), + Config: testAccAWSSpotFleetRequestLaunchTemplateConfig(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - "aws_spot_fleet_request.foo", &after), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "spot_request_state", "active"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_specification.#", "0"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr( - "aws_spot_fleet_request.foo", "launch_template_configs.4018047529.overrides.#", "0"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &after), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.overrides.#", "0"), testAccCheckAWSSpotFleetRequestConfigRecreated(t, &before, &after), ), }, @@ -499,7 +378,7 @@ func TestAccAWSSpotFleetRequest_fleetType(t *testing.T) { func TestAccAWSSpotFleetRequest_iamInstanceProfileArn(t *testing.T) { var sfr ec2.SpotFleetRequestConfig - rName := acctest.RandString(10) + rName := acctest.RandString(10) rInt := acctest.RandInt() validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) resourceName := "aws_spot_fleet_request.test" @@ -1004,7 +883,7 @@ func TestAccAWSSpotFleetRequest_withEBSDisk(t *testing.T) { func TestAccAWSSpotFleetRequest_LaunchSpecification_EbsBlockDevice_KmsKeyId(t *testing.T) { var config ec2.SpotFleetRequestConfig rName := acctest.RandString(10) - rInt := acctest.RandInt() + rInt := acctest.RandInt() validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) resourceName := "aws_spot_fleet_request.test" @@ -1017,7 +896,7 @@ func TestAccAWSSpotFleetRequest_LaunchSpecification_EbsBlockDevice_KmsKeyId(t *t Config: testAccAWSSpotFleetRequestLaunchSpecificationEbsBlockDeviceKmsKeyId(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckAWSSpotFleetRequestExists(resourceName, &config), - ), + ), }, }, }) @@ -1033,12 +912,12 @@ func TestAccAWSSpotFleetRequest_LaunchSpecification_RootBlockDevice_KmsKeyId(t * resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSEc2SpotFleetRequest(t) }, Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, Steps: []resource.TestStep{ { Config: testAccAWSSpotFleetRequestLaunchSpecificationRootBlockDeviceKmsKeyId(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName,&config), + testAccCheckAWSSpotFleetRequestExists(resourceName, &config), ), }, }, @@ -1123,7 +1002,7 @@ func TestAccAWSSpotFleetRequest_WithTargetGroups(t *testing.T) { var sfr ec2.SpotFleetRequestConfig rName := acctest.RandString(10) rInt := acctest.RandInt() -validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) + validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) resourceName := "aws_spot_fleet_request.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSEc2SpotFleetRequest(t) }, @@ -1266,17 +1145,16 @@ func testAccCheckAWSSpotFleetRequest_PlacementAttributes( if placement == nil { return fmt.Errorf("Expected placement to be set, got nil") } - if *placement.Tenancy != "dedicated" { + if *placement.Tenancy != ec2.TenancyDedicated { return fmt.Errorf("Expected placement tenancy to be %q, got %q", "dedicated", *placement.Tenancy) } - if aws.StringValue(placement.GroupName) != fmt.Sprintf("test-pg-%s", rName) { return fmt.Errorf("Expected placement group to be %q, got %q", fmt.Sprintf("test-pg-%s", rName), aws.StringValue(placement.GroupName)) - } + } - return nil -} + return nil + } } @@ -1287,8 +1165,8 @@ func testAccPreCheckAWSEc2SpotFleetRequest(t *testing.T) { _, err := conn.DescribeSpotFleetRequests(input) - if testAccPreCheckSkipError(err) { - t.Skipf("skipping acceptance testing: %s", err) + if testAccPreCheckSkipError(err) { + t.Skipf("skipping acceptance testing: %s", err) } if err != nil { @@ -1472,96 +1350,40 @@ resource "aws_spot_fleet_request" "test" { `, validUntil) } -func testAccAWSSpotFleetRequestLaunchTemplateConfig(rName string, rInt int) string { - return fmt.Sprintf(` -resource "aws_key_pair" "debugging" { - key_name = "tmp-key-%s" - public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com" -} - -resource "aws_iam_policy" "test-policy" { - name = "test-policy-%d" - path = "/" - description = "Spot Fleet Request ACCTest Policy" - policy = < Date: Thu, 9 Apr 2020 01:44:23 +0300 Subject: [PATCH 26/67] fix config conflict test --- aws/resource_aws_spot_fleet_request.go | 4 ++-- aws/resource_aws_spot_fleet_request_test.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index ca6ffaccd26b..3520d785ca50 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -1555,9 +1555,9 @@ func deleteSpotFleetRequest(spotFleetRequestID string, terminateInstances bool, return resource.RetryableError(fmt.Errorf("fleet still has (%d) running instances", n)) } - instances := []*string{} + var instances []*string for _, instMap := range activeInsts { - instances = append(instances, aws.String(*instMap.InstanceId)) + instances = append(instances, instMap.InstanceId) } iresp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ InstanceIds: instances, diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index e6d56b8c7d53..84f3f9156ace 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -214,7 +214,7 @@ func TestAccAWSSpotFleetRequest_launchTemplateConflictLaunchSpecification(t *tes Steps: []resource.TestStep{ { Config: testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName), - ExpectError: regexp.MustCompile(`"launch_template_configs": conflicts with launch_specification`), + ExpectError: regexp.MustCompile(`"launch_specification": conflicts with launch_template_configs`), }, }, }) @@ -1458,8 +1458,8 @@ resource "aws_spot_fleet_request" "test" { launch_template_configs { launch_template_specification { - name = "${aws_launch_template.foo.name}" - version = "${aws_launch_template.foo.latest_version}" + name = "${aws_launch_template.test.name}" + version = "${aws_launch_template.test.latest_version}" } } @@ -1470,7 +1470,7 @@ resource "aws_spot_fleet_request" "test" { func testAccAWSSpotFleetRequestLaunchTemplateConfigWithOverrides(rName string, rInt int, validUntil string) string { return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + fmt.Sprintf(` -resource "aws_launch_template" "foo" { +resource "aws_launch_template" "test" { name = "test-launch-template-%[1]s" image_id = "ami-516b9131" instance_type = "m1.small" From 09b535c6fe4c46ad02b55c02406e3252f9f0e590 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Thu, 9 Apr 2020 01:45:40 +0300 Subject: [PATCH 27/67] fix docs lint --- website/docs/r/spot_fleet_request.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/r/spot_fleet_request.html.markdown b/website/docs/r/spot_fleet_request.html.markdown index d414bcc3c8fa..ef624140b784 100644 --- a/website/docs/r/spot_fleet_request.html.markdown +++ b/website/docs/r/spot_fleet_request.html.markdown @@ -13,7 +13,7 @@ instances to be requested on the Spot market. ## Example Usage -### Using launch specifications: +### Using launch specifications ```hcl # Request a Spot fleet @@ -54,7 +54,7 @@ resource "aws_spot_fleet_request" "cheap_compute" { } ``` -### Using launch templates: +### Using launch templates ``` resource "aws_launch_template" "foo" { From 9e8a9ee0cefc49d83a46d682645970a26e351cc9 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Thu, 9 Apr 2020 01:47:15 +0300 Subject: [PATCH 28/67] fix code lint --- aws/resource_aws_spot_fleet_request.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 3520d785ca50..2b92f6ff1a5d 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -1538,10 +1538,10 @@ func deleteSpotFleetRequest(spotFleetRequestID string, terminateInstances bool, }) if err != nil || resp == nil { - return 0, nil,fmt.Errorf("error reading Spot Fleet Instances (%s): %s", spotFleetRequestID, err) + return 0, nil, fmt.Errorf("error reading Spot Fleet Instances (%s): %s", spotFleetRequestID, err) } - return len(resp.ActiveInstances),resp.ActiveInstances, nil + return len(resp.ActiveInstances), resp.ActiveInstances, nil } err = resource.Retry(timeout, func() *resource.RetryError { From f7706f5d53a196f3246306f693c28463a7d36ece Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Thu, 9 Apr 2020 10:34:35 +0300 Subject: [PATCH 29/67] refactor docs --- .../docs/r/spot_fleet_request.html.markdown | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/website/docs/r/spot_fleet_request.html.markdown b/website/docs/r/spot_fleet_request.html.markdown index ef624140b784..18f3db31965e 100644 --- a/website/docs/r/spot_fleet_request.html.markdown +++ b/website/docs/r/spot_fleet_request.html.markdown @@ -56,13 +56,13 @@ resource "aws_spot_fleet_request" "cheap_compute" { ### Using launch templates -``` +```hcl resource "aws_launch_template" "foo" { - name = "test-launch-template" - image_id = "${var.ami}" + name = "test-launch-template" + image_id = "${var.ami}" instance_type = "${var.instance_type}" - key_name = "${var.key_name}" - spot_price = "0.05" + key_name = "${var.key_name}" + spot_price = "0.05" } resource "aws_spot_fleet_request" "foo" { @@ -72,10 +72,10 @@ resource "aws_spot_fleet_request" "foo" { valid_until = "2019-11-04T20:44:20Z" launch_template_configs { - launch_template_specification { - id = "${aws_launch_template.foo.id}" - version = "${aws_launch_template.foo.latest_version}" - } + launch_template_specification { + id = "${aws_launch_template.foo.id}" + version = "${aws_launch_template.foo.latest_version}" + } } depends_on = ["aws_iam_policy_attachment.test-attach"] @@ -85,10 +85,9 @@ resource "aws_spot_fleet_request" "foo" { ~> **NOTE:** Terraform does not support the functionality where multiple `subnet_id` or `availability_zone` parameters can be specified in the same launch configuration block. If you want to specify multiple values, then separate launch configuration blocks should be used or launch template overrides should be configured, one per subnet: +### Using multiple launch specifications + ```hcl -# -# Launch Specification Method -# resource "aws_spot_fleet_request" "foo" { iam_fleet_role = "arn:aws:iam::12345678:role/spot-fleet" spot_price = "0.005" @@ -109,21 +108,22 @@ resource "aws_spot_fleet_request" "foo" { availability_zone = "us-west-2a" } } +``` + -# -# Launch Template Method -# +### Using multiple launch configurations +```hcl data "aws_subnet_ids" "example" { vpc_id = "${var.vpc_id}" } resource "aws_launch_template" "foo" { - name = "test-launch-template" - image_id = "${var.ami}" + name = "test-launch-template" + image_id = "${var.ami}" instance_type = "${var.instance_type}" - key_name = "${var.key_name}" - spot_price = "0.05" + key_name = "${var.key_name}" + spot_price = "0.05" } resource "aws_spot_fleet_request" "foo" { @@ -133,20 +133,20 @@ resource "aws_spot_fleet_request" "foo" { valid_until = "2019-11-04T20:44:20Z" launch_template_configs { - launch_template_specification { - id = "${aws_launch_template.foo.id}" - version = "${aws_launch_template.foo.latest_version}" - } - overrides { - subnet_id = "${data.aws_subnets.example.ids[0]}" - } - overrides { - subnet_id = "${data.aws_subnets.example.ids[1]}" - } - overrides { - subnet_id = "${data.aws_subnets.example.ids[2]}" - } + launch_template_specification { + id = "${aws_launch_template.foo.id}" + version = "${aws_launch_template.foo.latest_version}" + } + overrides { + subnet_id = "${data.aws_subnets.example.ids[0]}" + } + overrides { + subnet_id = "${data.aws_subnets.example.ids[1]}" } + overrides { + subnet_id = "${data.aws_subnets.example.ids[2]}" + } + } depends_on = ["aws_iam_policy_attachment.test-attach"] } From afa407fd3c8e45579870f1da54994210d967c7fc Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Thu, 9 Apr 2020 10:44:06 +0300 Subject: [PATCH 30/67] refactor docs --- website/docs/r/spot_fleet_request.html.markdown | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/website/docs/r/spot_fleet_request.html.markdown b/website/docs/r/spot_fleet_request.html.markdown index 18f3db31965e..9988d74ed704 100644 --- a/website/docs/r/spot_fleet_request.html.markdown +++ b/website/docs/r/spot_fleet_request.html.markdown @@ -58,10 +58,10 @@ resource "aws_spot_fleet_request" "cheap_compute" { ```hcl resource "aws_launch_template" "foo" { - name = "test-launch-template" - image_id = "${var.ami}" - instance_type = "${var.instance_type}" - key_name = "${var.key_name}" + name = "launch-template" + image_id = "ami-516b9131" + instance_type = "m1.small" + key_name = "some-key" spot_price = "0.05" } @@ -119,10 +119,10 @@ data "aws_subnet_ids" "example" { } resource "aws_launch_template" "foo" { - name = "test-launch-template" - image_id = "${var.ami}" - instance_type = "${var.instance_type}" - key_name = "${var.key_name}" + name = "launch-template" + image_id = "ami-516b9131" + instance_type = "m1.small" + key_name = "some-key" spot_price = "0.05" } From 2b2bf4237ae5e9981beccf952dcd4b8f8c86a666 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Thu, 9 Apr 2020 10:48:31 +0300 Subject: [PATCH 31/67] remove on demand test, docs and code --- aws/resource_aws_spot_fleet_request_test.go | 59 --------------------- 1 file changed, 59 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 84f3f9156ace..91c5ae14f63c 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -175,35 +175,6 @@ func TestAccAWSSpotFleetRequest_launchTemplate(t *testing.T) { }) } -//On-Demand capacity requires launch template defined spot fleet, so can't test without it. -func TestAccAWSSpotFleetRequest_launchTemplateWithOnDemandCapacity(t *testing.T) { - var sfr ec2.SpotFleetRequestConfig - rName := acctest.RandString(10) - rInt := acctest.RandInt() - validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) - resourceName := "aws_spot_fleet_request.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName, rInt, validUntil), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.overrides.#", "0"), - resource.TestCheckResourceAttr(resourceName, "on_demand_target_capacity", "2"), - ), - }, - }, - }) -} - func TestAccAWSSpotFleetRequest_launchTemplateConflictLaunchSpecification(t *testing.T) { rName := acctest.RandString(10) @@ -1438,36 +1409,6 @@ resource "aws_spot_fleet_request" "test" { `, rName) } -func testAccAWSSpotFleetRequestLaunchTemplateConfigWithOnDemandCapacity(rName string, rInt int, validUntil string) string { - return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + fmt.Sprintf(` -resource "aws_launch_template" "test" { - name = "test-launch-template-%[1]s" - image_id = "ami-516b9131" - instance_type = "m1.small" - key_name = "${aws_key_pair.debugging.key_name}" -} - -resource "aws_spot_fleet_request" "test" { - iam_fleet_role = "${aws_iam_role.test-role.arn}" - spot_price = "0.005" - target_capacity = 2 - valid_until = %[2]q - terminate_instances_with_expiration = true - wait_for_fulfillment = true - on_demand_target_capacity = 2 - - launch_template_configs { - launch_template_specification { - name = "${aws_launch_template.test.name}" - version = "${aws_launch_template.test.latest_version}" - } - } - - depends_on = ["aws_iam_policy_attachment.test-attach"] -} -`, rName, validUntil) -} - func testAccAWSSpotFleetRequestLaunchTemplateConfigWithOverrides(rName string, rInt int, validUntil string) string { return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + fmt.Sprintf(` resource "aws_launch_template" "test" { From a10956422c5390c8f9452a906bfd2a035486144e Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Thu, 9 Apr 2020 12:52:43 +0300 Subject: [PATCH 32/67] add priority argument fix some launch template tests --- aws/resource_aws_spot_fleet_request.go | 91 ++++++++----------- aws/resource_aws_spot_fleet_request_test.go | 98 +++++++++++---------- 2 files changed, 89 insertions(+), 100 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 2b92f6ff1a5d..fc0160b1c3a5 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -386,6 +386,12 @@ func resourceAwsSpotFleetRequest() *schema.Resource { Computed: true, ForceNew: true, }, + "priority": { + Type: schema.TypeFloat, + Optional: true, + Computed: true, + ForceNew: true, + }, }, }, Set: hashLaunchTemplateOverrides, @@ -771,17 +777,18 @@ func buildAwsSpotFleetLaunchSpecifications( } func buildLaunchTemplateConfigs(d *schema.ResourceData) ([]*ec2.LaunchTemplateConfig, error) { - launch_template_cfgs := d.Get("launch_template_configs").(*schema.Set).List() - cfgs := make([]*ec2.LaunchTemplateConfig, len(launch_template_cfgs)) + launchTemplateConfigs := d.Get("launch_template_configs").(*schema.Set) + log.Printf("haha %#v", launchTemplateConfigs) + configs := make([]*ec2.LaunchTemplateConfig, 0) - for _, launch_template_cfg := range launch_template_cfgs { + for _, launchTemplateConfig := range launchTemplateConfigs.List() { ltc := &ec2.LaunchTemplateConfig{} - ltc_map := launch_template_cfg.(map[string]interface{}) + ltcMap := launchTemplateConfig.(map[string]interface{}) //launch template spec - if v, ok := ltc_map["launch_template_specification"]; ok { + if v, ok := ltcMap["launch_template_specification"]; ok { vL := v.([]interface{}) lts := vL[0].(map[string]interface{}) @@ -803,10 +810,10 @@ func buildLaunchTemplateConfigs(d *schema.ResourceData) ([]*ec2.LaunchTemplateCo } - overrides := make([]*ec2.LaunchTemplateOverrides, 0) - - if v, ok := ltc_map["overrides"]; ok { + if v, ok := ltcMap["overrides"]; ok && v.(*schema.Set).Len() > 0 { vL := v.(*schema.Set).List() + overrides := make([]*ec2.LaunchTemplateOverrides, 0) + for _, v := range vL { ors := v.(map[string]interface{}) lto := &ec2.LaunchTemplateOverrides{} @@ -831,16 +838,20 @@ func buildLaunchTemplateConfigs(d *schema.ResourceData) ([]*ec2.LaunchTemplateCo lto.WeightedCapacity = aws.Float64(v) } - overrides = append(overrides, lto) + if v, ok := ors["priority"].(float64); ok && v > 0 { + lto.Priority = aws.Float64(v) + } + overrides = append(overrides, lto) } + + ltc.Overrides = overrides } - ltc.Overrides = overrides - cfgs = append(cfgs, ltc) + configs = append(configs, ltc) } - return cfgs, nil + return configs, nil } func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) error { @@ -869,19 +880,19 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) var err error if launchSpecificationOk { - launch_specs, err := buildAwsSpotFleetLaunchSpecifications(d, meta) + launchSpecs, err := buildAwsSpotFleetLaunchSpecifications(d, meta) if err != nil { return err } - spotFleetConfig.LaunchSpecifications = launch_specs + spotFleetConfig.LaunchSpecifications = launchSpecs } if launchTemplateConfigsOk { - launch_templates, err := buildLaunchTemplateConfigs(d) + launchTemplates, err := buildLaunchTemplateConfigs(d) if err != nil { return err } - spotFleetConfig.LaunchTemplateConfigs = launch_templates + spotFleetConfig.LaunchTemplateConfigs = launchTemplates } if v, ok := d.GetOk("excess_capacity_termination_policy"); ok { @@ -903,11 +914,11 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) } if v, ok := d.GetOk("valid_from"); ok { - valid_from, err := time.Parse(time.RFC3339, v.(string)) + validFrom, err := time.Parse(time.RFC3339, v.(string)) if err != nil { return err } - spotFleetConfig.ValidFrom = aws.Time(valid_from) + spotFleetConfig.ValidFrom = aws.Time(validFrom) } if v, ok := d.GetOk("valid_until"); ok { @@ -917,8 +928,8 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) } spotFleetConfig.ValidUntil = aws.Time(valid_until) } else { - valid_until := time.Now().Add(24 * time.Hour) - spotFleetConfig.ValidUntil = aws.Time(valid_until) + validUntil := time.Now().Add(24 * time.Hour) + spotFleetConfig.ValidUntil = aws.Time(validUntil) } if v, ok := d.GetOk("load_balancers"); ok && v.(*schema.Set).Len() > 0 { @@ -968,12 +979,6 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) if isAWSErr(err, "InvalidSpotFleetRequestConfig", "") { return resource.RetryableError(fmt.Errorf("Error creating Spot fleet request, retrying: %s", err)) } - if isAWSErr(err, "InvalidSpotFleetRequestConfig", "LaunchTemplateSpecification") { - return resource.NonRetryableError(err) - } - if isAWSErr(err, "InvalidSpotFleetRequestConfig", "IamFleetRole") { - return resource.RetryableError(fmt.Errorf("Error creating Spot fleet request, retrying: %s", err)) - } if err != nil { return resource.NonRetryableError(err) } @@ -1140,9 +1145,9 @@ func resourceAwsSpotFleetRequestRead(d *schema.ResourceData, meta interface{}) e // if the request is cancelled, then it is gone cancelledStates := map[string]bool{ - "cancelled": true, - "cancelled_running": true, - "cancelled_terminating": true, + ec2.BatchStateCancelled: true, + ec2.BatchStateCancelledRunning: true, + ec2.BatchStateCancelledTerminating: true, } if _, ok := cancelledStates[*sfr.SpotFleetRequestState]; ok { d.SetId("") @@ -1532,20 +1537,20 @@ func deleteSpotFleetRequest(spotFleetRequestID string, terminateInstances bool, return nil } - activeInstances := func(fleetRequestID string) (int, []*ec2.ActiveInstance, error) { + activeInstances := func(fleetRequestID string) (int, error) { resp, err := conn.DescribeSpotFleetInstances(&ec2.DescribeSpotFleetInstancesInput{ SpotFleetRequestId: aws.String(fleetRequestID), }) if err != nil || resp == nil { - return 0, nil, fmt.Errorf("error reading Spot Fleet Instances (%s): %s", spotFleetRequestID, err) + return 0, fmt.Errorf("error reading Spot Fleet Instances (%s): %s", spotFleetRequestID, err) } - return len(resp.ActiveInstances), resp.ActiveInstances, nil + return len(resp.ActiveInstances), nil } err = resource.Retry(timeout, func() *resource.RetryError { - n, activeInsts, err := activeInstances(spotFleetRequestID) + n, err := activeInstances(spotFleetRequestID) if err != nil { return resource.NonRetryableError(err) } @@ -1555,30 +1560,12 @@ func deleteSpotFleetRequest(spotFleetRequestID string, terminateInstances bool, return resource.RetryableError(fmt.Errorf("fleet still has (%d) running instances", n)) } - var instances []*string - for _, instMap := range activeInsts { - instances = append(instances, instMap.InstanceId) - } - iresp, err := conn.DescribeInstances(&ec2.DescribeInstancesInput{ - InstanceIds: instances, - }) - if err != nil { - return resource.RetryableError( - fmt.Errorf("Error while trying to determine fleet status for fleet (%s): %s", spotFleetRequestID, err)) - } - if len(iresp.Reservations) == 0 { - log.Printf("[DEBUG] Active instance count is %d for Spot Fleet Request (%s), but instances have terminated, removing", n, spotFleetRequestID) - return nil - } else { - log.Printf("[DEBUG] Active instance count is %d for Spot Fleet Request (%s), and at least 1 instance is still running", n, spotFleetRequestID) - } - log.Printf("[DEBUG] Active instance count is 0 for Spot Fleet Request (%s), removing", spotFleetRequestID) return nil }) if isResourceTimeoutError(err) { - n, _, err := activeInstances(spotFleetRequestID) + n, err := activeInstances(spotFleetRequestID) if err != nil { return err } diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 91c5ae14f63c..c21e48dbb447 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -167,8 +167,8 @@ func TestAccAWSSpotFleetRequest_launchTemplate(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), resource.TestCheckResourceAttr(resourceName, "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.overrides.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.795271135.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.795271135.overrides.#", "0"), ), }, }, @@ -242,8 +242,8 @@ func TestAccAWSSpotFleetRequest_launchTemplateToLaunchSpec(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), resource.TestCheckResourceAttr(resourceName, "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.overrides.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.795271135.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.795271135.overrides.#", "0"), ), }, { @@ -288,8 +288,8 @@ func TestAccAWSSpotFleetRequest_launchSpecToLaunchTemplate(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), resource.TestCheckResourceAttr(resourceName, "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.4018047529.overrides.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.795271135.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.795271135.overrides.#", "0"), testAccCheckAWSSpotFleetRequestConfigRecreated(t, &before, &after), ), }, @@ -1324,31 +1324,31 @@ resource "aws_spot_fleet_request" "test" { func testAccAWSSpotFleetRequestLaunchTemplateConfig(rName string, rInt int, validUntil string) string { return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + fmt.Sprintf(` resource "aws_launch_template" "test" { - name = "test-launch-template-%[1]s" - image_id = "ami-516b9131" + name = "tf-acc-test-launch-template" + image_id = "ami-516b9131" instance_type = "m1.small" - key_name = "${aws_key_pair.debugging.key_name}" + key_name = "${aws_key_pair.debugging.key_name}" } resource "aws_spot_fleet_request" "test" { - iam_fleet_role = "${aws_iam_role.test-role.arn}" - spot_price = "0.005" - target_capacity = 2 - valid_until = %[2]q - terminate_instances_with_expiration = true - instance_interruption_behaviour = "stop" - wait_for_fulfillment = true + iam_fleet_role = "${aws_iam_role.test-role.arn}" + spot_price = "0.005" + target_capacity = 2 + valid_until = %[1]q + terminate_instances_with_expiration = true + instance_interruption_behaviour = "stop" + wait_for_fulfillment = true - launch_template_configs { - launch_template_specification { - name = "${aws_launch_template.test.name}" - version = "${aws_launch_template.test.latest_version}" - } + launch_template_configs { + launch_template_specification { + name = "${aws_launch_template.test.name}" + version = "${aws_launch_template.test.latest_version}" } + } - depends_on = ["aws_iam_policy_attachment.test-attach"] + depends_on = ["aws_iam_policy_attachment.test-attach"] } -`, rName, validUntil) +`, validUntil) } func testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName string) string { @@ -1412,40 +1412,42 @@ resource "aws_spot_fleet_request" "test" { func testAccAWSSpotFleetRequestLaunchTemplateConfigWithOverrides(rName string, rInt int, validUntil string) string { return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + fmt.Sprintf(` resource "aws_launch_template" "test" { - name = "test-launch-template-%[1]s" - image_id = "ami-516b9131" + name = "tf-acc-test-launch-template" + image_id = "ami-516b9131" instance_type = "m1.small" - key_name = "${aws_key_pair.debugging.key_name}" + key_name = "${aws_key_pair.debugging.key_name}" } resource "aws_spot_fleet_request" "test" { - iam_fleet_role = "${aws_iam_role.test-role.arn}" - spot_price = "0.005" - target_capacity = 2 - valid_until = %[2]q - terminate_instances_with_expiration = true - instance_interruption_behaviour = "stop" - wait_for_fulfillment = true + iam_fleet_role = "${aws_iam_role.test-role.arn}" + spot_price = "0.005" + target_capacity = 2 + valid_until = %[1]q + terminate_instances_with_expiration = true + instance_interruption_behaviour = "stop" + wait_for_fulfillment = true - launch_template_configs { - launch_template_specification { - name = "${aws_launch_template.test.name}" - version = "${aws_launch_template.test.latest_version}" - } - overrides { - instance_type = "t1.micro" - weighted_capacity = "2" - } - overrides { - instance_type = "m3.medium" - spot_price = "0.26" - } + launch_template_configs { + launch_template_specification { + name = "${aws_launch_template.test.name}" + version = "${aws_launch_template.test.latest_version}" + } + overrides { + instance_type = "t1.micro" + weighted_capacity = "2" } - depends_on = ["aws_iam_policy_attachment.test-attach"] + overrides { + instance_type = "m3.medium" + spot_price = "0.26" + } + + } + + depends_on = ["aws_iam_policy_attachment.test-attach"] } -`, rName, validUntil) +`, validUntil) } func testAccAWSSpotFleetRequestConfigExcessCapacityTermination(rName string, rInt int, validUntil string) string { From 0221ddcb07cf9be56f44afaecc32db7ec69b858a Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Thu, 9 Apr 2020 13:01:07 +0300 Subject: [PATCH 33/67] add priority to docs --- website/docs/r/spot_fleet_request.html.markdown | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/website/docs/r/spot_fleet_request.html.markdown b/website/docs/r/spot_fleet_request.html.markdown index 9988d74ed704..f36bb3710908 100644 --- a/website/docs/r/spot_fleet_request.html.markdown +++ b/website/docs/r/spot_fleet_request.html.markdown @@ -223,11 +223,12 @@ The `launch_template_configs` block supports the following: ### Overrides -* `instance_type` - (Optional) The type of instance to request. * `availability_zone` - (Optional) The availability zone in which to place the request. +* `instance_type` - (Optional) The type of instance to request. +* `priority` - (Optional) The priority for the launch template override. The lower the number, the higher the priority. If no number is set, the launch template override has the lowest priority. * `spot_price` - (Optional) The maximum spot bid for this override request. -* `weighted_capacity` - (Optional) The capacity added to the fleet by a fulfilled request. * `subnet_id` - (Optional) The subnet in which to launch the requested instance. +* `weighted_capacity` - (Optional) The capacity added to the fleet by a fulfilled request. **Note:** Instead of statically defining these override blocks they can be passed in as a list of maps containing the above keys and their values. This allows dynamic, programmatic generation of overrides based on variable or environment data. From a4d1ad9487dc1fc0fea115ad29b508e8fec65394 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Thu, 9 Apr 2020 13:01:42 +0300 Subject: [PATCH 34/67] allows zero value priority --- aws/resource_aws_spot_fleet_request.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index fc0160b1c3a5..a9cb3b51e27e 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -838,7 +838,7 @@ func buildLaunchTemplateConfigs(d *schema.ResourceData) ([]*ec2.LaunchTemplateCo lto.WeightedCapacity = aws.Float64(v) } - if v, ok := ors["priority"].(float64); ok && v > 0 { + if v, ok := ors["priority"].(float64); ok { lto.Priority = aws.Float64(v) } From c0550c97c1a62a96978693bf8a57f9f1399ded7a Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Thu, 9 Apr 2020 13:37:49 +0300 Subject: [PATCH 35/67] add priority and fix test hashes --- aws/resource_aws_spot_fleet_request.go | 9 ++++++++- aws/resource_aws_spot_fleet_request_test.go | 17 +++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index a9cb3b51e27e..e635b1d6391f 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -778,7 +778,6 @@ func buildAwsSpotFleetLaunchSpecifications( func buildLaunchTemplateConfigs(d *schema.ResourceData) ([]*ec2.LaunchTemplateConfig, error) { launchTemplateConfigs := d.Get("launch_template_configs").(*schema.Set) - log.Printf("haha %#v", launchTemplateConfigs) configs := make([]*ec2.LaunchTemplateConfig, 0) for _, launchTemplateConfig := range launchTemplateConfigs.List() { @@ -1256,6 +1255,10 @@ func flattenSpotFleetRequestLaunchTemplateOverrides(override *ec2.LaunchTemplate m["weighted_capacity"] = aws.Float64Value(override.WeightedCapacity) } + if override.Priority != nil { + m["priority"] = aws.Float64Value(override.Priority) + } + return m } @@ -1629,6 +1632,10 @@ func hashLaunchTemplateOverrides(v interface{}) int { if m["weighted_capacity"] != nil { buf.WriteString(fmt.Sprintf("%f-", m["weighted_capacity"].(float64))) } + if m["priority"] != nil { + buf.WriteString(fmt.Sprintf("%f-", m["priority"].(float64))) + } + return hashcode.String(buf.String()) } diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index c21e48dbb447..c62017fa9aec 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -210,13 +210,14 @@ func TestAccAWSSpotFleetRequest_launchTemplateWithOverrides(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), resource.TestCheckResourceAttr(resourceName, "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.3492852471.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.3492852471.overrides.#", "2"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.3492852471.overrides.#", "2"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.3492852471.overrides.3113255372.instance_type", "t1.micro"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.3492852471.overrides.3113255372.weighted_capacity", "2"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.3492852471.overrides.1994766569.instance_type", "m3.medium"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.3492852471.overrides.1994766569.spot_price", "0.26"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.overrides.#", "2"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.overrides.#", "2"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.overrides.1951041615.instance_type", "t1.micro"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.overrides.1951041615.weighted_capacity", "2"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.overrides.1866154075.instance_type", "m3.medium"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.overrides.1866154075.priority", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.overrides.1866154075.spot_price", "0.26"), ), }, }, @@ -1440,9 +1441,9 @@ resource "aws_spot_fleet_request" "test" { overrides { instance_type = "m3.medium" + priority = 1 spot_price = "0.26" } - } depends_on = ["aws_iam_policy_attachment.test-attach"] From aa87abeb39b1204cc322beeee8041b3446051ec6 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Thu, 9 Apr 2020 17:27:21 +0300 Subject: [PATCH 36/67] add disappearing test case --- aws/resource_aws_spot_fleet_request_test.go | 34 +++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index c62017fa9aec..11f9be53edcc 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -1015,6 +1015,30 @@ func TestAccAWSSpotFleetRequest_WithInstanceStoreAmi(t *testing.T) { }) } +func TestAccAWSSpotFleetRequest_disappears(t *testing.T) { + var sfr ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() + validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) + resourceName := "aws_spot_fleet_request.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSEc2SpotFleetRequest(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestConfig(rName, rInt, validUntil), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + testAccCheckAWSSpotFleetRequestDisappears(&sfr), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + func testAccCheckAWSSpotFleetRequestConfigRecreated(t *testing.T, before, after *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { return func(s *terraform.State) error { @@ -1058,6 +1082,16 @@ func testAccCheckAWSSpotFleetRequestExists( } } +func testAccCheckAWSSpotFleetRequestDisappears(sfr *ec2.SpotFleetRequestConfig) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).ec2conn + sfrId := aws.StringValue(sfr.SpotFleetRequestId) + err := deleteSpotFleetRequest(sfrId, true, 5*time.Minute, conn) + + return err + } +} + func testAccCheckAWSSpotFleetRequestDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).ec2conn From 2c433eb66adfc44801aecba47ad5d666a4013428 Mon Sep 17 00:00:00 2001 From: Ilia Lazebnik Date: Fri, 24 Apr 2020 12:53:06 +0300 Subject: [PATCH 37/67] Update aws/resource_aws_spot_fleet_request.go Co-Authored-By: Brian Flad --- aws/resource_aws_spot_fleet_request.go | 1 - 1 file changed, 1 deletion(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index e635b1d6391f..375323f417e7 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -331,7 +331,6 @@ func resourceAwsSpotFleetRequest() *schema.Resource { Optional: true, Computed: true, ForceNew: true, - ConflictsWith: []string{"launch_template_configs.0.launch_template_specification.0.name"}, ValidateFunc: validateLaunchTemplateId, }, "name": { From 035f9ef1165b1d852d8a96d82ac9a4dbf6694ca2 Mon Sep 17 00:00:00 2001 From: Ilia Lazebnik Date: Fri, 24 Apr 2020 12:53:18 +0300 Subject: [PATCH 38/67] Update aws/resource_aws_spot_fleet_request.go Co-Authored-By: Brian Flad --- aws/resource_aws_spot_fleet_request.go | 1 - 1 file changed, 1 deletion(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 375323f417e7..ba5c4da658a0 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -338,7 +338,6 @@ func resourceAwsSpotFleetRequest() *schema.Resource { Optional: true, Computed: true, ForceNew: true, - ConflictsWith: []string{"launch_template_configs.0.launch_template_specification.0.id"}, ValidateFunc: validateLaunchTemplateName, }, "version": { From 47a1cff222810ac45070c3589cd285544a16d4c0 Mon Sep 17 00:00:00 2001 From: Ilia Lazebnik Date: Fri, 24 Apr 2020 12:54:04 +0300 Subject: [PATCH 39/67] Update aws/resource_aws_spot_fleet_request.go Co-Authored-By: Brian Flad --- aws/resource_aws_spot_fleet_request.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index ba5c4da658a0..68d46208ac07 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -505,17 +505,6 @@ func resourceAwsSpotFleetRequest() *schema.Resource { }, "tags": tagsSchema(), }, - // A launch template can be created with an id or a name, but once created will have both even though we specify only one. - // If either changes, this makes sure the other (which was specified) will register as changed in order to correctly determine diffs. - // This was taken from the original implementation of launch templates in resource_aws_autoscaling_group.go - CustomizeDiff: customdiff.Sequence( - customdiff.ComputedIf("launch_template_configs.0.launch_template_specification.0.id", func(diff *schema.ResourceDiff, meta interface{}) bool { - return diff.HasChange("launch_template_configs.0.launch_template_specification.0.name") - }), - customdiff.ComputedIf("launch_template_configs.0.launch_template_specification.0.name", func(diff *schema.ResourceDiff, meta interface{}) bool { - return diff.HasChange("launch_template_configs.0.launch_template_specification.0.id") - }), - ), } } From 3cc8379fb3da3230292d7a05a8995c5c875fcad7 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 12:58:12 +0300 Subject: [PATCH 40/67] rename `launch_template_configs` to `launch_template_config` --- aws/resource_aws_spot_fleet_request.go | 35 +++++++-------- aws/resource_aws_spot_fleet_request_test.go | 44 +++++++++---------- .../docs/r/spot_fleet_request.html.markdown | 10 ++--- 3 files changed, 44 insertions(+), 45 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 68d46208ac07..aef44dcc783f 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -9,7 +9,6 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/hashicorp/terraform-plugin-sdk/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/helper/hashcode" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" @@ -56,7 +55,7 @@ func resourceAwsSpotFleetRequest() *schema.Resource { "launch_specification": { Type: schema.TypeSet, Optional: true, - ConflictsWith: []string{"launch_template_configs"}, + ConflictsWith: []string{"launch_template_config"}, ForceNew: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -313,7 +312,7 @@ func resourceAwsSpotFleetRequest() *schema.Resource { }, Set: hashLaunchSpecification, }, - "launch_template_configs": { + "launch_template_config": { Type: schema.TypeSet, Optional: true, ForceNew: true, @@ -327,18 +326,18 @@ func resourceAwsSpotFleetRequest() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ValidateFunc: validateLaunchTemplateId, + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validateLaunchTemplateId, }, "name": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ValidateFunc: validateLaunchTemplateName, + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validateLaunchTemplateName, }, "version": { Type: schema.TypeString, @@ -764,7 +763,7 @@ func buildAwsSpotFleetLaunchSpecifications( } func buildLaunchTemplateConfigs(d *schema.ResourceData) ([]*ec2.LaunchTemplateConfig, error) { - launchTemplateConfigs := d.Get("launch_template_configs").(*schema.Set) + launchTemplateConfigs := d.Get("launch_template_config").(*schema.Set) configs := make([]*ec2.LaunchTemplateConfig, 0) for _, launchTemplateConfig := range launchTemplateConfigs.List() { @@ -845,7 +844,7 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) conn := meta.(*AWSClient).ec2conn _, launchSpecificationOk := d.GetOk("launch_specification") - _, launchTemplateConfigsOk := d.GetOk("launch_template_configs") + _, launchTemplateConfigsOk := d.GetOk("launch_template_config") if !launchSpecificationOk && !launchTemplateConfigsOk { return fmt.Errorf("One of `launch_specification` or `launch_template` must be set for a fleet request") @@ -1203,10 +1202,10 @@ func resourceAwsSpotFleetRequestRead(d *schema.ResourceData, meta interface{}) e } if len(config.LaunchTemplateConfigs) > 0 { - d.Set("launch_template_configs.0.launch_template_specification.0", flattenFleetLaunchTemplateSpecification(config.LaunchTemplateConfigs[0].LaunchTemplateSpecification)) - d.Set("launch_template_configs.0.overrides", setLaunchTemplateOverrides(config.LaunchTemplateConfigs[0].Overrides)) + d.Set("launch_template_config.0.launch_template_specification.0", flattenFleetLaunchTemplateSpecification(config.LaunchTemplateConfigs[0].LaunchTemplateSpecification)) + d.Set("launch_template_config.0.overrides", setLaunchTemplateOverrides(config.LaunchTemplateConfigs[0].Overrides)) } else { - d.Set("launch_template_configs.0.launch_template_specification.0", nil) + d.Set("launch_template_config.0.launch_template_specification.0", nil) } return nil diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 11f9be53edcc..1dc8644c959e 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -166,9 +166,9 @@ func TestAccAWSSpotFleetRequest_launchTemplate(t *testing.T) { testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.795271135.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.795271135.overrides.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.overrides.#", "0"), ), }, }, @@ -185,7 +185,7 @@ func TestAccAWSSpotFleetRequest_launchTemplateConflictLaunchSpecification(t *tes Steps: []resource.TestStep{ { Config: testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName), - ExpectError: regexp.MustCompile(`"launch_specification": conflicts with launch_template_configs`), + ExpectError: regexp.MustCompile(`"launch_specification": conflicts with launch_template_config`), }, }, }) @@ -209,15 +209,15 @@ func TestAccAWSSpotFleetRequest_launchTemplateWithOverrides(t *testing.T) { testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.overrides.#", "2"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.overrides.#", "2"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.overrides.1951041615.instance_type", "t1.micro"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.overrides.1951041615.weighted_capacity", "2"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.overrides.1866154075.instance_type", "m3.medium"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.overrides.1866154075.priority", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.2247196053.overrides.1866154075.spot_price", "0.26"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.overrides.#", "2"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.overrides.#", "2"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.overrides.1951041615.instance_type", "t1.micro"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.overrides.1951041615.weighted_capacity", "2"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.overrides.1866154075.instance_type", "m3.medium"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.overrides.1866154075.priority", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.overrides.1866154075.spot_price", "0.26"), ), }, }, @@ -242,9 +242,9 @@ func TestAccAWSSpotFleetRequest_launchTemplateToLaunchSpec(t *testing.T) { testAccCheckAWSSpotFleetRequestExists(resourceName, &before), resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.795271135.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.795271135.overrides.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.overrides.#", "0"), ), }, { @@ -288,9 +288,9 @@ func TestAccAWSSpotFleetRequest_launchSpecToLaunchTemplate(t *testing.T) { testAccCheckAWSSpotFleetRequestExists(resourceName, &after), resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.795271135.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_configs.795271135.overrides.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.overrides.#", "0"), testAccCheckAWSSpotFleetRequestConfigRecreated(t, &before, &after), ), }, @@ -1374,7 +1374,7 @@ resource "aws_spot_fleet_request" "test" { instance_interruption_behaviour = "stop" wait_for_fulfillment = true - launch_template_configs { + launch_template_config { launch_template_specification { name = "${aws_launch_template.test.name}" version = "${aws_launch_template.test.latest_version}" @@ -1421,7 +1421,7 @@ resource "aws_spot_fleet_request" "test" { spot_price = "0.005" target_capacity = 2 - launch_template_configs { + launch_template_config { launch_template_specification { name = "${aws_launch_template.test.name}" version = "${aws_launch_template.test.latest_version}" @@ -1462,7 +1462,7 @@ resource "aws_spot_fleet_request" "test" { instance_interruption_behaviour = "stop" wait_for_fulfillment = true - launch_template_configs { + launch_template_config { launch_template_specification { name = "${aws_launch_template.test.name}" version = "${aws_launch_template.test.latest_version}" diff --git a/website/docs/r/spot_fleet_request.html.markdown b/website/docs/r/spot_fleet_request.html.markdown index f36bb3710908..aebda29db767 100644 --- a/website/docs/r/spot_fleet_request.html.markdown +++ b/website/docs/r/spot_fleet_request.html.markdown @@ -71,7 +71,7 @@ resource "aws_spot_fleet_request" "foo" { target_capacity = 2 valid_until = "2019-11-04T20:44:20Z" - launch_template_configs { + launch_template_config { launch_template_specification { id = "${aws_launch_template.foo.id}" version = "${aws_launch_template.foo.latest_version}" @@ -132,7 +132,7 @@ resource "aws_spot_fleet_request" "foo" { target_capacity = 2 valid_until = "2019-11-04T20:44:20Z" - launch_template_configs { + launch_template_config { launch_template_specification { id = "${aws_launch_template.foo.id}" version = "${aws_launch_template.foo.latest_version}" @@ -164,7 +164,7 @@ terminateInstancesWithExpiration. * `replace_unhealthy_instances` - (Optional) Indicates whether Spot fleet should replace unhealthy instances. Default `false`. * `launch_specification` - (Optional) Used to define the launch configuration of the spot-fleet request. Can be specified multiple times to define different bids -across different markets and instance types. Conflicts with `launch_template_configs`. At least one of `launch_specification` or `launch_template_configs` is required. +across different markets and instance types. Conflicts with `launch_template_config`. At least one of `launch_specification` or `launch_template_config` is required. **Note:** This takes in similar but not identical inputs as [`aws_instance`](instance.html). There are limitations on @@ -172,7 +172,7 @@ across different markets and instance types. Conflicts with `launch_template_con [reference documentation](http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_SpotFleetLaunchSpecification.html). Any normal [`aws_instance`](instance.html) parameter that corresponds to those inputs may be used and it have a additional parameter `iam_instance_profile_arn` takes `aws_iam_instance_profile` attribute `arn` as input. -* `launch_template_configs` - (Optional) Launch template configuration block. See [Launch Template Configs](#launch-template-configs) below for more details. Conflicts with `launch_specification`. At least one of `launch_specification` or `launch_template_configs` is required. +* `launch_template_config` - (Optional) Launch template configuration block. See [Launch Template Configs](#launch-template-configs) below for more details. Conflicts with `launch_specification`. At least one of `launch_specification` or `launch_template_config` is required. * `spot_price` - (Optional; Default: On-demand price) The maximum bid price per unit hour. * `wait_for_fulfillment` - (Optional; Default: false) If set, Terraform will wait for the Spot Request to be fulfilled, and will throw an error if the @@ -206,7 +206,7 @@ across different markets and instance types. Conflicts with `launch_template_con ### Launch Template Configs -The `launch_template_configs` block supports the following: +The `launch_template_config` block supports the following: * `launch_template_specification` - (Required) Launch template specification. See [Launch Template Specification](#launch-template-specification) below for more details. * `overrides` - (Optional) One or more overide configurations. See [Overrides](#overrides) below for more details. From 856bde58ba6f1f64b241670ba492c646d3e3c00b Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 14:27:03 +0300 Subject: [PATCH 41/67] remove new line --- aws/resource_aws_spot_fleet_request_test.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 1dc8644c959e..e4155f17136a 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -337,10 +337,8 @@ func TestAccAWSSpotFleetRequest_fleetType(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigFleetType(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - resourceName, &sfr), - resource.TestCheckResourceAttr( - resourceName, "spot_request_state", "active"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "fleet_type", "request"), ), }, From 2814a5fbe0dc8ff4ebac2451db79fe9d26949c9f Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 14:30:17 +0300 Subject: [PATCH 42/67] remove new lines from tests --- aws/resource_aws_spot_fleet_request_test.go | 174 +++++++------------- 1 file changed, 58 insertions(+), 116 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index e4155f17136a..141bfd159a72 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -385,27 +385,19 @@ func TestAccAWSSpotFleetRequest_changePriceForcesNewRequest(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfig(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - resourceName, &before), - resource.TestCheckResourceAttr( - resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr( - resourceName, "spot_price", "0.005"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.#", "1"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &before), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "spot_price", "0.005"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "1"), ), }, { Config: testAccAWSSpotFleetRequestConfigChangeSpotBidPrice(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - resourceName, &after), - resource.TestCheckResourceAttr( - resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.#", "1"), - resource.TestCheckResourceAttr( - resourceName, "spot_price", "0.01"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &after), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spot_price", "0.01"), testAccCheckAWSSpotFleetRequestConfigRecreated(t, &before, &after), ), }, @@ -498,12 +490,9 @@ func TestAccAWSSpotFleetRequest_lowestPriceAzOrSubnetInRegion(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfig(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - resourceName, &sfr), - resource.TestCheckResourceAttr( - resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.#", "1"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "1"), ), }, }, @@ -525,16 +514,11 @@ func TestAccAWSSpotFleetRequest_lowestPriceAzInGivenList(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigWithAzs(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - resourceName, &sfr), - resource.TestCheckResourceAttr( - resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.#", "2"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.1991689378.availability_zone", "us-west-2a"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.19404370.availability_zone", "us-west-2b"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "2"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.1991689378.availability_zone", "us-west-2a"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.19404370.availability_zone", "us-west-2b"), ), }, }, @@ -556,12 +540,9 @@ func TestAccAWSSpotFleetRequest_lowestPriceSubnetInGivenList(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigWithSubnet(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - resourceName, &sfr), - resource.TestCheckResourceAttr( - resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.#", "2"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "2"), ), }, }, @@ -583,20 +564,13 @@ func TestAccAWSSpotFleetRequest_multipleInstanceTypesInSameAz(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigMultipleInstanceTypesinSameAz(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - resourceName, &sfr), - resource.TestCheckResourceAttr( - resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.#", "2"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.1991689378.instance_type", "m1.small"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.1991689378.availability_zone", "us-west-2a"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.590403189.instance_type", "m3.large"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.590403189.availability_zone", "us-west-2a"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "2"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.1991689378.instance_type", "m1.small"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.1991689378.availability_zone", "us-west-2a"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.590403189.instance_type", "m3.large"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.590403189.availability_zone", "us-west-2a"), ), }, }, @@ -641,12 +615,9 @@ func TestAccAWSSpotFleetRequest_multipleInstanceTypesInSameSubnet(t *testing.T) { Config: testAccAWSSpotFleetRequestConfigMultipleInstanceTypesinSameSubnet(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - resourceName, &sfr), - resource.TestCheckResourceAttr( - resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.#", "2"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "2"), ), }, }, @@ -668,22 +639,14 @@ func TestAccAWSSpotFleetRequest_overriddingSpotPrice(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigOverridingSpotPrice(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - resourceName, &sfr), - resource.TestCheckResourceAttr( - resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr( - resourceName, "spot_price", "0.035"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.#", "2"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.4143232216.spot_price", "0.01"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.4143232216.instance_type", "m3.large"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.1991689378.spot_price", ""), //there will not be a value here since it's not overriding - resource.TestCheckResourceAttr( - resourceName, "launch_specification.1991689378.instance_type", "m1.small"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "spot_price", "0.035"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "2"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.4143232216.spot_price", "0.01"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.4143232216.instance_type", "m3.large"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.1991689378.spot_price", ""), //there will not be a value here since it's not overriding + resource.TestCheckResourceAttr(resourceName, "launch_specification.1991689378.instance_type", "m1.small"), ), }, }, @@ -705,12 +668,9 @@ func TestAccAWSSpotFleetRequest_withoutSpotPrice(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigWithoutSpotPrice(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - resourceName, &sfr), - resource.TestCheckResourceAttr( - resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.#", "2"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "2"), ), }, }, @@ -732,14 +692,10 @@ func TestAccAWSSpotFleetRequest_diversifiedAllocation(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigDiversifiedAllocation(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - resourceName, &sfr), - resource.TestCheckResourceAttr( - resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.#", "3"), - resource.TestCheckResourceAttr( - resourceName, "allocation_strategy", "diversified"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "3"), + resource.TestCheckResourceAttr(resourceName, "allocation_strategy", "diversified"), ), }, }, @@ -761,16 +717,11 @@ func TestAccAWSSpotFleetRequest_multipleInstancePools(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigMultipleInstancePools(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - resourceName, &sfr), - resource.TestCheckResourceAttr( - resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.#", "3"), - resource.TestCheckResourceAttr( - resourceName, "allocation_strategy", "lowestPrice"), - resource.TestCheckResourceAttr( - resourceName, "instance_pools_to_use_count", "2"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "3"), + resource.TestCheckResourceAttr(resourceName, "allocation_strategy", "lowestPrice"), + resource.TestCheckResourceAttr(resourceName, "instance_pools_to_use_count", "2"), ), }, }, @@ -807,20 +758,13 @@ func TestAccAWSSpotFleetRequest_withWeightedCapacity(t *testing.T) { Config: testAccAWSSpotFleetRequestConfigWithWeightedCapacity(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( fulfillSleep(), - testAccCheckAWSSpotFleetRequestExists( - resourceName, &sfr), - resource.TestCheckResourceAttr( - resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.#", "2"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.4120185872.weighted_capacity", "3"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.4120185872.instance_type", "r3.large"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.590403189.weighted_capacity", "6"), - resource.TestCheckResourceAttr( - resourceName, "launch_specification.590403189.instance_type", "m3.large"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "2"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.4120185872.weighted_capacity", "3"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.4120185872.instance_type", "r3.large"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.590403189.weighted_capacity", "6"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.590403189.instance_type", "m3.large"), ), }, }, @@ -982,10 +926,8 @@ func TestAccAWSSpotFleetRequest_WithTargetGroups(t *testing.T) { { Config: testAccAWSSpotFleetRequestConfigWithTargetGroups(rName, rInt, validUntil), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSSpotFleetRequestExists( - resourceName, &sfr), - resource.TestCheckResourceAttr( - resourceName, "spot_request_state", "active"), + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "1"), resource.TestCheckResourceAttr(resourceName, "target_group_arns.#", "1"), ), From 659e268e8a7d7087ee0aea6e319f35e65a912ab6 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 14:58:24 +0300 Subject: [PATCH 43/67] ar least one of lunch spec or config --- aws/resource_aws_spot_fleet_request.go | 4 +- aws/resource_aws_spot_fleet_request_test.go | 71 +++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index aef44dcc783f..8c0d3365ffc5 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -310,13 +310,15 @@ func resourceAwsSpotFleetRequest() *schema.Resource { }, }, }, - Set: hashLaunchSpecification, + Set: hashLaunchSpecification, + AtLeastOneOf: []string{"launch_specification", "launch_template_config"}, }, "launch_template_config": { Type: schema.TypeSet, Optional: true, ForceNew: true, ConflictsWith: []string{"launch_specification"}, + AtLeastOneOf: []string{"launch_specification", "launch_template_config"}, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "launch_template_specification": { diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 141bfd159a72..44ce69e072c6 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -175,6 +175,33 @@ func TestAccAWSSpotFleetRequest_launchTemplate(t *testing.T) { }) } +func TestAccAWSSpotFleetRequest_launchTemplate_multiple(t *testing.T) { + var sfr ec2.SpotFleetRequestConfig + rName := acctest.RandString(10) + rInt := acctest.RandInt() + validUntil := time.Now().UTC().Add(24 * time.Hour).Format(time.RFC3339) + resourceName := "aws_spot_fleet_request.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSSpotFleetRequestLaunchTemplateMultipleConfig(rName, rInt, validUntil), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), + resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), + resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.overrides.#", "0"), + ), + }, + }, + }) +} + func TestAccAWSSpotFleetRequest_launchTemplateConflictLaunchSpecification(t *testing.T) { rName := acctest.RandString(10) @@ -1326,6 +1353,50 @@ resource "aws_spot_fleet_request" "test" { `, validUntil) } +func testAccAWSSpotFleetRequestLaunchTemplateMultipleConfig(rName string, rInt int, validUntil string) string { + return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + fmt.Sprintf(` +resource "aws_launch_template" "test1" { + name = "%[2]s-1" + image_id = "ami-516b9131" + instance_type = "m1.small" + key_name = "${aws_key_pair.debugging.key_name}" +} + +resource "aws_launch_template" "test2" { + name = "%[2]s-2" + image_id = "ami-516b9131" + instance_type = "t3.small" + key_name = "${aws_key_pair.debugging.key_name}" +} + +resource "aws_spot_fleet_request" "test" { + iam_fleet_role = "${aws_iam_role.test-role.arn}" + spot_price = "0.005" + target_capacity = 2 + valid_until = %[1]q + terminate_instances_with_expiration = true + instance_interruption_behaviour = "stop" + wait_for_fulfillment = true + + launch_template_config { + launch_template_specification { + name = "${aws_launch_template.test1.name}" + version = "${aws_launch_template.test1.latest_version}" + } + } + + launch_template_config { + launch_template_specification { + name = "${aws_launch_template.test2.name}" + version = "${aws_launch_template.test2.latest_version}" + } + } + + depends_on = ["aws_iam_policy_attachment.test-attach"] +} +`, validUntil, rName) +} + func testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName string) string { return fmt.Sprintf(` resource "aws_iam_role" "test-role" { From 24cc585d3825cbdca355100504302b911be1e8f8 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 15:10:11 +0300 Subject: [PATCH 44/67] typo in doc --- website/docs/r/spot_fleet_request.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/spot_fleet_request.html.markdown b/website/docs/r/spot_fleet_request.html.markdown index aebda29db767..3b16021896a2 100644 --- a/website/docs/r/spot_fleet_request.html.markdown +++ b/website/docs/r/spot_fleet_request.html.markdown @@ -209,7 +209,7 @@ across different markets and instance types. Conflicts with `launch_template_con The `launch_template_config` block supports the following: * `launch_template_specification` - (Required) Launch template specification. See [Launch Template Specification](#launch-template-specification) below for more details. -* `overrides` - (Optional) One or more overide configurations. See [Overrides](#overrides) below for more details. +* `overrides` - (Optional) One or more override configurations. See [Overrides](#overrides) below for more details. ### Launch Template Specification From 75f648fbb34ab188861060c84eecd4e21b957c83 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 15:12:47 +0300 Subject: [PATCH 45/67] remove comment --- website/docs/r/spot_fleet_request.html.markdown | 2 -- 1 file changed, 2 deletions(-) diff --git a/website/docs/r/spot_fleet_request.html.markdown b/website/docs/r/spot_fleet_request.html.markdown index 3b16021896a2..553beb5a3733 100644 --- a/website/docs/r/spot_fleet_request.html.markdown +++ b/website/docs/r/spot_fleet_request.html.markdown @@ -230,8 +230,6 @@ The `launch_template_config` block supports the following: * `subnet_id` - (Optional) The subnet in which to launch the requested instance. * `weighted_capacity` - (Optional) The capacity added to the fleet by a fulfilled request. - **Note:** Instead of statically defining these override blocks they can be passed in as a list of maps containing the above keys and their values. This allows dynamic, programmatic generation of overrides based on variable or environment data. - ### Timeouts The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: From eed405f1882f684b46ea2fd318170bd31ed911c3 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 15:19:15 +0300 Subject: [PATCH 46/67] add multi config test --- aws/resource_aws_spot_fleet_request.go | 7 ------- aws/resource_aws_spot_fleet_request_test.go | 12 ++++++++---- aws/structure.go | 6 +++--- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 8c0d3365ffc5..cd5acea7f0b3 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -330,21 +330,18 @@ func resourceAwsSpotFleetRequest() *schema.Resource { "id": { Type: schema.TypeString, Optional: true, - Computed: true, ForceNew: true, ValidateFunc: validateLaunchTemplateId, }, "name": { Type: schema.TypeString, Optional: true, - Computed: true, ForceNew: true, ValidateFunc: validateLaunchTemplateName, }, "version": { Type: schema.TypeString, Optional: true, - Computed: true, ForceNew: true, ValidateFunc: validation.StringLenBetween(1, 255), }, @@ -848,10 +845,6 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) _, launchSpecificationOk := d.GetOk("launch_specification") _, launchTemplateConfigsOk := d.GetOk("launch_template_config") - if !launchSpecificationOk && !launchTemplateConfigsOk { - return fmt.Errorf("One of `launch_specification` or `launch_template` must be set for a fleet request") - } - // http://docs.aws.amazon.com/sdk-for-go/api/service/ec2.html#type-SpotFleetRequestConfigData spotFleetConfig := &ec2.SpotFleetRequestConfigData{ IamFleetRole: aws.String(d.Get("iam_fleet_role").(string)), diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 44ce69e072c6..fe4029f3ff24 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -194,8 +194,12 @@ func TestAccAWSSpotFleetRequest_launchTemplate_multiple(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), resource.TestCheckResourceAttr(resourceName, "launch_template_config.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.overrides.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.1500071693.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.1500071693.launch_template_specification.0.name", fmt.Sprintf("%s-1", rName)), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.1500071693.overrides.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.4234226785.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.4234226785.launch_template_specification.0.name", fmt.Sprintf("%s-2", rName)), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.4234226785.overrides.#", "0"), ), }, }, @@ -1356,14 +1360,14 @@ resource "aws_spot_fleet_request" "test" { func testAccAWSSpotFleetRequestLaunchTemplateMultipleConfig(rName string, rInt int, validUntil string) string { return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + fmt.Sprintf(` resource "aws_launch_template" "test1" { - name = "%[2]s-1" + name = "tf-acc-test-1" image_id = "ami-516b9131" instance_type = "m1.small" key_name = "${aws_key_pair.debugging.key_name}" } resource "aws_launch_template" "test2" { - name = "%[2]s-2" + name = "tf-acc-test-2" image_id = "ami-516b9131" instance_type = "t3.small" key_name = "${aws_key_pair.debugging.key_name}" diff --git a/aws/structure.go b/aws/structure.go index c95d9b95eb44..336c8bab24e0 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -4690,16 +4690,16 @@ func flattenFleetLaunchTemplateSpecification(flt *ec2.FleetLaunchTemplateSpecifi // unlike autoscaling.LaunchTemplateConfiguration, FleetLaunchTemplateSpecs only return what was set if flt.LaunchTemplateId != nil { - attrs["id"] = *flt.LaunchTemplateId + attrs["id"] = aws.StringValue(flt.LaunchTemplateId) } if flt.LaunchTemplateName != nil { - attrs["name"] = *flt.LaunchTemplateName + attrs["name"] = aws.StringValue(flt.LaunchTemplateName) } // version is returned only if it was previously set if flt.Version != nil { - attrs["version"] = *flt.Version + attrs["version"] = aws.StringValue(flt.Version) } else { attrs["version"] = nil } From ba21702ad5ed3bbfdd168e60696553dc721130e6 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 15:26:12 +0300 Subject: [PATCH 47/67] fix multi test --- aws/resource_aws_spot_fleet_request_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index fe4029f3ff24..c9781eda18aa 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -194,12 +194,12 @@ func TestAccAWSSpotFleetRequest_launchTemplate_multiple(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), resource.TestCheckResourceAttr(resourceName, "launch_template_config.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.1500071693.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.1500071693.launch_template_specification.0.name", fmt.Sprintf("%s-1", rName)), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.1500071693.overrides.#", "0"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.4234226785.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.4234226785.launch_template_specification.0.name", fmt.Sprintf("%s-2", rName)), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.4234226785.overrides.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.2826857687.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.2826857687.launch_template_specification.0.name", "tf-acc-test-1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.2826857687.overrides.#", "0"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.225839035.launch_template_specification.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.225839035.launch_template_specification.0.name", "tf-acc-test-2"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.225839035.overrides.#", "0"), ), }, }, @@ -1398,7 +1398,7 @@ resource "aws_spot_fleet_request" "test" { depends_on = ["aws_iam_policy_attachment.test-attach"] } -`, validUntil, rName) +`, validUntil) } func testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName string) string { From 9c42827862e4a09e4a7fb1c4c5800f9b878e731a Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 16:02:41 +0300 Subject: [PATCH 48/67] fix multi test --- aws/resource_aws_spot_fleet_request_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index c9781eda18aa..4a72192bb5bd 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -193,7 +193,7 @@ func TestAccAWSSpotFleetRequest_launchTemplate_multiple(t *testing.T) { testAccCheckAWSSpotFleetRequestExists(resourceName, &sfr), resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "launch_template_config.#", "2"), resource.TestCheckResourceAttr(resourceName, "launch_template_config.2826857687.launch_template_specification.#", "1"), resource.TestCheckResourceAttr(resourceName, "launch_template_config.2826857687.launch_template_specification.0.name", "tf-acc-test-1"), resource.TestCheckResourceAttr(resourceName, "launch_template_config.2826857687.overrides.#", "0"), From 52aa1ce042028871df821170abee4f23504f811a Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 17:27:19 +0300 Subject: [PATCH 49/67] remove hardcoded ami + instance types remove hash checks --- aws/resource_aws_spot_fleet_request_test.go | 138 +++++++++++--------- 1 file changed, 76 insertions(+), 62 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 4a72192bb5bd..10032fb18301 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -167,8 +167,6 @@ func TestAccAWSSpotFleetRequest_launchTemplate(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), resource.TestCheckResourceAttr(resourceName, "launch_template_config.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.overrides.#", "0"), ), }, }, @@ -194,12 +192,6 @@ func TestAccAWSSpotFleetRequest_launchTemplate_multiple(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), resource.TestCheckResourceAttr(resourceName, "launch_template_config.#", "2"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.2826857687.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.2826857687.launch_template_specification.0.name", "tf-acc-test-1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.2826857687.overrides.#", "0"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.225839035.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.225839035.launch_template_specification.0.name", "tf-acc-test-2"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.225839035.overrides.#", "0"), ), }, }, @@ -241,14 +233,6 @@ func TestAccAWSSpotFleetRequest_launchTemplateWithOverrides(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), resource.TestCheckResourceAttr(resourceName, "launch_template_config.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.overrides.#", "2"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.overrides.#", "2"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.overrides.1951041615.instance_type", "t1.micro"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.overrides.1951041615.weighted_capacity", "2"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.overrides.1866154075.instance_type", "m3.medium"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.overrides.1866154075.priority", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.2247196053.overrides.1866154075.spot_price", "0.26"), ), }, }, @@ -274,8 +258,6 @@ func TestAccAWSSpotFleetRequest_launchTemplateToLaunchSpec(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), resource.TestCheckResourceAttr(resourceName, "launch_template_config.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.overrides.#", "0"), ), }, { @@ -320,8 +302,6 @@ func TestAccAWSSpotFleetRequest_launchSpecToLaunchTemplate(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "launch_specification.#", "0"), resource.TestCheckResourceAttr(resourceName, "launch_template_config.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.launch_template_specification.#", "1"), - resource.TestCheckResourceAttr(resourceName, "launch_template_config.795271135.overrides.#", "0"), testAccCheckAWSSpotFleetRequestConfigRecreated(t, &before, &after), ), }, @@ -1327,12 +1307,42 @@ resource "aws_spot_fleet_request" "test" { `, validUntil) } +func testAccAWSSpotFleetRequestLaunchTemplateConfigBase() string { + return fmt.Sprintf(` +data "aws_ami" "amzn-ami-minimal-hvm-ebs" { + most_recent = true + owners = ["amazon"] + + filter { + name = "name" + values = ["amzn-ami-minimal-hvm-*"] + } + + filter { + name = "root-device-type" + values = ["ebs"] + } +} + +data "aws_ec2_instance_type_offering" "available" { + filter { + name = "instance-type" + values = ["t3.micro", "t2.micro"] + } + + preferred_instance_types = ["t3.micro", "t2.micro"] +} +`) +} + func testAccAWSSpotFleetRequestLaunchTemplateConfig(rName string, rInt int, validUntil string) string { - return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + fmt.Sprintf(` + return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + + testAccAWSSpotFleetRequestLaunchTemplateConfigBase() + + fmt.Sprintf(` resource "aws_launch_template" "test" { - name = "tf-acc-test-launch-template" - image_id = "ami-516b9131" - instance_type = "m1.small" + name = %[2]q + image_id = "${data.aws_ami.amzn-ami-minimal-hvm-ebs.id}" + instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" key_name = "${aws_key_pair.debugging.key_name}" } @@ -1354,22 +1364,24 @@ resource "aws_spot_fleet_request" "test" { depends_on = ["aws_iam_policy_attachment.test-attach"] } -`, validUntil) +`, validUntil, rName) } func testAccAWSSpotFleetRequestLaunchTemplateMultipleConfig(rName string, rInt int, validUntil string) string { - return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + fmt.Sprintf(` + return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + + testAccAWSSpotFleetRequestLaunchTemplateConfigBase() + + fmt.Sprintf(` resource "aws_launch_template" "test1" { - name = "tf-acc-test-1" - image_id = "ami-516b9131" - instance_type = "m1.small" + name = "%[2]s-1" + image_id = "${data.aws_ami.amzn-ami-minimal-hvm-ebs.id}" + instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" key_name = "${aws_key_pair.debugging.key_name}" } resource "aws_launch_template" "test2" { - name = "tf-acc-test-2" - image_id = "ami-516b9131" - instance_type = "t3.small" + name = "%[2]s-2" + image_id = "${data.aws_ami.amzn-ami-minimal-hvm-ebs.id}" + instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" key_name = "${aws_key_pair.debugging.key_name}" } @@ -1398,11 +1410,11 @@ resource "aws_spot_fleet_request" "test" { depends_on = ["aws_iam_policy_attachment.test-attach"] } -`, validUntil) +`, validUntil, rName) } func testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName string) string { - return fmt.Sprintf(` + return testAccAWSSpotFleetRequestLaunchTemplateConfigBase() + fmt.Sprintf(` resource "aws_iam_role" "test-role" { name = "test-role-%[1]s" assume_role_policy = < Date: Fri, 24 Apr 2020 17:32:56 +0300 Subject: [PATCH 50/67] remove extraneous error var --- aws/resource_aws_spot_fleet_request.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index cd5acea7f0b3..8d6f92b4c579 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -857,8 +857,6 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) TagSpecifications: ec2TagSpecificationsFromMap(d.Get("tags").(map[string]interface{}), ec2.ResourceTypeSpotFleetRequest), } - var err error - if launchSpecificationOk { launchSpecs, err := buildAwsSpotFleetLaunchSpecifications(d, meta) if err != nil { @@ -953,8 +951,8 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) // Since IAM is eventually consistent, we retry creation as a newly created role may not // take effect immediately, resulting in an InvalidSpotFleetRequestConfig error var resp *ec2.RequestSpotFleetOutput - err = resource.Retry(10*time.Minute, func() *resource.RetryError { - resp, err = conn.RequestSpotFleet(spotFleetOpts) + err := resource.Retry(10*time.Minute, func() *resource.RetryError { + _, err := conn.RequestSpotFleet(spotFleetOpts) if isAWSErr(err, "InvalidSpotFleetRequestConfig", "") { return resource.RetryableError(fmt.Errorf("Error creating Spot fleet request, retrying: %s", err)) From d81c17734bf561fadd77a98468d8faaf2790aad8 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 17:41:51 +0300 Subject: [PATCH 51/67] replace ConflictsWith + AtLeastOneOf with ExactlyOneOf --- aws/resource_aws_spot_fleet_request.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 8d6f92b4c579..68d038bdb896 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -53,10 +53,9 @@ func resourceAwsSpotFleetRequest() *schema.Resource { // http://docs.aws.amazon.com/sdk-for-go/api/service/ec2.html#type-SpotFleetLaunchSpecification // http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_SpotFleetLaunchSpecification.html "launch_specification": { - Type: schema.TypeSet, - Optional: true, - ConflictsWith: []string{"launch_template_config"}, - ForceNew: true, + Type: schema.TypeSet, + Optional: true, + ForceNew: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "vpc_security_group_ids": { @@ -311,14 +310,13 @@ func resourceAwsSpotFleetRequest() *schema.Resource { }, }, Set: hashLaunchSpecification, - AtLeastOneOf: []string{"launch_specification", "launch_template_config"}, + ExactlyOneOf: []string{"launch_specification", "launch_template_config"}, }, "launch_template_config": { - Type: schema.TypeSet, - Optional: true, - ForceNew: true, - ConflictsWith: []string{"launch_specification"}, - AtLeastOneOf: []string{"launch_specification", "launch_template_config"}, + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + ExactlyOneOf: []string{"launch_specification", "launch_template_config"}, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "launch_template_specification": { From c938898f85642c7b051cb9fe86ab48fbabe72a0a Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 17:58:17 +0300 Subject: [PATCH 52/67] flatten `launch_template_config` --- aws/resource_aws_spot_fleet_request.go | 69 +++++++++++++++++++++----- aws/structure.go | 25 ---------- 2 files changed, 56 insertions(+), 38 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 68d038bdb896..8cd3dc5fbab6 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -1192,24 +1192,13 @@ func resourceAwsSpotFleetRequestRead(d *schema.ResourceData, meta interface{}) e return fmt.Errorf("error setting tags: %s", err) } - if len(config.LaunchTemplateConfigs) > 0 { - d.Set("launch_template_config.0.launch_template_specification.0", flattenFleetLaunchTemplateSpecification(config.LaunchTemplateConfigs[0].LaunchTemplateSpecification)) - d.Set("launch_template_config.0.overrides", setLaunchTemplateOverrides(config.LaunchTemplateConfigs[0].Overrides)) - } else { - d.Set("launch_template_config.0.launch_template_specification.0", nil) + if err := d.Set("launch_template_config", flattenFleetLaunchTemplateConfig(config.LaunchTemplateConfigs)); err != nil { + return fmt.Errorf("error setting tags: %s", err) } return nil } -func setLaunchTemplateOverrides(overrides []*ec2.LaunchTemplateOverrides) *schema.Set { - overrideSet := &schema.Set{F: hashLaunchTemplateOverrides} - for _, override := range overrides { - overrideSet.Add(flattenSpotFleetRequestLaunchTemplateOverrides(override)) - } - return overrideSet -} - func flattenSpotFleetRequestLaunchTemplateOverrides(override *ec2.LaunchTemplateOverrides) map[string]interface{} { m := make(map[string]interface{}) @@ -1627,3 +1616,57 @@ func hashEbsBlockDevice(v interface{}) int { } return hashcode.String(buf.String()) } + +func flattenFleetLaunchTemplateConfig(ltcs []*ec2.LaunchTemplateConfig) []map[string]interface{} { + attrs := map[string]interface{}{} + result := make([]map[string]interface{}, 0) + + for _, ltc := range ltcs { + ltcRes := map[string]interface{}{} + + if ltc.LaunchTemplateSpecification != nil { + ltcRes["launch_template_specification"] = flattenFleetLaunchTemplateSpecification(ltc.LaunchTemplateSpecification) + } + + if ltc.Overrides != nil { + ltcRes["overrides"] = flattenLaunchTemplateOverrides(ltc.Overrides) + } + } + + result = append(result, attrs) + + return result +} + +func flattenFleetLaunchTemplateSpecification(flt *ec2.FleetLaunchTemplateSpecification) []map[string]interface{} { + attrs := map[string]interface{}{} + result := make([]map[string]interface{}, 0) + + // unlike autoscaling.LaunchTemplateConfiguration, FleetLaunchTemplateSpecs only return what was set + if flt.LaunchTemplateId != nil { + attrs["id"] = aws.StringValue(flt.LaunchTemplateId) + } + + if flt.LaunchTemplateName != nil { + attrs["name"] = aws.StringValue(flt.LaunchTemplateName) + } + + // version is returned only if it was previously set + if flt.Version != nil { + attrs["version"] = aws.StringValue(flt.Version) + } else { + attrs["version"] = nil + } + + result = append(result, attrs) + + return result +} + +func flattenLaunchTemplateOverrides(overrides []*ec2.LaunchTemplateOverrides) *schema.Set { + overrideSet := &schema.Set{F: hashLaunchTemplateOverrides} + for _, override := range overrides { + overrideSet.Add(flattenSpotFleetRequestLaunchTemplateOverrides(override)) + } + return overrideSet +} diff --git a/aws/structure.go b/aws/structure.go index 336c8bab24e0..6a733e9fbb2d 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -4684,31 +4684,6 @@ func flattenLaunchTemplateSpecification(lt *autoscaling.LaunchTemplateSpecificat return result } -func flattenFleetLaunchTemplateSpecification(flt *ec2.FleetLaunchTemplateSpecification) []map[string]interface{} { - attrs := map[string]interface{}{} - result := make([]map[string]interface{}, 0) - - // unlike autoscaling.LaunchTemplateConfiguration, FleetLaunchTemplateSpecs only return what was set - if flt.LaunchTemplateId != nil { - attrs["id"] = aws.StringValue(flt.LaunchTemplateId) - } - - if flt.LaunchTemplateName != nil { - attrs["name"] = aws.StringValue(flt.LaunchTemplateName) - } - - // version is returned only if it was previously set - if flt.Version != nil { - attrs["version"] = aws.StringValue(flt.Version) - } else { - attrs["version"] = nil - } - - result = append(result, attrs) - - return result -} - func flattenVpcPeeringConnectionOptions(options *ec2.VpcPeeringConnectionOptionsDescription) []interface{} { // When the VPC Peering Connection is pending acceptance, // the details about accepter and/or requester peering From d727686cb3161cf2926bd652adc70eab1a53f709 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 18:00:08 +0300 Subject: [PATCH 53/67] fix error --- aws/resource_aws_spot_fleet_request.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 8cd3dc5fbab6..58378f12bc86 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -950,7 +950,8 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) // take effect immediately, resulting in an InvalidSpotFleetRequestConfig error var resp *ec2.RequestSpotFleetOutput err := resource.Retry(10*time.Minute, func() *resource.RetryError { - _, err := conn.RequestSpotFleet(spotFleetOpts) + var err error + resp, err = conn.RequestSpotFleet(spotFleetOpts) if isAWSErr(err, "InvalidSpotFleetRequestConfig", "") { return resource.RetryableError(fmt.Errorf("Error creating Spot fleet request, retrying: %s", err)) From 8ad1fcd883638039db0eaaafc3a0b6677e80e378 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 18:24:42 +0300 Subject: [PATCH 54/67] fix flattening launch template config --- aws/resource_aws_spot_fleet_request.go | 11 ++++++----- aws/resource_aws_spot_fleet_request_test.go | 8 ++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 58378f12bc86..ebc15e18d736 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -1193,8 +1193,10 @@ func resourceAwsSpotFleetRequestRead(d *schema.ResourceData, meta interface{}) e return fmt.Errorf("error setting tags: %s", err) } - if err := d.Set("launch_template_config", flattenFleetLaunchTemplateConfig(config.LaunchTemplateConfigs)); err != nil { - return fmt.Errorf("error setting tags: %s", err) + if len(config.LaunchTemplateConfigs) > 0 { + if err := d.Set("launch_template_config", flattenFleetLaunchTemplateConfig(config.LaunchTemplateConfigs)); err != nil { + return fmt.Errorf("error setting tags: %s", err) + } } return nil @@ -1619,7 +1621,6 @@ func hashEbsBlockDevice(v interface{}) int { } func flattenFleetLaunchTemplateConfig(ltcs []*ec2.LaunchTemplateConfig) []map[string]interface{} { - attrs := map[string]interface{}{} result := make([]map[string]interface{}, 0) for _, ltc := range ltcs { @@ -1632,9 +1633,9 @@ func flattenFleetLaunchTemplateConfig(ltcs []*ec2.LaunchTemplateConfig) []map[st if ltc.Overrides != nil { ltcRes["overrides"] = flattenLaunchTemplateOverrides(ltc.Overrides) } - } - result = append(result, attrs) + result = append(result, ltcRes) + } return result } diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 10032fb18301..3a7a5f24094d 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -1454,11 +1454,11 @@ resource "aws_spot_fleet_request" "test" { version = "${aws_launch_template.test.latest_version}" } overrides { - instance_type = "t1.micro" + instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" weighted_capacity = "2" } overrides { - instance_type = "m3.medium" + instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" spot_price = "0.26" } } @@ -1498,12 +1498,12 @@ resource "aws_spot_fleet_request" "test" { } overrides { - instance_type = "t1.micro" + instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" weighted_capacity = "2" } overrides { - instance_type = "m3.medium" + instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" priority = 1 spot_price = "0.26" } From cbb1a1d4134a5fef7a69516702e5c74ed8eb6448 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 18:50:26 +0300 Subject: [PATCH 55/67] cant have duplicate in override --- aws/resource_aws_spot_fleet_request_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 3a7a5f24094d..10032fb18301 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -1454,11 +1454,11 @@ resource "aws_spot_fleet_request" "test" { version = "${aws_launch_template.test.latest_version}" } overrides { - instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" + instance_type = "t1.micro" weighted_capacity = "2" } overrides { - instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" + instance_type = "m3.medium" spot_price = "0.26" } } @@ -1498,12 +1498,12 @@ resource "aws_spot_fleet_request" "test" { } overrides { - instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" + instance_type = "t1.micro" weighted_capacity = "2" } overrides { - instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" + instance_type = "m3.medium" priority = 1 spot_price = "0.26" } From 061ff7e7e27342b96c5e01f9186bbf50a259633c Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 18:56:22 +0300 Subject: [PATCH 56/67] dont retry for Duplicate: Parameter combination exception --- aws/resource_aws_spot_fleet_request.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index ebc15e18d736..0b3609261c0c 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -953,6 +953,9 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) var err error resp, err = conn.RequestSpotFleet(spotFleetOpts) + if isAWSErr(err, "InvalidSpotFleetRequestConfig", "Duplicate: Parameter combination") { + return resource.RetryableError(fmt.Errorf("Error creating Spot fleet request: %s", err)) + } if isAWSErr(err, "InvalidSpotFleetRequestConfig", "") { return resource.RetryableError(fmt.Errorf("Error creating Spot fleet request, retrying: %s", err)) } From b1e25cc0a9753c20072d1f133469d5b380b60fa6 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 19:30:19 +0300 Subject: [PATCH 57/67] changes --- aws/resource_aws_spot_fleet_request_test.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 10032fb18301..e92ce21c91ee 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -208,7 +208,7 @@ func TestAccAWSSpotFleetRequest_launchTemplateConflictLaunchSpecification(t *tes Steps: []resource.TestStep{ { Config: testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName), - ExpectError: regexp.MustCompile(`"launch_specification": conflicts with launch_template_config`), + ExpectError: regexp.MustCompile(`"launch_specification": only one of .+`), }, }, }) @@ -1371,6 +1371,15 @@ func testAccAWSSpotFleetRequestLaunchTemplateMultipleConfig(rName string, rInt i return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + testAccAWSSpotFleetRequestLaunchTemplateConfigBase() + fmt.Sprintf(` +data "aws_ec2_instance_type_offering" "test" { + filter { + name = "instance-type" + values = ["t1.micro"] + } + + preferred_instance_types = ["t1.micro"] +} + resource "aws_launch_template" "test1" { name = "%[2]s-1" image_id = "${data.aws_ami.amzn-ami-minimal-hvm-ebs.id}" @@ -1381,7 +1390,7 @@ resource "aws_launch_template" "test1" { resource "aws_launch_template" "test2" { name = "%[2]s-2" image_id = "${data.aws_ami.amzn-ami-minimal-hvm-ebs.id}" - instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" + instance_type = "${data.aws_ec2_instance_type_offering.available.test}" key_name = "${aws_key_pair.debugging.key_name}" } From b6e31cfac85a200ae5b8de494d538a55ec2f4976 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 19:40:44 +0300 Subject: [PATCH 58/67] change from RetryableError to NonRetryableError for duplicate exception --- aws/resource_aws_spot_fleet_request.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 0b3609261c0c..2484fde5deb5 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -954,7 +954,7 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) resp, err = conn.RequestSpotFleet(spotFleetOpts) if isAWSErr(err, "InvalidSpotFleetRequestConfig", "Duplicate: Parameter combination") { - return resource.RetryableError(fmt.Errorf("Error creating Spot fleet request: %s", err)) + return resource.NonRetryableError(fmt.Errorf("Error creating Spot fleet request: %s", err)) } if isAWSErr(err, "InvalidSpotFleetRequestConfig", "") { return resource.RetryableError(fmt.Errorf("Error creating Spot fleet request, retrying: %s", err)) From af6885dc823423892f6dce61fd3b427b62c5660b Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 20:32:12 +0300 Subject: [PATCH 59/67] fix multi test --- aws/resource_aws_spot_fleet_request_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index e92ce21c91ee..732299b62130 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -1390,7 +1390,7 @@ resource "aws_launch_template" "test1" { resource "aws_launch_template" "test2" { name = "%[2]s-2" image_id = "${data.aws_ami.amzn-ami-minimal-hvm-ebs.id}" - instance_type = "${data.aws_ec2_instance_type_offering.available.test}" + instance_type = "${data.aws_ec2_instance_type_offering.test.instance_type}" key_name = "${aws_key_pair.debugging.key_name}" } From e19d346ddf8d97766ad7acd69f37b27a90030820 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Fri, 24 Apr 2020 20:49:32 +0300 Subject: [PATCH 60/67] format --- aws/resource_aws_spot_fleet_request.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index 2484fde5deb5..fe763107da08 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -744,12 +744,12 @@ func readSpotFleetBlockDeviceMappingsFromConfig( func buildAwsSpotFleetLaunchSpecifications( d *schema.ResourceData, meta interface{}) ([]*ec2.SpotFleetLaunchSpecification, error) { - user_specs := d.Get("launch_specification").(*schema.Set).List() - specs := make([]*ec2.SpotFleetLaunchSpecification, len(user_specs)) - for i, user_spec := range user_specs { - user_spec_map := user_spec.(map[string]interface{}) + userSpecs := d.Get("launch_specification").(*schema.Set).List() + specs := make([]*ec2.SpotFleetLaunchSpecification, len(userSpecs)) + for i, userSpec := range userSpecs { + userSpecMap := userSpec.(map[string]interface{}) // panic: interface conversion: interface {} is map[string]interface {}, not *schema.ResourceData - opts, err := buildSpotFleetLaunchSpecification(user_spec_map, meta) + opts, err := buildSpotFleetLaunchSpecification(userSpecMap, meta) if err != nil { return nil, err } @@ -898,11 +898,11 @@ func resourceAwsSpotFleetRequestCreate(d *schema.ResourceData, meta interface{}) } if v, ok := d.GetOk("valid_until"); ok { - valid_until, err := time.Parse(time.RFC3339, v.(string)) + validUntil, err := time.Parse(time.RFC3339, v.(string)) if err != nil { return err } - spotFleetConfig.ValidUntil = aws.Time(valid_until) + spotFleetConfig.ValidUntil = aws.Time(validUntil) } else { validUntil := time.Now().Add(24 * time.Hour) spotFleetConfig.ValidUntil = aws.Time(validUntil) From 1396b55a0d900e1c2b83a6a1f51bdae1509acc64 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Sun, 26 Apr 2020 11:05:10 +0300 Subject: [PATCH 61/67] add tags + reuse --- aws/resource_aws_spot_fleet_request_test.go | 147 ++++++++------------ 1 file changed, 56 insertions(+), 91 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 732299b62130..d6aea21aca67 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -200,6 +200,7 @@ func TestAccAWSSpotFleetRequest_launchTemplate_multiple(t *testing.T) { func TestAccAWSSpotFleetRequest_launchTemplateConflictLaunchSpecification(t *testing.T) { rName := acctest.RandString(10) + rInt := acctest.RandInt() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -207,7 +208,7 @@ func TestAccAWSSpotFleetRequest_launchTemplateConflictLaunchSpecification(t *tes CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName), + Config: testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName, rInt), ExpectError: regexp.MustCompile(`"launch_specification": only one of .+`), }, }, @@ -1132,7 +1133,7 @@ func testAccPreCheckAWSEc2SpotFleetRequest(t *testing.T) { } func testAccAWSSpotFleetRequestConfigBase(rName string, rInt int) string { - return fmt.Sprintf(` + return testAccLatestAmazonLinuxHvmEbsAmiConfig() + fmt.Sprintf(` data "aws_availability_zones" "available" { state = "available" @@ -1141,9 +1142,13 @@ data "aws_availability_zones" "available" { values = ["opt-in-not-required"] } } -resource "aws_key_pair" "debugging" { +resource "aws_key_pair" "test" { key_name = "tmp-key-%[1]s" public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com" + + tags = { + Name = %[1]q + } } resource "aws_iam_role" "test-role" { @@ -1167,6 +1172,10 @@ resource "aws_iam_role" "test-role" { ] } EOF + + tags = { + Name = %[1]q + } } resource "aws_iam_policy" "test-policy" { @@ -1198,6 +1207,15 @@ resource "aws_iam_policy_attachment" "test-attach" { roles = ["${aws_iam_role.test-role.name}"] policy_arn = "${aws_iam_policy.test-policy.arn}" } + +data "aws_ec2_instance_type_offering" "available" { + filter { + name = "instance-type" + values = ["t3.micro", "t2.micro"] + } + + preferred_instance_types = ["t3.micro", "t2.micro"] +} `, rName, rInt) } @@ -1214,7 +1232,7 @@ resource "aws_spot_fleet_request" "test" { launch_specification { instance_type = "m1.small" ami = "ami-516b9131" - key_name = "${aws_key_pair.debugging.key_name}" + key_name = "${aws_key_pair.test.key_name}" } depends_on = ["aws_iam_policy_attachment.test-attach"] } @@ -1234,7 +1252,7 @@ resource "aws_spot_fleet_request" "test" { launch_specification { instance_type = "m1.small" ami = "ami-516b9131" - key_name = "${aws_key_pair.debugging.key_name}" + key_name = "${aws_key_pair.test.key_name}" } tags = { %[2]q = %[3]q @@ -1257,7 +1275,7 @@ resource "aws_spot_fleet_request" "test" { launch_specification { instance_type = "m1.small" ami = "ami-516b9131" - key_name = "${aws_key_pair.debugging.key_name}" + key_name = "${aws_key_pair.test.key_name}" } tags = { %[2]q = %[3]q @@ -1280,7 +1298,7 @@ resource "aws_spot_fleet_request" "test" { launch_specification { instance_type = "m1.small" ami = "ami-516b9131" - key_name = "${aws_key_pair.debugging.key_name}" + key_name = "${aws_key_pair.test.key_name}" associate_public_ip_address = true } depends_on = ["aws_iam_policy_attachment.test-attach"] @@ -1307,43 +1325,14 @@ resource "aws_spot_fleet_request" "test" { `, validUntil) } -func testAccAWSSpotFleetRequestLaunchTemplateConfigBase() string { - return fmt.Sprintf(` -data "aws_ami" "amzn-ami-minimal-hvm-ebs" { - most_recent = true - owners = ["amazon"] - - filter { - name = "name" - values = ["amzn-ami-minimal-hvm-*"] - } - - filter { - name = "root-device-type" - values = ["ebs"] - } -} - -data "aws_ec2_instance_type_offering" "available" { - filter { - name = "instance-type" - values = ["t3.micro", "t2.micro"] - } - - preferred_instance_types = ["t3.micro", "t2.micro"] -} -`) -} - func testAccAWSSpotFleetRequestLaunchTemplateConfig(rName string, rInt int, validUntil string) string { return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + - testAccAWSSpotFleetRequestLaunchTemplateConfigBase() + fmt.Sprintf(` resource "aws_launch_template" "test" { name = %[2]q image_id = "${data.aws_ami.amzn-ami-minimal-hvm-ebs.id}" instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" - key_name = "${aws_key_pair.debugging.key_name}" + key_name = "${aws_key_pair.test.key_name}" } resource "aws_spot_fleet_request" "test" { @@ -1369,7 +1358,6 @@ resource "aws_spot_fleet_request" "test" { func testAccAWSSpotFleetRequestLaunchTemplateMultipleConfig(rName string, rInt int, validUntil string) string { return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + - testAccAWSSpotFleetRequestLaunchTemplateConfigBase() + fmt.Sprintf(` data "aws_ec2_instance_type_offering" "test" { filter { @@ -1384,14 +1372,14 @@ resource "aws_launch_template" "test1" { name = "%[2]s-1" image_id = "${data.aws_ami.amzn-ami-minimal-hvm-ebs.id}" instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" - key_name = "${aws_key_pair.debugging.key_name}" + key_name = "${aws_key_pair.test.key_name}" } resource "aws_launch_template" "test2" { name = "%[2]s-2" image_id = "${data.aws_ami.amzn-ami-minimal-hvm-ebs.id}" instance_type = "${data.aws_ec2_instance_type_offering.test.instance_type}" - key_name = "${aws_key_pair.debugging.key_name}" + key_name = "${aws_key_pair.test.key_name}" } resource "aws_spot_fleet_request" "test" { @@ -1422,30 +1410,8 @@ resource "aws_spot_fleet_request" "test" { `, validUntil, rName) } -func testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName string) string { - return testAccAWSSpotFleetRequestLaunchTemplateConfigBase() + fmt.Sprintf(` -resource "aws_iam_role" "test-role" { - name = "test-role-%[1]s" - assume_role_policy = < Date: Sun, 26 Apr 2020 12:58:19 +0300 Subject: [PATCH 62/67] use rname --- aws/resource_aws_spot_fleet_request_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index d6aea21aca67..8451c99dda13 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -1179,7 +1179,7 @@ EOF } resource "aws_iam_policy" "test-policy" { - name = "test-policy-%[2]d" + name = %[1]q path = "/" description = "Spot Fleet Request ACCTest Policy" @@ -1203,7 +1203,7 @@ EOF } resource "aws_iam_policy_attachment" "test-attach" { - name = "test-attachment-%[2]d" + name = %[1]q roles = ["${aws_iam_role.test-role.name}"] policy_arn = "${aws_iam_policy.test-policy.arn}" } From 3a909722443cb371412b8f391b7ad9e13d5beab4 Mon Sep 17 00:00:00 2001 From: DrFaust92 Date: Sun, 26 Apr 2020 14:33:43 +0300 Subject: [PATCH 63/67] use rname --- aws/resource_aws_spot_fleet_request_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 8451c99dda13..f4487bb47cdc 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -1143,7 +1143,7 @@ data "aws_availability_zones" "available" { } } resource "aws_key_pair" "test" { - key_name = "tmp-key-%[1]s" + key_name = %[1]q public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3F6tyPEFEzV0LX3X8BsXdMsQz1x2cEikKDEY0aIj41qgxMCP/iteneqXSIFZBp5vizPvaoIR3Um9xK7PGoW8giupGn+EPuxIA4cDM4vzOqOkiMPhz5XK0whEjkVzTo4+S0puvDZuwIsdiW9mxhJc7tgBNL0cYlWSYVkz4G/fslNfRPW5mYAM49f4fhtxPb5ok4Q2Lg9dPKVHO/Bgeu5woMc7RY0p1ej6D4CKFE6lymSDJpW0YHX/wqE9+cfEauh7xZcG0q9t2ta6F6fmX0agvpFyZo8aFbXeUBr7osSCJNgvavWbM/06niWrOvYX2xwWdhXmXSrbX8ZbabVohBK41 phodgson@thoughtworks.com" tags = { @@ -1152,7 +1152,7 @@ resource "aws_key_pair" "test" { } resource "aws_iam_role" "test-role" { - name = "test-role-%[1]s" + name = %[1]q assume_role_policy = < Date: Sun, 26 Apr 2020 21:24:29 +0300 Subject: [PATCH 64/67] consolidate ami usage --- aws/resource_aws_spot_fleet_request_test.go | 42 +++++---------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index f4487bb47cdc..8d8293b83487 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -2055,23 +2055,12 @@ resource "aws_spot_fleet_request" "test" { func testAccAWSSpotFleetRequestLaunchSpecificationEbsBlockDeviceKmsKeyId(rName string, rInt int, validUntil string) string { return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + fmt.Sprintf(` -data "aws_ami" "amzn-ami-minimal-hvm-ebs" { - most_recent = true - owners = ["amazon"] - - filter { - name = "name" - values = ["amzn-ami-minimal-hvm-*"] - } - - filter { - name = "root-device-type" - values = ["ebs"] - } -} - resource "aws_kms_key" "test" { deletion_window_in_days = 7 + + tags = { + Name = %[2]q + } } resource "aws_spot_fleet_request" "test" { @@ -2103,28 +2092,17 @@ resource "aws_spot_fleet_request" "test" { depends_on = ["aws_iam_policy_attachment.test-attach"] } -`, validUntil) +`, validUntil, rName) } func testAccAWSSpotFleetRequestLaunchSpecificationRootBlockDeviceKmsKeyId(rName string, rInt int, validUntil string) string { return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + fmt.Sprintf(` -data "aws_ami" "amzn-ami-minimal-hvm-ebs" { - most_recent = true - owners = ["amazon"] - - filter { - name = "name" - values = ["amzn-ami-minimal-hvm-*"] - } - - filter { - name = "root-device-type" - values = ["ebs"] - } -} - resource "aws_kms_key" "test" { deletion_window_in_days = 7 + + tags = { + Name = %[2]q + } } resource "aws_spot_fleet_request" "test" { @@ -2149,7 +2127,7 @@ resource "aws_spot_fleet_request" "test" { depends_on = ["aws_iam_policy_attachment.test-attach"] } -`, validUntil) +`, validUntil, rName) } func testAccAWSSpotFleetRequestLaunchSpecificationWithInstanceStoreAmi(rName string, rInt int, validUntil string) string { From 4b3ea3121bdf66a48d2403826f95f737ca98d036 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Mon, 27 Apr 2020 23:11:15 -0400 Subject: [PATCH 65/67] resource/aws_spot_fleet_request: Fix minor typo in error message --- aws/resource_aws_spot_fleet_request.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_spot_fleet_request.go b/aws/resource_aws_spot_fleet_request.go index fe763107da08..110198d2ead7 100644 --- a/aws/resource_aws_spot_fleet_request.go +++ b/aws/resource_aws_spot_fleet_request.go @@ -1198,7 +1198,7 @@ func resourceAwsSpotFleetRequestRead(d *schema.ResourceData, meta interface{}) e if len(config.LaunchTemplateConfigs) > 0 { if err := d.Set("launch_template_config", flattenFleetLaunchTemplateConfig(config.LaunchTemplateConfigs)); err != nil { - return fmt.Errorf("error setting tags: %s", err) + return fmt.Errorf("error setting launch_template_config: %s", err) } } From 618cd5bac6a7f7a209c26a54ab6e468b1a324a68 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Tue, 28 Apr 2020 00:19:32 -0400 Subject: [PATCH 66/67] tests/resource/aws_spot_fleet_request: Remove failing TestAccAWSSpotFleetRequest_launchTemplateConflictLaunchSpecification --- aws/resource_aws_spot_fleet_request_test.go | 51 --------------------- 1 file changed, 51 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 8d8293b83487..1296962eab15 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -198,22 +198,6 @@ func TestAccAWSSpotFleetRequest_launchTemplate_multiple(t *testing.T) { }) } -func TestAccAWSSpotFleetRequest_launchTemplateConflictLaunchSpecification(t *testing.T) { - rName := acctest.RandString(10) - rInt := acctest.RandInt() - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckAWSSpotFleetRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName, rInt), - ExpectError: regexp.MustCompile(`"launch_specification": only one of .+`), - }, - }, - }) -} func TestAccAWSSpotFleetRequest_launchTemplateWithOverrides(t *testing.T) { var sfr ec2.SpotFleetRequestConfig @@ -1410,41 +1394,6 @@ resource "aws_spot_fleet_request" "test" { `, validUntil, rName) } -func testAccAWSSpotFleetRequestLaunchTemplateConflictLaunchSpecification(rName string, rInt int) string { - return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + fmt.Sprintf(` -resource "aws_launch_template" "test" { - name = %[1]q - image_id = "${data.aws_ami.amzn-ami-minimal-hvm-ebs.id}" - instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" -} - -resource "aws_spot_fleet_request" "test" { - iam_fleet_role = "${aws_iam_role.test-role.arn}" - spot_price = "0.005" - target_capacity = 2 - - launch_template_config { - launch_template_specification { - name = "${aws_launch_template.test.name}" - version = "${aws_launch_template.test.latest_version}" - } - overrides { - instance_type = "t1.micro" - weighted_capacity = "2" - } - overrides { - instance_type = "m3.medium" - spot_price = "0.26" - } - } - - launch_specification { - ami = "${data.aws_ami.amzn-ami-minimal-hvm-ebs.id}" - instance_type = "${data.aws_ec2_instance_type_offering.available.instance_type}" - } -} -`, rName) -} func testAccAWSSpotFleetRequestLaunchTemplateConfigWithOverrides(rName string, rInt int, validUntil string) string { return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + From d98d7d77628251043bf189c36697de110b65f0cd Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Tue, 28 Apr 2020 00:29:33 -0400 Subject: [PATCH 67/67] tests/resource/aws_spot_fleet_request: Remove extraneous newlines from GitHub suggested changes --- aws/resource_aws_spot_fleet_request_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/aws/resource_aws_spot_fleet_request_test.go b/aws/resource_aws_spot_fleet_request_test.go index 1296962eab15..8ab04a02c0fc 100644 --- a/aws/resource_aws_spot_fleet_request_test.go +++ b/aws/resource_aws_spot_fleet_request_test.go @@ -198,7 +198,6 @@ func TestAccAWSSpotFleetRequest_launchTemplate_multiple(t *testing.T) { }) } - func TestAccAWSSpotFleetRequest_launchTemplateWithOverrides(t *testing.T) { var sfr ec2.SpotFleetRequestConfig rName := acctest.RandString(10) @@ -1394,7 +1393,6 @@ resource "aws_spot_fleet_request" "test" { `, validUntil, rName) } - func testAccAWSSpotFleetRequestLaunchTemplateConfigWithOverrides(rName string, rInt int, validUntil string) string { return testAccAWSSpotFleetRequestConfigBase(rName, rInt) + fmt.Sprintf(`