diff --git a/.changelog/18560.txt b/.changelog/18560.txt new file mode 100644 index 00000000000..3b152e3bcda --- /dev/null +++ b/.changelog/18560.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_cloud9_environment_ec2: Add plan time validations for `name`, `automatic_stop_time_minutes`, `description`. +``` diff --git a/internal/service/cloud9/environment_ec2.go b/internal/service/cloud9/environment_ec2.go index 79949481c96..ba5906d5821 100644 --- a/internal/service/cloud9/environment_ec2.go +++ b/internal/service/cloud9/environment_ec2.go @@ -3,13 +3,13 @@ package cloud9 import ( "fmt" "log" - "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/cloud9" "github.com/hashicorp/aws-sdk-go-base/tfawserr" "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/hashicorp/terraform-provider-aws/internal/conns" tfiam "github.com/hashicorp/terraform-provider-aws/internal/service/iam" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" @@ -30,8 +30,9 @@ func ResourceEnvironmentEC2() *schema.Resource { Schema: map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 60), }, "instance_type": { Type: schema.TypeString, @@ -39,13 +40,15 @@ func ResourceEnvironmentEC2() *schema.Resource { ForceNew: true, }, "automatic_stop_time_minutes": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + ValidateFunc: validation.IntAtMost(20160), }, "description": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(1, 200), }, "owner_arn": { Type: schema.TypeString, @@ -80,30 +83,32 @@ func resourceEnvironmentEC2Create(d *schema.ResourceData, meta interface{}) erro defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{}))) - params := &cloud9.CreateEnvironmentEC2Input{ - InstanceType: aws.String(d.Get("instance_type").(string)), - Name: aws.String(d.Get("name").(string)), + name := d.Get("name").(string) + input := &cloud9.CreateEnvironmentEC2Input{ ClientRequestToken: aws.String(resource.UniqueId()), + InstanceType: aws.String(d.Get("instance_type").(string)), + Name: aws.String(name), Tags: Tags(tags.IgnoreAWS()), } if v, ok := d.GetOk("automatic_stop_time_minutes"); ok { - params.AutomaticStopTimeMinutes = aws.Int64(int64(v.(int))) + input.AutomaticStopTimeMinutes = aws.Int64(int64(v.(int))) } if v, ok := d.GetOk("description"); ok { - params.Description = aws.String(v.(string)) + input.Description = aws.String(v.(string)) } if v, ok := d.GetOk("owner_arn"); ok { - params.OwnerArn = aws.String(v.(string)) + input.OwnerArn = aws.String(v.(string)) } if v, ok := d.GetOk("subnet_id"); ok { - params.SubnetId = aws.String(v.(string)) + input.SubnetId = aws.String(v.(string)) } - var out *cloud9.CreateEnvironmentEC2Output + log.Printf("[INFO] Creating Cloud9 EC2 Environment: %s", input) + var output *cloud9.CreateEnvironmentEC2Output err := resource.Retry(tfiam.PropagationTimeout, func() *resource.RetryError { var err error - out, err = conn.CreateEnvironmentEC2(params) + output, err = conn.CreateEnvironmentEC2(input) if err != nil { // NotFoundException: User arn:aws:iam::*******:user/****** does not exist. if tfawserr.ErrMessageContains(err, cloud9.ErrCodeNotFoundException, "User") { @@ -113,44 +118,21 @@ func resourceEnvironmentEC2Create(d *schema.ResourceData, meta interface{}) erro } return nil }) + if tfresource.TimedOut(err) { - out, err = conn.CreateEnvironmentEC2(params) + output, err = conn.CreateEnvironmentEC2(input) } if err != nil { - return fmt.Errorf("Error creating Cloud9 EC2 Environment: %s", err) + return fmt.Errorf("error creating Cloud9 EC2 Environment (%s): %w", name, err) } - d.SetId(aws.StringValue(out.EnvironmentId)) - stateConf := resource.StateChangeConf{ - Pending: []string{ - cloud9.EnvironmentStatusConnecting, - cloud9.EnvironmentStatusCreating, - }, - Target: []string{ - cloud9.EnvironmentStatusReady, - }, - Timeout: 10 * time.Minute, - Refresh: func() (interface{}, string, error) { - out, err := conn.DescribeEnvironmentStatus(&cloud9.DescribeEnvironmentStatusInput{ - EnvironmentId: aws.String(d.Id()), - }) - if err != nil { - return 42, "", err - } + d.SetId(aws.StringValue(output.EnvironmentId)) - status := aws.StringValue(out.Status) + _, err = waitEnvironmentReady(conn, d.Id()) - if status == cloud9.EnvironmentStatusError && out.Message != nil { - return out, status, fmt.Errorf("Reason: %s", aws.StringValue(out.Message)) - } - - return out, status, nil - }, - } - _, err = stateConf.WaitForState() if err != nil { - return err + return fmt.Errorf("error waiting for Cloud9 EC2 Environment (%s) create: %w", d.Id(), err) } return resourceEnvironmentEC2Read(d, meta) @@ -161,25 +143,17 @@ func resourceEnvironmentEC2Read(d *schema.ResourceData, meta interface{}) error defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig - log.Printf("[INFO] Reading Cloud9 Environment EC2 %s", d.Id()) + env, err := FindEnvironmentByID(conn, d.Id()) - out, err := conn.DescribeEnvironments(&cloud9.DescribeEnvironmentsInput{ - EnvironmentIds: []*string{aws.String(d.Id())}, - }) - if err != nil { - if tfawserr.ErrMessageContains(err, cloud9.ErrCodeNotFoundException, "") { - log.Printf("[WARN] Cloud9 Environment EC2 (%s) not found, removing from state", d.Id()) - d.SetId("") - return nil - } - return err - } - if len(out.Environments) == 0 { - log.Printf("[WARN] Cloud9 Environment EC2 (%s) not found, removing from state", d.Id()) + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] Cloud9 EC2 Environment (%s) not found, removing from state", d.Id()) d.SetId("") return nil } - env := out.Environments[0] + + if err != nil { + return fmt.Errorf("error reading Cloud9 EC2 Environment (%s): %w", d.Id(), err) + } arn := aws.StringValue(env.Arn) d.Set("arn", arn) @@ -191,7 +165,7 @@ func resourceEnvironmentEC2Read(d *schema.ResourceData, meta interface{}) error tags, err := ListTags(conn, arn) if err != nil { - return fmt.Errorf("error listing tags for Cloud9 EC2 Environment (%s): %s", arn, err) + return fmt.Errorf("error listing tags for Cloud9 EC2 Environment (%s): %w", arn, err) } tags = tags.IgnoreAWS().IgnoreConfig(ignoreTagsConfig) @@ -205,35 +179,33 @@ func resourceEnvironmentEC2Read(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("error setting tags_all: %w", err) } - log.Printf("[DEBUG] Received Cloud9 Environment EC2: %s", env) - return nil } func resourceEnvironmentEC2Update(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).Cloud9Conn - input := cloud9.UpdateEnvironmentInput{ - Description: aws.String(d.Get("description").(string)), - EnvironmentId: aws.String(d.Id()), - Name: aws.String(d.Get("name").(string)), - } + if d.HasChangesExcept("tags_all", "tags") { + input := cloud9.UpdateEnvironmentInput{ + Description: aws.String(d.Get("description").(string)), + EnvironmentId: aws.String(d.Id()), + Name: aws.String(d.Get("name").(string)), + } - log.Printf("[INFO] Updating Cloud9 Environment EC2: %s", input) + log.Printf("[INFO] Updating Cloud9 EC2 Environment: %s", input) + _, err := conn.UpdateEnvironment(&input) - out, err := conn.UpdateEnvironment(&input) - if err != nil { - return err + if err != nil { + return fmt.Errorf("error updating Cloud9 EC2 Environment (%s): %w", d.Id(), err) + } } - log.Printf("[DEBUG] Cloud9 Environment EC2 updated: %s", out) - if d.HasChange("tags_all") { o, n := d.GetChange("tags_all") arn := d.Get("arn").(string) if err := UpdateTags(conn, arn, o, n); err != nil { - return fmt.Errorf("error updating Cloud9 EC2 Environment (%s) tags: %s", arn, err) + return fmt.Errorf("error updating Cloud9 EC2 Environment (%s) tags: %w", arn, err) } } @@ -243,45 +215,24 @@ func resourceEnvironmentEC2Update(d *schema.ResourceData, meta interface{}) erro func resourceEnvironmentEC2Delete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).Cloud9Conn + log.Printf("[INFO] Deleting Cloud9 EC2 Environment: %s", d.Id()) _, err := conn.DeleteEnvironment(&cloud9.DeleteEnvironmentInput{ EnvironmentId: aws.String(d.Id()), }) - if err != nil { - return err - } - input := &cloud9.DescribeEnvironmentsInput{ - EnvironmentIds: []*string{aws.String(d.Id())}, + if tfawserr.ErrCodeEquals(err, cloud9.ErrCodeNotFoundException) { + return nil } - var out *cloud9.DescribeEnvironmentsOutput - err = resource.Retry(20*time.Minute, func() *resource.RetryError { // Deleting instances can take a long time - out, err = conn.DescribeEnvironments(input) - if err != nil { - if tfawserr.ErrMessageContains(err, cloud9.ErrCodeNotFoundException, "") { - return nil - } - // :'-( - if tfawserr.ErrMessageContains(err, "AccessDeniedException", "is not authorized to access this resource") { - return nil - } - return resource.NonRetryableError(err) - } - if len(out.Environments) == 0 { - return nil - } - return resource.RetryableError(fmt.Errorf("Cloud9 EC2 Environment %q still exists", d.Id())) - }) - if tfresource.TimedOut(err) { - out, err = conn.DescribeEnvironments(input) - if tfawserr.ErrMessageContains(err, cloud9.ErrCodeNotFoundException, "") { - return nil - } - if tfawserr.ErrMessageContains(err, "AccessDeniedException", "is not authorized to access this resource") { - return nil - } + + if err != nil { + return fmt.Errorf("error deleting Cloud9 EC2 Environment (%s): %w", d.Id(), err) } + + _, err = waitEnvironmentDeleted(conn, d.Id()) + if err != nil { - return fmt.Errorf("Error deleting Cloud9 EC2 Environment: %s", err) + return fmt.Errorf("error waiting for Cloud9 EC2 Environment (%s) delete: %w", d.Id(), err) } + return nil } diff --git a/internal/service/cloud9/environment_ec2_test.go b/internal/service/cloud9/environment_ec2_test.go index 0a93afc3de9..e6da44fa33f 100644 --- a/internal/service/cloud9/environment_ec2_test.go +++ b/internal/service/cloud9/environment_ec2_test.go @@ -4,16 +4,15 @@ import ( "fmt" "regexp" "testing" - "time" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/cloud9" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" sdkacctest "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" "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" + tfcloud9 "github.com/hashicorp/terraform-provider-aws/internal/service/cloud9" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) func TestAccCloud9EnvironmentEC2_basic(t *testing.T) { @@ -172,7 +171,8 @@ func TestAccCloud9EnvironmentEC2_disappears(t *testing.T) { Config: testAccEnvironmentEC2Config(rName), Check: resource.ComposeTestCheckFunc( testAccCheckEnvironmentEC2Exists(resourceName, &conf), - testAccCheckEnvironmentEC2Disappears(&conf), + acctest.CheckResourceDisappears(acctest.Provider, tfcloud9.ResourceEnvironmentEC2(), resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfcloud9.ResourceEnvironmentEC2(), resourceName), ), ExpectNonEmptyPlan: true, }, @@ -193,63 +193,17 @@ func testAccCheckEnvironmentEC2Exists(n string, res *cloud9.Environment) resourc conn := acctest.Provider.Meta().(*conns.AWSClient).Cloud9Conn - out, err := conn.DescribeEnvironments(&cloud9.DescribeEnvironmentsInput{ - EnvironmentIds: []*string{aws.String(rs.Primary.ID)}, - }) + out, err := tfcloud9.FindEnvironmentByID(conn, rs.Primary.ID) if err != nil { - if tfawserr.ErrMessageContains(err, cloud9.ErrCodeNotFoundException, "") { - return fmt.Errorf("Cloud9 Environment EC2 (%q) not found", rs.Primary.ID) - } return err } - if len(out.Environments) == 0 { - return fmt.Errorf("Cloud9 Environment EC2 (%q) not found", rs.Primary.ID) - } - env := out.Environments[0] - *res = *env + *res = *out return nil } } -func testAccCheckEnvironmentEC2Disappears(res *cloud9.Environment) resource.TestCheckFunc { - return func(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).Cloud9Conn - - _, err := conn.DeleteEnvironment(&cloud9.DeleteEnvironmentInput{ - EnvironmentId: res.Id, - }) - - if err != nil { - return err - } - - input := &cloud9.DescribeEnvironmentsInput{ - EnvironmentIds: []*string{res.Id}, - } - var out *cloud9.DescribeEnvironmentsOutput - err = resource.Retry(20*time.Minute, func() *resource.RetryError { // Deleting instances can take a long time - out, err = conn.DescribeEnvironments(input) - if err != nil { - if tfawserr.ErrMessageContains(err, cloud9.ErrCodeNotFoundException, "") { - return nil - } - if tfawserr.ErrMessageContains(err, "AccessDeniedException", "is not authorized to access this resource") { - return nil - } - return resource.NonRetryableError(err) - } - if len(out.Environments) == 0 { - return nil - } - return resource.RetryableError(fmt.Errorf("Cloud9 EC2 Environment %q still exists", aws.StringValue(res.Id))) - }) - - return err - } -} - func testAccCheckEnvironmentEC2Destroy(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).Cloud9Conn @@ -258,22 +212,15 @@ func testAccCheckEnvironmentEC2Destroy(s *terraform.State) error { continue } - out, err := conn.DescribeEnvironments(&cloud9.DescribeEnvironmentsInput{ - EnvironmentIds: []*string{aws.String(rs.Primary.ID)}, - }) + _, err := tfcloud9.FindEnvironmentByID(conn, rs.Primary.ID) + + if tfresource.NotFound(err) { + continue + } + if err != nil { - if tfawserr.ErrMessageContains(err, cloud9.ErrCodeNotFoundException, "") { - return nil - } - // :'-( - if tfawserr.ErrMessageContains(err, "AccessDeniedException", "is not authorized to access this resource") { - return nil - } return err } - if len(out.Environments) == 0 { - return nil - } return fmt.Errorf("Cloud9 Environment EC2 %q still exists.", rs.Primary.ID) } @@ -330,8 +277,6 @@ resource "aws_route" "test" { func testAccEnvironmentEC2Config(name string) string { return testAccEnvironmentEC2BaseConfig() + fmt.Sprintf(` resource "aws_cloud9_environment_ec2" "test" { - depends_on = [aws_route.test] - instance_type = "t2.micro" name = %[1]q subnet_id = aws_subnet.test.id @@ -345,8 +290,6 @@ data "aws_caller_identity" "current" {} func testAccEnvironmentEC2AllFieldsConfig(name, description, userName string) string { return testAccEnvironmentEC2BaseConfig() + fmt.Sprintf(` resource "aws_cloud9_environment_ec2" "test" { - depends_on = [aws_route.test] - automatic_stop_time_minutes = 60 description = %[2]q instance_type = "t2.micro" @@ -364,8 +307,6 @@ resource "aws_iam_user" "test" { func testAccEnvironmentEC2Tags1Config(name, tagKey1, tagValue1 string) string { return testAccEnvironmentEC2BaseConfig() + fmt.Sprintf(` resource "aws_cloud9_environment_ec2" "test" { - depends_on = [aws_route.test] - instance_type = "t2.micro" name = %[1]q subnet_id = aws_subnet.test.id @@ -380,8 +321,6 @@ resource "aws_cloud9_environment_ec2" "test" { func testAccEnvironmentEC2Tags2Config(name, tagKey1, tagValue1, tagKey2, tagValue2 string) string { return testAccEnvironmentEC2BaseConfig() + fmt.Sprintf(` resource "aws_cloud9_environment_ec2" "test" { - depends_on = [aws_route.test] - instance_type = "t2.micro" name = %[1]q subnet_id = aws_subnet.test.id diff --git a/internal/service/cloud9/find.go b/internal/service/cloud9/find.go new file mode 100644 index 00000000000..4a1dd65aa54 --- /dev/null +++ b/internal/service/cloud9/find.go @@ -0,0 +1,41 @@ +package cloud9 + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/cloud9" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" +) + +func FindEnvironmentByID(conn *cloud9.Cloud9, id string) (*cloud9.Environment, error) { + input := &cloud9.DescribeEnvironmentsInput{ + EnvironmentIds: []*string{aws.String(id)}, + } + out, err := conn.DescribeEnvironments(input) + + if tfawserr.ErrCodeEquals(err, cloud9.ErrCodeNotFoundException) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + envs := out.Environments + + if len(envs) == 0 { + return nil, tfresource.NewEmptyResultError(input) + } + + env := envs[0] + + if env == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + return env, nil +} diff --git a/internal/service/cloud9/status.go b/internal/service/cloud9/status.go new file mode 100644 index 00000000000..8e263f10f61 --- /dev/null +++ b/internal/service/cloud9/status.go @@ -0,0 +1,31 @@ +package cloud9 + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/cloud9" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" +) + +func statusEnvironmentStatus(conn *cloud9.Cloud9, id string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + out, err := FindEnvironmentByID(conn, id) + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + lifecycle := out.Lifecycle + status := aws.StringValue(lifecycle.Status) + if status == cloud9.EnvironmentStatusError && lifecycle.Reason != nil { + return out, status, fmt.Errorf("Reason: %s", aws.StringValue(lifecycle.Reason)) + } + + return out, status, nil + } +} diff --git a/internal/service/cloud9/sweep.go b/internal/service/cloud9/sweep.go new file mode 100644 index 00000000000..a60f64a2d4d --- /dev/null +++ b/internal/service/cloud9/sweep.go @@ -0,0 +1,65 @@ +//go:build sweep +// +build sweep + +package cloud9 + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/cloud9" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/sweep" +) + +func init() { + resource.AddTestSweepers("aws_cloud9_environment_ec2", &resource.Sweeper{ + Name: "aws_cloud9_environment_ec2", + F: sweepEnvironmentEC2s, + }) +} + +func sweepEnvironmentEC2s(region string) error { + client, err := sweep.SharedRegionalSweepClient(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*conns.AWSClient).Cloud9Conn + input := &cloud9.ListEnvironmentsInput{} + sweepResources := make([]*sweep.SweepResource, 0) + + err = conn.ListEnvironmentsPages(input, func(page *cloud9.ListEnvironmentsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.EnvironmentIds { + r := ResourceEnvironmentEC2() + d := r.Data(nil) + d.SetId(aws.StringValue(v)) + + sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) + } + + return !lastPage + }) + + if sweep.SkipSweepError(err) { + log.Printf("[WARN] Skipping Cloud9 EC2 Environment sweep for %s: %s", region, err) + return nil + } + + if err != nil { + return fmt.Errorf("error listing Cloud9 EC2 Environments (%s): %w", region, err) + } + + err = sweep.SweepOrchestrator(sweepResources) + + if err != nil { + return fmt.Errorf("error sweeping Cloud9 EC2 Environments (%s): %w", region, err) + } + + return nil +} diff --git a/internal/service/cloud9/wait.go b/internal/service/cloud9/wait.go new file mode 100644 index 00000000000..893f682d004 --- /dev/null +++ b/internal/service/cloud9/wait.go @@ -0,0 +1,47 @@ +package cloud9 + +import ( + "time" + + "github.com/aws/aws-sdk-go/service/cloud9" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +const ( + EnvironmentReadyTimeout = 10 * time.Minute + EnvironmentDeletedTimeout = 20 * time.Minute +) + +func waitEnvironmentReady(conn *cloud9.Cloud9, id string) (*cloud9.DescribeEnvironmentStatusOutput, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{cloud9.EnvironmentLifecycleStatusCreating}, + Target: []string{cloud9.EnvironmentLifecycleStatusCreated}, + Refresh: statusEnvironmentStatus(conn, id), + Timeout: EnvironmentReadyTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if output, ok := outputRaw.(*cloud9.DescribeEnvironmentStatusOutput); ok { + return output, err + } + + return nil, err +} + +func waitEnvironmentDeleted(conn *cloud9.Cloud9, id string) (*cloud9.DescribeEnvironmentStatusOutput, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{cloud9.EnvironmentLifecycleStatusDeleting}, + Target: []string{}, + Refresh: statusEnvironmentStatus(conn, id), + Timeout: EnvironmentDeletedTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if output, ok := outputRaw.(*cloud9.DescribeEnvironmentStatusOutput); ok { + return output, err + } + + return nil, err +} diff --git a/internal/service/ec2/sweep.go b/internal/service/ec2/sweep.go index 7f543b29df7..47934a017f2 100644 --- a/internal/service/ec2/sweep.go +++ b/internal/service/ec2/sweep.go @@ -167,6 +167,7 @@ func init() { "aws_autoscaling_group", "aws_batch_compute_environment", "aws_elastic_beanstalk_environment", + "aws_cloud9_environment_ec2", "aws_cloudhsm_v2_cluster", "aws_db_subnet_group", "aws_directory_service_directory", diff --git a/internal/sweep/sweep_test.go b/internal/sweep/sweep_test.go index b41ebdce0be..d113b173884 100644 --- a/internal/sweep/sweep_test.go +++ b/internal/sweep/sweep_test.go @@ -23,6 +23,7 @@ import ( _ "github.com/hashicorp/terraform-provider-aws/internal/service/backup" _ "github.com/hashicorp/terraform-provider-aws/internal/service/batch" _ "github.com/hashicorp/terraform-provider-aws/internal/service/budgets" + _ "github.com/hashicorp/terraform-provider-aws/internal/service/cloud9" _ "github.com/hashicorp/terraform-provider-aws/internal/service/cloudformation" _ "github.com/hashicorp/terraform-provider-aws/internal/service/cloudfront" _ "github.com/hashicorp/terraform-provider-aws/internal/service/cloudhsmv2"