From 26862f2a2ae5d37bb682c55cbad5c307ce7f7da9 Mon Sep 17 00:00:00 2001 From: andrew Date: Sat, 23 Nov 2019 18:24:02 -0600 Subject: [PATCH 01/15] Added Lightsail load balancer resource, fixed 'disapear' typo in lightsail resources. --- aws/provider.go | 1 + aws/resource_aws_lightsail_domain_test.go | 2 +- aws/resource_aws_lightsail_instance_test.go | 2 +- aws/resource_aws_lightsail_load_balancer.go | 236 +++++++++++++ ...source_aws_lightsail_load_balancer_test.go | 316 ++++++++++++++++++ aws/resource_aws_lightsail_static_ip_test.go | 2 +- website/aws.erb | 3 + .../r/lightsail_load_balancer.html.markdown | 52 +++ 8 files changed, 611 insertions(+), 3 deletions(-) create mode 100644 aws/resource_aws_lightsail_load_balancer.go create mode 100644 aws/resource_aws_lightsail_load_balancer_test.go create mode 100644 website/docs/r/lightsail_load_balancer.html.markdown diff --git a/aws/provider.go b/aws/provider.go index 72c1e9e3bff..c2e71419d29 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -611,6 +611,7 @@ func Provider() terraform.ResourceProvider { "aws_lightsail_domain": resourceAwsLightsailDomain(), "aws_lightsail_instance": resourceAwsLightsailInstance(), "aws_lightsail_key_pair": resourceAwsLightsailKeyPair(), + "aws_lightsail_load_balancer": resourceAwsLightsailLoadBalancer(), "aws_lightsail_static_ip": resourceAwsLightsailStaticIp(), "aws_lightsail_static_ip_attachment": resourceAwsLightsailStaticIpAttachment(), "aws_lb_cookie_stickiness_policy": resourceAwsLBCookieStickinessPolicy(), diff --git a/aws/resource_aws_lightsail_domain_test.go b/aws/resource_aws_lightsail_domain_test.go index 2f2c1b033c9..1eef8d025ad 100644 --- a/aws/resource_aws_lightsail_domain_test.go +++ b/aws/resource_aws_lightsail_domain_test.go @@ -44,7 +44,7 @@ func TestAccAWSLightsailDomain_disappears(t *testing.T) { }) if err != nil { - return fmt.Errorf("Error deleting Lightsail Domain in disapear test") + return fmt.Errorf("Error deleting Lightsail Domain in disappear test") } return nil diff --git a/aws/resource_aws_lightsail_instance_test.go b/aws/resource_aws_lightsail_instance_test.go index 5c4b9b687eb..3a9f3107a82 100644 --- a/aws/resource_aws_lightsail_instance_test.go +++ b/aws/resource_aws_lightsail_instance_test.go @@ -178,7 +178,7 @@ func TestAccAWSLightsailInstance_Tags(t *testing.T) { }) } -func TestAccAWSLightsailInstance_disapear(t *testing.T) { +func TestAccAWSLightsailInstance_disappear(t *testing.T) { var conf lightsail.Instance lightsailName := fmt.Sprintf("tf-test-lightsail-%d", acctest.RandInt()) diff --git a/aws/resource_aws_lightsail_load_balancer.go b/aws/resource_aws_lightsail_load_balancer.go new file mode 100644 index 00000000000..ea39410c5f6 --- /dev/null +++ b/aws/resource_aws_lightsail_load_balancer.go @@ -0,0 +1,236 @@ +package aws + +import ( + "fmt" + "log" + "regexp" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/lightsail" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" +) + +func resourceAwsLightsailLoadBalancer() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsLightsailLoadBalancerCreate, + Read: resourceAwsLightsailLoadBalancerRead, + Update: resourceAwsLightsailLoadBalancerUpdate, + Delete: resourceAwsLightsailLoadBalancerDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.All( + validation.StringLenBetween(2, 255), + validation.StringMatch(regexp.MustCompile(`^[a-zA-Z]`), "must begin with an alphabetic character"), + validation.StringMatch(regexp.MustCompile(`^[a-zA-Z0-9_\-.]+[^._\-]$`), "must contain only alphanumeric characters, underscores, hyphens, and dots"), + ), + }, + "health_check_path": { + Type: schema.TypeString, + Optional: true, + Default: "/", + }, + "instance_port": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + ValidateFunc: validation.IntBetween(0, 65535), + }, + "tags": tagsSchema(), + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + }, + "dns_name": { + Type: schema.TypeString, + Computed: true, + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + }, + "public_ports": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeInt}, + }, + }, + } +} + +func resourceAwsLightsailLoadBalancerCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).lightsailconn + + req := lightsail.CreateLoadBalancerInput{ + HealthCheckPath: aws.String(d.Get("health_check_path").(string)), + InstancePort: aws.Int64(int64(d.Get("instance_port").(int))), + LoadBalancerName: aws.String(d.Get("name").(string)), + } + + if v := d.Get("tags").(map[string]interface{}); len(v) > 0 { + req.Tags = keyvaluetags.New(v).IgnoreAws().LightsailTags() + } + + resp, err := conn.CreateLoadBalancer(&req) + if err != nil { + return err + } + + if len(resp.Operations) == 0 { + return fmt.Errorf("No operations found for CreateInstance request") + } + + op := resp.Operations[0] + d.SetId(d.Get("name").(string)) + + stateConf := &resource.StateChangeConf{ + Pending: []string{"Started"}, + Target: []string{"Completed", "Succeeded"}, + Refresh: resourceAwsLightsailLoadBalancerOperationRefreshFunc(op.Id, meta), + Timeout: 10 * time.Minute, + Delay: 5 * time.Second, + MinTimeout: 3 * time.Second, + } + + _, err = stateConf.WaitForState() + if err != nil { + // We don't return an error here because the Create call succeeded + log.Printf("[ERR] Error waiting for load balancer (%s) to become ready: %s", d.Id(), err) + } + + return resourceAwsLightsailLoadBalancerRead(d, meta) +} + +func resourceAwsLightsailLoadBalancerRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).lightsailconn + resp, err := conn.GetLoadBalancer(&lightsail.GetLoadBalancerInput{ + LoadBalancerName: aws.String(d.Id()), + }) + + if err != nil { + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "NotFoundException" { + log.Printf("[WARN] Lightsail load balancer (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + return err + } + return err + } + + d.Set("arn", resp.LoadBalancer.Arn) + d.Set("created_at", resp.LoadBalancer.CreatedAt.Format(time.RFC3339)) + d.Set("health_check_path", resp.LoadBalancer.HealthCheckPath) + d.Set("instance_port", resp.LoadBalancer.InstancePort) + d.Set("name", resp.LoadBalancer.Name) + d.Set("protocol", resp.LoadBalancer.Protocol) + d.Set("public_ports", resp.LoadBalancer.PublicPorts) + + if err := d.Set("tags", keyvaluetags.LightsailKeyValueTags(resp.LoadBalancer.Tags).IgnoreAws().Map()); err != nil { + return fmt.Errorf("error setting tags: %s", err) + } + + return nil +} + +func resourceAwsLightsailLoadBalancerDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).lightsailconn + resp, err := conn.DeleteLoadBalancer(&lightsail.DeleteLoadBalancerInput{ + LoadBalancerName: aws.String(d.Id()), + }) + + op := resp.Operations[0] + + if err != nil { + return err + } + + stateConf := &resource.StateChangeConf{ + Pending: []string{"Started"}, + Target: []string{"Completed", "Succeeded"}, + Refresh: resourceAwsLightsailLoadBalancerOperationRefreshFunc(op.Id, meta), + Timeout: 10 * time.Minute, + Delay: 5 * time.Second, + MinTimeout: 3 * time.Second, + } + + _, err = stateConf.WaitForState() + if err != nil { + return fmt.Errorf( + "Error waiting for load balancer (%s) to become destroyed: %s", + d.Id(), err) + } + + return err +} + +func resourceAwsLightsailLoadBalancerUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).lightsailconn + + if d.HasChange("health_check_path") { + _, err := conn.UpdateLoadBalancerAttribute(&lightsail.UpdateLoadBalancerAttributeInput{ + AttributeName: aws.String("HealthCheckPath"), + AttributeValue: aws.String(d.Get("health_check_path").(string)), + LoadBalancerName: aws.String(d.Get("name").(string)), + }) + d.SetPartial("health_check_path") + if err != nil { + return err + } + } + + if d.HasChange("tags") { + o, n := d.GetChange("tags") + + if err := keyvaluetags.LightsailUpdateTags(conn, d.Id(), o, n); err != nil { + return fmt.Errorf("error updating Lightsail Instance (%s) tags: %s", d.Id(), err) + } + } + + return resourceAwsLightsailLoadBalancerRead(d, meta) +} + +// method to check the status of an Operation, which is returned from +// Create/Delete methods. +// Status's are an aws.OperationStatus enum: +// - NotStarted +// - Started +// - Failed +// - Completed +// - Succeeded (not documented?) +func resourceAwsLightsailLoadBalancerOperationRefreshFunc( + oid *string, meta interface{}) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + conn := meta.(*AWSClient).lightsailconn + log.Printf("[DEBUG] Checking if Lightsail Operation (%s) is Completed", *oid) + o, err := conn.GetOperation(&lightsail.GetOperationInput{ + OperationId: oid, + }) + if err != nil { + return o, "FAILED", err + } + + if o.Operation == nil { + return nil, "Failed", fmt.Errorf("Error retrieving Operation info for operation (%s)", *oid) + } + + log.Printf("[DEBUG] Lightsail Operation (%s) is currently %q", *oid, *o.Operation.Status) + return o, *o.Operation.Status, nil + } +} diff --git a/aws/resource_aws_lightsail_load_balancer_test.go b/aws/resource_aws_lightsail_load_balancer_test.go new file mode 100644 index 00000000000..f7e61129690 --- /dev/null +++ b/aws/resource_aws_lightsail_load_balancer_test.go @@ -0,0 +1,316 @@ +package aws + +import ( + "errors" + "fmt" + "log" + "regexp" + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/lightsail" + "github.com/hashicorp/go-multierror" + "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_lightsail_load_balancer", &resource.Sweeper{ + Name: "aws_lightsail_load_balancer", + F: testSweepLightsailLoadBalancers, + }) +} + +func testSweepLightsailLoadBalancers(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("Error getting client: %s", err) + } + conn := client.(*AWSClient).lightsailconn + + input := &lightsail.GetLoadBalancersInput{} + var sweeperErrs *multierror.Error + + for { + output, err := conn.GetLoadBalancers(input) + + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping Lightsail Load Balancer sweep for %s: %s", region, err) + return nil + } + + if err != nil { + return fmt.Errorf("Error retrieving Lightsail Load Balancers: %s", err) + } + + for _, loadBalancer := range output.LoadBalancers { + name := aws.StringValue(loadBalancer.Name) + input := &lightsail.DeleteLoadBalancerInput{ + LoadBalancerName: loadBalancer.Name, + } + + log.Printf("[INFO] Deleting Lightsail Load Balancer: %s", name) + _, err := conn.DeleteLoadBalancer(input) + + if err != nil { + sweeperErr := fmt.Errorf("error deleting Lightsail Load Balancer (%s): %s", name, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + } + } + + if aws.StringValue(output.NextPageToken) == "" { + break + } + + input.PageToken = output.NextPageToken + } + + return sweeperErrs.ErrorOrNil() +} + +func TestAccAWSLightsailLoadBalancer_basic(t *testing.T) { + var loadBalancer lightsail.LoadBalancer + lightsailLoadBalancerName := fmt.Sprintf("tf-test-lightsail-%d", acctest.RandInt()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSLightsail(t) }, + IDRefreshName: "aws_lightsail_load_balancer.lightsail_load_balancer_test", + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSLightsailLoadBalancerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailLoadBalancerName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSLightsailLoadBalancerExists("aws_lightsail_load_balancer.lightsail_load_balancer_test", &loadBalancer), + resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "health_check_path"), + resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "instance_port"), + resource.TestCheckResourceAttr("aws_lightsail_load_balancer.lightsail_load_balancer_test", "tags.%", "0"), + ), + }, + }, + }) +} + +func TestAccAWSLightsailLoadBalancer_Name(t *testing.T) { + var conf lightsail.LoadBalancer + lightsailName := fmt.Sprintf("tf-test-lightsail-%d", acctest.RandInt()) + lightsailNameWithSpaces := fmt.Sprint(lightsailName, "string with spaces") + lightsailNameWithStartingDigit := fmt.Sprintf("01-%s", lightsailName) + lightsailNameWithUnderscore := fmt.Sprintf("%s_123456", lightsailName) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + IDRefreshName: "aws_lightsail_load_balancer.lightsail_load_balancer_test", + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSLightsailLoadBalancerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailNameWithSpaces), + ExpectError: regexp.MustCompile(`must contain only alphanumeric characters, underscores, hyphens, and dots`), + }, + { + Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailNameWithStartingDigit), + ExpectError: regexp.MustCompile(`must begin with an alphabetic character`), + }, + { + Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSLightsailLoadBalancerExists("aws_lightsail_load_balancer.lightsail_load_balancer_test", &conf), + resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "health_check_path"), + resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "instance_port"), + ), + }, + { + Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailNameWithUnderscore), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSLightsailLoadBalancerExists("aws_lightsail_load_balancer.lightsail_load_balancer_test", &conf), + resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "health_check_path"), + resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "instance_port"), + ), + }, + }, + }) +} + +func TestAccAWSLightsailLoadBalancer_Tags(t *testing.T) { + var conf lightsail.LoadBalancer + lightsailLoadBalancerName := fmt.Sprintf("tf-test-lightsail-%d", acctest.RandInt()) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSLightsail(t) }, + IDRefreshName: "aws_lightsail_load_balancer.lightsail_load_balancer_test", + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSLightsailLoadBalancerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSLightsailLoadBalancerConfig_tags1(lightsailLoadBalancerName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSLightsailLoadBalancerExists("aws_lightsail_load_balancer.lightsail_load_balancer_test", &conf), + resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "health_check_path"), + resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "instance_port"), + resource.TestCheckResourceAttr("aws_lightsail_load_balancer.lightsail_load_balancer_test", "tags.%", "1"), + ), + }, + { + Config: testAccAWSLightsailLoadBalancerConfig_tags2(lightsailLoadBalancerName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSLightsailLoadBalancerExists("aws_lightsail_load_balancer.lightsail_load_balancer_test", &conf), + resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "health_check_path"), + resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "instance_port"), + resource.TestCheckResourceAttr("aws_lightsail_load_balancer.lightsail_load_balancer_test", "tags.%", "2"), + ), + }, + }, + }) +} + +func testAccCheckAWSLightsailLoadBalancerExists(n string, res *lightsail.LoadBalancer) 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 LightsailLoadBalancer ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).lightsailconn + + respLoadBalancer, err := conn.GetLoadBalancer(&lightsail.GetLoadBalancerInput{ + LoadBalancerName: aws.String(rs.Primary.Attributes["name"]), + }) + + if err != nil { + return err + } + + if respLoadBalancer == nil || respLoadBalancer.LoadBalancer == nil { + return fmt.Errorf("Load Balancer (%s) not found", rs.Primary.Attributes["name"]) + } + *res = *respLoadBalancer.LoadBalancer + return nil + } +} + +func TestAccAWSLightsailLoadBalancer_disappear(t *testing.T) { + var conf lightsail.LoadBalancer + lightsailLoadBalancerName := fmt.Sprintf("tf-test-lightsail-%d", acctest.RandInt()) + + testDestroy := func(*terraform.State) error { + // reach out and DELETE the Load Balancer + conn := testAccProvider.Meta().(*AWSClient).lightsailconn + _, err := conn.DeleteLoadBalancer(&lightsail.DeleteLoadBalancerInput{ + LoadBalancerName: aws.String(lightsailLoadBalancerName), + }) + + if err != nil { + return fmt.Errorf("error deleting Lightsail Load Balancer in disappear test") + } + + // sleep 7 seconds to give it time, so we don't have to poll + time.Sleep(7 * time.Second) + + return nil + } + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSLightsail(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSLightsailLoadBalancerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailLoadBalancerName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSLightsailLoadBalancerExists("aws_lightsail_load_balancer.lightsail_load_balancer_test", &conf), + testDestroy, + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccCheckAWSLightsailLoadBalancerDestroy(s *terraform.State) error { + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_lightsail_load_balancer" { + continue + } + + conn := testAccProvider.Meta().(*AWSClient).lightsailconn + + resp, err := conn.GetLoadBalancer(&lightsail.GetLoadBalancerInput{ + LoadBalancerName: aws.String(rs.Primary.ID), + }) + + if err == nil { + if resp.LoadBalancer != nil { + return fmt.Errorf("Lightsail Load Balancer %q still exists", rs.Primary.ID) + } + } + + // Verify the error + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "NotFoundException" { + return nil + } + } + return err + } + + return nil +} + +func testAccAWSLightsailLoadBalancerConfig_basic(lightsailLoadBalancerName string) string { + return fmt.Sprintf(` +provider "aws" { + region = "us-east-1" +} + +resource "aws_lightsail_load_balancer" "lightsail_load_balancer_test" { + name = "%s" + health_check_path = "/" + instance_port = "80" +} +`, lightsailLoadBalancerName) +} + +func testAccAWSLightsailLoadBalancerConfig_tags1(lightsailLoadBalancerName string) string { + return fmt.Sprintf(` +provider "aws" { + region = "us-east-1" +} + +resource "aws_lightsail_load_balancer" "lightsail_load_balancer_test" { + name = "%s" + health_check_path = "/" + instance_port = "80" + tags = { + Name = "tf-test" + } +} +`, lightsailLoadBalancerName) +} + +func testAccAWSLightsailLoadBalancerConfig_tags2(lightsailLoadBalancerName string) string { + return fmt.Sprintf(` +provider "aws" { + region = "us-east-1" +} + +resource "aws_lightsail_load_balancer" "lightsail_load_balancer_test" { + name = "%s" + health_check_path = "/" + instance_port = "80" + tags = { + Name = "tf-test", + ExtraName = "tf-test" + } +} +`, lightsailLoadBalancerName) +} diff --git a/aws/resource_aws_lightsail_static_ip_test.go b/aws/resource_aws_lightsail_static_ip_test.go index 74ff6078f04..7a29ac2cc33 100644 --- a/aws/resource_aws_lightsail_static_ip_test.go +++ b/aws/resource_aws_lightsail_static_ip_test.go @@ -96,7 +96,7 @@ func TestAccAWSLightsailStaticIp_disappears(t *testing.T) { }) if err != nil { - return fmt.Errorf("Error deleting Lightsail Static IP in disapear test") + return fmt.Errorf("Error deleting Lightsail Static IP in disappear test") } return nil diff --git a/website/aws.erb b/website/aws.erb index 8e36181d06d..18cb225b3e4 100644 --- a/website/aws.erb +++ b/website/aws.erb @@ -1990,6 +1990,9 @@
  • aws_lightsail_key_pair
  • +
  • + aws_lightsail_load_balancer +
  • aws_lightsail_static_ip
  • diff --git a/website/docs/r/lightsail_load_balancer.html.markdown b/website/docs/r/lightsail_load_balancer.html.markdown new file mode 100644 index 00000000000..5f83eaa2697 --- /dev/null +++ b/website/docs/r/lightsail_load_balancer.html.markdown @@ -0,0 +1,52 @@ +--- +subcategory: "Lightsail" +layout: "aws" +page_title: "AWS: aws_lightsail_load_balancer" +description: |- + Provides a Lightsail Load Balancer +--- + +# Resource: aws_lightsail_load_balancer + +Creates a Lightsail load balancer resource. + +~> **Note:** Lightsail is currently only supported in a limited number of AWS Regions, please see ["Regions and Availability Zones in Amazon Lightsail"](https://lightsail.aws.amazon.com/ls/docs/overview/article/understanding-regions-and-availability-zones-in-amazon-lightsail) for more details + +## Example Usage, creating a new load balancer + +```hcl +resource "aws_lightsail_load_balancer" "load_balancer_test" { + name = "test-load-balancer" + health_check_path = "/" + instance_port = "80" + tags = { + foo = "bar" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the Lightsail load balancer. +* `instance_port` - (Required) The instance port the load balancer will connect. +* `health_check_path` - (Optional) The health check path of the load balancer. Default value "/". +* `tags` - (Optional) A mapping of tags to assign to the resource. + +## Attributes Reference + +The following attributes are exported in addition to the arguments listed above: + +* `arn` - The ARN of the Lightsail load balancer. +* `created_at` - The timestamp when the load balancer was created. +* `dns_name` - The DNS name of the load balancer. +* `id` - The name used for this load balancer. +* `protocol` - The protocol of the load balancer. +* `public_ports` - The public ports of the load balancer. + +Lightsail Load Balancers can be imported using their name, e.g. + +``` +$ terraform import aws_lightsail_load_balancer.website_load_balancer_ 'example-load-balancer' +``` From 3e88cf86819ff8eb64d15bb321386971a5fabe37 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Wed, 24 Feb 2021 16:23:12 -0500 Subject: [PATCH 02/15] Action Required: Removal of website/aws.erb File Reference: #14712 --- website/aws.erb | 3408 ----------------------------------------------- 1 file changed, 3408 deletions(-) delete mode 100644 website/aws.erb diff --git a/website/aws.erb b/website/aws.erb deleted file mode 100644 index 18cb225b3e4..00000000000 --- a/website/aws.erb +++ /dev/null @@ -1,3408 +0,0 @@ -<% wrap_layout :inner do %> - <% content_for :sidebar do %> - - <% end %> - <%= yield %> -<% end %> From 4fa980541791e38e7dbb75299dc5bf96b8c749f2 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung Date: Wed, 24 Feb 2021 16:40:27 -0500 Subject: [PATCH 03/15] Fixed: Action Required: Terraform Plugin SDK V2 Reference: #14551 --- aws/resource_aws_lightsail_load_balancer.go | 6 +++--- aws/resource_aws_lightsail_load_balancer_test.go | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/aws/resource_aws_lightsail_load_balancer.go b/aws/resource_aws_lightsail_load_balancer.go index ea39410c5f6..668d986aa37 100644 --- a/aws/resource_aws_lightsail_load_balancer.go +++ b/aws/resource_aws_lightsail_load_balancer.go @@ -9,9 +9,9 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/lightsail" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) diff --git a/aws/resource_aws_lightsail_load_balancer_test.go b/aws/resource_aws_lightsail_load_balancer_test.go index f7e61129690..61377171d94 100644 --- a/aws/resource_aws_lightsail_load_balancer_test.go +++ b/aws/resource_aws_lightsail_load_balancer_test.go @@ -12,9 +12,9 @@ import ( "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/lightsail" "github.com/hashicorp/go-multierror" - "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" - "github.com/hashicorp/terraform-plugin-sdk/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" ) func init() { From 43bbaf4d61dcb58148720e97ffed678fda1717de Mon Sep 17 00:00:00 2001 From: Brittan DeYoung <32572259+brittandeyoung@users.noreply.github.com> Date: Thu, 25 Feb 2021 08:11:52 -0500 Subject: [PATCH 04/15] Removed conflicting changes This Spelling error is already resolved in the main branch and this change is causing a conflict. --- aws/resource_aws_lightsail_domain_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_lightsail_domain_test.go b/aws/resource_aws_lightsail_domain_test.go index 1eef8d025ad..2f2c1b033c9 100644 --- a/aws/resource_aws_lightsail_domain_test.go +++ b/aws/resource_aws_lightsail_domain_test.go @@ -44,7 +44,7 @@ func TestAccAWSLightsailDomain_disappears(t *testing.T) { }) if err != nil { - return fmt.Errorf("Error deleting Lightsail Domain in disappear test") + return fmt.Errorf("Error deleting Lightsail Domain in disapear test") } return nil From 7f65c4098fafd598f871d701b1a44846adac1f62 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung Date: Thu, 25 Feb 2021 10:15:44 -0500 Subject: [PATCH 05/15] * Fixed usage of SetPartial * Added dns_name to Read --- aws/resource_aws_lightsail_load_balancer.go | 3 ++- aws/resource_aws_lightsail_load_balancer_test.go | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/aws/resource_aws_lightsail_load_balancer.go b/aws/resource_aws_lightsail_load_balancer.go index 668d986aa37..13a636b7497 100644 --- a/aws/resource_aws_lightsail_load_balancer.go +++ b/aws/resource_aws_lightsail_load_balancer.go @@ -141,6 +141,7 @@ func resourceAwsLightsailLoadBalancerRead(d *schema.ResourceData, meta interface d.Set("name", resp.LoadBalancer.Name) d.Set("protocol", resp.LoadBalancer.Protocol) d.Set("public_ports", resp.LoadBalancer.PublicPorts) + d.Set("dns_name", resp.LoadBalancer.DnsName) if err := d.Set("tags", keyvaluetags.LightsailKeyValueTags(resp.LoadBalancer.Tags).IgnoreAws().Map()); err != nil { return fmt.Errorf("error setting tags: %s", err) @@ -189,7 +190,7 @@ func resourceAwsLightsailLoadBalancerUpdate(d *schema.ResourceData, meta interfa AttributeValue: aws.String(d.Get("health_check_path").(string)), LoadBalancerName: aws.String(d.Get("name").(string)), }) - d.SetPartial("health_check_path") + d.Set("health_check_path", d.Get("health_check_path").(string)) if err != nil { return err } diff --git a/aws/resource_aws_lightsail_load_balancer_test.go b/aws/resource_aws_lightsail_load_balancer_test.go index 61377171d94..052b45d7d95 100644 --- a/aws/resource_aws_lightsail_load_balancer_test.go +++ b/aws/resource_aws_lightsail_load_balancer_test.go @@ -88,6 +88,7 @@ func TestAccAWSLightsailLoadBalancer_basic(t *testing.T) { testAccCheckAWSLightsailLoadBalancerExists("aws_lightsail_load_balancer.lightsail_load_balancer_test", &loadBalancer), resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "health_check_path"), resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "instance_port"), + resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "dns_name"), resource.TestCheckResourceAttr("aws_lightsail_load_balancer.lightsail_load_balancer_test", "tags.%", "0"), ), }, @@ -271,7 +272,6 @@ func testAccAWSLightsailLoadBalancerConfig_basic(lightsailLoadBalancerName strin provider "aws" { region = "us-east-1" } - resource "aws_lightsail_load_balancer" "lightsail_load_balancer_test" { name = "%s" health_check_path = "/" @@ -285,7 +285,6 @@ func testAccAWSLightsailLoadBalancerConfig_tags1(lightsailLoadBalancerName strin provider "aws" { region = "us-east-1" } - resource "aws_lightsail_load_balancer" "lightsail_load_balancer_test" { name = "%s" health_check_path = "/" @@ -302,7 +301,6 @@ func testAccAWSLightsailLoadBalancerConfig_tags2(lightsailLoadBalancerName strin provider "aws" { region = "us-east-1" } - resource "aws_lightsail_load_balancer" "lightsail_load_balancer_test" { name = "%s" health_check_path = "/" From 9e4d71b2566a5a38da0d0da6cf6d825da19d3615 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung Date: Fri, 26 Feb 2021 13:40:04 -0500 Subject: [PATCH 06/15] Fixed: * terrafmt issue * Removed provider from tests * added missing semgrp.yml config file --- .semgrep.yml | 188 ++++++++++++++++++ ...source_aws_lightsail_load_balancer_test.go | 29 +-- .../r/lightsail_load_balancer.html.markdown | 6 +- 3 files changed, 201 insertions(+), 22 deletions(-) create mode 100644 .semgrep.yml diff --git a/.semgrep.yml b/.semgrep.yml new file mode 100644 index 00000000000..cc6d638df50 --- /dev/null +++ b/.semgrep.yml @@ -0,0 +1,188 @@ +rules: + - id: acceptance-test-naming-parent-disappears + languages: [go] + message: Prefer naming acceptance tests with _disappears_Parent suffix + paths: + include: + - 'aws/*_test.go' + patterns: + - pattern: func $FUNCNAME(t *testing.T) { ... } + - metavariable-regex: + metavariable: "$FUNCNAME" + regex: "^TestAcc[^_]+_([a-zA-Z]+[dD]isappears|[^_]+_disappears)$" + severity: WARNING + + - id: aws-sdk-go-multiple-service-imports + languages: [go] + message: Resources should not implement multiple AWS service functionality + paths: + exclude: + - aws/config.go + - aws/structure.go + - aws/validators.go + - aws/*wafregional*.go + - aws/resource_aws_serverlessapplicationrepository_cloudformation_stack.go + - aws/*_test.go + - aws/internal/keyvaluetags/ + - aws/internal/service/wafregional/ + # Legacy resource handling + - aws/resource_aws_autoscaling_group.go + - aws/resource_aws_efs_mount_target.go + - aws/resource_aws_elastic_beanstalk_environment.go + - aws/resource_aws_elb.go + - aws/resource_aws_iam_server_certificate.go + - aws/resource_aws_lambda_event_source_mapping.go + - aws/resource_aws_launch_configuration.go + - aws/resource_aws_lb.go + - aws/resource_aws_s3_bucket_object.go + include: + - aws/ + patterns: + - pattern: | + import ("$X") + import ("$Y") + - metavariable-regex: + metavariable: '$X' + regex: '^"github.com/aws/aws-sdk-go/service/[^/]+"$' + - metavariable-regex: + metavariable: '$Y' + regex: '^"github.com/aws/aws-sdk-go/service/[^/]+"$' + severity: WARNING + + - id: prefer-aws-go-sdk-pointer-conversion-assignment + languages: [go] + message: Prefer AWS Go SDK pointer conversion functions for dereferencing during assignment, e.g. aws.StringValue() + paths: + exclude: + - aws/cloudfront_distribution_configuration_structure.go + - aws/data_source_aws_route_table.go + - aws/opsworks_layers.go + - aws/resource* + - aws/structure.go + - aws/waf_helpers.go + - aws/internal/generators/ + - aws/internal/keyvaluetags/ + - awsproviderlint/vendor/ + include: + - aws/ + patterns: + - pattern: '$LHS = *$RHS' + - pattern-not: '*$LHS2 = *$RHS' + severity: WARNING + + - id: aws-go-sdk-pointer-conversion-ResourceData-SetId + fix: d.SetId(aws.StringValue($VALUE)) + languages: [go] + message: Prefer AWS Go SDK pointer conversion aws.StringValue() function for dereferencing during d.SetId() + paths: + include: + - aws/ + pattern: 'd.SetId(*$VALUE)' + severity: WARNING + + - id: helper-schema-Set-extraneous-NewSet-with-flattenStringList + languages: [go] + message: Prefer `flattenStringSet()` function for casting a list of string pointers to a set + paths: + include: + - aws/ + patterns: + - pattern: schema.NewSet(schema.HashString, flattenStringList($APIOBJECT)) + - pattern-not-inside: func flattenStringSet(list []*string) *schema.Set { ... } + severity: WARNING + + - id: helper-schema-Set-extraneous-expandStringList-with-List + languages: [go] + message: Prefer `expandStringSet()` function for casting a set to a list of string pointers + paths: + include: + - aws/ + patterns: + - pattern-either: + - pattern: expandStringList($SET.List()) + - pattern: | + $LIST := $SET.List() + ... + expandStringList($LIST) + - pattern-not-inside: func expandStringSet(configured *schema.Set) []*string { ... } + severity: WARNING + + + - id: helper-schema-ResourceData-GetOk-with-extraneous-conditional + languages: [go] + message: Zero value conditional check after `d.GetOk()` is extraneous + paths: + include: + - aws/ + patterns: + - pattern-either: + - pattern: if $VALUE, $OK := d.GetOk($KEY); $OK && $VALUE.(bool) { $BODY } + - pattern: if $VALUE, $OK := d.GetOk($KEY); $OK && $VALUE.(int) != 0 { $BODY } + - pattern: if $VALUE, $OK := d.GetOk($KEY); $OK && $VALUE.(int) > 0 { $BODY } + - pattern: if $VALUE, $OK := d.GetOk($KEY); $OK && $VALUE.(string) != "" { $BODY } + - pattern: if $VALUE, $OK := d.GetOk($KEY); $OK && len($VALUE.(string)) > 0 { $BODY } + severity: WARNING + + - id: helper-schema-resource-Retry-without-TimeoutError-check + languages: [go] + message: Check resource.Retry() errors with tfresource.TimedOut() + paths: + exclude: + - "*_test.go" + include: + - aws/ + patterns: + - pattern-either: + - pattern: | + $ERR := resource.Retry(...) + ... + return ... + - pattern: | + $ERR = resource.Retry(...) + ... + return ... + - pattern-not: | + $ERR := resource.Retry(...) + ... + if isResourceTimeoutError($ERR) { ... } + ... + return ... + - pattern-not: | + $ERR = resource.Retry(...) + ... + if isResourceTimeoutError($ERR) { ... } + ... + return ... + - pattern-not: | + $ERR := resource.Retry(...) + ... + if tfresource.TimedOut($ERR) { ... } + ... + return ... + - pattern-not: | + $ERR = resource.Retry(...) + ... + if tfresource.TimedOut($ERR) { ... } + ... + return ... + severity: WARNING + + - id: is-not-found-error + languages: [go] + message: Check for resource.NotFoundError errors with tfresource.NotFound() + paths: + include: + - aws/ + patterns: + - pattern-either: + - patterns: + - pattern: | + var $CAST *resource.NotFoundError + ... + errors.As($ERR, &$CAST) + - pattern-not-inside: func NotFound(err error) bool { ... } + - patterns: + - pattern: | + $X, $Y := $ERR.(*resource.NotFoundError) + - pattern-not-inside: func isResourceNotFoundError(err error) bool { ... } + severity: WARNING \ No newline at end of file diff --git a/aws/resource_aws_lightsail_load_balancer_test.go b/aws/resource_aws_lightsail_load_balancer_test.go index 052b45d7d95..32fdc2b2214 100644 --- a/aws/resource_aws_lightsail_load_balancer_test.go +++ b/aws/resource_aws_lightsail_load_balancer_test.go @@ -269,26 +269,20 @@ func testAccCheckAWSLightsailLoadBalancerDestroy(s *terraform.State) error { func testAccAWSLightsailLoadBalancerConfig_basic(lightsailLoadBalancerName string) string { return fmt.Sprintf(` -provider "aws" { - region = "us-east-1" -} resource "aws_lightsail_load_balancer" "lightsail_load_balancer_test" { - name = "%s" - health_check_path = "/" - instance_port = "80" + name = "%s" + health_check_path = "/" + instance_port = "80" } `, lightsailLoadBalancerName) } func testAccAWSLightsailLoadBalancerConfig_tags1(lightsailLoadBalancerName string) string { return fmt.Sprintf(` -provider "aws" { - region = "us-east-1" -} resource "aws_lightsail_load_balancer" "lightsail_load_balancer_test" { - name = "%s" - health_check_path = "/" - instance_port = "80" + name = "%s" + health_check_path = "/" + instance_port = "80" tags = { Name = "tf-test" } @@ -298,15 +292,12 @@ resource "aws_lightsail_load_balancer" "lightsail_load_balancer_test" { func testAccAWSLightsailLoadBalancerConfig_tags2(lightsailLoadBalancerName string) string { return fmt.Sprintf(` -provider "aws" { - region = "us-east-1" -} resource "aws_lightsail_load_balancer" "lightsail_load_balancer_test" { - name = "%s" - health_check_path = "/" - instance_port = "80" + name = "%s" + health_check_path = "/" + instance_port = "80" tags = { - Name = "tf-test", + Name = "tf-test" ExtraName = "tf-test" } } diff --git a/website/docs/r/lightsail_load_balancer.html.markdown b/website/docs/r/lightsail_load_balancer.html.markdown index 5f83eaa2697..8a49945cee8 100644 --- a/website/docs/r/lightsail_load_balancer.html.markdown +++ b/website/docs/r/lightsail_load_balancer.html.markdown @@ -16,9 +16,9 @@ Creates a Lightsail load balancer resource. ```hcl resource "aws_lightsail_load_balancer" "load_balancer_test" { - name = "test-load-balancer" - health_check_path = "/" - instance_port = "80" + name = "test-load-balancer" + health_check_path = "/" + instance_port = "80" tags = { foo = "bar" } From 7c24c548da8554862c60783801ad948be31dc46f Mon Sep 17 00:00:00 2001 From: Brittan DeYoung Date: Fri, 26 Feb 2021 14:55:45 -0500 Subject: [PATCH 07/15] fixed: AWSR002 --- aws/resource_aws_lightsail_load_balancer.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_lightsail_load_balancer.go b/aws/resource_aws_lightsail_load_balancer.go index 13a636b7497..eb7b46ac921 100644 --- a/aws/resource_aws_lightsail_load_balancer.go +++ b/aws/resource_aws_lightsail_load_balancer.go @@ -118,6 +118,8 @@ func resourceAwsLightsailLoadBalancerCreate(d *schema.ResourceData, meta interfa func resourceAwsLightsailLoadBalancerRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).lightsailconn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + resp, err := conn.GetLoadBalancer(&lightsail.GetLoadBalancerInput{ LoadBalancerName: aws.String(d.Id()), }) @@ -143,7 +145,7 @@ func resourceAwsLightsailLoadBalancerRead(d *schema.ResourceData, meta interface d.Set("public_ports", resp.LoadBalancer.PublicPorts) d.Set("dns_name", resp.LoadBalancer.DnsName) - if err := d.Set("tags", keyvaluetags.LightsailKeyValueTags(resp.LoadBalancer.Tags).IgnoreAws().Map()); err != nil { + if err := d.Set("tags", keyvaluetags.LightsailKeyValueTags(resp.LoadBalancer.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { return fmt.Errorf("error setting tags: %s", err) } From a2c4807f3fe62fcfb7863f309ccb950384b93a64 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung Date: Tue, 2 Mar 2021 10:45:51 -0500 Subject: [PATCH 08/15] Created Internal Waiter files --- .../service/lightsail/waiter/status.go | 32 ++++++++ .../service/lightsail/waiter/waiter.go | 48 +++++++++++ aws/resource_aws_lightsail_load_balancer.go | 81 ++++--------------- ...source_aws_lightsail_load_balancer_test.go | 64 ++++++++------- 4 files changed, 131 insertions(+), 94 deletions(-) create mode 100644 aws/internal/service/lightsail/waiter/status.go create mode 100644 aws/internal/service/lightsail/waiter/waiter.go diff --git a/aws/internal/service/lightsail/waiter/status.go b/aws/internal/service/lightsail/waiter/status.go new file mode 100644 index 00000000000..a31c50e5d70 --- /dev/null +++ b/aws/internal/service/lightsail/waiter/status.go @@ -0,0 +1,32 @@ +package waiter + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/service/lightsail" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +// LightsailOperationStatus is a method to check the status of a Lightsail Operation +func LightsailOperationStatus(conn *lightsail.Lightsail, oid string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + input := &lightsail.GetOperationInput{ + OperationId: oid, + } + log.Printf("[DEBUG] Checking if Lightsail Operation (%s) is Completed", &oid) + + output, err := conn.GetOperation(input) + + if err != nil { + return output, "FAILED", err + } + + if output.Operation == nil { + return nil, "Failed", fmt.Errorf("Error retrieving Operation info for operation (%s)", &oid) + } + + log.Printf("[DEBUG] Lightsail Operation (%s) is currently %q", &oid, *output.Operation.Status) + return output, *output.Operation.Status, nil + } +} diff --git a/aws/internal/service/lightsail/waiter/waiter.go b/aws/internal/service/lightsail/waiter/waiter.go new file mode 100644 index 00000000000..467eeb88acb --- /dev/null +++ b/aws/internal/service/lightsail/waiter/waiter.go @@ -0,0 +1,48 @@ +package waiter + +import ( + "time" + + "github.com/aws/aws-sdk-go/service/lightsail" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const ( + // OperationStatusNotStarted is a OperationStatus enum value + OperationStatusNotStarted = "NotStarted" + // OperationStatusStarted is a OperationStatus enum value + OperationStatusStarted = "Started" + // OperationStatusFailed is a OperationStatus enum value + OperationStatusFailed = "Failed" + // OperationStatusCompleted is a OperationStatus enum value + OperationStatusCompleted = "Completed" + // OperationStatusSucceeded is a OperationStatus enum value + OperationStatusSucceeded = "Succeeded" + + // OperationTimeout is the Timout Value for Operations + OperationTimeout = 10 * time.Minute + // OperationDelay is the Delay Value for Operations + OperationDelay = 5 * time.Second + // OperationMinTimeout is the MinTimout Value for Operations + OperationMinTimeout = 3 * time.Second +) + +// OperationCreated waits for an Operation to return Succeeded or Compleated +func OperationCreated(conn *lightsail.Lightsail, oid string) (*lightsail.GetOperationOutput, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{OperationStatusStarted}, + Target: []string{OperationStatusCompleted, OperationStatusSucceeded}, + Refresh: LightsailOperationStatus(conn, oid), + Timeout: OperationTimeout, + Delay: OperationDelay, + MinTimeout: OperationMinTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if output, ok := outputRaw.(*glue.GetOperationOutput); ok { + return output, err + } + + return nil, err +} diff --git a/aws/resource_aws_lightsail_load_balancer.go b/aws/resource_aws_lightsail_load_balancer.go index eb7b46ac921..7f58594d840 100644 --- a/aws/resource_aws_lightsail_load_balancer.go +++ b/aws/resource_aws_lightsail_load_balancer.go @@ -6,10 +6,11 @@ import ( "regexp" "time" + "./aws/internal/service/lightsail/waiter" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/lightsail" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" @@ -98,19 +99,9 @@ func resourceAwsLightsailLoadBalancerCreate(d *schema.ResourceData, meta interfa op := resp.Operations[0] d.SetId(d.Get("name").(string)) - stateConf := &resource.StateChangeConf{ - Pending: []string{"Started"}, - Target: []string{"Completed", "Succeeded"}, - Refresh: resourceAwsLightsailLoadBalancerOperationRefreshFunc(op.Id, meta), - Timeout: 10 * time.Minute, - Delay: 5 * time.Second, - MinTimeout: 3 * time.Second, - } - - _, err = stateConf.WaitForState() + _, err = waiter.OperationCreated(conn, op.Id) if err != nil { - // We don't return an error here because the Create call succeeded - log.Printf("[ERR] Error waiting for load balancer (%s) to become ready: %s", d.Id(), err) + return fmt.Errorf("Error waiting for load balancer (%s) to become ready: %s", d.Id(), err) } return resourceAwsLightsailLoadBalancerRead(d, meta) @@ -124,6 +115,8 @@ func resourceAwsLightsailLoadBalancerRead(d *schema.ResourceData, meta interface LoadBalancerName: aws.String(d.Id()), }) + lb := resp.LoadBalancer + if err != nil { if awsErr, ok := err.(awserr.Error); ok { if awsErr.Code() == "NotFoundException" { @@ -136,16 +129,16 @@ func resourceAwsLightsailLoadBalancerRead(d *schema.ResourceData, meta interface return err } - d.Set("arn", resp.LoadBalancer.Arn) - d.Set("created_at", resp.LoadBalancer.CreatedAt.Format(time.RFC3339)) - d.Set("health_check_path", resp.LoadBalancer.HealthCheckPath) - d.Set("instance_port", resp.LoadBalancer.InstancePort) - d.Set("name", resp.LoadBalancer.Name) - d.Set("protocol", resp.LoadBalancer.Protocol) - d.Set("public_ports", resp.LoadBalancer.PublicPorts) - d.Set("dns_name", resp.LoadBalancer.DnsName) + d.Set("arn", lb.Arn) + d.Set("created_at", lb.CreatedAt.Format(time.RFC3339)) + d.Set("health_check_path", lb.HealthCheckPath) + d.Set("instance_port", lb.InstancePort) + d.Set("name", lb.Name) + d.Set("protocol", lb.Protocol) + d.Set("public_ports", lb.PublicPorts) + d.Set("dns_name", lb.DnsName) - if err := d.Set("tags", keyvaluetags.LightsailKeyValueTags(resp.LoadBalancer.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + if err := d.Set("tags", keyvaluetags.LightsailKeyValueTags(lb.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { return fmt.Errorf("error setting tags: %s", err) } @@ -164,20 +157,9 @@ func resourceAwsLightsailLoadBalancerDelete(d *schema.ResourceData, meta interfa return err } - stateConf := &resource.StateChangeConf{ - Pending: []string{"Started"}, - Target: []string{"Completed", "Succeeded"}, - Refresh: resourceAwsLightsailLoadBalancerOperationRefreshFunc(op.Id, meta), - Timeout: 10 * time.Minute, - Delay: 5 * time.Second, - MinTimeout: 3 * time.Second, - } - - _, err = stateConf.WaitForState() + _, err = waiter.OperationCreated(conn, op.Id) if err != nil { - return fmt.Errorf( - "Error waiting for load balancer (%s) to become destroyed: %s", - d.Id(), err) + return fmt.Errorf("Error waiting for load balancer (%s) to become destroyed: %s", d.Id(), err) } return err @@ -208,32 +190,3 @@ func resourceAwsLightsailLoadBalancerUpdate(d *schema.ResourceData, meta interfa return resourceAwsLightsailLoadBalancerRead(d, meta) } - -// method to check the status of an Operation, which is returned from -// Create/Delete methods. -// Status's are an aws.OperationStatus enum: -// - NotStarted -// - Started -// - Failed -// - Completed -// - Succeeded (not documented?) -func resourceAwsLightsailLoadBalancerOperationRefreshFunc( - oid *string, meta interface{}) resource.StateRefreshFunc { - return func() (interface{}, string, error) { - conn := meta.(*AWSClient).lightsailconn - log.Printf("[DEBUG] Checking if Lightsail Operation (%s) is Completed", *oid) - o, err := conn.GetOperation(&lightsail.GetOperationInput{ - OperationId: oid, - }) - if err != nil { - return o, "FAILED", err - } - - if o.Operation == nil { - return nil, "Failed", fmt.Errorf("Error retrieving Operation info for operation (%s)", *oid) - } - - log.Printf("[DEBUG] Lightsail Operation (%s) is currently %q", *oid, *o.Operation.Status) - return o, *o.Operation.Status, nil - } -} diff --git a/aws/resource_aws_lightsail_load_balancer_test.go b/aws/resource_aws_lightsail_load_balancer_test.go index 32fdc2b2214..07e3ec9df0d 100644 --- a/aws/resource_aws_lightsail_load_balancer_test.go +++ b/aws/resource_aws_lightsail_load_balancer_test.go @@ -74,22 +74,23 @@ func testSweepLightsailLoadBalancers(region string) error { func TestAccAWSLightsailLoadBalancer_basic(t *testing.T) { var loadBalancer lightsail.LoadBalancer - lightsailLoadBalancerName := fmt.Sprintf("tf-test-lightsail-%d", acctest.RandInt()) + lightsailLoadBalancerName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_lightsail_load_balancer.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSLightsail(t) }, - IDRefreshName: "aws_lightsail_load_balancer.lightsail_load_balancer_test", + IDRefreshName: resourceName, Providers: testAccProviders, CheckDestroy: testAccCheckAWSLightsailLoadBalancerDestroy, Steps: []resource.TestStep{ { Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailLoadBalancerName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSLightsailLoadBalancerExists("aws_lightsail_load_balancer.lightsail_load_balancer_test", &loadBalancer), - resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "health_check_path"), - resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "instance_port"), - resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "dns_name"), - resource.TestCheckResourceAttr("aws_lightsail_load_balancer.lightsail_load_balancer_test", "tags.%", "0"), + testAccCheckAWSLightsailLoadBalancerExists(resourceName, &loadBalancer), + resource.TestCheckResourceAttrSet(resourceName, "health_check_path"), + resource.TestCheckResourceAttrSet(resourceName, "instance_port"), + resource.TestCheckResourceAttrSet(resourceName, "dns_name"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, }, @@ -98,14 +99,15 @@ func TestAccAWSLightsailLoadBalancer_basic(t *testing.T) { func TestAccAWSLightsailLoadBalancer_Name(t *testing.T) { var conf lightsail.LoadBalancer - lightsailName := fmt.Sprintf("tf-test-lightsail-%d", acctest.RandInt()) + lightsailName := acctest.RandomWithPrefix("tf-acc-test") lightsailNameWithSpaces := fmt.Sprint(lightsailName, "string with spaces") lightsailNameWithStartingDigit := fmt.Sprintf("01-%s", lightsailName) lightsailNameWithUnderscore := fmt.Sprintf("%s_123456", lightsailName) + resourceName := "aws_lightsail_load_balancer.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, - IDRefreshName: "aws_lightsail_load_balancer.lightsail_load_balancer_test", + IDRefreshName: resourceName, Providers: testAccProviders, CheckDestroy: testAccCheckAWSLightsailLoadBalancerDestroy, Steps: []resource.TestStep{ @@ -120,17 +122,17 @@ func TestAccAWSLightsailLoadBalancer_Name(t *testing.T) { { Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSLightsailLoadBalancerExists("aws_lightsail_load_balancer.lightsail_load_balancer_test", &conf), - resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "health_check_path"), - resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "instance_port"), + testAccCheckAWSLightsailLoadBalancerExists(resourceName, &conf), + resource.TestCheckResourceAttrSet(resourceName, "health_check_path"), + resource.TestCheckResourceAttrSet(resourceName, "instance_port"), ), }, { Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailNameWithUnderscore), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSLightsailLoadBalancerExists("aws_lightsail_load_balancer.lightsail_load_balancer_test", &conf), - resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "health_check_path"), - resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "instance_port"), + testAccCheckAWSLightsailLoadBalancerExists(resourceName, &conf), + resource.TestCheckResourceAttrSet(resourceName, "health_check_path"), + resource.TestCheckResourceAttrSet(resourceName, "instance_port"), ), }, }, @@ -139,30 +141,31 @@ func TestAccAWSLightsailLoadBalancer_Name(t *testing.T) { func TestAccAWSLightsailLoadBalancer_Tags(t *testing.T) { var conf lightsail.LoadBalancer - lightsailLoadBalancerName := fmt.Sprintf("tf-test-lightsail-%d", acctest.RandInt()) + lightsailLoadBalancerName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_lightsail_load_balancer.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSLightsail(t) }, - IDRefreshName: "aws_lightsail_load_balancer.lightsail_load_balancer_test", + IDRefreshName: resourceName, Providers: testAccProviders, CheckDestroy: testAccCheckAWSLightsailLoadBalancerDestroy, Steps: []resource.TestStep{ { Config: testAccAWSLightsailLoadBalancerConfig_tags1(lightsailLoadBalancerName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSLightsailLoadBalancerExists("aws_lightsail_load_balancer.lightsail_load_balancer_test", &conf), - resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "health_check_path"), - resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "instance_port"), - resource.TestCheckResourceAttr("aws_lightsail_load_balancer.lightsail_load_balancer_test", "tags.%", "1"), + testAccCheckAWSLightsailLoadBalancerExists(resourceName, &conf), + resource.TestCheckResourceAttrSet(resourceName, "health_check_path"), + resource.TestCheckResourceAttrSet(resourceName, "instance_port"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), ), }, { Config: testAccAWSLightsailLoadBalancerConfig_tags2(lightsailLoadBalancerName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSLightsailLoadBalancerExists("aws_lightsail_load_balancer.lightsail_load_balancer_test", &conf), - resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "health_check_path"), - resource.TestCheckResourceAttrSet("aws_lightsail_load_balancer.lightsail_load_balancer_test", "instance_port"), - resource.TestCheckResourceAttr("aws_lightsail_load_balancer.lightsail_load_balancer_test", "tags.%", "2"), + testAccCheckAWSLightsailLoadBalancerExists(resourceName, &conf), + resource.TestCheckResourceAttrSet(resourceName, "health_check_path"), + resource.TestCheckResourceAttrSet(resourceName, "instance_port"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), ), }, }, @@ -200,7 +203,8 @@ func testAccCheckAWSLightsailLoadBalancerExists(n string, res *lightsail.LoadBal func TestAccAWSLightsailLoadBalancer_disappear(t *testing.T) { var conf lightsail.LoadBalancer - lightsailLoadBalancerName := fmt.Sprintf("tf-test-lightsail-%d", acctest.RandInt()) + lightsailLoadBalancerName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_lightsail_load_balancer.test" testDestroy := func(*terraform.State) error { // reach out and DELETE the Load Balancer @@ -227,7 +231,7 @@ func TestAccAWSLightsailLoadBalancer_disappear(t *testing.T) { { Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailLoadBalancerName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSLightsailLoadBalancerExists("aws_lightsail_load_balancer.lightsail_load_balancer_test", &conf), + testAccCheckAWSLightsailLoadBalancerExists(resourceName, &conf), testDestroy, ), ExpectNonEmptyPlan: true, @@ -269,7 +273,7 @@ func testAccCheckAWSLightsailLoadBalancerDestroy(s *terraform.State) error { func testAccAWSLightsailLoadBalancerConfig_basic(lightsailLoadBalancerName string) string { return fmt.Sprintf(` -resource "aws_lightsail_load_balancer" "lightsail_load_balancer_test" { +resource "aws_lightsail_load_balancer" "test" { name = "%s" health_check_path = "/" instance_port = "80" @@ -279,7 +283,7 @@ resource "aws_lightsail_load_balancer" "lightsail_load_balancer_test" { func testAccAWSLightsailLoadBalancerConfig_tags1(lightsailLoadBalancerName string) string { return fmt.Sprintf(` -resource "aws_lightsail_load_balancer" "lightsail_load_balancer_test" { +resource "aws_lightsail_load_balancer" "test" { name = "%s" health_check_path = "/" instance_port = "80" @@ -292,7 +296,7 @@ resource "aws_lightsail_load_balancer" "lightsail_load_balancer_test" { func testAccAWSLightsailLoadBalancerConfig_tags2(lightsailLoadBalancerName string) string { return fmt.Sprintf(` -resource "aws_lightsail_load_balancer" "lightsail_load_balancer_test" { +resource "aws_lightsail_load_balancer" "test" { name = "%s" health_check_path = "/" instance_port = "80" From 6a146ba316a57d195685425c370c232b3e6fc700 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung Date: Tue, 2 Mar 2021 10:50:46 -0500 Subject: [PATCH 09/15] FIxed: * old reference to glue * string reference oid * waiter import --- aws/internal/service/lightsail/waiter/status.go | 2 +- aws/internal/service/lightsail/waiter/waiter.go | 2 +- aws/resource_aws_lightsail_load_balancer.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/aws/internal/service/lightsail/waiter/status.go b/aws/internal/service/lightsail/waiter/status.go index a31c50e5d70..9acac3d115d 100644 --- a/aws/internal/service/lightsail/waiter/status.go +++ b/aws/internal/service/lightsail/waiter/status.go @@ -12,7 +12,7 @@ import ( func LightsailOperationStatus(conn *lightsail.Lightsail, oid string) resource.StateRefreshFunc { return func() (interface{}, string, error) { input := &lightsail.GetOperationInput{ - OperationId: oid, + OperationId: aws.String(oid), } log.Printf("[DEBUG] Checking if Lightsail Operation (%s) is Completed", &oid) diff --git a/aws/internal/service/lightsail/waiter/waiter.go b/aws/internal/service/lightsail/waiter/waiter.go index 467eeb88acb..bb51f3a96c4 100644 --- a/aws/internal/service/lightsail/waiter/waiter.go +++ b/aws/internal/service/lightsail/waiter/waiter.go @@ -40,7 +40,7 @@ func OperationCreated(conn *lightsail.Lightsail, oid string) (*lightsail.GetOper outputRaw, err := stateConf.WaitForState() - if output, ok := outputRaw.(*glue.GetOperationOutput); ok { + if output, ok := outputRaw.(*lightsail.GetOperationOutput); ok { return output, err } diff --git a/aws/resource_aws_lightsail_load_balancer.go b/aws/resource_aws_lightsail_load_balancer.go index 7f58594d840..d981e8e6265 100644 --- a/aws/resource_aws_lightsail_load_balancer.go +++ b/aws/resource_aws_lightsail_load_balancer.go @@ -6,7 +6,7 @@ import ( "regexp" "time" - "./aws/internal/service/lightsail/waiter" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/lightsail/waiter" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" From df2e0e340e3a83b4ea8becefd68d78108b5e10d2 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung Date: Tue, 2 Mar 2021 10:52:01 -0500 Subject: [PATCH 10/15] added aws sdk import --- aws/internal/service/lightsail/waiter/status.go | 1 + 1 file changed, 1 insertion(+) diff --git a/aws/internal/service/lightsail/waiter/status.go b/aws/internal/service/lightsail/waiter/status.go index 9acac3d115d..70a28bdd6f2 100644 --- a/aws/internal/service/lightsail/waiter/status.go +++ b/aws/internal/service/lightsail/waiter/status.go @@ -4,6 +4,7 @@ import ( "fmt" "log" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/lightsail" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) From 26ae51426849d85f432ee9e36888e604ca955b68 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung Date: Tue, 2 Mar 2021 13:59:32 -0500 Subject: [PATCH 11/15] Fixed: Waiter input type Feature: Path acctests added --- .../service/lightsail/waiter/status.go | 5 +- .../service/lightsail/waiter/waiter.go | 2 +- ...source_aws_lightsail_load_balancer_test.go | 175 +++++++++++------- 3 files changed, 111 insertions(+), 71 deletions(-) diff --git a/aws/internal/service/lightsail/waiter/status.go b/aws/internal/service/lightsail/waiter/status.go index 70a28bdd6f2..a072135a6fe 100644 --- a/aws/internal/service/lightsail/waiter/status.go +++ b/aws/internal/service/lightsail/waiter/status.go @@ -4,16 +4,15 @@ import ( "fmt" "log" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/lightsail" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) // LightsailOperationStatus is a method to check the status of a Lightsail Operation -func LightsailOperationStatus(conn *lightsail.Lightsail, oid string) resource.StateRefreshFunc { +func LightsailOperationStatus(conn *lightsail.Lightsail, oid *string) resource.StateRefreshFunc { return func() (interface{}, string, error) { input := &lightsail.GetOperationInput{ - OperationId: aws.String(oid), + OperationId: oid, } log.Printf("[DEBUG] Checking if Lightsail Operation (%s) is Completed", &oid) diff --git a/aws/internal/service/lightsail/waiter/waiter.go b/aws/internal/service/lightsail/waiter/waiter.go index bb51f3a96c4..a8737f25355 100644 --- a/aws/internal/service/lightsail/waiter/waiter.go +++ b/aws/internal/service/lightsail/waiter/waiter.go @@ -28,7 +28,7 @@ const ( ) // OperationCreated waits for an Operation to return Succeeded or Compleated -func OperationCreated(conn *lightsail.Lightsail, oid string) (*lightsail.GetOperationOutput, error) { +func OperationCreated(conn *lightsail.Lightsail, oid *string) (*lightsail.GetOperationOutput, error) { stateConf := &resource.StateChangeConf{ Pending: []string{OperationStatusStarted}, Target: []string{OperationStatusCompleted, OperationStatusSucceeded}, diff --git a/aws/resource_aws_lightsail_load_balancer_test.go b/aws/resource_aws_lightsail_load_balancer_test.go index 07e3ec9df0d..8947b3dcc53 100644 --- a/aws/resource_aws_lightsail_load_balancer_test.go +++ b/aws/resource_aws_lightsail_load_balancer_test.go @@ -6,7 +6,6 @@ import ( "log" "regexp" "testing" - "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" @@ -73,8 +72,8 @@ func testSweepLightsailLoadBalancers(region string) error { } func TestAccAWSLightsailLoadBalancer_basic(t *testing.T) { - var loadBalancer lightsail.LoadBalancer - lightsailLoadBalancerName := acctest.RandomWithPrefix("tf-acc-test") + var lb lightsail.LoadBalancer + rName := acctest.RandomWithPrefix("tf-acc-test") resourceName := "aws_lightsail_load_balancer.test" resource.ParallelTest(t, resource.TestCase{ @@ -84,25 +83,29 @@ func TestAccAWSLightsailLoadBalancer_basic(t *testing.T) { CheckDestroy: testAccCheckAWSLightsailLoadBalancerDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailLoadBalancerName), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSLightsailLoadBalancerExists(resourceName, &loadBalancer), - resource.TestCheckResourceAttrSet(resourceName, "health_check_path"), - resource.TestCheckResourceAttrSet(resourceName, "instance_port"), + Config: testAccAWSLightsailLoadBalancerConfigBasic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSLightsailLoadBalancerExists(resourceName, &lb), + resource.TestCheckResourceAttr(resourceName, "health_check_path", "/"), + resource.TestCheckResourceAttr(resourceName, "instance_port", "80"), resource.TestCheckResourceAttrSet(resourceName, "dns_name"), - resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } func TestAccAWSLightsailLoadBalancer_Name(t *testing.T) { - var conf lightsail.LoadBalancer - lightsailName := acctest.RandomWithPrefix("tf-acc-test") - lightsailNameWithSpaces := fmt.Sprint(lightsailName, "string with spaces") - lightsailNameWithStartingDigit := fmt.Sprintf("01-%s", lightsailName) - lightsailNameWithUnderscore := fmt.Sprintf("%s_123456", lightsailName) + var lb lightsail.LoadBalancer + rName := acctest.RandomWithPrefix("tf-acc-test") + lightsailNameWithSpaces := fmt.Sprint(rName, "string with spaces") + lightsailNameWithStartingDigit := fmt.Sprintf("01-%s", rName) + lightsailNameWithUnderscore := fmt.Sprintf("%s_123456", rName) resourceName := "aws_lightsail_load_balancer.test" resource.ParallelTest(t, resource.TestCase{ @@ -112,25 +115,25 @@ func TestAccAWSLightsailLoadBalancer_Name(t *testing.T) { CheckDestroy: testAccCheckAWSLightsailLoadBalancerDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailNameWithSpaces), + Config: testAccAWSLightsailLoadBalancerConfigBasic(lightsailNameWithSpaces), ExpectError: regexp.MustCompile(`must contain only alphanumeric characters, underscores, hyphens, and dots`), }, { - Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailNameWithStartingDigit), + Config: testAccAWSLightsailLoadBalancerConfigBasic(lightsailNameWithStartingDigit), ExpectError: regexp.MustCompile(`must begin with an alphabetic character`), }, { - Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailName), + Config: testAccAWSLightsailLoadBalancerConfigBasic(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSLightsailLoadBalancerExists(resourceName, &conf), + testAccCheckAWSLightsailLoadBalancerExists(resourceName, &lb), resource.TestCheckResourceAttrSet(resourceName, "health_check_path"), resource.TestCheckResourceAttrSet(resourceName, "instance_port"), ), }, { - Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailNameWithUnderscore), + Config: testAccAWSLightsailLoadBalancerConfigBasic(lightsailNameWithUnderscore), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSLightsailLoadBalancerExists(resourceName, &conf), + testAccCheckAWSLightsailLoadBalancerExists(resourceName, &lb), resource.TestCheckResourceAttrSet(resourceName, "health_check_path"), resource.TestCheckResourceAttrSet(resourceName, "instance_port"), ), @@ -139,9 +142,42 @@ func TestAccAWSLightsailLoadBalancer_Name(t *testing.T) { }) } +func TestAccAWSLightsailLoadBalancer_Path(t *testing.T) { + var lb lightsail.LoadBalancer + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_lightsail_load_balancer.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSLightsail(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSLightsailLoadBalancerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSLightsailLoadBalancerConfigPath(rName, "/"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSLightsailLoadBalancerExists(resourceName, &lb), + resource.TestCheckResourceAttr(resourceName, "health_check_path", "/"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSLightsailLoadBalancerConfigPath(rName, "/healthcheck"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSLightsailLoadBalancerExists(resourceName, &lb), + resource.TestCheckResourceAttr(resourceName, "health_check_path", "/healthcheck"), + ), + }, + }, + }) +} + func TestAccAWSLightsailLoadBalancer_Tags(t *testing.T) { - var conf lightsail.LoadBalancer - lightsailLoadBalancerName := acctest.RandomWithPrefix("tf-acc-test") + var lb1, lb2, lb3 lightsail.LoadBalancer + rName := acctest.RandomWithPrefix("tf-acc-test") resourceName := "aws_lightsail_load_balancer.test" resource.ParallelTest(t, resource.TestCase{ @@ -151,21 +187,33 @@ func TestAccAWSLightsailLoadBalancer_Tags(t *testing.T) { CheckDestroy: testAccCheckAWSLightsailLoadBalancerDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSLightsailLoadBalancerConfig_tags1(lightsailLoadBalancerName), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSLightsailLoadBalancerExists(resourceName, &conf), - resource.TestCheckResourceAttrSet(resourceName, "health_check_path"), - resource.TestCheckResourceAttrSet(resourceName, "instance_port"), + Config: testAccAWSLightsailLoadBalancerConfigTags1(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSLightsailLoadBalancerExists(resourceName, &lb1), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), ), }, { - Config: testAccAWSLightsailLoadBalancerConfig_tags2(lightsailLoadBalancerName), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSLightsailLoadBalancerExists(resourceName, &conf), - resource.TestCheckResourceAttrSet(resourceName, "health_check_path"), - resource.TestCheckResourceAttrSet(resourceName, "instance_port"), + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAWSLightsailLoadBalancerConfigTags2(rName, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSLightsailLoadBalancerExists(resourceName, &lb2), resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccAWSLightsailLoadBalancerConfigTags1(rName, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSLightsailLoadBalancerExists(resourceName, &lb3), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), ), }, }, @@ -201,38 +249,21 @@ func testAccCheckAWSLightsailLoadBalancerExists(n string, res *lightsail.LoadBal } } -func TestAccAWSLightsailLoadBalancer_disappear(t *testing.T) { - var conf lightsail.LoadBalancer - lightsailLoadBalancerName := acctest.RandomWithPrefix("tf-acc-test") +func TestAccAWSLightsailLoadBalancer_disappears(t *testing.T) { + var lb lightsail.LoadBalancer + rName := acctest.RandomWithPrefix("tf-acc-test") resourceName := "aws_lightsail_load_balancer.test" - testDestroy := func(*terraform.State) error { - // reach out and DELETE the Load Balancer - conn := testAccProvider.Meta().(*AWSClient).lightsailconn - _, err := conn.DeleteLoadBalancer(&lightsail.DeleteLoadBalancerInput{ - LoadBalancerName: aws.String(lightsailLoadBalancerName), - }) - - if err != nil { - return fmt.Errorf("error deleting Lightsail Load Balancer in disappear test") - } - - // sleep 7 seconds to give it time, so we don't have to poll - time.Sleep(7 * time.Second) - - return nil - } - resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSLightsail(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAWSLightsailLoadBalancerDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSLightsailLoadBalancerConfig_basic(lightsailLoadBalancerName), + Config: testAccAWSLightsailLoadBalancerConfigBasic(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSLightsailLoadBalancerExists(resourceName, &conf), - testDestroy, + testAccCheckAWSLightsailLoadBalancerExists(resourceName, &lb), + testAccCheckResourceDisappears(testAccProvider, resourceAwsLightsailLoadBalancer(), resourceName), ), ExpectNonEmptyPlan: true, }, @@ -271,39 +302,49 @@ func testAccCheckAWSLightsailLoadBalancerDestroy(s *terraform.State) error { return nil } -func testAccAWSLightsailLoadBalancerConfig_basic(lightsailLoadBalancerName string) string { +func testAccAWSLightsailLoadBalancerConfigBasic(rName string) string { return fmt.Sprintf(` resource "aws_lightsail_load_balancer" "test" { - name = "%s" + name = %[1]q health_check_path = "/" instance_port = "80" } -`, lightsailLoadBalancerName) +`, rName) +} + +func testAccAWSLightsailLoadBalancerConfigPath(rName string, rPath string) string { + return fmt.Sprintf(` +resource "aws_lightsail_load_balancer" "test" { + name = %[1]q + health_check_path = %[2]q + instance_port = "80" +} +`, rName, rPath) } -func testAccAWSLightsailLoadBalancerConfig_tags1(lightsailLoadBalancerName string) string { +func testAccAWSLightsailLoadBalancerConfigTags1(rName string, tagKey1, tagValue1 string) string { return fmt.Sprintf(` resource "aws_lightsail_load_balancer" "test" { - name = "%s" + name = %[1]q health_check_path = "/" instance_port = "80" tags = { - Name = "tf-test" + %[2]q = %[3]q } } -`, lightsailLoadBalancerName) +`, rName, tagKey1, tagValue1) } -func testAccAWSLightsailLoadBalancerConfig_tags2(lightsailLoadBalancerName string) string { +func testAccAWSLightsailLoadBalancerConfigTags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { return fmt.Sprintf(` resource "aws_lightsail_load_balancer" "test" { - name = "%s" + name = %[1]q health_check_path = "/" instance_port = "80" tags = { - Name = "tf-test" - ExtraName = "tf-test" + %[2]q = %[3]q + %[4]q = %[5]q } } -`, lightsailLoadBalancerName) +`, rName, tagKey1, tagValue1, tagKey2, tagValue2) } From d9beabdd3fbcc2604573d095606e800ac709c37a Mon Sep 17 00:00:00 2001 From: Brittan DeYoung Date: Tue, 2 Mar 2021 14:15:09 -0500 Subject: [PATCH 12/15] Updated healthcheckpath test name --- aws/resource_aws_lightsail_load_balancer_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/aws/resource_aws_lightsail_load_balancer_test.go b/aws/resource_aws_lightsail_load_balancer_test.go index 8947b3dcc53..deab8830fa9 100644 --- a/aws/resource_aws_lightsail_load_balancer_test.go +++ b/aws/resource_aws_lightsail_load_balancer_test.go @@ -142,7 +142,7 @@ func TestAccAWSLightsailLoadBalancer_Name(t *testing.T) { }) } -func TestAccAWSLightsailLoadBalancer_Path(t *testing.T) { +func TestAccAWSLightsailLoadBalancer_HealthCheckPath(t *testing.T) { var lb lightsail.LoadBalancer rName := acctest.RandomWithPrefix("tf-acc-test") resourceName := "aws_lightsail_load_balancer.test" @@ -153,7 +153,7 @@ func TestAccAWSLightsailLoadBalancer_Path(t *testing.T) { CheckDestroy: testAccCheckAWSLightsailLoadBalancerDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSLightsailLoadBalancerConfigPath(rName, "/"), + Config: testAccAWSLightsailLoadBalancerConfigHealthCheckPath(rName, "/"), Check: resource.ComposeTestCheckFunc( testAccCheckAWSLightsailLoadBalancerExists(resourceName, &lb), resource.TestCheckResourceAttr(resourceName, "health_check_path", "/"), @@ -165,7 +165,7 @@ func TestAccAWSLightsailLoadBalancer_Path(t *testing.T) { ImportStateVerify: true, }, { - Config: testAccAWSLightsailLoadBalancerConfigPath(rName, "/healthcheck"), + Config: testAccAWSLightsailLoadBalancerConfigHealthCheckPath(rName, "/healthcheck"), Check: resource.ComposeTestCheckFunc( testAccCheckAWSLightsailLoadBalancerExists(resourceName, &lb), resource.TestCheckResourceAttr(resourceName, "health_check_path", "/healthcheck"), @@ -312,7 +312,7 @@ resource "aws_lightsail_load_balancer" "test" { `, rName) } -func testAccAWSLightsailLoadBalancerConfigPath(rName string, rPath string) string { +func testAccAWSLightsailLoadBalancerConfigHealthCheckPath(rName string, rPath string) string { return fmt.Sprintf(` resource "aws_lightsail_load_balancer" "test" { name = %[1]q From be02e54585d3652a5dd9fe4633b1c41916a529ba Mon Sep 17 00:00:00 2001 From: Brittan DeYoung Date: Tue, 2 Mar 2021 14:51:44 -0500 Subject: [PATCH 13/15] fixed import order an String format --- aws/internal/service/lightsail/waiter/status.go | 8 +++++--- aws/resource_aws_lightsail_load_balancer.go | 3 +-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/aws/internal/service/lightsail/waiter/status.go b/aws/internal/service/lightsail/waiter/status.go index a072135a6fe..49aabe6625d 100644 --- a/aws/internal/service/lightsail/waiter/status.go +++ b/aws/internal/service/lightsail/waiter/status.go @@ -14,7 +14,9 @@ func LightsailOperationStatus(conn *lightsail.Lightsail, oid *string) resource.S input := &lightsail.GetOperationInput{ OperationId: oid, } - log.Printf("[DEBUG] Checking if Lightsail Operation (%s) is Completed", &oid) + + oidValue := *oid + log.Printf("[DEBUG] Checking if Lightsail Operation (%s) is Completed", oidValue) output, err := conn.GetOperation(input) @@ -23,10 +25,10 @@ func LightsailOperationStatus(conn *lightsail.Lightsail, oid *string) resource.S } if output.Operation == nil { - return nil, "Failed", fmt.Errorf("Error retrieving Operation info for operation (%s)", &oid) + return nil, "Failed", fmt.Errorf("Error retrieving Operation info for operation (%s)", oidValue) } - log.Printf("[DEBUG] Lightsail Operation (%s) is currently %q", &oid, *output.Operation.Status) + log.Printf("[DEBUG] Lightsail Operation (%s) is currently %q", oidValue, *output.Operation.Status) return output, *output.Operation.Status, nil } } diff --git a/aws/resource_aws_lightsail_load_balancer.go b/aws/resource_aws_lightsail_load_balancer.go index d981e8e6265..935bdbd7549 100644 --- a/aws/resource_aws_lightsail_load_balancer.go +++ b/aws/resource_aws_lightsail_load_balancer.go @@ -6,14 +6,13 @@ import ( "regexp" "time" - "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/lightsail/waiter" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/lightsail" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/lightsail/waiter" ) func resourceAwsLightsailLoadBalancer() *schema.Resource { From 72ad6568975a0240b6f393ec1e4d59c40b958226 Mon Sep 17 00:00:00 2001 From: Brittan DeYoung Date: Tue, 2 Mar 2021 14:54:59 -0500 Subject: [PATCH 14/15] switched to aws.stringvalue --- aws/internal/service/lightsail/waiter/status.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/aws/internal/service/lightsail/waiter/status.go b/aws/internal/service/lightsail/waiter/status.go index 49aabe6625d..2fc3d562da9 100644 --- a/aws/internal/service/lightsail/waiter/status.go +++ b/aws/internal/service/lightsail/waiter/status.go @@ -4,6 +4,8 @@ import ( "fmt" "log" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/lightsail" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) @@ -15,7 +17,7 @@ func LightsailOperationStatus(conn *lightsail.Lightsail, oid *string) resource.S OperationId: oid, } - oidValue := *oid + oidValue := aws.StringValue(oid) log.Printf("[DEBUG] Checking if Lightsail Operation (%s) is Completed", oidValue) output, err := conn.GetOperation(input) From cb72b94102d1d959438c6259eead34f95ee89bff Mon Sep 17 00:00:00 2001 From: Brittan DeYoung Date: Tue, 2 Mar 2021 15:03:31 -0500 Subject: [PATCH 15/15] resolved import order --- aws/internal/service/lightsail/waiter/status.go | 1 - 1 file changed, 1 deletion(-) diff --git a/aws/internal/service/lightsail/waiter/status.go b/aws/internal/service/lightsail/waiter/status.go index 2fc3d562da9..1be4377c7f3 100644 --- a/aws/internal/service/lightsail/waiter/status.go +++ b/aws/internal/service/lightsail/waiter/status.go @@ -5,7 +5,6 @@ import ( "log" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/lightsail" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" )