From 0c8f3811c9bfe2974a0fa27c403478cebd11bc1c Mon Sep 17 00:00:00 2001 From: Boran Car Date: Mon, 1 Feb 2021 20:49:55 +0100 Subject: [PATCH 001/116] Fix data source aws_vpc_peering_connections The data source errors out if there are no connections to return, but should instead return an empty array and let the user decide. --- .changelog/17382.txt | 3 +++ internal/service/ec2/vpc_peering_connections_data_source.go | 5 ----- 2 files changed, 3 insertions(+), 5 deletions(-) create mode 100644 .changelog/17382.txt diff --git a/.changelog/17382.txt b/.changelog/17382.txt new file mode 100644 index 00000000000..d9da4cf9cf3 --- /dev/null +++ b/.changelog/17382.txt @@ -0,0 +1,3 @@ +```release-note:bug +data-source/aws_vpc_peering_connections: Return empty array instead of error when no connections found. +``` diff --git a/internal/service/ec2/vpc_peering_connections_data_source.go b/internal/service/ec2/vpc_peering_connections_data_source.go index 948a0b296de..d06baf8a3f9 100644 --- a/internal/service/ec2/vpc_peering_connections_data_source.go +++ b/internal/service/ec2/vpc_peering_connections_data_source.go @@ -1,8 +1,6 @@ package ec2 import ( - "fmt" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -47,9 +45,6 @@ func dataSourceVPCPeeringConnectionsRead(d *schema.ResourceData, meta interface{ if err != nil { return err } - if resp == nil || len(resp.VpcPeeringConnections) == 0 { - return fmt.Errorf("no matching VPC peering connections found") - } var ids []string for _, pcx := range resp.VpcPeeringConnections { From b0b7b7e92eca2f0290377b1167eb1d8106750d96 Mon Sep 17 00:00:00 2001 From: Boran Car Date: Thu, 11 Feb 2021 18:05:07 +0100 Subject: [PATCH 002/116] Prevent potential panics --- internal/service/ec2/vpc_peering_connections_data_source.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/service/ec2/vpc_peering_connections_data_source.go b/internal/service/ec2/vpc_peering_connections_data_source.go index d06baf8a3f9..698c511fe8f 100644 --- a/internal/service/ec2/vpc_peering_connections_data_source.go +++ b/internal/service/ec2/vpc_peering_connections_data_source.go @@ -45,6 +45,9 @@ func dataSourceVPCPeeringConnectionsRead(d *schema.ResourceData, meta interface{ if err != nil { return err } + if resp == nil { + return fmt.Errorf("error reading EC2 VPC Peering Connections: empty response") + } var ids []string for _, pcx := range resp.VpcPeeringConnections { From 10c02d63b628e1b1b309b342f8c034c2a20910d0 Mon Sep 17 00:00:00 2001 From: Boran Car Date: Thu, 11 Feb 2021 18:59:26 +0100 Subject: [PATCH 003/116] Re-add fmt --- internal/service/ec2/vpc_peering_connections_data_source.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/service/ec2/vpc_peering_connections_data_source.go b/internal/service/ec2/vpc_peering_connections_data_source.go index 698c511fe8f..70ac96734ef 100644 --- a/internal/service/ec2/vpc_peering_connections_data_source.go +++ b/internal/service/ec2/vpc_peering_connections_data_source.go @@ -1,6 +1,8 @@ package ec2 import ( + "fmt" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" From ce2a46826b2f72eb41ec485487e90a3d1c0624a4 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Wed, 19 Jan 2022 12:18:32 -0500 Subject: [PATCH 004/116] r/route and r/route_table: deprecate 'instance_id' --- internal/service/ec2/route.go | 1 + internal/service/ec2/route_table.go | 5 +++-- website/docs/r/route.html.markdown | 2 +- website/docs/r/route_table.html.markdown | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/internal/service/ec2/route.go b/internal/service/ec2/route.go index 91cc643f8f7..445f5b5c720 100644 --- a/internal/service/ec2/route.go +++ b/internal/service/ec2/route.go @@ -110,6 +110,7 @@ func ResourceRoute() *schema.Resource { Type: schema.TypeString, Optional: true, Computed: true, + Deprecated: "Use network_interface_id instead", ExactlyOneOf: routeValidTargets, }, "local_gateway_id": { diff --git a/internal/service/ec2/route_table.go b/internal/service/ec2/route_table.go index fd40abb9f7c..d479c1a5b72 100644 --- a/internal/service/ec2/route_table.go +++ b/internal/service/ec2/route_table.go @@ -121,8 +121,9 @@ func ResourceRouteTable() *schema.Resource { Optional: true, }, "instance_id": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + Deprecated: "Use network_interface_id instead", }, "local_gateway_id": { Type: schema.TypeString, diff --git a/website/docs/r/route.html.markdown b/website/docs/r/route.html.markdown index 42ca414ded4..12702130c5a 100644 --- a/website/docs/r/route.html.markdown +++ b/website/docs/r/route.html.markdown @@ -61,7 +61,7 @@ One of the following target arguments must be supplied: * `carrier_gateway_id` - (Optional) Identifier of a carrier gateway. This attribute can only be used when the VPC contains a subnet which is associated with a Wavelength Zone. * `egress_only_gateway_id` - (Optional) Identifier of a VPC Egress Only Internet Gateway. * `gateway_id` - (Optional) Identifier of a VPC internet gateway or a virtual private gateway. -* `instance_id` - (Optional) Identifier of an EC2 instance. +* `instance_id` - (Optional, **Deprecated** use `network_interface_id` instead) Identifier of an EC2 instance. * `nat_gateway_id` - (Optional) Identifier of a VPC NAT gateway. * `local_gateway_id` - (Optional) Identifier of a Outpost local gateway. * `network_interface_id` - (Optional) Identifier of an EC2 network interface. diff --git a/website/docs/r/route_table.html.markdown b/website/docs/r/route_table.html.markdown index 37779a3df5a..2ad02c9968e 100644 --- a/website/docs/r/route_table.html.markdown +++ b/website/docs/r/route_table.html.markdown @@ -90,7 +90,7 @@ One of the following target arguments must be supplied: * `carrier_gateway_id` - (Optional) Identifier of a carrier gateway. This attribute can only be used when the VPC contains a subnet which is associated with a Wavelength Zone. * `egress_only_gateway_id` - (Optional) Identifier of a VPC Egress Only Internet Gateway. * `gateway_id` - (Optional) Identifier of a VPC internet gateway or a virtual private gateway. -* `instance_id` - (Optional) Identifier of an EC2 instance. +* `instance_id` - (Optional, **Deprecated** use `network_interface_id` instead) Identifier of an EC2 instance. * `local_gateway_id` - (Optional) Identifier of a Outpost local gateway. * `nat_gateway_id` - (Optional) Identifier of a VPC NAT gateway. * `network_interface_id` - (Optional) Identifier of an EC2 network interface. From 256b7f52d530d21916384969cf9ada730ca2e689 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Wed, 19 Jan 2022 12:21:56 -0500 Subject: [PATCH 005/116] Update CHANGELOG for #22664 --- .changelog/22664.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changelog/22664.txt diff --git a/.changelog/22664.txt b/.changelog/22664.txt new file mode 100644 index 00000000000..5a7cde63858 --- /dev/null +++ b/.changelog/22664.txt @@ -0,0 +1,7 @@ +```release-note:note +resource/aws_route: The `instance_id` argument has been deprecated. All configurations using `instance_id` should be updated to use the `network_interface_id` argument instead +``` + +```release-note:note +resource/aws_route_table: The `instance_id` argument of the `route` configuration block has been deprecated. All configurations using `route` `instance_id` should be updated to use the `route` `network_interface_id` argument instead +``` \ No newline at end of file From e7207624c3b63c8988aebb345e52285dd4df97af Mon Sep 17 00:00:00 2001 From: angie pinilla Date: Wed, 19 Jan 2022 16:16:39 -0500 Subject: [PATCH 006/116] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dda76730756..3288f90022c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 4.0.0 (Unreleased) + +NOTES: + +* resource/aws_route: The `instance_id` argument has been deprecated. All configurations using `instance_id` should be updated to use the `network_interface_id` argument instead ([#22664](https://github.com/hashicorp/terraform-provider-aws/issues/22664)) +* resource/aws_route_table: The `instance_id` argument of the `route` configuration block has been deprecated. All configurations using `route` `instance_id` should be updated to use the `route` `network_interface_id` argument instead ([#22664](https://github.com/hashicorp/terraform-provider-aws/issues/22664)) + ## 3.75.0 (Unreleased) ENHANCEMENTS: From 40333d1749a7095b255dc46cc9cbc9e9273e73d4 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Thu, 20 Jan 2022 14:25:56 -0500 Subject: [PATCH 007/116] add acceptance test coverage --- ...pc_peering_connections_data_source_test.go | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/internal/service/ec2/vpc_peering_connections_data_source_test.go b/internal/service/ec2/vpc_peering_connections_data_source_test.go index c61efa8b67c..67454597835 100644 --- a/internal/service/ec2/vpc_peering_connections_data_source_test.go +++ b/internal/service/ec2/vpc_peering_connections_data_source_test.go @@ -24,6 +24,22 @@ func TestAccEC2VPCPeeringConnectionsDataSource_basic(t *testing.T) { }) } +func TestAccEC2VPCPeeringConnectionsDataSource_NoMatches(t *testing.T) { + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccVPCPeeringConnectionsDataSourceConfig_NoMatches, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.aws_vpc_peering_connections.test", "ids.#", "0"), + ), + }, + }, + }) +} + const testAccVPCPeeringConnectionsDataSourceConfig = ` resource "aws_vpc" "foo" { cidr_block = "10.1.0.0/16" @@ -81,3 +97,11 @@ data "aws_vpc_peering_connections" "test_by_filters" { } } ` + +const testAccVPCPeeringConnectionsDataSourceConfig_NoMatches = ` +data "aws_vpc_peering_connections" "test" { + tags = { + Name = "Non-Existent" + } +} +` From b68c7a3a403be98aee3245dd2f388c642b0a808a Mon Sep 17 00:00:00 2001 From: Devon Bleak Date: Mon, 9 Jul 2018 15:03:54 -0700 Subject: [PATCH 008/116] Add resource aws_s3_bucket_versioning --- .../docs/r/s3_bucket_versioning.html.markdown | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 website/docs/r/s3_bucket_versioning.html.markdown diff --git a/website/docs/r/s3_bucket_versioning.html.markdown b/website/docs/r/s3_bucket_versioning.html.markdown new file mode 100644 index 00000000000..8b17f432573 --- /dev/null +++ b/website/docs/r/s3_bucket_versioning.html.markdown @@ -0,0 +1,40 @@ +--- +layout: "aws" +page_title: "AWS - aws_s3_bucket_versioning" +sidebar_current: "docs-aws-s3-bucket-versioning" +description: |- + Provides a resource for controlling S3 bucket versioning +--- + +# aws_s3_bucket_versioning + +Provides a resource for controlling versioning on an [S3 bucket][1]. Note that this +may conflict with the `versioning` block of an [aws_s3_bucket][1] if the settings are +not the same. + +## Example Usage + +```hcl +resource "aws_s3_bucket" "b" { + bucket = "example-bucket" + acl = "private" +} + +resource "aws_s3_bucket_versioning" "versioning_example" { + bucket = "${aws_s3_bucket.b.id}" + enabled = true +} +``` + +## Argument Reference + +The following arguments are supported: + +* `bucket` - (Required) The name of the S3 bucket +* `enabled` - (Required) Whether to enable versioning on the bucket + +## Deletion + +Deleting this resource will disable versioning on the bucket. + +[1]: /docs/providers/aws/r/s3_bucket.html From dd55a03f92bc4b899ad80ca54d46e5b38ec3a39b Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 21 Jan 2022 10:14:58 -0500 Subject: [PATCH 009/116] CR updates: align with API and update overall provider design patterns --- internal/provider/provider.go | 1 + internal/service/s3/bucket.go | 6 +- internal/service/s3/bucket_versioning.go | 249 ++++++++++++++++++ internal/service/s3/bucket_versioning_test.go | 229 ++++++++++++++++ internal/service/s3/id.go | 41 +++ internal/service/s3/id_test.go | 62 +++++ .../docs/r/s3_bucket_versioning.html.markdown | 59 +++-- 7 files changed, 628 insertions(+), 19 deletions(-) create mode 100644 internal/service/s3/bucket_versioning.go create mode 100644 internal/service/s3/bucket_versioning_test.go create mode 100644 internal/service/s3/id.go create mode 100644 internal/service/s3/id_test.go diff --git a/internal/provider/provider.go b/internal/provider/provider.go index eac45701a60..ddf46311474 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1596,6 +1596,7 @@ func Provider() *schema.Provider { "aws_s3_bucket_policy": s3.ResourceBucketPolicy(), "aws_s3_bucket_public_access_block": s3.ResourceBucketPublicAccessBlock(), "aws_s3_bucket_replication_configuration": s3.ResourceBucketReplicationConfiguration(), + "aws_s3_bucket_versioning": s3.ResourceBucketVersioning(), "aws_s3_object_copy": s3.ResourceObjectCopy(), "aws_s3_access_point": s3control.ResourceAccessPoint(), diff --git a/internal/service/s3/bucket.go b/internal/service/s3/bucket.go index bc53a63aad6..cda17ff1bbd 100644 --- a/internal/service/s3/bucket.go +++ b/internal/service/s3/bucket.go @@ -781,13 +781,13 @@ func resourceBucketUpdate(d *schema.ResourceData, meta interface{}) error { if d.IsNewResource() { if versioning := expandVersioningWhenIsNewResource(v); versioning != nil { - err := resourceBucketVersioningUpdate(conn, d.Id(), versioning) + err := resourceBucketInternalVersioningUpdate(conn, d.Id(), versioning) if err != nil { return err } } } else { - if err := resourceBucketVersioningUpdate(conn, d.Id(), expandVersioning(v)); err != nil { + if err := resourceBucketInternalVersioningUpdate(conn, d.Id(), expandVersioning(v)); err != nil { return err } } @@ -1851,7 +1851,7 @@ func resourceBucketACLUpdate(conn *s3.S3, d *schema.ResourceData) error { return nil } -func resourceBucketVersioningUpdate(conn *s3.S3, bucket string, versioningConfig *s3.VersioningConfiguration) error { +func resourceBucketInternalVersioningUpdate(conn *s3.S3, bucket string, versioningConfig *s3.VersioningConfiguration) error { input := &s3.PutBucketVersioningInput{ Bucket: aws.String(bucket), VersioningConfiguration: versioningConfig, diff --git a/internal/service/s3/bucket_versioning.go b/internal/service/s3/bucket_versioning.go new file mode 100644 index 00000000000..cfd797c3337 --- /dev/null +++ b/internal/service/s3/bucket_versioning.go @@ -0,0 +1,249 @@ +package s3 + +import ( + "context" + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/s3" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "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" + "github.com/hashicorp/terraform-provider-aws/internal/verify" +) + +func ResourceBucketVersioning() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceBucketVersioningCreate, + ReadContext: resourceBucketVersioningRead, + UpdateContext: resourceBucketVersioningUpdate, + DeleteContext: resourceBucketVersioningDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Schema: map[string]*schema.Schema{ + "bucket": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 63), + }, + "expected_bucket_owner": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: verify.ValidAccountID, + }, + "mfa": { + Type: schema.TypeString, + Optional: true, + }, + "versioning_configuration": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "mfa_delete": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice(s3.MFADelete_Values(), false), + }, + "status": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(s3.BucketVersioningStatus_Values(), false), + }, + }, + }, + }, + }, + } +} + +func resourceBucketVersioningCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).S3Conn + + bucket := d.Get("bucket").(string) + expectedBucketOwner := d.Get("expected_bucket_owner").(string) + + input := &s3.PutBucketVersioningInput{ + Bucket: aws.String(bucket), + VersioningConfiguration: expandBucketVersioningConfiguration(d.Get("versioning_configuration").([]interface{})), + } + + if expectedBucketOwner != "" { + input.ExpectedBucketOwner = aws.String(expectedBucketOwner) + } + + if v, ok := d.GetOk("mfa"); ok { + input.MFA = aws.String(v.(string)) + } + + _, err := verify.RetryOnAWSCode(s3.ErrCodeNoSuchBucket, func() (interface{}, error) { + return conn.PutBucketVersioningWithContext(ctx, input) + }) + + if err != nil { + return diag.FromErr(fmt.Errorf("error creating S3 bucket versioning for %s: %w", bucket, err)) + } + + d.SetId(CreateResourceID(bucket, expectedBucketOwner)) + + return resourceBucketVersioningRead(ctx, d, meta) +} + +func resourceBucketVersioningRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).S3Conn + + bucket, expectedBucketOwner, err := ParseResourceID(d.Id()) + if err != nil { + return diag.FromErr(err) + } + + input := &s3.GetBucketVersioningInput{ + Bucket: aws.String(bucket), + } + + if expectedBucketOwner != "" { + input.ExpectedBucketOwner = aws.String(expectedBucketOwner) + } + + output, err := conn.GetBucketVersioningWithContext(ctx, input) + + if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, s3.ErrCodeNoSuchBucket) { + log.Printf("[WARN] S3 Bucket Versioning (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return diag.FromErr(fmt.Errorf("error getting S3 bucket versioning (%s): %w", d.Id(), err)) + } + + if output == nil { + if d.IsNewResource() { + return diag.FromErr(fmt.Errorf("error getting S3 bucket versioning (%s): empty output", d.Id())) + } + log.Printf("[WARN] S3 Bucket Versioning (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + d.Set("bucket", bucket) + d.Set("expected_bucket_owner", expectedBucketOwner) + if err := d.Set("versioning_configuration", flattenBucketVersioningConfiguration(output)); err != nil { + return diag.FromErr(fmt.Errorf("error setting versioning_configuration: %w", err)) + } + + return nil +} + +func resourceBucketVersioningUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).S3Conn + + bucket, expectedBucketOwner, err := ParseResourceID(d.Id()) + if err != nil { + return diag.FromErr(err) + } + + input := &s3.PutBucketVersioningInput{ + Bucket: aws.String(bucket), + VersioningConfiguration: expandBucketVersioningConfiguration(d.Get("versioning_configuration").([]interface{})), + } + + if expectedBucketOwner != "" { + input.ExpectedBucketOwner = aws.String(expectedBucketOwner) + } + + if v, ok := d.GetOk("mfa"); ok { + input.MFA = aws.String(v.(string)) + } + + _, err = conn.PutBucketVersioningWithContext(ctx, input) + + if err != nil { + return diag.FromErr(fmt.Errorf("error updating S3 bucket versioning (%s): %w", d.Id(), err)) + } + + return resourceBucketVersioningRead(ctx, d, meta) +} + +func resourceBucketVersioningDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).S3Conn + + bucket, expectedBucketOwner, err := ParseResourceID(d.Id()) + if err != nil { + return diag.FromErr(err) + } + + input := &s3.PutBucketVersioningInput{ + Bucket: aws.String(bucket), + VersioningConfiguration: &s3.VersioningConfiguration{ + // Status must be provided thus to "remove" this resource, + // we suspend versioning + Status: aws.String(s3.BucketVersioningStatusSuspended), + }, + } + + if expectedBucketOwner != "" { + input.ExpectedBucketOwner = aws.String(expectedBucketOwner) + } + + _, err = conn.PutBucketVersioningWithContext(ctx, input) + + if tfawserr.ErrCodeEquals(err, s3.ErrCodeNoSuchBucket) { + return nil + } + + if err != nil { + return diag.FromErr(fmt.Errorf("error deleting S3 bucket versioning (%s): %w", d.Id(), err)) + } + + return nil +} + +func expandBucketVersioningConfiguration(l []interface{}) *s3.VersioningConfiguration { + if len(l) == 0 || l[0] == nil { + return nil + } + + tfMap, ok := l[0].(map[string]interface{}) + if !ok { + return nil + } + + result := &s3.VersioningConfiguration{} + + if v, ok := tfMap["mfa_delete"].(string); ok && v != "" { + result.MFADelete = aws.String(v) + } + + if v, ok := tfMap["status"].(string); ok && v != "" { + result.Status = aws.String(v) + } + + return result +} + +func flattenBucketVersioningConfiguration(config *s3.GetBucketVersioningOutput) []interface{} { + if config == nil { + return []interface{}{} + } + + m := make(map[string]interface{}) + + if config.MFADelete != nil { + m["mfa_delete"] = aws.StringValue(config.MFADelete) + } + + if config.Status != nil { + m["status"] = aws.StringValue(config.Status) + } + + return []interface{}{m} +} diff --git a/internal/service/s3/bucket_versioning_test.go b/internal/service/s3/bucket_versioning_test.go new file mode 100644 index 00000000000..f0391f42b83 --- /dev/null +++ b/internal/service/s3/bucket_versioning_test.go @@ -0,0 +1,229 @@ +package s3_test + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/s3" + "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" + tfs3 "github.com/hashicorp/terraform-provider-aws/internal/service/s3" +) + +func TestAccS3BucketVersioning_basic(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_s3_bucket_versioning.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckBucketVersioningDestroy, + Steps: []resource.TestStep{ + { + Config: testAccBucketVersioningBasicConfig(rName, s3.BucketVersioningStatusEnabled), + Check: resource.ComposeTestCheckFunc( + testAccCheckBucketVersioningExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "bucket", "aws_s3_bucket.test", "id"), + resource.TestCheckResourceAttr(resourceName, "versioning_configuration.#", "1"), + resource.TestCheckResourceAttr(resourceName, "versioning_configuration.0.status", s3.BucketVersioningStatusEnabled), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccS3BucketVersioning_disappears(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_s3_bucket_versioning.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckBucketVersioningDestroy, + Steps: []resource.TestStep{ + { + Config: testAccBucketVersioningBasicConfig(rName, s3.BucketVersioningStatusEnabled), + Check: resource.ComposeTestCheckFunc( + testAccCheckBucketVersioningExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfs3.ResourceBucketVersioning(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccS3BucketVersioning_update(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_s3_bucket_versioning.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckBucketVersioningDestroy, + Steps: []resource.TestStep{ + { + Config: testAccBucketVersioningBasicConfig(rName, s3.BucketVersioningStatusEnabled), + Check: resource.ComposeTestCheckFunc( + testAccCheckBucketVersioningExists(resourceName), + ), + }, + { + Config: testAccBucketVersioningBasicConfig(rName, s3.BucketVersioningStatusSuspended), + Check: resource.ComposeTestCheckFunc( + testAccCheckBucketVersioningExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "versioning_configuration.0.status", s3.BucketVersioningStatusSuspended), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccBucketVersioningBasicConfig(rName, s3.BucketVersioningStatusEnabled), + Check: resource.ComposeTestCheckFunc( + testAccCheckBucketVersioningExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "versioning_configuration.0.status", s3.BucketVersioningStatusEnabled), + ), + }, + }, + }) +} + +// TestAccBucketVersioning_MFADelete can only test for a "Disabled" +// mfa_delete configuration as the "mfa" argument is required if it's enabled +func TestAccS3BucketVersioning_MFADelete(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_s3_bucket_versioning.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: testAccCheckBucketVersioningDestroy, + Steps: []resource.TestStep{ + { + Config: testAccBucketVersioningConfig_MFADelete(rName, s3.MFADeleteDisabled), + Check: resource.ComposeTestCheckFunc( + testAccCheckBucketVersioningExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "versioning_configuration.#", "1"), + resource.TestCheckResourceAttr(resourceName, "versioning_configuration.0.mfa_delete", s3.MFADeleteDisabled), + resource.TestCheckResourceAttr(resourceName, "versioning_configuration.0.status", s3.BucketVersioningStatusEnabled), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckBucketVersioningDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).S3Conn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_s3_bucket_versioning" { + continue + } + + input := &s3.GetBucketVersioningInput{ + Bucket: aws.String(rs.Primary.ID), + } + + output, err := conn.GetBucketVersioning(input) + + if tfawserr.ErrCodeEquals(err, s3.ErrCodeNoSuchBucket) { + continue + } + + if err != nil { + return fmt.Errorf("error getting S3 bucket versioning (%s): %w", rs.Primary.ID, err) + } + + if output != nil && aws.StringValue(output.Status) != s3.BucketVersioningStatusSuspended { + return fmt.Errorf("S3 bucket versioning (%s) still exists", rs.Primary.ID) + } + } + + return nil +} + +func testAccCheckBucketVersioningExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("Resource (%s) ID not set", resourceName) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).S3Conn + + input := &s3.GetBucketVersioningInput{ + Bucket: aws.String(rs.Primary.ID), + } + + output, err := conn.GetBucketVersioning(input) + + if err != nil { + return fmt.Errorf("error getting S3 bucket versioning (%s): %w", rs.Primary.ID, err) + } + + if output == nil { + return fmt.Errorf("S3 Bucket versioning (%s) not found", rs.Primary.ID) + } + + return nil + } +} + +func testAccBucketVersioningBasicConfig(rName, status string) string { + return fmt.Sprintf(` +resource "aws_s3_bucket" "test" { + bucket = %[1]q + acl = "private" +} + +resource "aws_s3_bucket_versioning" "test" { + bucket = aws_s3_bucket.test.id + versioning_configuration { + status = %[2]q + } +} +`, rName, status) +} + +func testAccBucketVersioningConfig_MFADelete(rName, mfaDelete string) string { + return fmt.Sprintf(` +resource "aws_s3_bucket" "test" { + bucket = %[1]q + acl = "private" +} + +resource "aws_s3_bucket_versioning" "test" { + bucket = aws_s3_bucket.test.id + versioning_configuration { + mfa_delete = %[2]q + status = "Enabled" + } +} +`, rName, mfaDelete) +} diff --git a/internal/service/s3/id.go b/internal/service/s3/id.go new file mode 100644 index 00000000000..23e67789579 --- /dev/null +++ b/internal/service/s3/id.go @@ -0,0 +1,41 @@ +package s3 + +import ( + "fmt" + "strings" +) + +const resourceIDSeparator = "," + +// CreateResourceID is a generic method for creating an ID string for a bucket-related resource e.g. aws_s3_bucket_versioning. +// The method expects a bucket name and an optional accountID. +func CreateResourceID(bucket, expectedBucketOwner string) string { + if expectedBucketOwner == "" { + return bucket + } + + parts := []string{bucket, expectedBucketOwner} + id := strings.Join(parts, resourceIDSeparator) + + return id +} + +// ParseResourceID is a generic method for parsing an ID string +// for a bucket name and accountID if provided. +func ParseResourceID(id string) (bucket, expectedBucketOwner string, err error) { + parts := strings.Split(id, resourceIDSeparator) + + if len(parts) == 1 && parts[0] != "" { + bucket = parts[0] + return + } + + if len(parts) == 2 && parts[0] != "" && parts[1] != "" { + bucket = parts[0] + expectedBucketOwner = parts[1] + return + } + + err = fmt.Errorf("unexpected format for ID (%s), expected BUCKET or BUCKET%sEXPECTED_BUCKET_OWNER", id, resourceIDSeparator) + return +} diff --git a/internal/service/s3/id_test.go b/internal/service/s3/id_test.go new file mode 100644 index 00000000000..295d58164ea --- /dev/null +++ b/internal/service/s3/id_test.go @@ -0,0 +1,62 @@ +package s3_test + +import ( + "testing" + + tfs3 "github.com/hashicorp/terraform-provider-aws/internal/service/s3" +) + +func TestParseResourceID(t *testing.T) { + testCases := []struct { + TestName string + InputID string + ExpectError bool + ExpectedBucket string + ExpectedBucketOwner string + }{ + { + TestName: "empty ID", + InputID: "", + ExpectError: true, + }, + { + TestName: "incorrect format", + InputID: "test,example,123456789012", + ExpectError: true, + }, + { + TestName: "valid ID with bucket", + InputID: tfs3.CreateResourceID("example", ""), + ExpectedBucket: "example", + ExpectedBucketOwner: "", + }, + { + TestName: "valid ID with bucket and bucket owner", + InputID: tfs3.CreateResourceID("example", "123456789012"), + ExpectedBucket: "example", + ExpectedBucketOwner: "123456789012", + }, + } + + for _, testCase := range testCases { + t.Run(testCase.TestName, func(t *testing.T) { + gotBucket, gotExpectedBucketOwner, err := tfs3.ParseResourceID(testCase.InputID) + + if err == nil && testCase.ExpectError { + t.Fatalf("expected error") + } + + if err != nil && !testCase.ExpectError { + t.Fatalf("unexpected error") + } + + if gotBucket != testCase.ExpectedBucket { + t.Errorf("got bucket %s, expected %s", gotBucket, testCase.ExpectedBucket) + } + + if gotExpectedBucketOwner != testCase.ExpectedBucketOwner { + t.Errorf("got ExpectedBucketOwner %s, expected %s", gotExpectedBucketOwner, testCase.ExpectedBucketOwner) + } + }) + } +} diff --git a/website/docs/r/s3_bucket_versioning.html.markdown b/website/docs/r/s3_bucket_versioning.html.markdown index 8b17f432573..61ab0fe8640 100644 --- a/website/docs/r/s3_bucket_versioning.html.markdown +++ b/website/docs/r/s3_bucket_versioning.html.markdown @@ -1,28 +1,32 @@ --- +subcategory: "S3" layout: "aws" -page_title: "AWS - aws_s3_bucket_versioning" -sidebar_current: "docs-aws-s3-bucket-versioning" +page_title: "AWS: aws_s3_bucket_versioning" description: |- - Provides a resource for controlling S3 bucket versioning + Provides an S3 bucket versioning resource. --- -# aws_s3_bucket_versioning +# Resource: aws_s3_bucket_versioning -Provides a resource for controlling versioning on an [S3 bucket][1]. Note that this -may conflict with the `versioning` block of an [aws_s3_bucket][1] if the settings are -not the same. +Provides a resource for controlling versioning on an S3 bucket. +Deleting this resource will suspend versioning on the associated S3 bucket. +For more information, see [How S3 versioning works](https://docs.aws.amazon.com/AmazonS3/latest/userguide/manage-versioning-examples.html). + +~> **NOTE:** If you are enabling versioning on the bucket for the first time, AWS recommends that you wait for 15 minutes after enabling versioning before issuing write operations (PUT or DELETE) on objects in the bucket. ## Example Usage -```hcl -resource "aws_s3_bucket" "b" { +```terraform +resource "aws_s3_bucket" "example" { bucket = "example-bucket" acl = "private" } resource "aws_s3_bucket_versioning" "versioning_example" { - bucket = "${aws_s3_bucket.b.id}" - enabled = true + bucket = aws_s3_bucket.example.id + versioning_configuration { + status = "Enabled" + } } ``` @@ -30,11 +34,34 @@ resource "aws_s3_bucket_versioning" "versioning_example" { The following arguments are supported: -* `bucket` - (Required) The name of the S3 bucket -* `enabled` - (Required) Whether to enable versioning on the bucket +* `bucket` - (Required, Forces new resource) The name of the S3 bucket. +* `versioning_configuration` - (Required) Configuration block for the versioning parameters [detailed below](#versioning_configuration). +* `expected_bucket_owner` - (Optional, Forces new resource) The account ID of the expected bucket owner. +* `mfa` - (Optional, Required if `versioning_configuration` `mfa_delete` is enabled) The concatenation of the authentication device's serial number, a space, and the value that is displayed on your authentication device. + +### versioning_configuration + +The `versioning_configuration` configuration block supports the following arguments: + +* `status` - (Required) The versioning state of the bucket. Valid values: `Enabled` or `Suspended`. +* `mfa_delete` - (Optional) Specifies whether MFA delete is enabled in the bucket versioning configuration. Valid values: `Enabled` or `Disabled`. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The `bucket` or `bucket` and `expected_bucket_owner` separated by a comma (`,`) if the latter is provided. -## Deletion +## Import -Deleting this resource will disable versioning on the bucket. +S3 bucket versioning can be imported using the `bucket`, e.g. -[1]: /docs/providers/aws/r/s3_bucket.html +``` +$ terraform import aws_s3_bucket_versioning.example bucket-name +``` + +In addition, S3 bucket versioning can be imported using the `bucket` and `expected_bucket_owner` separated by a comma (`,`), e.g. + +``` +$ terraform import aws_s3_bucket_versioning.example bucket-name,123456789012 +``` From 8bfa32e5c7174a1eaadd95d1688d622f53f04af0 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 21 Jan 2022 10:15:14 -0500 Subject: [PATCH 010/116] Update CHANGELOG for #5132 --- .changelog/5132.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/5132.txt diff --git a/.changelog/5132.txt b/.changelog/5132.txt new file mode 100644 index 00000000000..897a24e95aa --- /dev/null +++ b/.changelog/5132.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_s3_bucket_versioning +``` \ No newline at end of file From b4243b47d694ba0fed5f5860e913c12d669a4acb Mon Sep 17 00:00:00 2001 From: Andrea Quintino Date: Tue, 14 Dec 2021 18:00:23 +0100 Subject: [PATCH 011/116] first draft Signed-off-by: Andrea Quintino --- internal/service/ec2/default_vpc.go | 31 +++++++---------------------- 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/internal/service/ec2/default_vpc.go b/internal/service/ec2/default_vpc.go index 3fa607285a6..36982755fd2 100644 --- a/internal/service/ec2/default_vpc.go +++ b/internal/service/ec2/default_vpc.go @@ -2,7 +2,6 @@ package ec2 import ( "fmt" - "log" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" @@ -11,10 +10,9 @@ import ( ) func ResourceDefaultVPC() *schema.Resource { - // reuse aws_vpc schema, and methods for READ, UPDATE + // reuse aws_vpc schema, and methods for READ, UPDATE, DELETE dvpc := ResourceVPC() dvpc.Create = resourceDefaultVPCCreate - dvpc.Delete = resourceDefaultVPCDelete // cidr_block is a computed value for Default VPCs dvpc.Schema["cidr_block"] = &schema.Schema{ @@ -37,30 +35,15 @@ func ResourceDefaultVPC() *schema.Resource { func resourceDefaultVPCCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - req := &ec2.DescribeVpcsInput{ - Filters: []*ec2.Filter{ - { - Name: aws.String("isDefault"), - Values: aws.StringSlice([]string{"true"}), - }, - }, + req := &ec2.CreateDefaultVpcInput{ + DryRun: aws.Bool(false), } - resp, err := conn.DescribeVpcs(req) + resp, err := conn.CreateDefaultVpc(req) if err != nil { - return err + return fmt.Errorf("Error creating default VPC: %s", err) } + d.SetId(aws.StringValue(resp.Vpc.VpcId)) - if resp.Vpcs == nil || len(resp.Vpcs) == 0 { - return fmt.Errorf("No default VPC found in this region.") - } - - d.SetId(aws.StringValue(resp.Vpcs[0].VpcId)) - - return resourceVPCUpdate(d, meta) -} - -func resourceDefaultVPCDelete(d *schema.ResourceData, meta interface{}) error { - log.Printf("[WARN] Cannot destroy Default VPC. Terraform will remove this resource from the state file, however resources may remain.") - return nil + return resourceVPCRead(d, meta) } From 887a7cfe0c7747c8df732dea229e556fda24414c Mon Sep 17 00:00:00 2001 From: Andrea Quintino Date: Tue, 14 Dec 2021 22:19:22 +0100 Subject: [PATCH 012/116] ok Signed-off-by: Andrea Quintino --- internal/service/ec2/default_vpc.go | 2 +- internal/service/ec2/default_vpc_test.go | 58 +++++++++++++++++++++++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/internal/service/ec2/default_vpc.go b/internal/service/ec2/default_vpc.go index 36982755fd2..dfc6beeae10 100644 --- a/internal/service/ec2/default_vpc.go +++ b/internal/service/ec2/default_vpc.go @@ -45,5 +45,5 @@ func resourceDefaultVPCCreate(d *schema.ResourceData, meta interface{}) error { } d.SetId(aws.StringValue(resp.Vpc.VpcId)) - return resourceVPCRead(d, meta) + return resourceVPCUpdate(d, meta) } diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index fa43dfb6cf9..643e9491ff2 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -3,10 +3,12 @@ package ec2_test import ( "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "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" ) func TestAccEC2DefaultVPC_basic(t *testing.T) { @@ -19,7 +21,8 @@ func TestAccEC2DefaultVPC_basic(t *testing.T) { CheckDestroy: testAccCheckDefaultVPCDestroy, Steps: []resource.TestStep{ { - Config: testAccDefaultVPCBasicConfig, + PreConfig: func() { destroyDefaultVPCBeforeTest(t) }, + Config: testAccDefaultVPCBasicConfig, Check: resource.ComposeTestCheckFunc( acctest.CheckVPCExists("aws_default_vpc.foo", &vpc), resource.TestCheckResourceAttr("aws_default_vpc.foo", "cidr_block", "172.31.0.0/16"), @@ -44,6 +47,59 @@ func TestAccEC2DefaultVPC_basic(t *testing.T) { }) } +func destroyDefaultVPCBeforeTest(t *testing.T) { + conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn + req := &ec2.DescribeVpcsInput{ + Filters: []*ec2.Filter{ + { + Name: aws.String("isDefault"), + Values: aws.StringSlice([]string{"true"}), + }, + }, + } + + resp, err := conn.DescribeVpcs(req) + if err != nil { + t.Fatalf("Error describing default vpcs: %s", err) + } + + if resp.Vpcs == nil || len(resp.Vpcs) == 0 { + return // No vpc, all good + } + + //delete all subnets + reqDS := &ec2.DescribeSubnetsInput{ + Filters: []*ec2.Filter{ + { + Name: aws.String("vpc-id"), + Values: aws.StringSlice([]string{aws.StringValue(resp.Vpcs[0].VpcId)}), + }, + }, + } + + respDS, err := conn.DescribeSubnets(reqDS) + if err != nil { + t.Fatalf("Error describing default subnets: %s", err) + } + for _, subnet := range respDS.Subnets { + _, err := conn.DeleteSubnet(&ec2.DeleteSubnetInput{ + SubnetId: subnet.SubnetId, + }) + if err != nil { + t.Fatalf("Error deleting default subnet: %s", err) + } + } + + delReq := &ec2.DeleteVpcInput{ + VpcId: resp.Vpcs[0].VpcId, + } + + _, err = conn.DeleteVpc(delReq) + if err != nil { + t.Fatalf("Error deleting default VPC: %s", err) + } +} + func testAccCheckDefaultVPCDestroy(s *terraform.State) error { // We expect VPC to still exist return nil From 2765485c77306b1220be26b10c5e34abaaadd034 Mon Sep 17 00:00:00 2001 From: Andrea Quintino Date: Wed, 15 Dec 2021 22:30:37 +0100 Subject: [PATCH 013/116] test ok. manage destroy Signed-off-by: Andrea Quintino --- internal/service/ec2/default_vpc_test.go | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index 643e9491ff2..c2eb98ea32e 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -90,6 +90,36 @@ func destroyDefaultVPCBeforeTest(t *testing.T) { } } + //delete internet gateway + reqIG := &ec2.DescribeInternetGatewaysInput{ + Filters: []*ec2.Filter{ + { + Name: aws.String("attachment.vpc-id"), + Values: aws.StringSlice([]string{aws.StringValue(resp.Vpcs[0].VpcId)}), + }, + }, + } + + respIG, err := conn.DescribeInternetGateways(reqIG) + if err != nil { + t.Fatalf("Error describing default internet gateways: %s", err) + } + for _, ig := range respIG.InternetGateways { + _, err := conn.DetachInternetGateway(&ec2.DetachInternetGatewayInput{ + InternetGatewayId: ig.InternetGatewayId, + VpcId: ig.Attachments[0].VpcId, + }) + if err != nil { + t.Fatalf("Error detaching default internet gateway: %s", err) + } + _, err = conn.DeleteInternetGateway(&ec2.DeleteInternetGatewayInput{ + InternetGatewayId: ig.InternetGatewayId, + }) + if err != nil { + t.Fatalf("Error deleting default internet gateway: %s", err) + } + } + delReq := &ec2.DeleteVpcInput{ VpcId: resp.Vpcs[0].VpcId, } From f4b6ecbb89b572386ffbe8ca512e30164fe7d21c Mon Sep 17 00:00:00 2001 From: Andrea Quintino Date: Wed, 15 Dec 2021 22:57:17 +0100 Subject: [PATCH 014/116] test ok. destroy ok Signed-off-by: Andrea Quintino --- internal/service/ec2/default_vpc.go | 70 +++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/internal/service/ec2/default_vpc.go b/internal/service/ec2/default_vpc.go index dfc6beeae10..019ef3a2cb8 100644 --- a/internal/service/ec2/default_vpc.go +++ b/internal/service/ec2/default_vpc.go @@ -13,6 +13,7 @@ func ResourceDefaultVPC() *schema.Resource { // reuse aws_vpc schema, and methods for READ, UPDATE, DELETE dvpc := ResourceVPC() dvpc.Create = resourceDefaultVPCCreate + dvpc.Delete = resourceDefaultVPCDelete // cidr_block is a computed value for Default VPCs dvpc.Schema["cidr_block"] = &schema.Schema{ @@ -47,3 +48,72 @@ func resourceDefaultVPCCreate(d *schema.ResourceData, meta interface{}) error { return resourceVPCUpdate(d, meta) } + +func resourceDefaultVPCDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).EC2Conn + vpcId := d.Id() + + //delete all subnets + reqDS := &ec2.DescribeSubnetsInput{ + Filters: []*ec2.Filter{ + { + Name: aws.String("vpc-id"), + Values: aws.StringSlice([]string{vpcId}), + }, + }, + } + + respDS, err := conn.DescribeSubnets(reqDS) + if err != nil { + return fmt.Errorf("Error describing default subnets: %s", err) + } + for _, subnet := range respDS.Subnets { + _, err := conn.DeleteSubnet(&ec2.DeleteSubnetInput{ + SubnetId: subnet.SubnetId, + }) + if err != nil { + return fmt.Errorf("Error deleting default subnet: %s", err) + } + } + + //delete internet gateway + reqIG := &ec2.DescribeInternetGatewaysInput{ + Filters: []*ec2.Filter{ + { + Name: aws.String("attachment.vpc-id"), + Values: aws.StringSlice([]string{vpcId}), + }, + }, + } + + respIG, err := conn.DescribeInternetGateways(reqIG) + if err != nil { + return fmt.Errorf("Error describing default internet gateways: %s", err) + } + for _, ig := range respIG.InternetGateways { + _, err := conn.DetachInternetGateway(&ec2.DetachInternetGatewayInput{ + InternetGatewayId: ig.InternetGatewayId, + VpcId: ig.Attachments[0].VpcId, + }) + if err != nil { + return fmt.Errorf("Error detaching default internet gateway: %s", err) + } + _, err = conn.DeleteInternetGateway(&ec2.DeleteInternetGatewayInput{ + InternetGatewayId: ig.InternetGatewayId, + }) + if err != nil { + return fmt.Errorf("Error deleting default internet gateway: %s", err) + } + } + + delReq := &ec2.DeleteVpcInput{ + VpcId: aws.String(vpcId), + } + + _, err = conn.DeleteVpc(delReq) + if err != nil { + return fmt.Errorf("Error deleting default VPC: %s", err) + } + + return nil +} From 5de2b4c13f478bdb033d2fdc12f57e9e9cba8477 Mon Sep 17 00:00:00 2001 From: Andrea Quintino Date: Wed, 15 Dec 2021 23:00:13 +0100 Subject: [PATCH 015/116] test ok. destroy ok Signed-off-by: Andrea Quintino --- internal/service/ec2/default_vpc_test.go | 33 +++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index c2eb98ea32e..12cd7417f2b 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -1,9 +1,11 @@ package ec2_test import ( + "fmt" "testing" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" @@ -131,7 +133,36 @@ func destroyDefaultVPCBeforeTest(t *testing.T) { } func testAccCheckDefaultVPCDestroy(s *terraform.State) error { - // We expect VPC to still exist + conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_vpc" { + continue + } + + // Try to find the VPC + DescribeVpcOpts := &ec2.DescribeVpcsInput{ + VpcIds: []*string{aws.String(rs.Primary.ID)}, + } + resp, err := conn.DescribeVpcs(DescribeVpcOpts) + if err == nil { + if len(resp.Vpcs) > 0 { + return fmt.Errorf("VPCs still exist.") + } + + return nil + } + + // Verify the error is what we want + ec2err, ok := err.(awserr.Error) + if !ok { + return err + } + if ec2err.Code() != "InvalidVpcID.NotFound" { + return err + } + } + return nil } From 59b4246c3a8c1521e81d07d874a32b02000b934e Mon Sep 17 00:00:00 2001 From: dirk39 Date: Thu, 16 Dec 2021 13:55:37 +0100 Subject: [PATCH 016/116] updated doc Signed-off-by: dirk39 --- website/docs/r/default_vpc.html.markdown | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/website/docs/r/default_vpc.html.markdown b/website/docs/r/default_vpc.html.markdown index 26030ae3f2f..3e6fa2e8184 100644 --- a/website/docs/r/default_vpc.html.markdown +++ b/website/docs/r/default_vpc.html.markdown @@ -15,10 +15,6 @@ For AWS accounts created after 2013-12-04, each region comes with a Default VPC. **This is an advanced resource**, and has special caveats to be aware of when using it. Please read this document in its entirety before using this resource. -The `aws_default_vpc` behaves differently from normal resources, in that -Terraform does not _create_ this resource, but instead "adopts" it -into management. - ## Example Usage Basic usage with tags: @@ -44,13 +40,6 @@ arguments are computed. The following arguments are still supported: See the [ClassicLink documentation][1] for more information. Defaults false. * `tags` - (Optional) A map of tags to assign to the resource. -### Removing `aws_default_vpc` from your configuration - -The `aws_default_vpc` resource allows you to manage a region's default VPC, -but Terraform cannot destroy it. Removing this resource from your configuration -will remove it from your statefile and management, but will not destroy the VPC. -You can resume managing the VPC via the AWS Console. - ## Attributes Reference In addition to all arguments above, the following attributes are exported: From 729aaa926d69a2d82837d564a02b0cbb9afa90e8 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 18 Jan 2022 15:48:22 -0500 Subject: [PATCH 017/116] Revert "updated doc" This reverts commit 068311abc61af4ed43c841ffbce2b70690aec271. --- website/docs/r/default_vpc.html.markdown | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/website/docs/r/default_vpc.html.markdown b/website/docs/r/default_vpc.html.markdown index 3e6fa2e8184..26030ae3f2f 100644 --- a/website/docs/r/default_vpc.html.markdown +++ b/website/docs/r/default_vpc.html.markdown @@ -15,6 +15,10 @@ For AWS accounts created after 2013-12-04, each region comes with a Default VPC. **This is an advanced resource**, and has special caveats to be aware of when using it. Please read this document in its entirety before using this resource. +The `aws_default_vpc` behaves differently from normal resources, in that +Terraform does not _create_ this resource, but instead "adopts" it +into management. + ## Example Usage Basic usage with tags: @@ -40,6 +44,13 @@ arguments are computed. The following arguments are still supported: See the [ClassicLink documentation][1] for more information. Defaults false. * `tags` - (Optional) A map of tags to assign to the resource. +### Removing `aws_default_vpc` from your configuration + +The `aws_default_vpc` resource allows you to manage a region's default VPC, +but Terraform cannot destroy it. Removing this resource from your configuration +will remove it from your statefile and management, but will not destroy the VPC. +You can resume managing the VPC via the AWS Console. + ## Attributes Reference In addition to all arguments above, the following attributes are exported: From 190dd9a90cfd0a715d554162f4238898516960f3 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 18 Jan 2022 15:48:30 -0500 Subject: [PATCH 018/116] Revert "test ok. destroy ok" This reverts commit 8d7b56c2e0058c52a14008d5ffdd8fdee46318c4. --- internal/service/ec2/default_vpc_test.go | 33 +----------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index 12cd7417f2b..c2eb98ea32e 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -1,11 +1,9 @@ package ec2_test import ( - "fmt" "testing" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" @@ -133,36 +131,7 @@ func destroyDefaultVPCBeforeTest(t *testing.T) { } func testAccCheckDefaultVPCDestroy(s *terraform.State) error { - conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn - - for _, rs := range s.RootModule().Resources { - if rs.Type != "aws_vpc" { - continue - } - - // Try to find the VPC - DescribeVpcOpts := &ec2.DescribeVpcsInput{ - VpcIds: []*string{aws.String(rs.Primary.ID)}, - } - resp, err := conn.DescribeVpcs(DescribeVpcOpts) - if err == nil { - if len(resp.Vpcs) > 0 { - return fmt.Errorf("VPCs still exist.") - } - - return nil - } - - // Verify the error is what we want - ec2err, ok := err.(awserr.Error) - if !ok { - return err - } - if ec2err.Code() != "InvalidVpcID.NotFound" { - return err - } - } - + // We expect VPC to still exist return nil } From bf165a498137c1a0fb42e4dae0b3c9ec44d8eb99 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 18 Jan 2022 15:48:38 -0500 Subject: [PATCH 019/116] Revert "test ok. destroy ok" This reverts commit b415b4808674068c3631f21ae4e4170aeb85720c. --- internal/service/ec2/default_vpc.go | 70 ----------------------------- 1 file changed, 70 deletions(-) diff --git a/internal/service/ec2/default_vpc.go b/internal/service/ec2/default_vpc.go index 019ef3a2cb8..dfc6beeae10 100644 --- a/internal/service/ec2/default_vpc.go +++ b/internal/service/ec2/default_vpc.go @@ -13,7 +13,6 @@ func ResourceDefaultVPC() *schema.Resource { // reuse aws_vpc schema, and methods for READ, UPDATE, DELETE dvpc := ResourceVPC() dvpc.Create = resourceDefaultVPCCreate - dvpc.Delete = resourceDefaultVPCDelete // cidr_block is a computed value for Default VPCs dvpc.Schema["cidr_block"] = &schema.Schema{ @@ -48,72 +47,3 @@ func resourceDefaultVPCCreate(d *schema.ResourceData, meta interface{}) error { return resourceVPCUpdate(d, meta) } - -func resourceDefaultVPCDelete(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*conns.AWSClient).EC2Conn - vpcId := d.Id() - - //delete all subnets - reqDS := &ec2.DescribeSubnetsInput{ - Filters: []*ec2.Filter{ - { - Name: aws.String("vpc-id"), - Values: aws.StringSlice([]string{vpcId}), - }, - }, - } - - respDS, err := conn.DescribeSubnets(reqDS) - if err != nil { - return fmt.Errorf("Error describing default subnets: %s", err) - } - for _, subnet := range respDS.Subnets { - _, err := conn.DeleteSubnet(&ec2.DeleteSubnetInput{ - SubnetId: subnet.SubnetId, - }) - if err != nil { - return fmt.Errorf("Error deleting default subnet: %s", err) - } - } - - //delete internet gateway - reqIG := &ec2.DescribeInternetGatewaysInput{ - Filters: []*ec2.Filter{ - { - Name: aws.String("attachment.vpc-id"), - Values: aws.StringSlice([]string{vpcId}), - }, - }, - } - - respIG, err := conn.DescribeInternetGateways(reqIG) - if err != nil { - return fmt.Errorf("Error describing default internet gateways: %s", err) - } - for _, ig := range respIG.InternetGateways { - _, err := conn.DetachInternetGateway(&ec2.DetachInternetGatewayInput{ - InternetGatewayId: ig.InternetGatewayId, - VpcId: ig.Attachments[0].VpcId, - }) - if err != nil { - return fmt.Errorf("Error detaching default internet gateway: %s", err) - } - _, err = conn.DeleteInternetGateway(&ec2.DeleteInternetGatewayInput{ - InternetGatewayId: ig.InternetGatewayId, - }) - if err != nil { - return fmt.Errorf("Error deleting default internet gateway: %s", err) - } - } - - delReq := &ec2.DeleteVpcInput{ - VpcId: aws.String(vpcId), - } - - _, err = conn.DeleteVpc(delReq) - if err != nil { - return fmt.Errorf("Error deleting default VPC: %s", err) - } - - return nil -} From 1cf4151c0ff15402edda1e7d5ae36da8bcd6fa34 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 18 Jan 2022 15:48:53 -0500 Subject: [PATCH 020/116] Revert "test ok. manage destroy" This reverts commit 972ff5e0e36be04287a5091bd2d5c58c87564618. --- internal/service/ec2/default_vpc_test.go | 30 ------------------------ 1 file changed, 30 deletions(-) diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index c2eb98ea32e..643e9491ff2 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -90,36 +90,6 @@ func destroyDefaultVPCBeforeTest(t *testing.T) { } } - //delete internet gateway - reqIG := &ec2.DescribeInternetGatewaysInput{ - Filters: []*ec2.Filter{ - { - Name: aws.String("attachment.vpc-id"), - Values: aws.StringSlice([]string{aws.StringValue(resp.Vpcs[0].VpcId)}), - }, - }, - } - - respIG, err := conn.DescribeInternetGateways(reqIG) - if err != nil { - t.Fatalf("Error describing default internet gateways: %s", err) - } - for _, ig := range respIG.InternetGateways { - _, err := conn.DetachInternetGateway(&ec2.DetachInternetGatewayInput{ - InternetGatewayId: ig.InternetGatewayId, - VpcId: ig.Attachments[0].VpcId, - }) - if err != nil { - t.Fatalf("Error detaching default internet gateway: %s", err) - } - _, err = conn.DeleteInternetGateway(&ec2.DeleteInternetGatewayInput{ - InternetGatewayId: ig.InternetGatewayId, - }) - if err != nil { - t.Fatalf("Error deleting default internet gateway: %s", err) - } - } - delReq := &ec2.DeleteVpcInput{ VpcId: resp.Vpcs[0].VpcId, } From 149c905083b095cc109d816ea62a40892702adbc Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 18 Jan 2022 15:49:03 -0500 Subject: [PATCH 021/116] Revert "ok" This reverts commit d74c36cdc05338b62c02df5244661e38ade6b4ab. --- internal/service/ec2/default_vpc.go | 2 +- internal/service/ec2/default_vpc_test.go | 58 +----------------------- 2 files changed, 2 insertions(+), 58 deletions(-) diff --git a/internal/service/ec2/default_vpc.go b/internal/service/ec2/default_vpc.go index dfc6beeae10..36982755fd2 100644 --- a/internal/service/ec2/default_vpc.go +++ b/internal/service/ec2/default_vpc.go @@ -45,5 +45,5 @@ func resourceDefaultVPCCreate(d *schema.ResourceData, meta interface{}) error { } d.SetId(aws.StringValue(resp.Vpc.VpcId)) - return resourceVPCUpdate(d, meta) + return resourceVPCRead(d, meta) } diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index 643e9491ff2..fa43dfb6cf9 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -3,12 +3,10 @@ package ec2_test import ( "testing" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "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" ) func TestAccEC2DefaultVPC_basic(t *testing.T) { @@ -21,8 +19,7 @@ func TestAccEC2DefaultVPC_basic(t *testing.T) { CheckDestroy: testAccCheckDefaultVPCDestroy, Steps: []resource.TestStep{ { - PreConfig: func() { destroyDefaultVPCBeforeTest(t) }, - Config: testAccDefaultVPCBasicConfig, + Config: testAccDefaultVPCBasicConfig, Check: resource.ComposeTestCheckFunc( acctest.CheckVPCExists("aws_default_vpc.foo", &vpc), resource.TestCheckResourceAttr("aws_default_vpc.foo", "cidr_block", "172.31.0.0/16"), @@ -47,59 +44,6 @@ func TestAccEC2DefaultVPC_basic(t *testing.T) { }) } -func destroyDefaultVPCBeforeTest(t *testing.T) { - conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn - req := &ec2.DescribeVpcsInput{ - Filters: []*ec2.Filter{ - { - Name: aws.String("isDefault"), - Values: aws.StringSlice([]string{"true"}), - }, - }, - } - - resp, err := conn.DescribeVpcs(req) - if err != nil { - t.Fatalf("Error describing default vpcs: %s", err) - } - - if resp.Vpcs == nil || len(resp.Vpcs) == 0 { - return // No vpc, all good - } - - //delete all subnets - reqDS := &ec2.DescribeSubnetsInput{ - Filters: []*ec2.Filter{ - { - Name: aws.String("vpc-id"), - Values: aws.StringSlice([]string{aws.StringValue(resp.Vpcs[0].VpcId)}), - }, - }, - } - - respDS, err := conn.DescribeSubnets(reqDS) - if err != nil { - t.Fatalf("Error describing default subnets: %s", err) - } - for _, subnet := range respDS.Subnets { - _, err := conn.DeleteSubnet(&ec2.DeleteSubnetInput{ - SubnetId: subnet.SubnetId, - }) - if err != nil { - t.Fatalf("Error deleting default subnet: %s", err) - } - } - - delReq := &ec2.DeleteVpcInput{ - VpcId: resp.Vpcs[0].VpcId, - } - - _, err = conn.DeleteVpc(delReq) - if err != nil { - t.Fatalf("Error deleting default VPC: %s", err) - } -} - func testAccCheckDefaultVPCDestroy(s *terraform.State) error { // We expect VPC to still exist return nil From 35d8a1cc26710f3c5cd35becde10b8e8035fa3b8 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 18 Jan 2022 15:49:11 -0500 Subject: [PATCH 022/116] Revert "first draft" This reverts commit 484f2921324b8fb202f396a8ac99d85bafa6d429. --- internal/service/ec2/default_vpc.go | 31 ++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/internal/service/ec2/default_vpc.go b/internal/service/ec2/default_vpc.go index 36982755fd2..3fa607285a6 100644 --- a/internal/service/ec2/default_vpc.go +++ b/internal/service/ec2/default_vpc.go @@ -2,6 +2,7 @@ package ec2 import ( "fmt" + "log" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" @@ -10,9 +11,10 @@ import ( ) func ResourceDefaultVPC() *schema.Resource { - // reuse aws_vpc schema, and methods for READ, UPDATE, DELETE + // reuse aws_vpc schema, and methods for READ, UPDATE dvpc := ResourceVPC() dvpc.Create = resourceDefaultVPCCreate + dvpc.Delete = resourceDefaultVPCDelete // cidr_block is a computed value for Default VPCs dvpc.Schema["cidr_block"] = &schema.Schema{ @@ -35,15 +37,30 @@ func ResourceDefaultVPC() *schema.Resource { func resourceDefaultVPCCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - req := &ec2.CreateDefaultVpcInput{ - DryRun: aws.Bool(false), + req := &ec2.DescribeVpcsInput{ + Filters: []*ec2.Filter{ + { + Name: aws.String("isDefault"), + Values: aws.StringSlice([]string{"true"}), + }, + }, } - resp, err := conn.CreateDefaultVpc(req) + resp, err := conn.DescribeVpcs(req) if err != nil { - return fmt.Errorf("Error creating default VPC: %s", err) + return err } - d.SetId(aws.StringValue(resp.Vpc.VpcId)) - return resourceVPCRead(d, meta) + if resp.Vpcs == nil || len(resp.Vpcs) == 0 { + return fmt.Errorf("No default VPC found in this region.") + } + + d.SetId(aws.StringValue(resp.Vpcs[0].VpcId)) + + return resourceVPCUpdate(d, meta) +} + +func resourceDefaultVPCDelete(d *schema.ResourceData, meta interface{}) error { + log.Printf("[WARN] Cannot destroy Default VPC. Terraform will remove this resource from the state file, however resources may remain.") + return nil } From dad5ce4ce92c33240e974caee52d40c877d17992 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 11 Jan 2022 16:43:01 -0500 Subject: [PATCH 023/116] r/aws_default_subnet: Full resource life cycle. First baby steps. Acceptance test output: % AWS_DEFAULT_REGION=eu-west-2 make testacc TESTARGS='-run=TestAccEC2DefaultSubnet_basic' PKG_NAME=internal/service/ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run=TestAccEC2DefaultSubnet_basic -timeout 180m === RUN TestAccEC2DefaultSubnet_basic === PAUSE TestAccEC2DefaultSubnet_basic === CONT TestAccEC2DefaultSubnet_basic default_subnet_test.go:17: Step 1/1 error: After applying this test step, the plan was not empty. stdout: Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: ~ update in-place Terraform will perform the following actions: # aws_default_subnet.test will be updated in-place ~ resource "aws_default_subnet" "test" { id = "subnet-5e636b26" ~ map_public_ip_on_launch = true -> false # (15 unchanged attributes hidden) } Plan: 0 to add, 1 to change, 0 to destroy. --- FAIL: TestAccEC2DefaultSubnet_basic (10.19s) FAIL FAIL github.com/hashicorp/terraform-provider-aws/internal/service/ec2 13.707s FAIL make: *** [testacc] Error 1 --- internal/service/ec2/default_subnet.go | 240 +++++++++++++++----- internal/service/ec2/default_subnet_test.go | 109 +-------- internal/service/ec2/subnet.go | 5 +- 3 files changed, 194 insertions(+), 160 deletions(-) diff --git a/internal/service/ec2/default_subnet.go b/internal/service/ec2/default_subnet.go index 1ada3130bef..73b997f7cae 100644 --- a/internal/service/ec2/default_subnet.go +++ b/internal/service/ec2/default_subnet.go @@ -3,84 +3,206 @@ package ec2 import ( "fmt" "log" + "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "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" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/internal/verify" ) func ResourceDefaultSubnet() *schema.Resource { - // reuse aws_subnet schema, and methods for READ, UPDATE - dsubnet := ResourceSubnet() - dsubnet.Create = resourceDefaultSubnetCreate - dsubnet.Delete = resourceDefaultSubnetDelete - - // availability_zone is a required value for Default Subnets - dsubnet.Schema["availability_zone"] = &schema.Schema{ - Type: schema.TypeString, - Required: true, - } - // availability_zone_id is a computed value for Default Subnets - dsubnet.Schema["availability_zone_id"] = &schema.Schema{ - Type: schema.TypeString, - Computed: true, - } - // vpc_id is a computed value for Default Subnets - dsubnet.Schema["vpc_id"] = &schema.Schema{ - Type: schema.TypeString, - Computed: true, - } - // cidr_block is a computed value for Default Subnets - dsubnet.Schema["cidr_block"] = &schema.Schema{ - Type: schema.TypeString, - Computed: true, - } - // ipv6_cidr_block is a computed value for Default Subnets - dsubnet.Schema["ipv6_cidr_block"] = &schema.Schema{ - Type: schema.TypeString, - Computed: true, - } - // map_public_ip_on_launch is a computed value for Default Subnets - dsubnet.Schema["map_public_ip_on_launch"] = &schema.Schema{ - Type: schema.TypeBool, - Optional: true, - Computed: true, - } - // assign_ipv6_address_on_creation is a computed value for Default Subnets - dsubnet.Schema["assign_ipv6_address_on_creation"] = &schema.Schema{ - Type: schema.TypeBool, - Computed: true, - } + //lintignore:R011 + return &schema.Resource{ + Create: resourceDefaultSubnetCreate, + Read: resourceSubnetRead, + Update: resourceSubnetUpdate, + Delete: resourceDefaultSubnetDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + CustomizeDiff: verify.SetTagsDiff, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(10 * time.Minute), + Delete: schema.DefaultTimeout(20 * time.Minute), + }, - return dsubnet + // Keep in sync with aws_subnet's schema with the following changes: + // - availability_zone is Required/ForceNew + // - availability_zone_id is Computed-only + // - cidr_block is Computed-only + // - outpost_arn is Computed-only + // - vpc_id is Computed-only + // and additions: + // - existing_default_subnet Computed-only, set in resourceDefaultSubnetCreate + // - force_destroy Optional/Computed, default calculated via CustomizeDiff + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "assign_ipv6_address_on_creation": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "availability_zone": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "availability_zone_id": { + Type: schema.TypeString, + Computed: true, + }, + "cidr_block": { + Type: schema.TypeString, + Computed: true, + }, + "customer_owned_ipv4_pool": { + Type: schema.TypeString, + Optional: true, + RequiredWith: []string{"map_customer_owned_ip_on_launch", "outpost_arn"}, + }, + "enable_dns64": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "enable_resource_name_dns_aaaa_record_on_launch": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "enable_resource_name_dns_a_record_on_launch": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "existing_default_subnet": { + Type: schema.TypeBool, + Computed: true, + }, + "force_destroy": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "ipv6_cidr_block": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: verify.ValidIPv6CIDRNetworkAddress, + }, + "ipv6_cidr_block_association_id": { + Type: schema.TypeString, + Computed: true, + }, + "ipv6_native": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Default: false, + }, + "map_customer_owned_ip_on_launch": { + Type: schema.TypeBool, + Optional: true, + RequiredWith: []string{"customer_owned_ipv4_pool", "outpost_arn"}, + }, + "map_public_ip_on_launch": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "outpost_arn": { + Type: schema.TypeString, + Computed: true, + }, + "owner_id": { + Type: schema.TypeString, + Computed: true, + }, + "private_dns_hostname_type_on_launch": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice(ec2.HostnameType_Values(), false), + }, + "tags": tftags.TagsSchema(), + "tags_all": tftags.TagsSchemaComputed(), + "vpc_id": { + Type: schema.TypeString, + Computed: true, + }, + }, + } } func resourceDefaultSubnetCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - req := &ec2.DescribeSubnetsInput{} - req.Filters = BuildAttributeFilterList( - map[string]string{ - "availabilityZone": d.Get("availability_zone").(string), - "defaultForAz": "true", - }, - ) - - log.Printf("[DEBUG] Reading Default Subnet: %s", req) - resp, err := conn.DescribeSubnets(req) - if err != nil { - return err + availabilityZone := d.Get("availability_zone").(string) + input := &ec2.DescribeSubnetsInput{ + Filters: BuildAttributeFilterList( + map[string]string{ + "availabilityZone": availabilityZone, + "defaultForAz": "true", + }, + ), } - if len(resp.Subnets) != 1 || resp.Subnets[0] == nil { - return fmt.Errorf("Default subnet not found") + + subnet, err := FindSubnet(conn, input) + + if err == nil { + log.Printf("[INFO] Found existing EC2 Default Subnet (%s)", availabilityZone) + d.SetId(aws.StringValue(subnet.SubnetId)) + d.Set("existing_default_subnet", true) + } else if tfresource.NotFound(err) { + input := &ec2.CreateDefaultSubnetInput{ + AvailabilityZone: aws.String(availabilityZone), + } + + if v, ok := d.GetOk("ipv6_native"); ok { + input.Ipv6Native = aws.Bool(v.(bool)) + } + + log.Printf("[DEBUG] Creating EC2 Default Subnet: %s", input) + output, err := conn.CreateDefaultSubnet(input) + + if err != nil { + return fmt.Errorf("error creating EC2 Default Subnet (%s): %w", availabilityZone, err) + } + + subnet = output.Subnet + + d.SetId(aws.StringValue(subnet.SubnetId)) + d.Set("existing_default_subnet", false) + + _, err = WaitSubnetAvailable(conn, d.Id(), d.Timeout(schema.TimeoutCreate)) + + if err != nil { + return fmt.Errorf("error waiting for EC2 Default Subnet (%s) to become available: %w", d.Id(), err) + } + } else { + return fmt.Errorf("error reading EC2 Default Subnet (%s): %w", d.Id(), err) } - d.SetId(aws.StringValue(resp.Subnets[0].SubnetId)) - return resourceSubnetUpdate(d, meta) + // TODO Compare Subnet with desired configuration and update. + + return resourceSubnetRead(d, meta) } func resourceDefaultSubnetDelete(d *schema.ResourceData, meta interface{}) error { - log.Printf("[WARN] Cannot destroy Default Subnet. Terraform will remove this resource from the state file, however resources may remain.") + if d.Get("force_destroy").(bool) { + return resourceSubnetDelete(d, meta) + } + + log.Printf("[WARN] EC2 Default Subnet (%s) not deleted, removing from state", d.Id()) + return nil } diff --git a/internal/service/ec2/default_subnet_test.go b/internal/service/ec2/default_subnet_test.go index 14bd71b6aed..fa2c694c172 100644 --- a/internal/service/ec2/default_subnet_test.go +++ b/internal/service/ec2/default_subnet_test.go @@ -1,11 +1,9 @@ package ec2_test import ( - "fmt" "testing" "github.com/aws/aws-sdk-go/service/ec2" - 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" @@ -13,10 +11,8 @@ import ( func TestAccEC2DefaultSubnet_basic(t *testing.T) { var v ec2.Subnet - - resourceName := "aws_default_subnet.foo" + resourceName := "aws_default_subnet.test" availabilityZonesDataSourceName := "data.aws_availability_zones.available" - rInt := sdkacctest.RandInt() resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -25,69 +21,14 @@ func TestAccEC2DefaultSubnet_basic(t *testing.T) { CheckDestroy: testAccCheckDefaultSubnetDestroy, Steps: []resource.TestStep{ { - Config: testAccDefaultSubnetBasicConfig(rInt), + Config: testAccDefaultSubnetConfig(), Check: resource.ComposeTestCheckFunc( testAccCheckSubnetExists(resourceName, &v), - resource.TestCheckResourceAttrPair( - resourceName, "availability_zone", availabilityZonesDataSourceName, "names.0"), - resource.TestCheckResourceAttrSet( - resourceName, "availability_zone_id"), - resource.TestCheckResourceAttr( - resourceName, "assign_ipv6_address_on_creation", "false"), - resource.TestCheckResourceAttr( - resourceName, "tags.%", "1"), - resource.TestCheckResourceAttr( - resourceName, "tags.Name", fmt.Sprintf("terraform-testacc-default-subnet-%d", rInt)), + resource.TestCheckResourceAttrPair(resourceName, "availability_zone", availabilityZonesDataSourceName, "names.0"), + resource.TestCheckResourceAttrSet(resourceName, "availability_zone_id"), + resource.TestCheckResourceAttr(resourceName, "assign_ipv6_address_on_creation", "false"), acctest.CheckResourceAttrAccountID(resourceName, "owner_id"), - ), - }, - }, - }) -} - -func TestAccEC2DefaultSubnet_publicIP(t *testing.T) { - var v ec2.Subnet - - resourceName := "aws_default_subnet.foo" - availabilityZonesDataSourceName := "data.aws_availability_zones.available" - rInt := sdkacctest.RandInt() - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t) }, - ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), - Providers: acctest.Providers, - CheckDestroy: testAccCheckDefaultSubnetDestroy, - Steps: []resource.TestStep{ - { - Config: testAccDefaultSubnetPublicIPConfig(rInt), - Check: resource.ComposeTestCheckFunc( - testAccCheckSubnetExists(resourceName, &v), - resource.TestCheckResourceAttrPair( - resourceName, "availability_zone", availabilityZonesDataSourceName, "names.1"), - resource.TestCheckResourceAttr( - resourceName, "map_public_ip_on_launch", "true"), - resource.TestCheckResourceAttr( - resourceName, "assign_ipv6_address_on_creation", "false"), - resource.TestCheckResourceAttr( - resourceName, "tags.%", "1"), - resource.TestCheckResourceAttr( - resourceName, "tags.Name", fmt.Sprintf("terraform-testacc-default-subnet-%d", rInt)), - ), - }, - { - Config: testAccDefaultSubnetNoPublicIPConfig(rInt), - Check: resource.ComposeTestCheckFunc( - testAccCheckSubnetExists(resourceName, &v), - resource.TestCheckResourceAttrPair( - resourceName, "availability_zone", availabilityZonesDataSourceName, "names.1"), - resource.TestCheckResourceAttr( - resourceName, "map_public_ip_on_launch", "false"), - resource.TestCheckResourceAttr( - resourceName, "assign_ipv6_address_on_creation", "false"), - resource.TestCheckResourceAttr( - resourceName, "tags.%", "1"), - resource.TestCheckResourceAttr( - resourceName, "tags.Name", fmt.Sprintf("terraform-testacc-default-subnet-%d", rInt)), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, }, @@ -99,40 +40,10 @@ func testAccCheckDefaultSubnetDestroy(s *terraform.State) error { return nil } -func testAccDefaultSubnetBasicConfig(rInt int) string { - return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` -resource "aws_default_subnet" "foo" { +func testAccDefaultSubnetConfig() string { + return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), ` +resource "aws_default_subnet" "test" { availability_zone = data.aws_availability_zones.available.names[0] - - tags = { - Name = "terraform-testacc-default-subnet-%d" - } -} -`, rInt)) -} - -func testAccDefaultSubnetPublicIPConfig(rInt int) string { - return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` -resource "aws_default_subnet" "foo" { - availability_zone = data.aws_availability_zones.available.names[1] - map_public_ip_on_launch = true - - tags = { - Name = "terraform-testacc-default-subnet-%d" - } -} -`, rInt)) -} - -func testAccDefaultSubnetNoPublicIPConfig(rInt int) string { - return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` -resource "aws_default_subnet" "foo" { - availability_zone = data.aws_availability_zones.available.names[1] - map_public_ip_on_launch = false - - tags = { - Name = "terraform-testacc-default-subnet-%d" - } } -`, rInt)) +`) } diff --git a/internal/service/ec2/subnet.go b/internal/service/ec2/subnet.go index 8d85d88578e..80595a55b1b 100644 --- a/internal/service/ec2/subnet.go +++ b/internal/service/ec2/subnet.go @@ -37,6 +37,7 @@ func ResourceSubnet() *schema.Resource { SchemaVersion: 1, MigrateState: SubnetMigrateState, + // Keep in sync with aws_default_subnet's schema. Schema: map[string]*schema.Schema{ "arn": { Type: schema.TypeString, @@ -319,13 +320,13 @@ func resourceSubnetRead(d *schema.ResourceData, meta interface{}) error { }, d.IsNewResource()) if !d.IsNewResource() && tfresource.NotFound(err) { - log.Printf("[WARN] Subnet (%s) not found, removing from state", d.Id()) + log.Printf("[WARN] EC2 Subnet (%s) not found, removing from state", d.Id()) d.SetId("") return nil } if err != nil { - return fmt.Errorf("error reading Subnet (%s): %w", d.Id(), err) + return fmt.Errorf("error reading EC2 Subnet (%s): %w", d.Id(), err) } subnet := outputRaw.(*ec2.Subnet) From df1b1d8cb6e94bc7a048aa0aacba676b2fc96002 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 11 Jan 2022 17:14:33 -0500 Subject: [PATCH 024/116] r/aws_default_subnet: Full resource life cycle. Playing with some ideas... Acceptance test output: % AWS_DEFAULT_REGION=eu-west-2 make testacc TESTARGS='-run=TestAccEC2DefaultSubnet_basic' PKG_NAME=internal/service/ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run=TestAccEC2DefaultSubnet_basic -timeout 180m === RUN TestAccEC2DefaultSubnet_basic === PAUSE TestAccEC2DefaultSubnet_basic === CONT TestAccEC2DefaultSubnet_basic --- PASS: TestAccEC2DefaultSubnet_basic (26.14s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 29.867s --- internal/service/ec2/default_subnet.go | 4 ++++ internal/service/ec2/subnet.go | 31 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/internal/service/ec2/default_subnet.go b/internal/service/ec2/default_subnet.go index 73b997f7cae..b51d662c202 100644 --- a/internal/service/ec2/default_subnet.go +++ b/internal/service/ec2/default_subnet.go @@ -194,6 +194,10 @@ func resourceDefaultSubnetCreate(d *schema.ResourceData, meta interface{}) error // TODO Compare Subnet with desired configuration and update. + if err := modifySubnetAttributesOnCreate(conn, d, subnet); err != nil { + return err + } + return resourceSubnetRead(d, meta) } diff --git a/internal/service/ec2/subnet.go b/internal/service/ec2/subnet.go index 80595a55b1b..ac056451e87 100644 --- a/internal/service/ec2/subnet.go +++ b/internal/service/ec2/subnet.go @@ -604,3 +604,34 @@ func resourceSubnetDelete(d *schema.ResourceData, meta interface{}) error { return nil } + +// modifySubnetAttributesOnCreate sets subnet attributes on resource Create. +// Called after new subnet creation or existing default subnet adoption. +func modifySubnetAttributesOnCreate(conn *ec2.EC2, d *schema.ResourceData, subnet *ec2.Subnet) error { + if new, old := d.Get("map_public_ip_on_launch").(bool), aws.BoolValue(subnet.MapPublicIpOnLaunch); old != new { + if err := modifySubnetMapPublicIpOnLaunch(conn, d.Id(), new); err != nil { + return err + } + } + + return nil +} + +func modifySubnetMapPublicIpOnLaunch(conn *ec2.EC2, subnetID string, v bool) error { + input := &ec2.ModifySubnetAttributeInput{ + MapPublicIpOnLaunch: &ec2.AttributeBooleanValue{ + Value: aws.Bool(v), + }, + SubnetId: aws.String(subnetID), + } + + if _, err := conn.ModifySubnetAttribute(input); err != nil { + return fmt.Errorf("error setting EC2 Subnet (%s) MapPublicIpOnLaunch: %w", subnetID, err) + } + + if _, err := WaitSubnetMapPublicIPOnLaunchUpdated(conn, subnetID, v); err != nil { + return fmt.Errorf("error waiting for EC2 Subnet (%s) MapPublicIpOnLaunch update: %w", subnetID, err) + } + + return nil +} From 9bcb97155d406fd6490e4abd0e228f6a5bbd0cc6 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 12 Jan 2022 09:52:03 -0500 Subject: [PATCH 025/116] r/aws_default_subnet: 'map_public_ip_on_launch' has a Default of true. --- internal/service/ec2/default_subnet.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/service/ec2/default_subnet.go b/internal/service/ec2/default_subnet.go index b51d662c202..e49d785bb21 100644 --- a/internal/service/ec2/default_subnet.go +++ b/internal/service/ec2/default_subnet.go @@ -37,6 +37,7 @@ func ResourceDefaultSubnet() *schema.Resource { // - availability_zone is Required/ForceNew // - availability_zone_id is Computed-only // - cidr_block is Computed-only + // - map_public_ip_on_launch has a Default of true // - outpost_arn is Computed-only // - vpc_id is Computed-only // and additions: @@ -117,7 +118,7 @@ func ResourceDefaultSubnet() *schema.Resource { "map_public_ip_on_launch": { Type: schema.TypeBool, Optional: true, - Default: false, + Default: true, }, "outpost_arn": { Type: schema.TypeString, From b0a4cff13874fd33013ceeba9f8727645fa0757d Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 12 Jan 2022 13:40:30 -0500 Subject: [PATCH 026/116] Additional 'modifySubnetAttriute' functions. --- internal/service/ec2/subnet.go | 135 ++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 52 deletions(-) diff --git a/internal/service/ec2/subnet.go b/internal/service/ec2/subnet.go index ac056451e87..316b13e262a 100644 --- a/internal/service/ec2/subnet.go +++ b/internal/service/ec2/subnet.go @@ -418,70 +418,26 @@ func resourceSubnetUpdate(d *schema.ResourceData, meta interface{}) error { } if d.HasChange("enable_dns64") { - input := &ec2.ModifySubnetAttributeInput{ - EnableDns64: &ec2.AttributeBooleanValue{ - Value: aws.Bool(d.Get("enable_dns64").(bool)), - }, - SubnetId: aws.String(d.Id()), - } - - if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) EnableDns64: %w", d.Id(), err) - } - - if _, err := WaitSubnetEnableDns64Updated(conn, d.Id(), d.Get("enable_dns64").(bool)); err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) EnableDns64 update: %w", d.Id(), err) + if err := modifySubnetEnableDns64(conn, d.Id(), d.Get("enable_dns64").(bool)); err != nil { + return err } } if d.HasChange("enable_resource_name_dns_aaaa_record_on_launch") { - input := &ec2.ModifySubnetAttributeInput{ - EnableResourceNameDnsAAAARecordOnLaunch: &ec2.AttributeBooleanValue{ - Value: aws.Bool(d.Get("enable_resource_name_dns_aaaa_record_on_launch").(bool)), - }, - SubnetId: aws.String(d.Id()), - } - - if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) EnableResourceNameDnsAAAARecordOnLaunch: %w", d.Id(), err) - } - - if _, err := WaitSubnetEnableResourceNameDnsAAAARecordOnLaunchUpdated(conn, d.Id(), d.Get("enable_resource_name_dns_aaaa_record_on_launch").(bool)); err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) EnableResourceNameDnsAAAARecordOnLaunch update: %w", d.Id(), err) + if err := modifySubnetEnableResourceNameDnsAAAARecordOnLaunch(conn, d.Id(), d.Get("enable_resource_name_dns_aaaa_record_on_launch").(bool)); err != nil { + return err } } if d.HasChange("enable_resource_name_dns_a_record_on_launch") { - input := &ec2.ModifySubnetAttributeInput{ - EnableResourceNameDnsARecordOnLaunch: &ec2.AttributeBooleanValue{ - Value: aws.Bool(d.Get("enable_resource_name_dns_a_record_on_launch").(bool)), - }, - SubnetId: aws.String(d.Id()), - } - - if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) EnableResourceNameDnsARecordOnLaunch: %w", d.Id(), err) - } - - if _, err := WaitSubnetEnableResourceNameDnsARecordOnLaunchUpdated(conn, d.Id(), d.Get("enable_resource_name_dns_a_record_on_launch").(bool)); err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) EnableResourceNameDnsARecordOnLaunch update: %w", d.Id(), err) + if err := modifySubnetEnableResourceNameDnsARecordOnLaunch(conn, d.Id(), d.Get("enable_resource_name_dns_a_record_on_launch").(bool)); err != nil { + return err } } if d.HasChange("map_public_ip_on_launch") { - input := &ec2.ModifySubnetAttributeInput{ - MapPublicIpOnLaunch: &ec2.AttributeBooleanValue{ - Value: aws.Bool(d.Get("map_public_ip_on_launch").(bool)), - }, - SubnetId: aws.String(d.Id()), - } - - if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) MapPublicIpOnLaunch: %w", d.Id(), err) - } - - if _, err := WaitSubnetMapPublicIPOnLaunchUpdated(conn, d.Id(), d.Get("map_public_ip_on_launch").(bool)); err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) MapPublicIpOnLaunch update: %w", d.Id(), err) + if err := modifySubnetMapPublicIpOnLaunch(conn, d.Id(), d.Get("map_public_ip_on_launch").(bool)); err != nil { + return err } } @@ -608,6 +564,24 @@ func resourceSubnetDelete(d *schema.ResourceData, meta interface{}) error { // modifySubnetAttributesOnCreate sets subnet attributes on resource Create. // Called after new subnet creation or existing default subnet adoption. func modifySubnetAttributesOnCreate(conn *ec2.EC2, d *schema.ResourceData, subnet *ec2.Subnet) error { + if new, old := d.Get("enable_dns64").(bool), aws.BoolValue(subnet.EnableDns64); old != new { + if err := modifySubnetEnableDns64(conn, d.Id(), new); err != nil { + return err + } + } + + if new, old := d.Get("enable_resource_name_dns_aaaa_record_on_launch").(bool), aws.BoolValue(subnet.PrivateDnsNameOptionsOnLaunch.EnableResourceNameDnsAAAARecord); old != new { + if err := modifySubnetEnableResourceNameDnsAAAARecordOnLaunch(conn, d.Id(), new); err != nil { + return err + } + } + + if new, old := d.Get("enable_resource_name_dns_a_record_on_launch").(bool), aws.BoolValue(subnet.PrivateDnsNameOptionsOnLaunch.EnableResourceNameDnsARecord); old != new { + if err := modifySubnetEnableResourceNameDnsARecordOnLaunch(conn, d.Id(), new); err != nil { + return err + } + } + if new, old := d.Get("map_public_ip_on_launch").(bool), aws.BoolValue(subnet.MapPublicIpOnLaunch); old != new { if err := modifySubnetMapPublicIpOnLaunch(conn, d.Id(), new); err != nil { return err @@ -617,6 +591,63 @@ func modifySubnetAttributesOnCreate(conn *ec2.EC2, d *schema.ResourceData, subne return nil } +func modifySubnetEnableDns64(conn *ec2.EC2, subnetID string, v bool) error { + input := &ec2.ModifySubnetAttributeInput{ + EnableDns64: &ec2.AttributeBooleanValue{ + Value: aws.Bool(v), + }, + SubnetId: aws.String(subnetID), + } + + if _, err := conn.ModifySubnetAttribute(input); err != nil { + return fmt.Errorf("error setting EC2 Subnet (%s) EnableDns64: %w", subnetID, err) + } + + if _, err := WaitSubnetEnableDns64Updated(conn, subnetID, v); err != nil { + return fmt.Errorf("error waiting for EC2 Subnet (%s) EnableDns64 update: %w", subnetID, err) + } + + return nil +} + +func modifySubnetEnableResourceNameDnsAAAARecordOnLaunch(conn *ec2.EC2, subnetID string, v bool) error { + input := &ec2.ModifySubnetAttributeInput{ + EnableResourceNameDnsAAAARecordOnLaunch: &ec2.AttributeBooleanValue{ + Value: aws.Bool(v), + }, + SubnetId: aws.String(subnetID), + } + + if _, err := conn.ModifySubnetAttribute(input); err != nil { + return fmt.Errorf("error setting EC2 Subnet (%s) EnableResourceNameDnsAAAARecordOnLaunch: %w", subnetID, err) + } + + if _, err := WaitSubnetEnableResourceNameDnsAAAARecordOnLaunchUpdated(conn, subnetID, v); err != nil { + return fmt.Errorf("error waiting for EC2 Subnet (%s) EnableResourceNameDnsAAAARecordOnLaunch update: %w", subnetID, err) + } + + return nil +} + +func modifySubnetEnableResourceNameDnsARecordOnLaunch(conn *ec2.EC2, subnetID string, v bool) error { + input := &ec2.ModifySubnetAttributeInput{ + EnableResourceNameDnsARecordOnLaunch: &ec2.AttributeBooleanValue{ + Value: aws.Bool(v), + }, + SubnetId: aws.String(subnetID), + } + + if _, err := conn.ModifySubnetAttribute(input); err != nil { + return fmt.Errorf("error setting EC2 Subnet (%s) EnableResourceNameDnsARecordOnLaunch: %w", subnetID, err) + } + + if _, err := WaitSubnetEnableResourceNameDnsARecordOnLaunchUpdated(conn, subnetID, v); err != nil { + return fmt.Errorf("error waiting for EC2 Subnet (%s) EnableResourceNameDnsARecordOnLaunch update: %w", subnetID, err) + } + + return nil +} + func modifySubnetMapPublicIpOnLaunch(conn *ec2.EC2, subnetID string, v bool) error { input := &ec2.ModifySubnetAttributeInput{ MapPublicIpOnLaunch: &ec2.AttributeBooleanValue{ From dac96410f7b14ffb5cb29c1383d89f1631d4e433 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 12 Jan 2022 15:51:09 -0500 Subject: [PATCH 027/116] r/aws_default_subnet: Complete 'modifySubnetAttributesOnCreate'. Acceptance test output: % AWS_DEFAULT_REGION=eu-west-2 make testacc TESTARGS='-run=TestAccEC2DefaultSubnet_basic' PKG_NAME=internal/service/ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run=TestAccEC2DefaultSubnet_basic -timeout 180m === RUN TestAccEC2DefaultSubnet_basic === PAUSE TestAccEC2DefaultSubnet_basic === CONT TestAccEC2DefaultSubnet_basic --- PASS: TestAccEC2DefaultSubnet_basic (16.30s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 20.128s % make testacc TESTARGS='-run=TestAccEC2Subnet_' PKG=ec2 ACCTEST_PARALLELISM=5 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 5 -run=TestAccEC2Subnet_ -timeout 180m === RUN TestAccEC2Subnet_basic === PAUSE TestAccEC2Subnet_basic === RUN TestAccEC2Subnet_tags === PAUSE TestAccEC2Subnet_tags === RUN TestAccEC2Subnet_DefaultTags_providerOnly === PAUSE TestAccEC2Subnet_DefaultTags_providerOnly === RUN TestAccEC2Subnet_DefaultTags_updateToProviderOnly === PAUSE TestAccEC2Subnet_DefaultTags_updateToProviderOnly === RUN TestAccEC2Subnet_DefaultTags_updateToResourceOnly === PAUSE TestAccEC2Subnet_DefaultTags_updateToResourceOnly === RUN TestAccEC2Subnet_DefaultTagsProviderAndResource_nonOverlappingTag === PAUSE TestAccEC2Subnet_DefaultTagsProviderAndResource_nonOverlappingTag === RUN TestAccEC2Subnet_DefaultTagsProviderAndResource_overlappingTag === PAUSE TestAccEC2Subnet_DefaultTagsProviderAndResource_overlappingTag === RUN TestAccEC2Subnet_DefaultTagsProviderAndResource_duplicateTag === PAUSE TestAccEC2Subnet_DefaultTagsProviderAndResource_duplicateTag === RUN TestAccEC2Subnet_defaultAndIgnoreTags === PAUSE TestAccEC2Subnet_defaultAndIgnoreTags === RUN TestAccEC2Subnet_updateTagsKnownAtApply === PAUSE TestAccEC2Subnet_updateTagsKnownAtApply === RUN TestAccEC2Subnet_ignoreTags === PAUSE TestAccEC2Subnet_ignoreTags === RUN TestAccEC2Subnet_ipv6 === PAUSE TestAccEC2Subnet_ipv6 === RUN TestAccEC2Subnet_enableIPv6 === PAUSE TestAccEC2Subnet_enableIPv6 === RUN TestAccEC2Subnet_availabilityZoneID === PAUSE TestAccEC2Subnet_availabilityZoneID === RUN TestAccEC2Subnet_disappears === PAUSE TestAccEC2Subnet_disappears === RUN TestAccEC2Subnet_customerOwnedIPv4Pool === PAUSE TestAccEC2Subnet_customerOwnedIPv4Pool === RUN TestAccEC2Subnet_mapCustomerOwnedIPOnLaunch === PAUSE TestAccEC2Subnet_mapCustomerOwnedIPOnLaunch === RUN TestAccEC2Subnet_mapPublicIPOnLaunch === PAUSE TestAccEC2Subnet_mapPublicIPOnLaunch === RUN TestAccEC2Subnet_outpost === PAUSE TestAccEC2Subnet_outpost === RUN TestAccEC2Subnet_enableDNS64 === PAUSE TestAccEC2Subnet_enableDNS64 === RUN TestAccEC2Subnet_privateDnsNameOptionsOnLaunch === PAUSE TestAccEC2Subnet_privateDnsNameOptionsOnLaunch === RUN TestAccEC2Subnet_ipv6Native === PAUSE TestAccEC2Subnet_ipv6Native === CONT TestAccEC2Subnet_basic === CONT TestAccEC2Subnet_enableIPv6 === CONT TestAccEC2Subnet_ipv6Native === CONT TestAccEC2Subnet_privateDnsNameOptionsOnLaunch === CONT TestAccEC2Subnet_enableDNS64 --- PASS: TestAccEC2Subnet_basic (36.19s) === CONT TestAccEC2Subnet_outpost --- PASS: TestAccEC2Subnet_ipv6Native (36.51s) === CONT TestAccEC2Subnet_mapPublicIPOnLaunch === CONT TestAccEC2Subnet_outpost acctest.go:1254: skipping since no Outposts found --- SKIP: TestAccEC2Subnet_outpost (0.62s) === CONT TestAccEC2Subnet_mapCustomerOwnedIPOnLaunch acctest.go:1254: skipping since no Outposts found --- SKIP: TestAccEC2Subnet_mapCustomerOwnedIPOnLaunch (0.55s) === CONT TestAccEC2Subnet_customerOwnedIPv4Pool acctest.go:1254: skipping since no Outposts found --- SKIP: TestAccEC2Subnet_customerOwnedIPv4Pool (0.60s) === CONT TestAccEC2Subnet_disappears --- PASS: TestAccEC2Subnet_disappears (27.28s) === CONT TestAccEC2Subnet_availabilityZoneID --- PASS: TestAccEC2Subnet_availabilityZoneID (31.74s) === CONT TestAccEC2Subnet_DefaultTagsProviderAndResource_overlappingTag --- PASS: TestAccEC2Subnet_enableIPv6 (105.09s) === CONT TestAccEC2Subnet_ipv6 --- PASS: TestAccEC2Subnet_enableDNS64 (123.19s) === CONT TestAccEC2Subnet_ignoreTags --- PASS: TestAccEC2Subnet_mapPublicIPOnLaunch (110.55s) === CONT TestAccEC2Subnet_updateTagsKnownAtApply --- PASS: TestAccEC2Subnet_DefaultTagsProviderAndResource_overlappingTag (77.30s) === CONT TestAccEC2Subnet_defaultAndIgnoreTags --- PASS: TestAccEC2Subnet_privateDnsNameOptionsOnLaunch (181.07s) === CONT TestAccEC2Subnet_DefaultTagsProviderAndResource_duplicateTag --- PASS: TestAccEC2Subnet_DefaultTagsProviderAndResource_duplicateTag (2.01s) === CONT TestAccEC2Subnet_DefaultTags_updateToProviderOnly --- PASS: TestAccEC2Subnet_ignoreTags (63.57s) === CONT TestAccEC2Subnet_DefaultTagsProviderAndResource_nonOverlappingTag --- PASS: TestAccEC2Subnet_ipv6 (105.70s) === CONT TestAccEC2Subnet_DefaultTags_updateToResourceOnly --- PASS: TestAccEC2Subnet_updateTagsKnownAtApply (77.98s) === CONT TestAccEC2Subnet_DefaultTags_providerOnly --- PASS: TestAccEC2Subnet_DefaultTags_updateToProviderOnly (62.21s) === CONT TestAccEC2Subnet_tags --- PASS: TestAccEC2Subnet_defaultAndIgnoreTags (72.81s) --- PASS: TestAccEC2Subnet_DefaultTagsProviderAndResource_nonOverlappingTag (83.96s) --- PASS: TestAccEC2Subnet_DefaultTags_updateToResourceOnly (60.94s) --- PASS: TestAccEC2Subnet_DefaultTags_providerOnly (80.64s) --- PASS: TestAccEC2Subnet_tags (77.07s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 328.734s --- internal/service/ec2/default_subnet.go | 4 +- internal/service/ec2/status.go | 20 +- internal/service/ec2/subnet.go | 393 +++++++++++-------------- internal/service/ec2/wait.go | 18 ++ 4 files changed, 211 insertions(+), 224 deletions(-) diff --git a/internal/service/ec2/default_subnet.go b/internal/service/ec2/default_subnet.go index e49d785bb21..fc0998d8443 100644 --- a/internal/service/ec2/default_subnet.go +++ b/internal/service/ec2/default_subnet.go @@ -187,14 +187,12 @@ func resourceDefaultSubnetCreate(d *schema.ResourceData, meta interface{}) error _, err = WaitSubnetAvailable(conn, d.Id(), d.Timeout(schema.TimeoutCreate)) if err != nil { - return fmt.Errorf("error waiting for EC2 Default Subnet (%s) to become available: %w", d.Id(), err) + return fmt.Errorf("error waiting for EC2 Default Subnet (%s) create: %w", d.Id(), err) } } else { return fmt.Errorf("error reading EC2 Default Subnet (%s): %w", d.Id(), err) } - // TODO Compare Subnet with desired configuration and update. - if err := modifySubnetAttributesOnCreate(conn, d, subnet); err != nil { return err } diff --git a/internal/service/ec2/status.go b/internal/service/ec2/status.go index c79acfc5a5b..080f527a01c 100644 --- a/internal/service/ec2/status.go +++ b/internal/service/ec2/status.go @@ -376,7 +376,7 @@ func StatusSubnetIPv6CIDRBlockAssociationState(conn *ec2.EC2, id string) resourc } } -func StatusSubnetMapCustomerOwnedIPOnLaunch(conn *ec2.EC2, id string) resource.StateRefreshFunc { +func StatusSubnetAssignIpv6AddressOnCreation(conn *ec2.EC2, id string) resource.StateRefreshFunc { return func() (interface{}, string, error) { output, err := FindSubnetByID(conn, id) @@ -388,7 +388,7 @@ func StatusSubnetMapCustomerOwnedIPOnLaunch(conn *ec2.EC2, id string) resource.S return nil, "", err } - return output, strconv.FormatBool(aws.BoolValue(output.MapCustomerOwnedIpOnLaunch)), nil + return output, strconv.FormatBool(aws.BoolValue(output.AssignIpv6AddressOnCreation)), nil } } @@ -440,6 +440,22 @@ func StatusSubnetEnableResourceNameDnsARecordOnLaunch(conn *ec2.EC2, id string) } } +func StatusSubnetMapCustomerOwnedIPOnLaunch(conn *ec2.EC2, id string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := FindSubnetByID(conn, id) + + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return output, strconv.FormatBool(aws.BoolValue(output.MapCustomerOwnedIpOnLaunch)), nil + } +} + func StatusSubnetMapPublicIPOnLaunch(conn *ec2.EC2, id string) resource.StateRefreshFunc { return func() (interface{}, string, error) { output, err := FindSubnetByID(conn, id) diff --git a/internal/service/ec2/subnet.go b/internal/service/ec2/subnet.go index 316b13e262a..e3ec55622af 100644 --- a/internal/service/ec2/subnet.go +++ b/internal/service/ec2/subnet.go @@ -183,128 +183,14 @@ func resourceSubnetCreate(d *schema.ResourceData, meta interface{}) error { d.SetId(aws.StringValue(output.Subnet.SubnetId)) - _, err = WaitSubnetAvailable(conn, d.Id(), d.Timeout(schema.TimeoutCreate)) + subnet, err := WaitSubnetAvailable(conn, d.Id(), d.Timeout(schema.TimeoutCreate)) if err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) to become available: %w", d.Id(), err) + return fmt.Errorf("error waiting for EC2 Subnet (%s) create: %w", d.Id(), err) } - // You cannot modify multiple subnet attributes in the same request, - // except CustomerOwnedIpv4Pool and MapCustomerOwnedIpOnLaunch. - // Reference: https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_ModifySubnetAttribute.html - - if d.Get("assign_ipv6_address_on_creation").(bool) { - input := &ec2.ModifySubnetAttributeInput{ - AssignIpv6AddressOnCreation: &ec2.AttributeBooleanValue{ - Value: aws.Bool(true), - }, - SubnetId: aws.String(d.Id()), - } - - if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) AssignIpv6AddressOnCreation: %w", d.Id(), err) - } - } - - if v, ok := d.GetOk("customer_owned_ipv4_pool"); ok { - input := &ec2.ModifySubnetAttributeInput{ - CustomerOwnedIpv4Pool: aws.String(v.(string)), - MapCustomerOwnedIpOnLaunch: &ec2.AttributeBooleanValue{ - Value: aws.Bool(d.Get("map_customer_owned_ip_on_launch").(bool)), - }, - SubnetId: aws.String(d.Id()), - } - - if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) CustomerOwnedIpv4Pool/MapCustomerOwnedIpOnLaunch: %w", d.Id(), err) - } - - if _, err := WaitSubnetMapCustomerOwnedIPOnLaunchUpdated(conn, d.Id(), d.Get("map_customer_owned_ip_on_launch").(bool)); err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) MapCustomerOwnedIpOnLaunch update: %w", d.Id(), err) - } - } - - if d.Get("enable_dns64").(bool) { - input := &ec2.ModifySubnetAttributeInput{ - EnableDns64: &ec2.AttributeBooleanValue{ - Value: aws.Bool(true), - }, - SubnetId: aws.String(d.Id()), - } - - if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) EnableDns64: %w", d.Id(), err) - } - - if _, err := WaitSubnetEnableDns64Updated(conn, d.Id(), d.Get("enable_dns64").(bool)); err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) EnableDns64 update: %w", d.Id(), err) - } - } - - if d.Get("enable_resource_name_dns_aaaa_record_on_launch").(bool) { - input := &ec2.ModifySubnetAttributeInput{ - EnableResourceNameDnsAAAARecordOnLaunch: &ec2.AttributeBooleanValue{ - Value: aws.Bool(true), - }, - SubnetId: aws.String(d.Id()), - } - - if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) EnableResourceNameDnsAAAARecordOnLaunch: %w", d.Id(), err) - } - - if _, err := WaitSubnetEnableResourceNameDnsAAAARecordOnLaunchUpdated(conn, d.Id(), d.Get("enable_resource_name_dns_aaaa_record_on_launch").(bool)); err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) EnableResourceNameDnsAAAARecordOnLaunch update: %w", d.Id(), err) - } - } - - if d.Get("enable_resource_name_dns_a_record_on_launch").(bool) { - input := &ec2.ModifySubnetAttributeInput{ - EnableResourceNameDnsARecordOnLaunch: &ec2.AttributeBooleanValue{ - Value: aws.Bool(true), - }, - SubnetId: aws.String(d.Id()), - } - - if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) EnableResourceNameDnsARecordOnLaunch: %w", d.Id(), err) - } - - if _, err := WaitSubnetEnableResourceNameDnsARecordOnLaunchUpdated(conn, d.Id(), d.Get("enable_resource_name_dns_a_record_on_launch").(bool)); err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) EnableResourceNameDnsARecordOnLaunch update: %w", d.Id(), err) - } - } - - if d.Get("map_public_ip_on_launch").(bool) { - input := &ec2.ModifySubnetAttributeInput{ - MapPublicIpOnLaunch: &ec2.AttributeBooleanValue{ - Value: aws.Bool(true), - }, - SubnetId: aws.String(d.Id()), - } - - if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) MapPublicIpOnLaunch: %w", d.Id(), err) - } - - if _, err := WaitSubnetMapPublicIPOnLaunchUpdated(conn, d.Id(), d.Get("map_public_ip_on_launch").(bool)); err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) MapPublicIpOnLaunch update: %w", d.Id(), err) - } - } - - if v, ok := d.GetOk("private_dns_hostname_type_on_launch"); ok { - input := &ec2.ModifySubnetAttributeInput{ - PrivateDnsHostnameTypeOnLaunch: aws.String(v.(string)), - SubnetId: aws.String(d.Id()), - } - - if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) PrivateDnsHostnameTypeOnLaunch: %w", d.Id(), err) - } - - if _, err := WaitSubnetPrivateDNSHostnameTypeOnLaunchUpdated(conn, d.Id(), d.Get("private_dns_hostname_type_on_launch").(string)); err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) PrivateDnsHostnameTypeOnLaunch update: %w", d.Id(), err) - } + if err := modifySubnetAttributesOnCreate(conn, d, subnet); err != nil { + return err } return resourceSubnetRead(d, meta) @@ -397,23 +283,8 @@ func resourceSubnetUpdate(d *schema.ResourceData, meta interface{}) error { // Reference: https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_ModifySubnetAttribute.html if d.HasChanges("customer_owned_ipv4_pool", "map_customer_owned_ip_on_launch") { - input := &ec2.ModifySubnetAttributeInput{ - MapCustomerOwnedIpOnLaunch: &ec2.AttributeBooleanValue{ - Value: aws.Bool(d.Get("map_customer_owned_ip_on_launch").(bool)), - }, - SubnetId: aws.String(d.Id()), - } - - if v, ok := d.GetOk("customer_owned_ipv4_pool"); ok { - input.CustomerOwnedIpv4Pool = aws.String(v.(string)) - } - - if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) CustomerOwnedIpv4Pool/MapCustomerOwnedIpOnLaunch: %w", d.Id(), err) - } - - if _, err := WaitSubnetMapCustomerOwnedIPOnLaunchUpdated(conn, d.Id(), d.Get("map_customer_owned_ip_on_launch").(bool)); err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) MapCustomerOwnedIpOnLaunch update: %w", d.Id(), err) + if err := modifySubnetOutpostRackAttributes(conn, d.Id(), d.Get("customer_owned_ipv4_pool").(string), d.Get("map_customer_owned_ip_on_launch").(bool)); err != nil { + return err } } @@ -442,93 +313,28 @@ func resourceSubnetUpdate(d *schema.ResourceData, meta interface{}) error { } if d.HasChange("private_dns_hostname_type_on_launch") { - input := &ec2.ModifySubnetAttributeInput{ - PrivateDnsHostnameTypeOnLaunch: aws.String(d.Get("private_dns_hostname_type_on_launch").(string)), - SubnetId: aws.String(d.Id()), - } - - if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) PrivateDnsHostnameTypeOnLaunch: %w", d.Id(), err) + if err := modifySubnetPrivateDnsHostnameTypeOnLaunch(conn, d.Id(), d.Get("private_dns_hostname_type_on_launch").(string)); err != nil { + return err } + } - if _, err := WaitSubnetPrivateDNSHostnameTypeOnLaunchUpdated(conn, d.Id(), d.Get("private_dns_hostname_type_on_launch").(string)); err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) PrivateDnsHostnameTypeOnLaunch update: %w", d.Id(), err) + // If we're disabling IPv6 assignment for new ENIs, do that before modifying the IPv6 CIDR block. + if d.HasChange("assign_ipv6_address_on_creation") && !d.Get("assign_ipv6_address_on_creation").(bool) { + if err := modifySubnetAssignIpv6AddressOnCreation(conn, d.Id(), false); err != nil { + return err } } if d.HasChange("ipv6_cidr_block") { - // We need to handle that we disassociate the IPv6 CIDR block before we try to associate the new one - // This could be an issue as, we could error out when we try to add the new one - // We may need to roll back the state and reattach the old one if this is the case - if v, ok := d.GetOk("ipv6_cidr_block_association_id"); ok { - if !d.Get("assign_ipv6_address_on_creation").(bool) { - input := &ec2.ModifySubnetAttributeInput{ - AssignIpv6AddressOnCreation: &ec2.AttributeBooleanValue{ - Value: aws.Bool(false), - }, - SubnetId: aws.String(d.Id()), - } - - if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) AssignIpv6AddressOnCreation: %w", d.Id(), err) - } - } - - associationID := v.(string) - - //Firstly we have to disassociate the old IPv6 CIDR Block - input := &ec2.DisassociateSubnetCidrBlockInput{ - AssociationId: aws.String(associationID), - } - - _, err := conn.DisassociateSubnetCidrBlock(input) - - if err != nil { - return fmt.Errorf("error disassociating EC2 Subnet (%s) CIDR block (%s): %w", d.Id(), associationID, err) - } - - _, err = WaitSubnetIPv6CIDRBlockAssociationDeleted(conn, associationID) - - if err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) CIDR block (%s) to become disassociated: %w", d.Id(), associationID, err) - } - } - - if newIpv6 := d.Get("ipv6_cidr_block").(string); newIpv6 != "" { - //Now we need to try to associate the new CIDR block - input := &ec2.AssociateSubnetCidrBlockInput{ - Ipv6CidrBlock: aws.String(newIpv6), - SubnetId: aws.String(d.Id()), - } - - output, err := conn.AssociateSubnetCidrBlock(input) - - if err != nil { - //The big question here is, do we want to try to reassociate the old one?? - //If we have a failure here, then we may be in a situation that we have nothing associated - return fmt.Errorf("error associating EC2 Subnet (%s) CIDR block (%s): %w", d.Id(), newIpv6, err) - } - - associationID := aws.StringValue(output.Ipv6CidrBlockAssociation.AssociationId) - - _, err = WaitSubnetIPv6CIDRBlockAssociationCreated(conn, associationID) - - if err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) CIDR block (%s) to become associated: %w", d.Id(), associationID, err) - } + if err := modifySubnetIPv6CIDRBlockAssociation(conn, d.Id(), d.Get("ipv6_cidr_block_association_id").(string), d.Get("ipv6_cidr_block").(string)); err != nil { + return err } } - if d.HasChange("assign_ipv6_address_on_creation") { - input := &ec2.ModifySubnetAttributeInput{ - AssignIpv6AddressOnCreation: &ec2.AttributeBooleanValue{ - Value: aws.Bool(d.Get("assign_ipv6_address_on_creation").(bool)), - }, - SubnetId: aws.String(d.Id()), - } - - if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error enabling EC2 Subnet (%s) AssignIpv6AddressOnCreation: %w", d.Id(), err) + // If we're enabling IPv6 assignment for new ENIs, do that after modifying the IPv6 CIDR block. + if d.HasChange("assign_ipv6_address_on_creation") && d.Get("assign_ipv6_address_on_creation").(bool) { + if err := modifySubnetAssignIpv6AddressOnCreation(conn, d.Id(), true); err != nil { + return err } } @@ -564,24 +370,66 @@ func resourceSubnetDelete(d *schema.ResourceData, meta interface{}) error { // modifySubnetAttributesOnCreate sets subnet attributes on resource Create. // Called after new subnet creation or existing default subnet adoption. func modifySubnetAttributesOnCreate(conn *ec2.EC2, d *schema.ResourceData, subnet *ec2.Subnet) error { - if new, old := d.Get("enable_dns64").(bool), aws.BoolValue(subnet.EnableDns64); old != new { - if err := modifySubnetEnableDns64(conn, d.Id(), new); err != nil { + // If we're disabling IPv6 assignment for new ENIs, do that before modifying the IPv6 CIDR block. + if new, old := d.Get("assign_ipv6_address_on_creation").(bool), aws.BoolValue(subnet.AssignIpv6AddressOnCreation); old != new && !new { + if err := modifySubnetAssignIpv6AddressOnCreation(conn, d.Id(), false); err != nil { return err } } - if new, old := d.Get("enable_resource_name_dns_aaaa_record_on_launch").(bool), aws.BoolValue(subnet.PrivateDnsNameOptionsOnLaunch.EnableResourceNameDnsAAAARecord); old != new { - if err := modifySubnetEnableResourceNameDnsAAAARecordOnLaunch(conn, d.Id(), new); err != nil { + for _, v := range subnet.Ipv6CidrBlockAssociationSet { + if aws.StringValue(v.Ipv6CidrBlockState.State) == ec2.SubnetCidrBlockStateCodeAssociated { //we can only ever have 1 IPv6 block associated at once + if new, old := d.Get("ipv6_cidr_block").(string), aws.StringValue(v.Ipv6CidrBlock); old != new { + if err := modifySubnetIPv6CIDRBlockAssociation(conn, d.Id(), aws.StringValue(v.AssociationId), new); err != nil { + return err + } + } + + break + } + } + + // If we're enabling IPv6 assignment for new ENIs, do that after modifying the IPv6 CIDR block. + if new, old := d.Get("assign_ipv6_address_on_creation").(bool), aws.BoolValue(subnet.AssignIpv6AddressOnCreation); old != new && new { + if err := modifySubnetAssignIpv6AddressOnCreation(conn, d.Id(), true); err != nil { + return err + } + } + + if newCustomerOwnedIPOnLaunch, oldCustomerOwnedIPOnLaunch, newMapCustomerOwnedIPOnLaunch, oldMapCustomerOwnedIPOnLaunch := + d.Get("customer_owned_ipv4_pool").(string), aws.StringValue(subnet.CustomerOwnedIpv4Pool), d.Get("map_customer_owned_ip_on_launch").(bool), aws.BoolValue(subnet.MapCustomerOwnedIpOnLaunch); oldCustomerOwnedIPOnLaunch != newCustomerOwnedIPOnLaunch || oldMapCustomerOwnedIPOnLaunch != newMapCustomerOwnedIPOnLaunch { + if err := modifySubnetOutpostRackAttributes(conn, d.Id(), newCustomerOwnedIPOnLaunch, newMapCustomerOwnedIPOnLaunch); err != nil { return err } } - if new, old := d.Get("enable_resource_name_dns_a_record_on_launch").(bool), aws.BoolValue(subnet.PrivateDnsNameOptionsOnLaunch.EnableResourceNameDnsARecord); old != new { - if err := modifySubnetEnableResourceNameDnsARecordOnLaunch(conn, d.Id(), new); err != nil { + if new, old := d.Get("enable_dns64").(bool), aws.BoolValue(subnet.EnableDns64); old != new { + if err := modifySubnetEnableDns64(conn, d.Id(), new); err != nil { return err } } + if subnet.PrivateDnsNameOptionsOnLaunch != nil { + if new, old := d.Get("enable_resource_name_dns_aaaa_record_on_launch").(bool), aws.BoolValue(subnet.PrivateDnsNameOptionsOnLaunch.EnableResourceNameDnsAAAARecord); old != new { + if err := modifySubnetEnableResourceNameDnsAAAARecordOnLaunch(conn, d.Id(), new); err != nil { + return err + } + } + + if new, old := d.Get("enable_resource_name_dns_a_record_on_launch").(bool), aws.BoolValue(subnet.PrivateDnsNameOptionsOnLaunch.EnableResourceNameDnsARecord); old != new { + if err := modifySubnetEnableResourceNameDnsARecordOnLaunch(conn, d.Id(), new); err != nil { + return err + } + } + + // private_dns_hostname_type_on_launch is Computed, so only modify if the new value is set. + if new, old := d.Get("private_dns_hostname_type_on_launch").(string), aws.StringValue(subnet.PrivateDnsNameOptionsOnLaunch.HostnameType); old != new && new != "" { + if err := modifySubnetPrivateDnsHostnameTypeOnLaunch(conn, d.Id(), new); err != nil { + return err + } + } + } + if new, old := d.Get("map_public_ip_on_launch").(bool), aws.BoolValue(subnet.MapPublicIpOnLaunch); old != new { if err := modifySubnetMapPublicIpOnLaunch(conn, d.Id(), new); err != nil { return err @@ -591,6 +439,25 @@ func modifySubnetAttributesOnCreate(conn *ec2.EC2, d *schema.ResourceData, subne return nil } +func modifySubnetAssignIpv6AddressOnCreation(conn *ec2.EC2, subnetID string, v bool) error { + input := &ec2.ModifySubnetAttributeInput{ + AssignIpv6AddressOnCreation: &ec2.AttributeBooleanValue{ + Value: aws.Bool(v), + }, + SubnetId: aws.String(subnetID), + } + + if _, err := conn.ModifySubnetAttribute(input); err != nil { + return fmt.Errorf("error setting EC2 Subnet (%s) AssignIpv6AddressOnCreation: %w", subnetID, err) + } + + if _, err := WaitSubnetAssignIpv6AddressOnCreationUpdated(conn, subnetID, v); err != nil { + return fmt.Errorf("error waiting for EC2 Subnet (%s) AssignIpv6AddressOnCreation update: %w", subnetID, err) + } + + return nil +} + func modifySubnetEnableDns64(conn *ec2.EC2, subnetID string, v bool) error { input := &ec2.ModifySubnetAttributeInput{ EnableDns64: &ec2.AttributeBooleanValue{ @@ -666,3 +533,91 @@ func modifySubnetMapPublicIpOnLaunch(conn *ec2.EC2, subnetID string, v bool) err return nil } + +func modifySubnetOutpostRackAttributes(conn *ec2.EC2, subnetID string, customerOwnedIPv4Pool string, mapCustomerOwnedIPOnLaunch bool) error { + input := &ec2.ModifySubnetAttributeInput{ + MapCustomerOwnedIpOnLaunch: &ec2.AttributeBooleanValue{ + Value: aws.Bool(mapCustomerOwnedIPOnLaunch), + }, + SubnetId: aws.String(subnetID), + } + + if customerOwnedIPv4Pool != "" { + input.CustomerOwnedIpv4Pool = aws.String(customerOwnedIPv4Pool) + } + + if _, err := conn.ModifySubnetAttribute(input); err != nil { + return fmt.Errorf("error setting EC2 Subnet (%s) CustomerOwnedIpv4Pool/MapCustomerOwnedIpOnLaunch: %w", subnetID, err) + } + + if _, err := WaitSubnetMapCustomerOwnedIPOnLaunchUpdated(conn, subnetID, mapCustomerOwnedIPOnLaunch); err != nil { + return fmt.Errorf("error waiting for EC2 Subnet (%s) MapCustomerOwnedIpOnLaunch update: %w", subnetID, err) + } + + return nil +} + +func modifySubnetPrivateDnsHostnameTypeOnLaunch(conn *ec2.EC2, subnetID string, v string) error { + input := &ec2.ModifySubnetAttributeInput{ + PrivateDnsHostnameTypeOnLaunch: aws.String(v), + SubnetId: aws.String(subnetID), + } + + if _, err := conn.ModifySubnetAttribute(input); err != nil { + return fmt.Errorf("error setting EC2 Subnet (%s) PrivateDnsHostnameTypeOnLaunch: %w", subnetID, err) + } + + if _, err := WaitSubnetPrivateDNSHostnameTypeOnLaunchUpdated(conn, subnetID, v); err != nil { + return fmt.Errorf("error waiting for EC2 Subnet (%s) PrivateDnsHostnameTypeOnLaunch update: %w", subnetID, err) + } + + return nil +} + +func modifySubnetIPv6CIDRBlockAssociation(conn *ec2.EC2, subnetID, associationID, cidrBlock string) error { + // We need to handle that we disassociate the IPv6 CIDR block before we try to associate the new one + // This could be an issue as, we could error out when we try to add the new one + // We may need to roll back the state and reattach the old one if this is the case + if associationID != "" { + input := &ec2.DisassociateSubnetCidrBlockInput{ + AssociationId: aws.String(associationID), + } + + _, err := conn.DisassociateSubnetCidrBlock(input) + + if err != nil { + return fmt.Errorf("error disassociating EC2 Subnet (%s) CIDR block (%s): %w", subnetID, associationID, err) + } + + _, err = WaitSubnetIPv6CIDRBlockAssociationDeleted(conn, associationID) + + if err != nil { + return fmt.Errorf("error waiting for EC2 Subnet (%s) CIDR block (%s) to become disassociated: %w", subnetID, associationID, err) + } + } + + if cidrBlock != "" { + input := &ec2.AssociateSubnetCidrBlockInput{ + Ipv6CidrBlock: aws.String(cidrBlock), + SubnetId: aws.String(subnetID), + } + + output, err := conn.AssociateSubnetCidrBlock(input) + + if err != nil { + //The big question here is, do we want to try to reassociate the old one?? + //If we have a failure here, then we may be in a situation that we have nothing associated + return fmt.Errorf("error associating EC2 Subnet (%s) CIDR block (%s): %w", subnetID, cidrBlock, err) + } + + associationID := aws.StringValue(output.Ipv6CidrBlockAssociation.AssociationId) + + _, err = WaitSubnetIPv6CIDRBlockAssociationCreated(conn, associationID) + + if err != nil { + return fmt.Errorf("error waiting for EC2 Subnet (%s) CIDR block (%s) to become associated: %w", subnetID, associationID, err) + } + } + + return nil +} diff --git a/internal/service/ec2/wait.go b/internal/service/ec2/wait.go index 490b2c0798c..5e8967e08bb 100644 --- a/internal/service/ec2/wait.go +++ b/internal/service/ec2/wait.go @@ -521,6 +521,24 @@ func WaitSubnetIPv6CIDRBlockAssociationDeleted(conn *ec2.EC2, id string) (*ec2.S return nil, err } +func WaitSubnetAssignIpv6AddressOnCreationUpdated(conn *ec2.EC2, subnetID string, expectedValue bool) (*ec2.Subnet, error) { + stateConf := &resource.StateChangeConf{ + Target: []string{strconv.FormatBool(expectedValue)}, + Refresh: StatusSubnetAssignIpv6AddressOnCreation(conn, subnetID), + Timeout: SubnetAttributePropagationTimeout, + Delay: 10 * time.Second, + MinTimeout: 3 * time.Second, + } + + outputRaw, err := stateConf.WaitForState() + + if output, ok := outputRaw.(*ec2.Subnet); ok { + return output, err + } + + return nil, err +} + func WaitSubnetEnableDns64Updated(conn *ec2.EC2, subnetID string, expectedValue bool) (*ec2.Subnet, error) { stateConf := &resource.StateChangeConf{ Target: []string{strconv.FormatBool(expectedValue)}, From e75de89d785e1c7d150bc77466aecf4cf12b0d22 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 13 Jan 2022 08:29:05 -0500 Subject: [PATCH 028/116] r/aws_default_subnet: Set tags on resource Create. Acceptance test output: % make testacc TESTARGS='-run=TestAccEC2DefaultSubnet_basic' PKG_NAME=internal/service/ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run=TestAccEC2DefaultSubnet_basic -timeout 180m === RUN TestAccEC2DefaultSubnet_basic === PAUSE TestAccEC2DefaultSubnet_basic === CONT TestAccEC2DefaultSubnet_basic --- PASS: TestAccEC2DefaultSubnet_basic (14.52s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 18.126s --- internal/service/ec2/default_subnet.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/internal/service/ec2/default_subnet.go b/internal/service/ec2/default_subnet.go index fc0998d8443..b58bb16c6a0 100644 --- a/internal/service/ec2/default_subnet.go +++ b/internal/service/ec2/default_subnet.go @@ -197,6 +197,17 @@ func resourceDefaultSubnetCreate(d *schema.ResourceData, meta interface{}) error return err } + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig + newTags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{}))).IgnoreConfig(ignoreTagsConfig) + oldTags := KeyValueTags(subnet.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) + + if !oldTags.Equal(newTags) { + if err := UpdateTags(conn, d.Id(), oldTags, newTags); err != nil { + return fmt.Errorf("error updating EC2 Default Subnet (%s) tags: %w", d.Id(), err) + } + } + return resourceSubnetRead(d, meta) } From 4e8e622abf318af7b8f6e8bf1912447879cdf81b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 13 Jan 2022 13:22:55 -0500 Subject: [PATCH 029/116] r/aws_default_subnet: Corrections after some testing. Acceptance test output: % make testacc TESTARGS='-run=TestAccEC2DefaultSubnet_basic' PKG_NAME=internal/service/ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run=TestAccEC2DefaultSubnet_basic -timeout 180m === RUN TestAccEC2DefaultSubnet_basic === PAUSE TestAccEC2DefaultSubnet_basic === CONT TestAccEC2DefaultSubnet_basic --- PASS: TestAccEC2DefaultSubnet_basic (14.92s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 18.662s % make testacc TESTARGS='-run=TestAccEC2Subnet_' PKG=ec2 ACCTEST_PARALLELISM=5 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 5 -run=TestAccEC2Subnet_ -timeout 180m === RUN TestAccEC2Subnet_basic === PAUSE TestAccEC2Subnet_basic === RUN TestAccEC2Subnet_tags === PAUSE TestAccEC2Subnet_tags === RUN TestAccEC2Subnet_DefaultTags_providerOnly === PAUSE TestAccEC2Subnet_DefaultTags_providerOnly === RUN TestAccEC2Subnet_DefaultTags_updateToProviderOnly === PAUSE TestAccEC2Subnet_DefaultTags_updateToProviderOnly === RUN TestAccEC2Subnet_DefaultTags_updateToResourceOnly === PAUSE TestAccEC2Subnet_DefaultTags_updateToResourceOnly === RUN TestAccEC2Subnet_DefaultTagsProviderAndResource_nonOverlappingTag === PAUSE TestAccEC2Subnet_DefaultTagsProviderAndResource_nonOverlappingTag === RUN TestAccEC2Subnet_DefaultTagsProviderAndResource_overlappingTag === PAUSE TestAccEC2Subnet_DefaultTagsProviderAndResource_overlappingTag === RUN TestAccEC2Subnet_DefaultTagsProviderAndResource_duplicateTag === PAUSE TestAccEC2Subnet_DefaultTagsProviderAndResource_duplicateTag === RUN TestAccEC2Subnet_defaultAndIgnoreTags === PAUSE TestAccEC2Subnet_defaultAndIgnoreTags === RUN TestAccEC2Subnet_updateTagsKnownAtApply === PAUSE TestAccEC2Subnet_updateTagsKnownAtApply === RUN TestAccEC2Subnet_ignoreTags === PAUSE TestAccEC2Subnet_ignoreTags === RUN TestAccEC2Subnet_ipv6 === PAUSE TestAccEC2Subnet_ipv6 === RUN TestAccEC2Subnet_enableIPv6 === PAUSE TestAccEC2Subnet_enableIPv6 === RUN TestAccEC2Subnet_availabilityZoneID === PAUSE TestAccEC2Subnet_availabilityZoneID === RUN TestAccEC2Subnet_disappears === PAUSE TestAccEC2Subnet_disappears === RUN TestAccEC2Subnet_customerOwnedIPv4Pool === PAUSE TestAccEC2Subnet_customerOwnedIPv4Pool === RUN TestAccEC2Subnet_mapCustomerOwnedIPOnLaunch === PAUSE TestAccEC2Subnet_mapCustomerOwnedIPOnLaunch === RUN TestAccEC2Subnet_mapPublicIPOnLaunch === PAUSE TestAccEC2Subnet_mapPublicIPOnLaunch === RUN TestAccEC2Subnet_outpost === PAUSE TestAccEC2Subnet_outpost === RUN TestAccEC2Subnet_enableDNS64 === PAUSE TestAccEC2Subnet_enableDNS64 === RUN TestAccEC2Subnet_privateDnsNameOptionsOnLaunch === PAUSE TestAccEC2Subnet_privateDnsNameOptionsOnLaunch === RUN TestAccEC2Subnet_ipv6Native === PAUSE TestAccEC2Subnet_ipv6Native === CONT TestAccEC2Subnet_basic === CONT TestAccEC2Subnet_ipv6Native === CONT TestAccEC2Subnet_ipv6 === CONT TestAccEC2Subnet_privateDnsNameOptionsOnLaunch === CONT TestAccEC2Subnet_customerOwnedIPv4Pool acctest.go:1254: skipping since no Outposts found --- SKIP: TestAccEC2Subnet_customerOwnedIPv4Pool (1.37s) === CONT TestAccEC2Subnet_disappears --- PASS: TestAccEC2Subnet_disappears (23.43s) === CONT TestAccEC2Subnet_availabilityZoneID --- PASS: TestAccEC2Subnet_basic (27.28s) === CONT TestAccEC2Subnet_enableIPv6 --- PASS: TestAccEC2Subnet_ipv6Native (28.20s) === CONT TestAccEC2Subnet_outpost acctest.go:1254: skipping since no Outposts found --- SKIP: TestAccEC2Subnet_outpost (0.61s) === CONT TestAccEC2Subnet_enableDNS64 --- PASS: TestAccEC2Subnet_availabilityZoneID (27.75s) === CONT TestAccEC2Subnet_mapCustomerOwnedIPOnLaunch acctest.go:1254: skipping since no Outposts found --- SKIP: TestAccEC2Subnet_mapCustomerOwnedIPOnLaunch (0.56s) === CONT TestAccEC2Subnet_DefaultTagsProviderAndResource_overlappingTag --- PASS: TestAccEC2Subnet_ipv6 (88.78s) === CONT TestAccEC2Subnet_mapPublicIPOnLaunch --- PASS: TestAccEC2Subnet_enableIPv6 (86.63s) === CONT TestAccEC2Subnet_ignoreTags --- PASS: TestAccEC2Subnet_DefaultTagsProviderAndResource_overlappingTag (61.66s) === CONT TestAccEC2Subnet_updateTagsKnownAtApply --- PASS: TestAccEC2Subnet_enableDNS64 (108.53s) === CONT TestAccEC2Subnet_defaultAndIgnoreTags --- PASS: TestAccEC2Subnet_privateDnsNameOptionsOnLaunch (166.30s) === CONT TestAccEC2Subnet_DefaultTagsProviderAndResource_duplicateTag --- PASS: TestAccEC2Subnet_DefaultTagsProviderAndResource_duplicateTag (1.07s) === CONT TestAccEC2Subnet_DefaultTags_updateToProviderOnly --- PASS: TestAccEC2Subnet_ignoreTags (53.90s) === CONT TestAccEC2Subnet_DefaultTagsProviderAndResource_nonOverlappingTag --- PASS: TestAccEC2Subnet_updateTagsKnownAtApply (64.59s) === CONT TestAccEC2Subnet_DefaultTags_updateToResourceOnly --- PASS: TestAccEC2Subnet_mapPublicIPOnLaunch (98.55s) === CONT TestAccEC2Subnet_DefaultTags_providerOnly --- PASS: TestAccEC2Subnet_defaultAndIgnoreTags (57.14s) === CONT TestAccEC2Subnet_tags --- PASS: TestAccEC2Subnet_DefaultTags_updateToProviderOnly (43.11s) --- PASS: TestAccEC2Subnet_DefaultTagsProviderAndResource_nonOverlappingTag (56.84s) --- PASS: TestAccEC2Subnet_DefaultTags_updateToResourceOnly (47.42s) --- PASS: TestAccEC2Subnet_DefaultTags_providerOnly (62.50s) --- PASS: TestAccEC2Subnet_tags (63.53s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 261.856s --- internal/service/ec2/default_subnet.go | 7 ++++--- internal/service/ec2/subnet.go | 26 +++++++++++++++++++------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/internal/service/ec2/default_subnet.go b/internal/service/ec2/default_subnet.go index b58bb16c6a0..680e1726db9 100644 --- a/internal/service/ec2/default_subnet.go +++ b/internal/service/ec2/default_subnet.go @@ -22,6 +22,7 @@ func ResourceDefaultSubnet() *schema.Resource { Read: resourceSubnetRead, Update: resourceSubnetUpdate, Delete: resourceDefaultSubnetDelete, + Importer: &schema.ResourceImporter{ State: schema.ImportStatePassthrough, }, @@ -42,7 +43,7 @@ func ResourceDefaultSubnet() *schema.Resource { // - vpc_id is Computed-only // and additions: // - existing_default_subnet Computed-only, set in resourceDefaultSubnetCreate - // - force_destroy Optional/Computed, default calculated via CustomizeDiff + // - force_destroy Optional Schema: map[string]*schema.Schema{ "arn": { Type: schema.TypeString, @@ -69,7 +70,7 @@ func ResourceDefaultSubnet() *schema.Resource { "customer_owned_ipv4_pool": { Type: schema.TypeString, Optional: true, - RequiredWith: []string{"map_customer_owned_ip_on_launch", "outpost_arn"}, + RequiredWith: []string{"map_customer_owned_ip_on_launch"}, }, "enable_dns64": { Type: schema.TypeBool, @@ -93,7 +94,7 @@ func ResourceDefaultSubnet() *schema.Resource { "force_destroy": { Type: schema.TypeBool, Optional: true, - Computed: true, + Default: false, }, "ipv6_cidr_block": { Type: schema.TypeString, diff --git a/internal/service/ec2/subnet.go b/internal/service/ec2/subnet.go index e3ec55622af..fc93c15a3a4 100644 --- a/internal/service/ec2/subnet.go +++ b/internal/service/ec2/subnet.go @@ -377,17 +377,28 @@ func modifySubnetAttributesOnCreate(conn *ec2.EC2, d *schema.ResourceData, subne } } + // If we're disabling DNS64, do that before modifying the IPv6 CIDR block. + if new, old := d.Get("enable_dns64").(bool), aws.BoolValue(subnet.EnableDns64); old != new && !new { + if err := modifySubnetEnableDns64(conn, d.Id(), false); err != nil { + return err + } + } + + var oldAssociationID string + var oldIPv6CIDRBlock string for _, v := range subnet.Ipv6CidrBlockAssociationSet { if aws.StringValue(v.Ipv6CidrBlockState.State) == ec2.SubnetCidrBlockStateCodeAssociated { //we can only ever have 1 IPv6 block associated at once - if new, old := d.Get("ipv6_cidr_block").(string), aws.StringValue(v.Ipv6CidrBlock); old != new { - if err := modifySubnetIPv6CIDRBlockAssociation(conn, d.Id(), aws.StringValue(v.AssociationId), new); err != nil { - return err - } - } + oldAssociationID = aws.StringValue(v.AssociationId) + oldIPv6CIDRBlock = aws.StringValue(v.Ipv6CidrBlock) break } } + if new := d.Get("ipv6_cidr_block").(string); oldIPv6CIDRBlock != new { + if err := modifySubnetIPv6CIDRBlockAssociation(conn, d.Id(), oldAssociationID, new); err != nil { + return err + } + } // If we're enabling IPv6 assignment for new ENIs, do that after modifying the IPv6 CIDR block. if new, old := d.Get("assign_ipv6_address_on_creation").(bool), aws.BoolValue(subnet.AssignIpv6AddressOnCreation); old != new && new { @@ -403,8 +414,9 @@ func modifySubnetAttributesOnCreate(conn *ec2.EC2, d *schema.ResourceData, subne } } - if new, old := d.Get("enable_dns64").(bool), aws.BoolValue(subnet.EnableDns64); old != new { - if err := modifySubnetEnableDns64(conn, d.Id(), new); err != nil { + // If we're enabling DNS64, do that after modifying the IPv6 CIDR block. + if new, old := d.Get("enable_dns64").(bool), aws.BoolValue(subnet.EnableDns64); old != new && new { + if err := modifySubnetEnableDns64(conn, d.Id(), true); err != nil { return err } } From 620561e1e260fc5d0b5f848f594dea2f126f12b9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 14 Jan 2022 13:46:33 -0500 Subject: [PATCH 030/116] 'setting' -> 'modifying' in error messages. --- internal/service/ec2/subnet.go | 111 ++++++++++++++++----------------- 1 file changed, 55 insertions(+), 56 deletions(-) diff --git a/internal/service/ec2/subnet.go b/internal/service/ec2/subnet.go index fc93c15a3a4..ac9b9cb3a20 100644 --- a/internal/service/ec2/subnet.go +++ b/internal/service/ec2/subnet.go @@ -384,8 +384,7 @@ func modifySubnetAttributesOnCreate(conn *ec2.EC2, d *schema.ResourceData, subne } } - var oldAssociationID string - var oldIPv6CIDRBlock string + var oldAssociationID, oldIPv6CIDRBlock string for _, v := range subnet.Ipv6CidrBlockAssociationSet { if aws.StringValue(v.Ipv6CidrBlockState.State) == ec2.SubnetCidrBlockStateCodeAssociated { //we can only ever have 1 IPv6 block associated at once oldAssociationID = aws.StringValue(v.AssociationId) @@ -479,7 +478,7 @@ func modifySubnetEnableDns64(conn *ec2.EC2, subnetID string, v bool) error { } if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) EnableDns64: %w", subnetID, err) + return fmt.Errorf("error modifying EC2 Subnet (%s) EnableDns64: %w", subnetID, err) } if _, err := WaitSubnetEnableDns64Updated(conn, subnetID, v); err != nil { @@ -498,7 +497,7 @@ func modifySubnetEnableResourceNameDnsAAAARecordOnLaunch(conn *ec2.EC2, subnetID } if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) EnableResourceNameDnsAAAARecordOnLaunch: %w", subnetID, err) + return fmt.Errorf("error modifying EC2 Subnet (%s) EnableResourceNameDnsAAAARecordOnLaunch: %w", subnetID, err) } if _, err := WaitSubnetEnableResourceNameDnsAAAARecordOnLaunchUpdated(conn, subnetID, v); err != nil { @@ -517,7 +516,7 @@ func modifySubnetEnableResourceNameDnsARecordOnLaunch(conn *ec2.EC2, subnetID st } if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) EnableResourceNameDnsARecordOnLaunch: %w", subnetID, err) + return fmt.Errorf("error modifying EC2 Subnet (%s) EnableResourceNameDnsARecordOnLaunch: %w", subnetID, err) } if _, err := WaitSubnetEnableResourceNameDnsARecordOnLaunchUpdated(conn, subnetID, v); err != nil { @@ -527,6 +526,54 @@ func modifySubnetEnableResourceNameDnsARecordOnLaunch(conn *ec2.EC2, subnetID st return nil } +func modifySubnetIPv6CIDRBlockAssociation(conn *ec2.EC2, subnetID, associationID, cidrBlock string) error { + // We need to handle that we disassociate the IPv6 CIDR block before we try to associate the new one + // This could be an issue as, we could error out when we try to add the new one + // We may need to roll back the state and reattach the old one if this is the case + if associationID != "" { + input := &ec2.DisassociateSubnetCidrBlockInput{ + AssociationId: aws.String(associationID), + } + + _, err := conn.DisassociateSubnetCidrBlock(input) + + if err != nil { + return fmt.Errorf("error disassociating EC2 Subnet (%s) CIDR block (%s): %w", subnetID, associationID, err) + } + + _, err = WaitSubnetIPv6CIDRBlockAssociationDeleted(conn, associationID) + + if err != nil { + return fmt.Errorf("error waiting for EC2 Subnet (%s) CIDR block (%s) to become disassociated: %w", subnetID, associationID, err) + } + } + + if cidrBlock != "" { + input := &ec2.AssociateSubnetCidrBlockInput{ + Ipv6CidrBlock: aws.String(cidrBlock), + SubnetId: aws.String(subnetID), + } + + output, err := conn.AssociateSubnetCidrBlock(input) + + if err != nil { + //The big question here is, do we want to try to reassociate the old one?? + //If we have a failure here, then we may be in a situation that we have nothing associated + return fmt.Errorf("error associating EC2 Subnet (%s) CIDR block (%s): %w", subnetID, cidrBlock, err) + } + + associationID := aws.StringValue(output.Ipv6CidrBlockAssociation.AssociationId) + + _, err = WaitSubnetIPv6CIDRBlockAssociationCreated(conn, associationID) + + if err != nil { + return fmt.Errorf("error waiting for EC2 Subnet (%s) CIDR block (%s) to become associated: %w", subnetID, associationID, err) + } + } + + return nil +} + func modifySubnetMapPublicIpOnLaunch(conn *ec2.EC2, subnetID string, v bool) error { input := &ec2.ModifySubnetAttributeInput{ MapPublicIpOnLaunch: &ec2.AttributeBooleanValue{ @@ -536,7 +583,7 @@ func modifySubnetMapPublicIpOnLaunch(conn *ec2.EC2, subnetID string, v bool) err } if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) MapPublicIpOnLaunch: %w", subnetID, err) + return fmt.Errorf("error modifying EC2 Subnet (%s) MapPublicIpOnLaunch: %w", subnetID, err) } if _, err := WaitSubnetMapPublicIPOnLaunchUpdated(conn, subnetID, v); err != nil { @@ -559,7 +606,7 @@ func modifySubnetOutpostRackAttributes(conn *ec2.EC2, subnetID string, customerO } if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) CustomerOwnedIpv4Pool/MapCustomerOwnedIpOnLaunch: %w", subnetID, err) + return fmt.Errorf("error modifying EC2 Subnet (%s) CustomerOwnedIpv4Pool/MapCustomerOwnedIpOnLaunch: %w", subnetID, err) } if _, err := WaitSubnetMapCustomerOwnedIPOnLaunchUpdated(conn, subnetID, mapCustomerOwnedIPOnLaunch); err != nil { @@ -576,7 +623,7 @@ func modifySubnetPrivateDnsHostnameTypeOnLaunch(conn *ec2.EC2, subnetID string, } if _, err := conn.ModifySubnetAttribute(input); err != nil { - return fmt.Errorf("error setting EC2 Subnet (%s) PrivateDnsHostnameTypeOnLaunch: %w", subnetID, err) + return fmt.Errorf("error modifying EC2 Subnet (%s) PrivateDnsHostnameTypeOnLaunch: %w", subnetID, err) } if _, err := WaitSubnetPrivateDNSHostnameTypeOnLaunchUpdated(conn, subnetID, v); err != nil { @@ -585,51 +632,3 @@ func modifySubnetPrivateDnsHostnameTypeOnLaunch(conn *ec2.EC2, subnetID string, return nil } - -func modifySubnetIPv6CIDRBlockAssociation(conn *ec2.EC2, subnetID, associationID, cidrBlock string) error { - // We need to handle that we disassociate the IPv6 CIDR block before we try to associate the new one - // This could be an issue as, we could error out when we try to add the new one - // We may need to roll back the state and reattach the old one if this is the case - if associationID != "" { - input := &ec2.DisassociateSubnetCidrBlockInput{ - AssociationId: aws.String(associationID), - } - - _, err := conn.DisassociateSubnetCidrBlock(input) - - if err != nil { - return fmt.Errorf("error disassociating EC2 Subnet (%s) CIDR block (%s): %w", subnetID, associationID, err) - } - - _, err = WaitSubnetIPv6CIDRBlockAssociationDeleted(conn, associationID) - - if err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) CIDR block (%s) to become disassociated: %w", subnetID, associationID, err) - } - } - - if cidrBlock != "" { - input := &ec2.AssociateSubnetCidrBlockInput{ - Ipv6CidrBlock: aws.String(cidrBlock), - SubnetId: aws.String(subnetID), - } - - output, err := conn.AssociateSubnetCidrBlock(input) - - if err != nil { - //The big question here is, do we want to try to reassociate the old one?? - //If we have a failure here, then we may be in a situation that we have nothing associated - return fmt.Errorf("error associating EC2 Subnet (%s) CIDR block (%s): %w", subnetID, cidrBlock, err) - } - - associationID := aws.StringValue(output.Ipv6CidrBlockAssociation.AssociationId) - - _, err = WaitSubnetIPv6CIDRBlockAssociationCreated(conn, associationID) - - if err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) CIDR block (%s) to become associated: %w", subnetID, associationID, err) - } - } - - return nil -} From bcc154581450a720601703ce2fa64e3bc9b2d7a6 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 19 Jan 2022 11:55:52 -0500 Subject: [PATCH 031/116] r/aws_default_vpc: Don't reuse ResourceVPC's schema. Acceptance test output: % make testacc TESTARGS='-run=TestAccEC2DefaultVPC_basic' PKG_NAME=internal/service/ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run=TestAccEC2DefaultVPC_basic -timeout 180m === RUN TestAccEC2DefaultVPC_basic === PAUSE TestAccEC2DefaultVPC_basic === CONT TestAccEC2DefaultVPC_basic --- PASS: TestAccEC2DefaultVPC_basic (21.81s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 25.294s --- internal/service/ec2/default_subnet.go | 3 + internal/service/ec2/default_vpc.go | 267 ++++++++++++++++++++--- internal/service/ec2/default_vpc_test.go | 53 ++--- internal/service/ec2/subnet.go | 1 + internal/service/ec2/vpc.go | 2 + 5 files changed, 265 insertions(+), 61 deletions(-) diff --git a/internal/service/ec2/default_subnet.go b/internal/service/ec2/default_subnet.go index 680e1726db9..03a84d77c3f 100644 --- a/internal/service/ec2/default_subnet.go +++ b/internal/service/ec2/default_subnet.go @@ -34,6 +34,9 @@ func ResourceDefaultSubnet() *schema.Resource { Delete: schema.DefaultTimeout(20 * time.Minute), }, + SchemaVersion: 1, + MigrateState: SubnetMigrateState, + // Keep in sync with aws_subnet's schema with the following changes: // - availability_zone is Required/ForceNew // - availability_zone_id is Computed-only diff --git a/internal/service/ec2/default_vpc.go b/internal/service/ec2/default_vpc.go index 3fa607285a6..e7cf2500024 100644 --- a/internal/service/ec2/default_vpc.go +++ b/internal/service/ec2/default_vpc.go @@ -7,60 +7,257 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "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" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/internal/verify" ) func ResourceDefaultVPC() *schema.Resource { - // reuse aws_vpc schema, and methods for READ, UPDATE - dvpc := ResourceVPC() - dvpc.Create = resourceDefaultVPCCreate - dvpc.Delete = resourceDefaultVPCDelete - - // cidr_block is a computed value for Default VPCs - dvpc.Schema["cidr_block"] = &schema.Schema{ - Type: schema.TypeString, - Computed: true, - } - // instance_tenancy is a computed value for Default VPCs - dvpc.Schema["instance_tenancy"] = &schema.Schema{ - Type: schema.TypeString, - Computed: true, - } - // assign_generated_ipv6_cidr_block is a computed value for Default VPCs - dvpc.Schema["assign_generated_ipv6_cidr_block"] = &schema.Schema{ - Type: schema.TypeBool, - Computed: true, - } + //lintignore:R011 + return &schema.Resource{ + Create: resourceDefaultVPCCreate, + Read: resourceVPCRead, + Update: resourceVPCUpdate, + Delete: resourceDefaultVPCDelete, + + Importer: &schema.ResourceImporter{ + State: resourceVPCImport, + }, + + CustomizeDiff: verify.SetTagsDiff, + + SchemaVersion: 1, + MigrateState: VPCMigrateState, - return dvpc + // Keep in sync with aws_vpc's schema with the following changes: + // - cidr_block is Computed-only + // - enable_dns_hostnames is not Computed has a Default of true + // - instance_tenancy is Computed-only + // - ipv4_ipam_pool_id is omitted as it's not set in resourceVPCRead + // - ipv4_netmask_length is omitted as it's not set in resourceVPCRead + // and additions: + // - existing_default_vpc Computed-only, set in resourceDefaultVPCCreate + // - force_destroy Optional + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "assign_generated_ipv6_cidr_block": { + Type: schema.TypeBool, + Optional: true, + ConflictsWith: []string{"ipv6_ipam_pool_id"}, + }, + "cidr_block": { + Type: schema.TypeString, + Computed: true, + }, + "default_network_acl_id": { + Type: schema.TypeString, + Computed: true, + }, + "default_route_table_id": { + Type: schema.TypeString, + Computed: true, + }, + "default_security_group_id": { + Type: schema.TypeString, + Computed: true, + }, + "dhcp_options_id": { + Type: schema.TypeString, + Computed: true, + }, + "enable_classiclink": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "enable_classiclink_dns_support": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + "enable_dns_hostnames": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "enable_dns_support": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "existing_default_vpc": { + Type: schema.TypeBool, + Computed: true, + }, + "force_destroy": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "instance_tenancy": { + Type: schema.TypeString, + Computed: true, + }, + "ipv6_association_id": { + Type: schema.TypeString, + Computed: true, + }, + "ipv6_cidr_block": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"ipv6_netmask_length", "assign_generated_ipv6_cidr_block"}, + RequiredWith: []string{"ipv6_ipam_pool_id"}, + ValidateFunc: validation.Any( + validation.StringIsEmpty, + validation.All( + verify.ValidIPv6CIDRNetworkAddress, + validation.IsCIDRNetwork(VPCCIDRMaxIPv6, VPCCIDRMaxIPv6)), + ), + }, + "ipv6_cidr_block_network_border_group": { + Type: schema.TypeString, + Computed: true, + Optional: true, + RequiredWith: []string{"assign_generated_ipv6_cidr_block"}, + }, + "ipv6_ipam_pool_id": { + Type: schema.TypeString, + Optional: true, + ConflictsWith: []string{"assign_generated_ipv6_cidr_block"}, + }, + "ipv6_netmask_length": { + Type: schema.TypeInt, + Optional: true, + ValidateFunc: validation.IntInSlice([]int{VPCCIDRMaxIPv6}), + ConflictsWith: []string{"ipv6_cidr_block"}, + RequiredWith: []string{"ipv6_ipam_pool_id"}, + }, + "main_route_table_id": { + Type: schema.TypeString, + Computed: true, + }, + "owner_id": { + Type: schema.TypeString, + Computed: true, + }, + "tags": tftags.TagsSchema(), + "tags_all": tftags.TagsSchemaComputed(), + }, + } } func resourceDefaultVPCCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - req := &ec2.DescribeVpcsInput{ - Filters: []*ec2.Filter{ - { - Name: aws.String("isDefault"), - Values: aws.StringSlice([]string{"true"}), + + input := &ec2.DescribeVpcsInput{ + Filters: BuildAttributeFilterList( + map[string]string{ + "isDefault": "true", }, - }, + ), } - resp, err := conn.DescribeVpcs(req) - if err != nil { - return err + vpcInfo := &vpcInfo{} + vpc, err := FindVPC(conn, input) + + if err == nil { + log.Printf("[INFO] Found existing EC2 Default VPC") + d.SetId(aws.StringValue(vpc.VpcId)) + d.Set("existing_default_vpc", true) + + vpcInfo.vpc = vpc + + if v, err := FindVPCClassicLinkEnabled(conn, d.Id()); err != nil { + if tfresource.NotFound(err) { + vpcInfo.enableClassicLink = false + } else { + return fmt.Errorf("error reading EC2 VPC (%s) ClassicLinkEnabled: %w", d.Id(), err) + } + } else { + vpcInfo.enableClassicLink = v + } + + if v, err := FindVPCClassicLinkDnsSupported(conn, d.Id()); err != nil { + if tfresource.NotFound(err) { + vpcInfo.enableClassicLinkDNSSupport = false + } else { + return fmt.Errorf("error reading EC2 VPC (%s) ClassicLinkDnsSupported: %w", d.Id(), err) + } + } else { + vpcInfo.enableClassicLinkDNSSupport = v + } + + if v, err := FindVPCAttribute(conn, d.Id(), ec2.VpcAttributeNameEnableDnsHostnames); err != nil { + return fmt.Errorf("error reading EC2 VPC (%s) Attribute (%s): %w", d.Id(), ec2.VpcAttributeNameEnableDnsHostnames, err) + } else { + vpcInfo.enableDnsHostnames = v + } + + if v, err := FindVPCAttribute(conn, d.Id(), ec2.VpcAttributeNameEnableDnsSupport); err != nil { + return fmt.Errorf("error reading EC2 VPC (%s) Attribute (%s): %w", d.Id(), ec2.VpcAttributeNameEnableDnsSupport, err) + } else { + vpcInfo.enableDnsSupport = v + } + } else if tfresource.NotFound(err) { + input := &ec2.CreateDefaultVpcInput{} + + log.Printf("[DEBUG] Creating EC2 Default VPC: %s", input) + output, err := conn.CreateDefaultVpc(input) + + if err != nil { + return fmt.Errorf("error creating EC2 Default VPC: %w", err) + } + + vpc = output.Vpc + + d.SetId(aws.StringValue(vpc.VpcId)) + d.Set("existing_default_vpc", false) + + vpc, err = WaitVPCCreated(conn, d.Id()) + + if err != nil { + return fmt.Errorf("error waiting for EC2 Default VPC (%s) create: %w", d.Id(), err) + } + + vpcInfo.vpc = vpc + vpcInfo.enableClassicLink = false + vpcInfo.enableClassicLinkDNSSupport = false + vpcInfo.enableDnsHostnames = true + vpcInfo.enableDnsSupport = true + } else { + return fmt.Errorf("error reading EC2 Default VPC (%s): %w", d.Id(), err) } - if resp.Vpcs == nil || len(resp.Vpcs) == 0 { - return fmt.Errorf("No default VPC found in this region.") + if err := modifyVPCAttributesOnCreate(conn, d, vpcInfo); err != nil { + return err } - d.SetId(aws.StringValue(resp.Vpcs[0].VpcId)) + defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig + ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig + newTags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{}))).IgnoreConfig(ignoreTagsConfig) + oldTags := KeyValueTags(vpc.Tags).IgnoreAWS().IgnoreConfig(ignoreTagsConfig) + + if !oldTags.Equal(newTags) { + if err := UpdateTags(conn, d.Id(), oldTags, newTags); err != nil { + return fmt.Errorf("error updating EC2 Default VPC (%s) tags: %w", d.Id(), err) + } + } - return resourceVPCUpdate(d, meta) + return resourceVPCRead(d, meta) } func resourceDefaultVPCDelete(d *schema.ResourceData, meta interface{}) error { - log.Printf("[WARN] Cannot destroy Default VPC. Terraform will remove this resource from the state file, however resources may remain.") + if d.Get("force_destroy").(bool) { + return resourceVPCDelete(d, meta) + } + + log.Printf("[WARN] EC2 Default VPC (%s) not deleted, removing from state", d.Id()) + return nil } diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index fa43dfb6cf9..6bdfba9e720 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -10,7 +10,8 @@ import ( ) func TestAccEC2DefaultVPC_basic(t *testing.T) { - var vpc ec2.Vpc + var v ec2.Vpc + resourceName := "aws_default_vpc.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -19,25 +20,29 @@ func TestAccEC2DefaultVPC_basic(t *testing.T) { CheckDestroy: testAccCheckDefaultVPCDestroy, Steps: []resource.TestStep{ { - Config: testAccDefaultVPCBasicConfig, - Check: resource.ComposeTestCheckFunc( - acctest.CheckVPCExists("aws_default_vpc.foo", &vpc), - resource.TestCheckResourceAttr("aws_default_vpc.foo", "cidr_block", "172.31.0.0/16"), - resource.TestCheckResourceAttr( - "aws_default_vpc.foo", "cidr_block", "172.31.0.0/16"), - resource.TestCheckResourceAttr( - "aws_default_vpc.foo", "tags.%", "1"), - resource.TestCheckResourceAttr( - "aws_default_vpc.foo", "tags.Name", "Default VPC"), - resource.TestCheckResourceAttrSet( - "aws_default_vpc.foo", "arn"), - resource.TestCheckResourceAttr( - "aws_default_vpc.foo", "assign_generated_ipv6_cidr_block", "false"), - resource.TestCheckResourceAttr( - "aws_default_vpc.foo", "ipv6_association_id", ""), - resource.TestCheckResourceAttr( - "aws_default_vpc.foo", "ipv6_cidr_block", ""), - acctest.CheckResourceAttrAccountID("aws_default_vpc.foo", "owner_id"), + Config: testAccDefaultVPCConfig, + Check: resource.ComposeAggregateTestCheckFunc( + acctest.CheckVPCExists(resourceName, &v), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "assign_generated_ipv6_cidr_block", "false"), + resource.TestCheckResourceAttr(resourceName, "cidr_block", "172.31.0.0/16"), + resource.TestCheckResourceAttrSet(resourceName, "default_network_acl_id"), + resource.TestCheckResourceAttrSet(resourceName, "default_route_table_id"), + resource.TestCheckResourceAttrSet(resourceName, "default_security_group_id"), + resource.TestCheckResourceAttrSet(resourceName, "dhcp_options_id"), + resource.TestCheckResourceAttr(resourceName, "enable_classiclink", "false"), + resource.TestCheckResourceAttr(resourceName, "enable_classiclink_dns_support", "false"), + resource.TestCheckResourceAttr(resourceName, "enable_dns_hostnames", "true"), + resource.TestCheckResourceAttr(resourceName, "enable_dns_support", "true"), + resource.TestCheckResourceAttr(resourceName, "instance_tenancy", "default"), + resource.TestCheckResourceAttr(resourceName, "ipv6_association_id", ""), + resource.TestCheckResourceAttr(resourceName, "ipv6_cidr_block", ""), + resource.TestCheckResourceAttr(resourceName, "ipv6_cidr_block_network_border_group", ""), + resource.TestCheckResourceAttr(resourceName, "ipv6_ipam_pool_id", ""), + resource.TestCheckResourceAttr(resourceName, "ipv6_netmask_length", "0"), + resource.TestCheckResourceAttrSet(resourceName, "main_route_table_id"), + acctest.CheckResourceAttrAccountID(resourceName, "owner_id"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, }, @@ -49,10 +54,6 @@ func testAccCheckDefaultVPCDestroy(s *terraform.State) error { return nil } -const testAccDefaultVPCBasicConfig = ` -resource "aws_default_vpc" "foo" { - tags = { - Name = "Default VPC" - } -} +const testAccDefaultVPCConfig = ` +resource "aws_default_vpc" "test" {} ` diff --git a/internal/service/ec2/subnet.go b/internal/service/ec2/subnet.go index ac9b9cb3a20..c19d2ca08bd 100644 --- a/internal/service/ec2/subnet.go +++ b/internal/service/ec2/subnet.go @@ -38,6 +38,7 @@ func ResourceSubnet() *schema.Resource { MigrateState: SubnetMigrateState, // Keep in sync with aws_default_subnet's schema. + // See notes in default_subnet.go. Schema: map[string]*schema.Schema{ "arn": { Type: schema.TypeString, diff --git a/internal/service/ec2/vpc.go b/internal/service/ec2/vpc.go index 7a2a5255101..2402da92bbd 100644 --- a/internal/service/ec2/vpc.go +++ b/internal/service/ec2/vpc.go @@ -45,6 +45,8 @@ func ResourceVPC() *schema.Resource { SchemaVersion: 1, MigrateState: VPCMigrateState, + // Keep in sync with aws_default_vpc's schema. + // See notes in default_vpc.go. Schema: map[string]*schema.Schema{ "arn": { Type: schema.TypeString, From f67f5cfac5bdefa4f8676e5d836bedae893642bc Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 19 Jan 2022 12:13:11 -0500 Subject: [PATCH 032/116] Tidy up subnet and VPC sweepers. --- internal/service/ec2/sweep.go | 76 ++++++++++++++--------------------- 1 file changed, 30 insertions(+), 46 deletions(-) diff --git a/internal/service/ec2/sweep.go b/internal/service/ec2/sweep.go index adf591dab62..ead759e8877 100644 --- a/internal/service/ec2/sweep.go +++ b/internal/service/ec2/sweep.go @@ -1497,37 +1497,27 @@ func sweepSpotFleetRequests(region string) error { func sweepSubnets(region string) error { client, err := sweep.SharedRegionalSweepClient(region) - if err != nil { return fmt.Errorf("error getting client: %w", err) } - conn := client.(*conns.AWSClient).EC2Conn - sweepResources := make([]*sweep.SweepResource, 0) - var errs *multierror.Error - input := &ec2.DescribeSubnetsInput{} + sweepResources := make([]*sweep.SweepResource, 0) err = conn.DescribeSubnetsPages(input, func(page *ec2.DescribeSubnetsOutput, lastPage bool) bool { if page == nil { return !lastPage } - for _, subnet := range page.Subnets { - if subnet == nil { - continue - } - - id := aws.StringValue(subnet.SubnetId) - - if aws.BoolValue(subnet.DefaultForAz) { - log.Printf("[DEBUG] Skipping default EC2 Subnet: %s", id) + for _, v := range page.Subnets { + // Skip default subnets. + if aws.BoolValue(v.DefaultForAz) { continue } r := ResourceSubnet() d := r.Data(nil) - d.SetId(id) + d.SetId(aws.StringValue(v.SubnetId)) sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) } @@ -1535,20 +1525,22 @@ func sweepSubnets(region string) error { return !lastPage }) - if err != nil { - errs = multierror.Append(errs, fmt.Errorf("error describing EC2 Subnets for %s: %w", region, err)) + if sweep.SkipSweepError(err) { + log.Printf("[WARN] Skipping EC2 Subnet sweep for %s: %s", region, err) + return nil } - if err = sweep.SweepOrchestrator(sweepResources); err != nil { - errs = multierror.Append(errs, fmt.Errorf("error sweeping EC2 Subnets for %s: %w", region, err)) + if err != nil { + return fmt.Errorf("error listing EC2 Subnets (%s): %w", region, err) } - if sweep.SkipSweepError(errs.ErrorOrNil()) { - log.Printf("[WARN] Skipping EC2 Subnet sweep for %s: %s", region, errs) - return nil + err = sweep.SweepOrchestrator(sweepResources) + + if err != nil { + return fmt.Errorf("error sweeping EC2 Subnets (%s): %w", region, err) } - return errs.ErrorOrNil() + return nil } func sweepTransitGatewayPeeringAttachments(region string) error { @@ -2007,37 +1999,27 @@ func sweepVPCPeeringConnections(region string) error { func sweepVPCs(region string) error { client, err := sweep.SharedRegionalSweepClient(region) - if err != nil { return fmt.Errorf("error getting client: %s", err) } - conn := client.(*conns.AWSClient).EC2Conn - sweepResources := make([]*sweep.SweepResource, 0) - var errs *multierror.Error - input := &ec2.DescribeVpcsInput{} + sweepResources := make([]*sweep.SweepResource, 0) err = conn.DescribeVpcsPages(input, func(page *ec2.DescribeVpcsOutput, lastPage bool) bool { if page == nil { return !lastPage } - for _, vpc := range page.Vpcs { - if vpc == nil { - continue - } - - id := aws.StringValue(vpc.VpcId) - - if aws.BoolValue(vpc.IsDefault) { - log.Printf("[DEBUG] Skipping default EC2 VPC: %s", id) + for _, v := range page.Vpcs { + // Skip default VPCs. + if aws.BoolValue(v.IsDefault) { continue } r := ResourceVPC() d := r.Data(nil) - d.SetId(id) + d.SetId(aws.StringValue(v.VpcId)) sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) } @@ -2045,20 +2027,22 @@ func sweepVPCs(region string) error { return !lastPage }) - if err != nil { - errs = multierror.Append(errs, fmt.Errorf("error describing EC2 VPCs for %s: %w", region, err)) + if sweep.SkipSweepError(err) { + log.Printf("[WARN] Skipping EC2 VPC sweep for %s: %s", region, err) + return nil } - if err = sweep.SweepOrchestrator(sweepResources); err != nil { - errs = multierror.Append(errs, fmt.Errorf("error sweeping EC2 VPCs for %s: %w", region, err)) + if err != nil { + return fmt.Errorf("error listing EC2 VPCs (%s): %w", region, err) } - if sweep.SkipSweepError(errs.ErrorOrNil()) { - log.Printf("[WARN] Skipping EC2 VPCs sweep for %s: %s", region, errs) - return nil + err = sweep.SweepOrchestrator(sweepResources) + + if err != nil { + return fmt.Errorf("error sweeping EC2 VPCs (%s): %w", region, err) } - return errs.ErrorOrNil() + return nil } func sweepVPNConnections(region string) error { From 3ba4b91205d5836bb02858e4e663de83a038a67c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 19 Jan 2022 13:24:01 -0500 Subject: [PATCH 033/116] r/aws_default_vpc: IPv6 changes. Acceptance test output: % make testacc TESTARGS='-run=TestAccEC2DefaultVPC_basic' PKG_NAME=internal/service/ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run=TestAccEC2DefaultVPC_basic -timeout 180m === RUN TestAccEC2DefaultVPC_basic === PAUSE TestAccEC2DefaultVPC_basic === CONT TestAccEC2DefaultVPC_basic --- PASS: TestAccEC2DefaultVPC_basic (21.50s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 24.967s --- internal/service/ec2/vpc.go | 89 +++++++++++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 18 deletions(-) diff --git a/internal/service/ec2/vpc.go b/internal/service/ec2/vpc.go index 2402da92bbd..376706dba70 100644 --- a/internal/service/ec2/vpc.go +++ b/internal/service/ec2/vpc.go @@ -343,25 +343,8 @@ func resourceVPCRead(d *schema.ResourceData, meta interface{}) error { d.Set("ipv6_ipam_pool_id", nil) d.Set("ipv6_netmask_length", nil) - // Try and find IPv6 CIDR block information, first by any stored association ID. - // Then if no IPv6 CIDR block information is available, use the first associated IPv6 CIDR block. - var ipv6CIDRBlockAssociation *ec2.VpcIpv6CidrBlockAssociation - if associationID := d.Get("ipv6_association_id").(string); associationID != "" { - for _, v := range vpc.Ipv6CidrBlockAssociationSet { - if state := aws.StringValue(v.Ipv6CidrBlockState.State); state == ec2.VpcCidrBlockStateCodeAssociated && aws.StringValue(v.AssociationId) == associationID { - ipv6CIDRBlockAssociation = v + ipv6CIDRBlockAssociation := defaultIPv6CIDRBlockAssociation(vpc, d.Get("ipv6_association_id").(string)) - break - } - } - } - if ipv6CIDRBlockAssociation == nil { - for _, v := range vpc.Ipv6CidrBlockAssociationSet { - if aws.StringValue(v.Ipv6CidrBlockState.State) == ec2.VpcCidrBlockStateCodeAssociated { - ipv6CIDRBlockAssociation = v - } - } - } if ipv6CIDRBlockAssociation == nil { d.Set("ipv6_association_id", nil) } else { @@ -527,6 +510,33 @@ func resourceVPCCustomizeDiff(_ context.Context, diff *schema.ResourceDiff, v in return nil } +// defaultIPv6CIDRBlockAssociation returns the "default" IPv6 CIDR block. +// Try and find IPv6 CIDR block information, first by any stored association ID. +// Then if no IPv6 CIDR block information is available, use the first associated IPv6 CIDR block. +func defaultIPv6CIDRBlockAssociation(vpc *ec2.Vpc, associationID string) *ec2.VpcIpv6CidrBlockAssociation { + var ipv6CIDRBlockAssociation *ec2.VpcIpv6CidrBlockAssociation + + if associationID != "" { + for _, v := range vpc.Ipv6CidrBlockAssociationSet { + if state := aws.StringValue(v.Ipv6CidrBlockState.State); state == ec2.VpcCidrBlockStateCodeAssociated && aws.StringValue(v.AssociationId) == associationID { + ipv6CIDRBlockAssociation = v + + break + } + } + } + + if ipv6CIDRBlockAssociation == nil { + for _, v := range vpc.Ipv6CidrBlockAssociationSet { + if aws.StringValue(v.Ipv6CidrBlockState.State) == ec2.VpcCidrBlockStateCodeAssociated { + ipv6CIDRBlockAssociation = v + } + } + } + + return ipv6CIDRBlockAssociation +} + type vpcInfo struct { vpc *ec2.Vpc enableClassicLink bool @@ -562,6 +572,49 @@ func modifyVPCAttributesOnCreate(conn *ec2.EC2, d *schema.ResourceData, vpcInfo } } + var associationID, oldIPv6PoolID, oldIPv6CIDRBlock, oldIPv6CIDRBlockNetworkBorderGroup string + var oldAssignGeneratedIPv6CIDRBlock bool + + if v := defaultIPv6CIDRBlockAssociation(vpcInfo.vpc, ""); v != nil { + associationID = aws.StringValue(v.AssociationId) + oldIPv6CIDRBlock = aws.StringValue(v.Ipv6CidrBlock) + oldIPv6CIDRBlockNetworkBorderGroup = aws.StringValue(v.NetworkBorderGroup) + ipv6PoolID := aws.StringValue(v.Ipv6Pool) + if ipv6PoolID == AmazonIPv6PoolID { + oldAssignGeneratedIPv6CIDRBlock = true + } else { + oldIPv6PoolID = ipv6PoolID + } + } + + if newIPv6CIDRBlock, newIPv6PoolID := d.Get("ipv6_cidr_block").(string), d.Get("ipv6_ipam_pool_id").(string); oldIPv6CIDRBlock != newIPv6CIDRBlock || oldIPv6PoolID != newIPv6PoolID { + _, err := modifyVPCIPv6CIDRBlockAssociation(conn, d.Id(), + associationID, + false, + newIPv6CIDRBlock, + newIPv6PoolID, + d.Get("ipv6_netmask_length").(int), + "") + + if err != nil { + return err + } + } + + if newAssignGeneratedIPv6CIDRBlock, newIPv6CIDRBlockNetworkBorderGroup := d.Get("assign_generated_ipv6_cidr_block").(bool), d.Get("ipv6_cidr_block_network_border_group").(string); oldAssignGeneratedIPv6CIDRBlock != newAssignGeneratedIPv6CIDRBlock || oldIPv6CIDRBlockNetworkBorderGroup != newIPv6CIDRBlockNetworkBorderGroup { + _, err := modifyVPCIPv6CIDRBlockAssociation(conn, d.Id(), + associationID, + false, + "", + "", + 0, + newIPv6CIDRBlockNetworkBorderGroup) + + if err != nil { + return err + } + } + return nil } From 452eeda58bc2a7954926d7823ca424d9c01d3ea0 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 19 Jan 2022 14:04:38 -0500 Subject: [PATCH 034/116] r/aws_default_vpc: Test IPv6 changes. Acceptance test output: % make testacc TESTARGS='-run=TestAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock' PKG_NAME=internal/service/ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run=TestAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock -timeout 180m === RUN TestAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock === PAUSE TestAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock === CONT TestAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock --- PASS: TestAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock (32.31s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 39.501s --- internal/service/ec2/default_subnet.go | 1 + internal/service/ec2/default_vpc.go | 45 +++++++++++++++++++ internal/service/ec2/default_vpc_test.go | 57 ++++++++++++++++++++++++ internal/service/ec2/vpc.go | 43 ------------------ 4 files changed, 103 insertions(+), 43 deletions(-) diff --git a/internal/service/ec2/default_subnet.go b/internal/service/ec2/default_subnet.go index 03a84d77c3f..ecba2ee81ef 100644 --- a/internal/service/ec2/default_subnet.go +++ b/internal/service/ec2/default_subnet.go @@ -201,6 +201,7 @@ func resourceDefaultSubnetCreate(d *schema.ResourceData, meta interface{}) error return err } + // Configure tags. defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig newTags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{}))).IgnoreConfig(ignoreTagsConfig) diff --git a/internal/service/ec2/default_vpc.go b/internal/service/ec2/default_vpc.go index e7cf2500024..9e339734e46 100644 --- a/internal/service/ec2/default_vpc.go +++ b/internal/service/ec2/default_vpc.go @@ -238,6 +238,51 @@ func resourceDefaultVPCCreate(d *schema.ResourceData, meta interface{}) error { return err } + // Configure IPv6. + var associationID, oldIPv6PoolID, oldIPv6CIDRBlock, oldIPv6CIDRBlockNetworkBorderGroup string + var oldAssignGeneratedIPv6CIDRBlock bool + + if v := defaultIPv6CIDRBlockAssociation(vpcInfo.vpc, ""); v != nil { + associationID = aws.StringValue(v.AssociationId) + oldIPv6CIDRBlock = aws.StringValue(v.Ipv6CidrBlock) + oldIPv6CIDRBlockNetworkBorderGroup = aws.StringValue(v.NetworkBorderGroup) + ipv6PoolID := aws.StringValue(v.Ipv6Pool) + if ipv6PoolID == AmazonIPv6PoolID { + oldAssignGeneratedIPv6CIDRBlock = true + } else { + oldIPv6PoolID = ipv6PoolID + } + } + + if newAssignGeneratedIPv6CIDRBlock, newIPv6CIDRBlockNetworkBorderGroup := d.Get("assign_generated_ipv6_cidr_block").(bool), d.Get("ipv6_cidr_block_network_border_group").(string); oldAssignGeneratedIPv6CIDRBlock != newAssignGeneratedIPv6CIDRBlock || oldIPv6CIDRBlockNetworkBorderGroup != newIPv6CIDRBlockNetworkBorderGroup { + _, err := modifyVPCIPv6CIDRBlockAssociation(conn, d.Id(), + associationID, + newAssignGeneratedIPv6CIDRBlock, + "", + "", + 0, + newIPv6CIDRBlockNetworkBorderGroup) + + if err != nil { + return err + } + } + + if newIPv6CIDRBlock, newIPv6PoolID := d.Get("ipv6_cidr_block").(string), d.Get("ipv6_ipam_pool_id").(string); oldIPv6CIDRBlock != newIPv6CIDRBlock || oldIPv6PoolID != newIPv6PoolID { + _, err := modifyVPCIPv6CIDRBlockAssociation(conn, d.Id(), + associationID, + false, + newIPv6CIDRBlock, + newIPv6PoolID, + d.Get("ipv6_netmask_length").(int), + "") + + if err != nil { + return err + } + } + + // Configure tags. defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig newTags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{}))).IgnoreConfig(ignoreTagsConfig) diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index 6bdfba9e720..13ce79f37eb 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -1,9 +1,12 @@ package ec2_test import ( + "fmt" + "regexp" "testing" "github.com/aws/aws-sdk-go/service/ec2" + 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" @@ -49,6 +52,48 @@ func TestAccEC2DefaultVPC_basic(t *testing.T) { }) } +func TestAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock(t *testing.T) { + var v ec2.Vpc + resourceName := "aws_default_vpc.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckDefaultVPCDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDefaultVPCAssignGeneratedIPv6CIDRBlockConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + acctest.CheckVPCExists(resourceName, &v), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "assign_generated_ipv6_cidr_block", "true"), + resource.TestCheckResourceAttr(resourceName, "cidr_block", "172.31.0.0/16"), + resource.TestCheckResourceAttrSet(resourceName, "default_network_acl_id"), + resource.TestCheckResourceAttrSet(resourceName, "default_route_table_id"), + resource.TestCheckResourceAttrSet(resourceName, "default_security_group_id"), + resource.TestCheckResourceAttrSet(resourceName, "dhcp_options_id"), + resource.TestCheckResourceAttr(resourceName, "enable_classiclink", "false"), + resource.TestCheckResourceAttr(resourceName, "enable_classiclink_dns_support", "false"), + resource.TestCheckResourceAttr(resourceName, "enable_dns_hostnames", "true"), + resource.TestCheckResourceAttr(resourceName, "enable_dns_support", "true"), + resource.TestCheckResourceAttr(resourceName, "instance_tenancy", "default"), + resource.TestCheckResourceAttrSet(resourceName, "ipv6_association_id"), + resource.TestMatchResourceAttr(resourceName, "ipv6_cidr_block", regexp.MustCompile(`/56$`)), + resource.TestCheckResourceAttr(resourceName, "ipv6_cidr_block_network_border_group", acctest.Region()), + resource.TestCheckResourceAttr(resourceName, "ipv6_ipam_pool_id", ""), + resource.TestCheckResourceAttr(resourceName, "ipv6_netmask_length", "0"), + resource.TestCheckResourceAttrSet(resourceName, "main_route_table_id"), + acctest.CheckResourceAttrAccountID(resourceName, "owner_id"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), + ), + }, + }, + }) +} + func testAccCheckDefaultVPCDestroy(s *terraform.State) error { // We expect VPC to still exist return nil @@ -57,3 +102,15 @@ func testAccCheckDefaultVPCDestroy(s *terraform.State) error { const testAccDefaultVPCConfig = ` resource "aws_default_vpc" "test" {} ` + +func testAccDefaultVPCAssignGeneratedIPv6CIDRBlockConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_default_vpc" "test" { + assign_generated_ipv6_cidr_block = true + + tags = { + Name = %[1]q + } +} +`, rName) +} diff --git a/internal/service/ec2/vpc.go b/internal/service/ec2/vpc.go index 376706dba70..16b7c0321ad 100644 --- a/internal/service/ec2/vpc.go +++ b/internal/service/ec2/vpc.go @@ -572,49 +572,6 @@ func modifyVPCAttributesOnCreate(conn *ec2.EC2, d *schema.ResourceData, vpcInfo } } - var associationID, oldIPv6PoolID, oldIPv6CIDRBlock, oldIPv6CIDRBlockNetworkBorderGroup string - var oldAssignGeneratedIPv6CIDRBlock bool - - if v := defaultIPv6CIDRBlockAssociation(vpcInfo.vpc, ""); v != nil { - associationID = aws.StringValue(v.AssociationId) - oldIPv6CIDRBlock = aws.StringValue(v.Ipv6CidrBlock) - oldIPv6CIDRBlockNetworkBorderGroup = aws.StringValue(v.NetworkBorderGroup) - ipv6PoolID := aws.StringValue(v.Ipv6Pool) - if ipv6PoolID == AmazonIPv6PoolID { - oldAssignGeneratedIPv6CIDRBlock = true - } else { - oldIPv6PoolID = ipv6PoolID - } - } - - if newIPv6CIDRBlock, newIPv6PoolID := d.Get("ipv6_cidr_block").(string), d.Get("ipv6_ipam_pool_id").(string); oldIPv6CIDRBlock != newIPv6CIDRBlock || oldIPv6PoolID != newIPv6PoolID { - _, err := modifyVPCIPv6CIDRBlockAssociation(conn, d.Id(), - associationID, - false, - newIPv6CIDRBlock, - newIPv6PoolID, - d.Get("ipv6_netmask_length").(int), - "") - - if err != nil { - return err - } - } - - if newAssignGeneratedIPv6CIDRBlock, newIPv6CIDRBlockNetworkBorderGroup := d.Get("assign_generated_ipv6_cidr_block").(bool), d.Get("ipv6_cidr_block_network_border_group").(string); oldAssignGeneratedIPv6CIDRBlock != newAssignGeneratedIPv6CIDRBlock || oldIPv6CIDRBlockNetworkBorderGroup != newIPv6CIDRBlockNetworkBorderGroup { - _, err := modifyVPCIPv6CIDRBlockAssociation(conn, d.Id(), - associationID, - false, - "", - "", - 0, - newIPv6CIDRBlockNetworkBorderGroup) - - if err != nil { - return err - } - } - return nil } From e59720d590689ddab3efcc4463dcbbe46036f1da Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 19 Jan 2022 14:12:25 -0500 Subject: [PATCH 035/116] r/aws_default_vpc and r/aws_default_subnet: Serialize tests. Acceptance test output: % make testacc TESTS=TestAccEC2DefaultVPCAndSubnet_serial PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2DefaultVPCAndSubnet_serial' -timeout 180m === RUN TestAccEC2DefaultVPCAndSubnet_serial === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/basic === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/basic === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/assignGeneratedIPv6CIDRBlock --- PASS: TestAccEC2DefaultVPCAndSubnet_serial (63.64s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet (14.60s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/basic (14.60s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC (49.04s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/basic (18.14s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/assignGeneratedIPv6CIDRBlock (30.90s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 67.232s --- internal/service/ec2/default_subnet_test.go | 4 +-- internal/service/ec2/default_vpc_test.go | 32 ++++++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/internal/service/ec2/default_subnet_test.go b/internal/service/ec2/default_subnet_test.go index fa2c694c172..0168f0c4c28 100644 --- a/internal/service/ec2/default_subnet_test.go +++ b/internal/service/ec2/default_subnet_test.go @@ -9,12 +9,12 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/acctest" ) -func TestAccEC2DefaultSubnet_basic(t *testing.T) { +func testAccEC2DefaultSubnet_basic(t *testing.T) { var v ec2.Subnet resourceName := "aws_default_subnet.test" availabilityZonesDataSourceName := "data.aws_availability_zones.available" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index 13ce79f37eb..3a03a46ff41 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -12,11 +12,35 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/acctest" ) -func TestAccEC2DefaultVPC_basic(t *testing.T) { +func TestAccEC2DefaultVPCAndSubnet_serial(t *testing.T) { + testCases := map[string]map[string]func(t *testing.T){ + "VPC": { + "basic": testAccEC2DefaultVPC_basic, + "assignGeneratedIPv6CIDRBlock": testAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock, + }, + "Subnet": { + "basic": testAccEC2DefaultSubnet_basic, + }, + } + + for group, m := range testCases { + m := m + t.Run(group, func(t *testing.T) { + for name, tc := range m { + tc := tc + t.Run(name, func(t *testing.T) { + tc(t) + }) + } + }) + } +} + +func testAccEC2DefaultVPC_basic(t *testing.T) { var v ec2.Vpc resourceName := "aws_default_vpc.test" - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, @@ -52,12 +76,12 @@ func TestAccEC2DefaultVPC_basic(t *testing.T) { }) } -func TestAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock(t *testing.T) { +func testAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock(t *testing.T) { var v ec2.Vpc resourceName := "aws_default_vpc.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resource.ParallelTest(t, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, From fea52f32cd0a737eb3b0f13514564ec5b124ec51 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 19 Jan 2022 14:19:24 -0500 Subject: [PATCH 036/116] Store any new IPv6 CIDR block association ID to state. --- internal/service/ec2/default_vpc.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/internal/service/ec2/default_vpc.go b/internal/service/ec2/default_vpc.go index 9e339734e46..cff41efe570 100644 --- a/internal/service/ec2/default_vpc.go +++ b/internal/service/ec2/default_vpc.go @@ -255,7 +255,7 @@ func resourceDefaultVPCCreate(d *schema.ResourceData, meta interface{}) error { } if newAssignGeneratedIPv6CIDRBlock, newIPv6CIDRBlockNetworkBorderGroup := d.Get("assign_generated_ipv6_cidr_block").(bool), d.Get("ipv6_cidr_block_network_border_group").(string); oldAssignGeneratedIPv6CIDRBlock != newAssignGeneratedIPv6CIDRBlock || oldIPv6CIDRBlockNetworkBorderGroup != newIPv6CIDRBlockNetworkBorderGroup { - _, err := modifyVPCIPv6CIDRBlockAssociation(conn, d.Id(), + associationID, err := modifyVPCIPv6CIDRBlockAssociation(conn, d.Id(), associationID, newAssignGeneratedIPv6CIDRBlock, "", @@ -266,10 +266,12 @@ func resourceDefaultVPCCreate(d *schema.ResourceData, meta interface{}) error { if err != nil { return err } + + d.Set("ipv6_association_id", associationID) } if newIPv6CIDRBlock, newIPv6PoolID := d.Get("ipv6_cidr_block").(string), d.Get("ipv6_ipam_pool_id").(string); oldIPv6CIDRBlock != newIPv6CIDRBlock || oldIPv6PoolID != newIPv6PoolID { - _, err := modifyVPCIPv6CIDRBlockAssociation(conn, d.Id(), + associationID, err := modifyVPCIPv6CIDRBlockAssociation(conn, d.Id(), associationID, false, newIPv6CIDRBlock, @@ -280,6 +282,8 @@ func resourceDefaultVPCCreate(d *schema.ResourceData, meta interface{}) error { if err != nil { return err } + + d.Set("ipv6_association_id", associationID) } // Configure tags. From cb90c4e360994b7ea66d63680d245c460f54f3ca Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Jan 2022 09:11:32 -0500 Subject: [PATCH 037/116] Add 'testAccPreCheckDefaultVPCAvailable'. --- internal/service/ec2/default_vpc_test.go | 14 ++++- internal/service/ec2/instance_test.go | 80 +++++++----------------- 2 files changed, 33 insertions(+), 61 deletions(-) diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index 3a03a46ff41..89cc919edc4 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -36,12 +36,18 @@ func TestAccEC2DefaultVPCAndSubnet_serial(t *testing.T) { } } +func testAccPreCheckDefaultVPCAvailable(t *testing.T) { + if !hasDefaultVPC(t) { + t.Skip("skipping since no default VPC is available") + } +} + func testAccEC2DefaultVPC_basic(t *testing.T) { var v ec2.Vpc resourceName := "aws_default_vpc.test" resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCAvailable(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultVPCDestroy, @@ -61,6 +67,8 @@ func testAccEC2DefaultVPC_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "enable_classiclink_dns_support", "false"), resource.TestCheckResourceAttr(resourceName, "enable_dns_hostnames", "true"), resource.TestCheckResourceAttr(resourceName, "enable_dns_support", "true"), + resource.TestCheckResourceAttr(resourceName, "existing_default_vpc", "true"), + resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), resource.TestCheckResourceAttr(resourceName, "instance_tenancy", "default"), resource.TestCheckResourceAttr(resourceName, "ipv6_association_id", ""), resource.TestCheckResourceAttr(resourceName, "ipv6_cidr_block", ""), @@ -82,7 +90,7 @@ func testAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCAvailable(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultVPCDestroy, @@ -102,6 +110,8 @@ func testAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "enable_classiclink_dns_support", "false"), resource.TestCheckResourceAttr(resourceName, "enable_dns_hostnames", "true"), resource.TestCheckResourceAttr(resourceName, "enable_dns_support", "true"), + resource.TestCheckResourceAttr(resourceName, "existing_default_vpc", "true"), + resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), resource.TestCheckResourceAttr(resourceName, "instance_tenancy", "default"), resource.TestCheckResourceAttrSet(resourceName, "ipv6_association_id"), resource.TestMatchResourceAttr(resourceName, "ipv6_cidr_block", regexp.MustCompile(`/56$`)), diff --git a/internal/service/ec2/instance_test.go b/internal/service/ec2/instance_test.go index 23421c6b304..44dc3aee530 100644 --- a/internal/service/ec2/instance_test.go +++ b/internal/service/ec2/instance_test.go @@ -4,7 +4,6 @@ import ( "fmt" "reflect" "regexp" - "sort" "strings" "testing" "time" @@ -3992,19 +3991,24 @@ func testAccPreCheckEC2ClassicOrHasDefaultVPCWithDefaultSubnets(t *testing.T) { func hasDefaultVPC(t *testing.T) bool { conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn - resp, err := conn.DescribeAccountAttributes(&ec2.DescribeAccountAttributesInput{ + output, err := conn.DescribeAccountAttributes(&ec2.DescribeAccountAttributesInput{ AttributeNames: aws.StringSlice([]string{ec2.AccountAttributeNameDefaultVpc}), }) - if acctest.PreCheckSkipError(err) || - len(resp.AccountAttributes) == 0 || - len(resp.AccountAttributes[0].AttributeValues) == 0 || - aws.StringValue(resp.AccountAttributes[0].AttributeValues[0].AttributeValue) == "none" { + + if acctest.PreCheckSkipError(err) { return false } + if err != nil { t.Fatalf("error describing EC2 account attributes: %s", err) } + if len(output.AccountAttributes) == 0 || + len(output.AccountAttributes[0].AttributeValues) == 0 || + aws.StringValue(output.AccountAttributes[0].AttributeValues[0].AttributeValue) == "none" { + return false + } + return true } @@ -4013,66 +4017,24 @@ func defaultSubnetCount(t *testing.T) int { conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn input := &ec2.DescribeSubnetsInput{ - Filters: buildAttributeFilterList(map[string]string{ - "defaultForAz": "true", - }), - } - output, err := conn.DescribeSubnets(input) - if acctest.PreCheckSkipError(err) { - return 0 - } - if err != nil { - t.Fatalf("error describing default subnets: %s", err) + Filters: tfec2.BuildAttributeFilterList( + map[string]string{ + "defaultForAz": "true", + }, + ), } - return len(output.Subnets) -} + subnets, err := tfec2.FindSubnets(conn, input) -// buildAttributeFilterList takes a flat map of scalar attributes (most -// likely values extracted from a *schema.ResourceData on an EC2-querying -// data source) and produces a []*ec2.Filter representing an exact match -// for each of the given non-empty attributes. -// -// The keys of the given attributes map are the attribute names expected -// by the EC2 API, which are usually either in camelcase or with dash-separated -// words. We conventionally map these to underscore-separated identifiers -// with the same words when presenting these as data source query attributes -// in Terraform. -// -// It's the callers responsibility to transform any non-string values into -// the appropriate string serialization required by the AWS API when -// encoding the given filter. Any attributes given with empty string values -// are ignored, assuming that the user wishes to leave that attribute -// unconstrained while filtering. -// -// The purpose of this function is to create values to pass in -// for the "Filters" attribute on most of the "Describe..." API functions in -// the EC2 API, to aid in the implementation of Terraform data sources that -// retrieve data about EC2 objects. -func buildAttributeFilterList(attrs map[string]string) []*ec2.Filter { - var filters []*ec2.Filter - - // sort the filters by name to make the output deterministic - var names []string - for filterName := range attrs { - names = append(names, filterName) + if acctest.PreCheckSkipError(err) { + return 0 } - sort.Strings(names) - - for _, filterName := range names { - value := attrs[filterName] - if value == "" { - continue - } - - filters = append(filters, &ec2.Filter{ - Name: aws.String(filterName), - Values: []*string{aws.String(value)}, - }) + if err != nil { + t.Fatalf("error listing default subnets: %s", err) } - return filters + return len(subnets) } func testAccAvailableAZsWavelengthZonesExcludeConfig(excludeZoneIds ...string) string { From 0af65b9172e6df6104e1a5a9cc2e415c2b6c44c5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Jan 2022 09:42:56 -0500 Subject: [PATCH 038/116] Add 'testAccPreCheckDefaultSubnetAvailable'. --- internal/service/ec2/default_subnet_test.go | 45 ++++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/internal/service/ec2/default_subnet_test.go b/internal/service/ec2/default_subnet_test.go index 0168f0c4c28..202d3d05254 100644 --- a/internal/service/ec2/default_subnet_test.go +++ b/internal/service/ec2/default_subnet_test.go @@ -7,15 +7,38 @@ import ( "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" + tfec2 "github.com/hashicorp/terraform-provider-aws/internal/service/ec2" ) +func testAccPreCheckDefaultSubnetAvailable(t *testing.T) { + conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn + + input := &ec2.DescribeSubnetsInput{ + Filters: tfec2.BuildAttributeFilterList( + map[string]string{ + "defaultForAz": "true", + }, + ), + } + + subnets, err := tfec2.FindSubnets(conn, input) + + if err != nil { + t.Fatalf("error listing default subnets: %s", err) + } + + if len(subnets) == 0 { + t.Skip("skipping since no default subnet is available") + } +} + func testAccEC2DefaultSubnet_basic(t *testing.T) { var v ec2.Subnet resourceName := "aws_default_subnet.test" - availabilityZonesDataSourceName := "data.aws_availability_zones.available" resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetAvailable(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultSubnetDestroy, @@ -24,7 +47,6 @@ func testAccEC2DefaultSubnet_basic(t *testing.T) { Config: testAccDefaultSubnetConfig(), Check: resource.ComposeTestCheckFunc( testAccCheckSubnetExists(resourceName, &v), - resource.TestCheckResourceAttrPair(resourceName, "availability_zone", availabilityZonesDataSourceName, "names.0"), resource.TestCheckResourceAttrSet(resourceName, "availability_zone_id"), resource.TestCheckResourceAttr(resourceName, "assign_ipv6_address_on_creation", "false"), acctest.CheckResourceAttrAccountID(resourceName, "owner_id"), @@ -40,10 +62,23 @@ func testAccCheckDefaultSubnetDestroy(s *terraform.State) error { return nil } +const testAccDefaultSubnetConfigBaseExisting = ` +data "aws_subnets" "test" { + filter { + name = "defaultForAz" + values = ["true"] + } +} + +data "aws_subnet" "test" { + id = data.aws_subnets.test.ids[0] +} +` + func testAccDefaultSubnetConfig() string { - return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), ` + return acctest.ConfigCompose(testAccDefaultSubnetConfigBaseExisting, ` resource "aws_default_subnet" "test" { - availability_zone = data.aws_availability_zones.available.names[0] + availability_zone = data.aws_subnet.test.availability_zone } `) } From 9581c6c334fb27846a094b174708444dca6aab5c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Jan 2022 11:39:21 -0500 Subject: [PATCH 039/116] r/aws_default_vpc and r/aws_default_subnet: Check existence in TestCase.CheckDestroy. Acceptance test output: % make testacc TESTS=TestAccEC2DefaultVPCAndSubnet_serial PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2DefaultVPCAndSubnet_serial' -timeout 180m === RUN TestAccEC2DefaultVPCAndSubnet_serial === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/basic === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/assignGeneratedIPv6CIDRBlock === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/basic --- PASS: TestAccEC2DefaultVPCAndSubnet_serial (89.54s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC (72.98s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/basic (41.84s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/assignGeneratedIPv6CIDRBlock (31.14s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet (16.56s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/basic (16.56s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 93.528s --- internal/service/ec2/default_subnet_test.go | 38 ++++++++++++++++++--- internal/service/ec2/default_vpc_test.go | 25 +++++++++++--- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/internal/service/ec2/default_subnet_test.go b/internal/service/ec2/default_subnet_test.go index 202d3d05254..3f652ba42ea 100644 --- a/internal/service/ec2/default_subnet_test.go +++ b/internal/service/ec2/default_subnet_test.go @@ -41,24 +41,52 @@ func testAccEC2DefaultSubnet_basic(t *testing.T) { PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetAvailable(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckDefaultSubnetDestroy, + CheckDestroy: testAccCheckDefaultSubnetDestroyExists, Steps: []resource.TestStep{ { Config: testAccDefaultSubnetConfig(), - Check: resource.ComposeTestCheckFunc( + Check: resource.ComposeAggregateTestCheckFunc( testAccCheckSubnetExists(resourceName, &v), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttrSet(resourceName, "availability_zone"), resource.TestCheckResourceAttrSet(resourceName, "availability_zone_id"), - resource.TestCheckResourceAttr(resourceName, "assign_ipv6_address_on_creation", "false"), + resource.TestCheckResourceAttrSet(resourceName, "cidr_block"), + resource.TestCheckResourceAttr(resourceName, "customer_owned_ipv4_pool", ""), + resource.TestCheckResourceAttr(resourceName, "enable_dns64", "false"), + resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_aaaa_record_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_a_record_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "ipv6_cidr_block", ""), + resource.TestCheckResourceAttr(resourceName, "ipv6_native", "false"), + resource.TestCheckResourceAttr(resourceName, "map_customer_owned_ip_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "map_public_ip_on_launch", "true"), + resource.TestCheckResourceAttr(resourceName, "outpost_arn", ""), acctest.CheckResourceAttrAccountID(resourceName, "owner_id"), + resource.TestCheckResourceAttr(resourceName, "private_dns_hostname_type_on_launch", "ip-name"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttrSet(resourceName, "vpc_id"), ), }, }, }) } -func testAccCheckDefaultSubnetDestroy(s *terraform.State) error { - // We expect subnet to still exist +// testAccCheckDefaultSubnetDestroyExists runs after all resources are destroyed. +// It verifies that the default subnet still exists. +func testAccCheckDefaultSubnetDestroyExists(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_subnet" { + continue + } + + _, err := tfec2.FindSubnetByID(conn, rs.Primary.ID) + + if err != nil { + return err + } + } + return nil } diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index 89cc919edc4..b35fd5e73d2 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -10,6 +10,8 @@ import ( "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" + tfec2 "github.com/hashicorp/terraform-provider-aws/internal/service/ec2" ) func TestAccEC2DefaultVPCAndSubnet_serial(t *testing.T) { @@ -50,7 +52,7 @@ func testAccEC2DefaultVPC_basic(t *testing.T) { PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCAvailable(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckDefaultVPCDestroy, + CheckDestroy: testAccCheckDefaultVPCDestroyExists, Steps: []resource.TestStep{ { Config: testAccDefaultVPCConfig, @@ -93,7 +95,7 @@ func testAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock(t *testing.T) { PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCAvailable(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckDefaultVPCDestroy, + CheckDestroy: testAccCheckDefaultVPCDestroyExists, Steps: []resource.TestStep{ { Config: testAccDefaultVPCAssignGeneratedIPv6CIDRBlockConfig(rName), @@ -128,8 +130,23 @@ func testAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock(t *testing.T) { }) } -func testAccCheckDefaultVPCDestroy(s *terraform.State) error { - // We expect VPC to still exist +// testAccCheckDefaultVPCDestroyExists runs after all resources are destroyed. +// It verifies that the default VPC still exists. +func testAccCheckDefaultVPCDestroyExists(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_default_vpc" { + continue + } + + _, err := tfec2.FindVPCByID(conn, rs.Primary.ID) + + if err != nil { + return err + } + } + return nil } From aef55cba123399d528487bc92f7b9c0f4a02e2c8 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Jan 2022 11:45:13 -0500 Subject: [PATCH 040/116] Add CHANGELOG entry. --- .changelog/22253.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changelog/22253.txt diff --git a/.changelog/22253.txt b/.changelog/22253.txt new file mode 100644 index 00000000000..c12d457e78b --- /dev/null +++ b/.changelog/22253.txt @@ -0,0 +1,7 @@ +```release-note:note +resource/aws_default_subnet: If no default subnet exists in the specified Availability Zone one is now created. The `force_destroy` destroy argument has been added (defaults to `false`). Setting this argument to `true` deletes the default subnet on `terraform destroy`. +``` + +```release-note:note +resource/aws_default_vpc: If no default VPC exists in the current AWS Region one is now created. The `force_destroy` destroy argument has been added (defaults to `false`). Setting this argument to `true` deletes the default VPC on `terraform destroy`. +``` \ No newline at end of file From 8be68b06ee0ca2e0167350f721c09b069973a1f7 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Jan 2022 12:14:44 -0500 Subject: [PATCH 041/116] d/aws_vpcs: Return empty list when no VPCs match. % make testacc TESTARGS='-run=TestAccEC2VPCsDataSource_' PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run=TestAccEC2VPCsDataSource_ -timeout 180m === RUN TestAccEC2VPCsDataSource_basic === PAUSE TestAccEC2VPCsDataSource_basic === RUN TestAccEC2VPCsDataSource_tags === PAUSE TestAccEC2VPCsDataSource_tags === RUN TestAccEC2VPCsDataSource_filters === PAUSE TestAccEC2VPCsDataSource_filters === RUN TestAccEC2VPCsDataSource_empty === PAUSE TestAccEC2VPCsDataSource_empty === CONT TestAccEC2VPCsDataSource_basic === CONT TestAccEC2VPCsDataSource_filters === CONT TestAccEC2VPCsDataSource_empty === CONT TestAccEC2VPCsDataSource_tags --- PASS: TestAccEC2VPCsDataSource_empty (11.70s) --- PASS: TestAccEC2VPCsDataSource_basic (22.28s) --- PASS: TestAccEC2VPCsDataSource_tags (23.42s) --- PASS: TestAccEC2VPCsDataSource_filters (23.45s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 27.424s --- .changelog/22253.txt | 8 +- internal/service/ec2/vpcs_data_source.go | 46 +++---- internal/service/ec2/vpcs_data_source_test.go | 118 ++++++++++-------- 3 files changed, 87 insertions(+), 85 deletions(-) diff --git a/.changelog/22253.txt b/.changelog/22253.txt index c12d457e78b..45807f2b396 100644 --- a/.changelog/22253.txt +++ b/.changelog/22253.txt @@ -1,7 +1,11 @@ ```release-note:note -resource/aws_default_subnet: If no default subnet exists in the specified Availability Zone one is now created. The `force_destroy` destroy argument has been added (defaults to `false`). Setting this argument to `true` deletes the default subnet on `terraform destroy`. +resource/aws_default_subnet: If no default subnet exists in the specified Availability Zone one is now created. The `force_destroy` destroy argument has been added (defaults to `false`). Setting this argument to `true` deletes the default subnet on `terraform destroy` ``` ```release-note:note -resource/aws_default_vpc: If no default VPC exists in the current AWS Region one is now created. The `force_destroy` destroy argument has been added (defaults to `false`). Setting this argument to `true` deletes the default VPC on `terraform destroy`. +resource/aws_default_vpc: If no default VPC exists in the current AWS Region one is now created. The `force_destroy` destroy argument has been added (defaults to `false`). Setting this argument to `true` deletes the default VPC on `terraform destroy` +``` + +```release-note:note +data-source/aws_vpcs: The type of the `ids` attributes has changed from Set to List. If no VPCs match the specified criteria an empty list is returned (previously an error was raised) ``` \ No newline at end of file diff --git a/internal/service/ec2/vpcs_data_source.go b/internal/service/ec2/vpcs_data_source.go index b9aaf5df3e9..6f00ce37845 100644 --- a/internal/service/ec2/vpcs_data_source.go +++ b/internal/service/ec2/vpcs_data_source.go @@ -2,7 +2,6 @@ package ec2 import ( "fmt" - "log" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" @@ -15,16 +14,13 @@ func DataSourceVPCs() *schema.Resource { return &schema.Resource{ Read: dataSourceVPCsRead, Schema: map[string]*schema.Schema{ - "filter": CustomFiltersSchema(), - - "tags": tftags.TagsSchemaComputed(), - + "filter": DataSourceFiltersSchema(), "ids": { - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, }, + "tags": tftags.TagsSchemaComputed(), }, } } @@ -32,45 +28,37 @@ func DataSourceVPCs() *schema.Resource { func dataSourceVPCsRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - req := &ec2.DescribeVpcsInput{} + input := &ec2.DescribeVpcsInput{} if tags, tagsOk := d.GetOk("tags"); tagsOk { - req.Filters = append(req.Filters, BuildTagFilterList( + input.Filters = append(input.Filters, BuildTagFilterList( Tags(tftags.New(tags.(map[string]interface{}))), )...) } if filters, filtersOk := d.GetOk("filter"); filtersOk { - req.Filters = append(req.Filters, BuildCustomFilterList( - filters.(*schema.Set), - )...) - } - if len(req.Filters) == 0 { - // Don't send an empty filters list; the EC2 API won't accept it. - req.Filters = nil + input.Filters = append(input.Filters, + BuildFiltersDataSource(filters.(*schema.Set))...) } - log.Printf("[DEBUG] DescribeVpcs %s\n", req) - resp, err := conn.DescribeVpcs(req) - if err != nil { - return err + if len(input.Filters) == 0 { + input.Filters = nil } - if resp == nil || len(resp.Vpcs) == 0 { - return fmt.Errorf("no matching VPC found") + output, err := FindVPCs(conn, input) + + if err != nil { + return fmt.Errorf("error reading EC2 VPCs: %w", err) } - vpcs := make([]string, 0) + var vpcIDs []string - for _, vpc := range resp.Vpcs { - vpcs = append(vpcs, aws.StringValue(vpc.VpcId)) + for _, v := range output { + vpcIDs = append(vpcIDs, aws.StringValue(v.VpcId)) } d.SetId(meta.(*conns.AWSClient).Region) - - if err := d.Set("ids", vpcs); err != nil { - return fmt.Errorf("error setting vpc ids: %w", err) - } + d.Set("ids", vpcIDs) return nil } diff --git a/internal/service/ec2/vpcs_data_source_test.go b/internal/service/ec2/vpcs_data_source_test.go index 465acf80e85..dc1aa069ffe 100644 --- a/internal/service/ec2/vpcs_data_source_test.go +++ b/internal/service/ec2/vpcs_data_source_test.go @@ -12,15 +12,17 @@ import ( ) func TestAccEC2VPCsDataSource_basic(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, Steps: []resource.TestStep{ { - Config: testAccVPCsDataSourceConfig(), + Config: testAccVPCsDataSourceConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckVPCsExistsDataSource("data.aws_vpcs.all"), + testCheckResourceAttrGreaterThanValue("data.aws_vpcs.test", "ids.#", "0"), ), }, }, @@ -28,7 +30,8 @@ func TestAccEC2VPCsDataSource_basic(t *testing.T) { } func TestAccEC2VPCsDataSource_tags(t *testing.T) { - rName := sdkacctest.RandString(5) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), @@ -37,8 +40,7 @@ func TestAccEC2VPCsDataSource_tags(t *testing.T) { { Config: testAccVPCsDataSourceConfig_tags(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckVPCsExistsDataSource("data.aws_vpcs.selected"), - resource.TestCheckResourceAttr("data.aws_vpcs.selected", "ids.#", "1"), + resource.TestCheckResourceAttr("data.aws_vpcs.test", "ids.#", "1"), ), }, }, @@ -46,7 +48,8 @@ func TestAccEC2VPCsDataSource_tags(t *testing.T) { } func TestAccEC2VPCsDataSource_filters(t *testing.T) { - rName := sdkacctest.RandString(5) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), @@ -55,102 +58,109 @@ func TestAccEC2VPCsDataSource_filters(t *testing.T) { { Config: testAccVPCsDataSourceConfig_filters(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckVPCsExistsDataSource("data.aws_vpcs.selected"), - testCheckResourceAttrGreaterThanValue("data.aws_vpcs.selected", "ids.#", "0"), + testCheckResourceAttrGreaterThanValue("data.aws_vpcs.test", "ids.#", "0"), ), }, }, }) } -func testCheckResourceAttrGreaterThanValue(name, key, value string) resource.TestCheckFunc { - return func(s *terraform.State) error { - ms := s.RootModule() - rs, ok := ms.Resources[name] - if !ok { - return fmt.Errorf("Not found: %s in %s", name, ms.Path) - } - - is := rs.Primary - if is == nil { - return fmt.Errorf("No primary instance: %s in %s", name, ms.Path) - } - - if v, ok := is.Attributes[key]; !ok || !(v > value) { - if !ok { - return fmt.Errorf("%s: Attribute '%s' not found", name, key) - } - - return fmt.Errorf( - "%s: Attribute '%s' is not greater than %#v, got %#v", - name, - key, - value, - v) - } - return nil +func TestAccEC2VPCsDataSource_empty(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - } + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccVPCsDataSourceConfig_empty(rName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.aws_vpcs.test", "ids.#", "0"), + ), + }, + }, + }) } -func testAccCheckVPCsExistsDataSource(n string) resource.TestCheckFunc { +func testCheckResourceAttrGreaterThanValue(n, key, value string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("Can't find aws_vpcs data source: %s", n) + return fmt.Errorf("Not found: %s", n) } - if rs.Primary.ID == "" { - return fmt.Errorf("aws_vpcs data source ID not set") + if v, ok := rs.Primary.Attributes[key]; !ok || !(v > value) { + if !ok { + return fmt.Errorf("%s: Attribute %q not found", n, key) + } + + return fmt.Errorf("%s: Attribute %q is not greater than %q, got %q", n, key, value, v) } + return nil + } } -func testAccVPCsDataSourceConfig() string { - return ` -resource "aws_vpc" "test-vpc" { +func testAccVPCsDataSourceConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { cidr_block = "10.0.0.0/24" + + tags = { + Name = %[1]q + } } -data "aws_vpcs" "all" {} -` +data "aws_vpcs" "test" {} +`, rName) } func testAccVPCsDataSourceConfig_tags(rName string) string { return fmt.Sprintf(` -resource "aws_vpc" "test-vpc" { +resource "aws_vpc" "test" { cidr_block = "10.0.0.0/24" tags = { - Name = "testacc-vpc-%s" + Name = %[1]q Service = "testacc-test" } } -data "aws_vpcs" "selected" { +data "aws_vpcs" "test" { tags = { - Name = "testacc-vpc-%s" - Service = aws_vpc.test-vpc.tags["Service"] + Name = %[1]q + Service = aws_vpc.test.tags["Service"] } } -`, rName, rName) +`, rName) } func testAccVPCsDataSourceConfig_filters(rName string) string { return fmt.Sprintf(` -resource "aws_vpc" "test-vpc" { +resource "aws_vpc" "test" { cidr_block = "192.168.0.0/25" tags = { - Name = "testacc-vpc-%s" + Name = %[1]q } } -data "aws_vpcs" "selected" { +data "aws_vpcs" "test" { filter { name = "cidr" - values = [aws_vpc.test-vpc.cidr_block] + values = [aws_vpc.test.cidr_block] + } +} +`, rName) +} + +func testAccVPCsDataSourceConfig_empty(rName string) string { + return fmt.Sprintf(` +data "aws_vpcs" "test" { + tags = { + Name = %[1]q } } `, rName) From 44e70ae039e79fe1f05720cdcb65bf78322c28c7 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Jan 2022 12:25:15 -0500 Subject: [PATCH 042/116] EC2: 'testCheckResourceAttrGreaterThanValue' -> 'acctest.CheckResourceAttrGreaterThanValue'. --- internal/acctest/acctest.go | 20 +++++++++++++++ .../service/ec2/coip_pool_data_source_test.go | 4 +-- .../ec2/coip_pools_data_source_test.go | 2 +- .../ec2/instance_types_data_source_test.go | 4 +-- ...l_gateway_route_tables_data_source_test.go | 2 +- .../ec2/local_gateways_data_source_test.go | 2 +- .../service/ec2/subnets_data_source_test.go | 2 +- ...t_gateway_route_tables_data_source_test.go | 4 +-- internal/service/ec2/vpcs_data_source_test.go | 25 ++----------------- 9 files changed, 32 insertions(+), 33 deletions(-) diff --git a/internal/acctest/acctest.go b/internal/acctest/acctest.go index ccf398fc60c..36b2c1d6d1f 100644 --- a/internal/acctest/acctest.go +++ b/internal/acctest/acctest.go @@ -1844,3 +1844,23 @@ func CheckCallerIdentityAccountID(n string) resource.TestCheckFunc { return nil } } + +func CheckResourceAttrGreaterThanValue(n, key, value string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if v, ok := rs.Primary.Attributes[key]; !ok || !(v > value) { + if !ok { + return fmt.Errorf("%s: Attribute %q not found", n, key) + } + + return fmt.Errorf("%s: Attribute %q is not greater than %q, got %q", n, key, value, v) + } + + return nil + + } +} diff --git a/internal/service/ec2/coip_pool_data_source_test.go b/internal/service/ec2/coip_pool_data_source_test.go index 89d5a8bb99e..740607df2ef 100644 --- a/internal/service/ec2/coip_pool_data_source_test.go +++ b/internal/service/ec2/coip_pool_data_source_test.go @@ -22,7 +22,7 @@ func TestAccEC2CoIPPoolDataSource_filter(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestMatchResourceAttr(dataSourceName, "local_gateway_route_table_id", regexp.MustCompile(`^lgw-rtb-`)), resource.TestMatchResourceAttr(dataSourceName, "pool_id", regexp.MustCompile(`^ipv4pool-coip-`)), - testCheckResourceAttrGreaterThanValue(dataSourceName, "pool_cidrs.#", "0"), + acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "pool_cidrs.#", "0"), ), }, }, @@ -43,7 +43,7 @@ func TestAccEC2CoIPPoolDataSource_id(t *testing.T) { resource.TestMatchResourceAttr(dataSourceName, "local_gateway_route_table_id", regexp.MustCompile(`^lgw-rtb-`)), resource.TestMatchResourceAttr(dataSourceName, "pool_id", regexp.MustCompile(`^ipv4pool-coip-`)), acctest.MatchResourceAttrRegionalARN(dataSourceName, "arn", "ec2", regexp.MustCompile(`coip-pool/ipv4pool-coip-.+$`)), - testCheckResourceAttrGreaterThanValue(dataSourceName, "pool_cidrs.#", "0"), + acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "pool_cidrs.#", "0"), ), }, }, diff --git a/internal/service/ec2/coip_pools_data_source_test.go b/internal/service/ec2/coip_pools_data_source_test.go index b718c18559a..f2cce07d0a5 100644 --- a/internal/service/ec2/coip_pools_data_source_test.go +++ b/internal/service/ec2/coip_pools_data_source_test.go @@ -19,7 +19,7 @@ func TestAccEC2CoIPPoolsDataSource_basic(t *testing.T) { { Config: testAccCoIPPoolsDataSourceConfig(), Check: resource.ComposeTestCheckFunc( - testCheckResourceAttrGreaterThanValue(dataSourceName, "pool_ids.#", "0"), + acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "pool_ids.#", "0"), ), }, }, diff --git a/internal/service/ec2/instance_types_data_source_test.go b/internal/service/ec2/instance_types_data_source_test.go index 4ae7ca75492..35e9d4f26d9 100644 --- a/internal/service/ec2/instance_types_data_source_test.go +++ b/internal/service/ec2/instance_types_data_source_test.go @@ -21,7 +21,7 @@ func TestAccEC2InstanceTypesDataSource_basic(t *testing.T) { { Config: testAccInstanceTypesDataSourceConfig(), Check: resource.ComposeTestCheckFunc( - testCheckResourceAttrGreaterThanValue(dataSourceName, "instance_types.#", "0"), + acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "instance_types.#", "0"), ), }, }, @@ -40,7 +40,7 @@ func TestAccEC2InstanceTypesDataSource_filter(t *testing.T) { { Config: testAccInstanceTypesDataSourceConfigFilter(), Check: resource.ComposeTestCheckFunc( - testCheckResourceAttrGreaterThanValue(dataSourceName, "instance_types.#", "0"), + acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "instance_types.#", "0"), ), }, }, diff --git a/internal/service/ec2/local_gateway_route_tables_data_source_test.go b/internal/service/ec2/local_gateway_route_tables_data_source_test.go index c37a6dc4f1f..f13e5fe12db 100644 --- a/internal/service/ec2/local_gateway_route_tables_data_source_test.go +++ b/internal/service/ec2/local_gateway_route_tables_data_source_test.go @@ -19,7 +19,7 @@ func TestAccEC2LocalGatewayRouteTablesDataSource_basic(t *testing.T) { { Config: testAccLocalGatewayRouteTablesDataSourceConfig(), Check: resource.ComposeTestCheckFunc( - testCheckResourceAttrGreaterThanValue(dataSourceName, "ids.#", "0"), + acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "ids.#", "0"), ), }, }, diff --git a/internal/service/ec2/local_gateways_data_source_test.go b/internal/service/ec2/local_gateways_data_source_test.go index a26c4a03d72..0fee22703c1 100644 --- a/internal/service/ec2/local_gateways_data_source_test.go +++ b/internal/service/ec2/local_gateways_data_source_test.go @@ -19,7 +19,7 @@ func TestAccEC2LocalGatewaysDataSource_basic(t *testing.T) { { Config: testAccLocalGatewaysDataSourceConfig(), Check: resource.ComposeTestCheckFunc( - testCheckResourceAttrGreaterThanValue(dataSourceName, "ids.#", "0"), + acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "ids.#", "0"), ), }, }, diff --git a/internal/service/ec2/subnets_data_source_test.go b/internal/service/ec2/subnets_data_source_test.go index 6c030aba54c..c2f901cf743 100644 --- a/internal/service/ec2/subnets_data_source_test.go +++ b/internal/service/ec2/subnets_data_source_test.go @@ -26,7 +26,7 @@ func TestAccEC2SubnetsDataSource_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("data.aws_subnets.selected", "ids.#", "4"), resource.TestCheckResourceAttr("data.aws_subnets.private", "ids.#", "2"), - testCheckResourceAttrGreaterThanValue("data.aws_subnets.all", "ids.#", "0"), + acctest.CheckResourceAttrGreaterThanValue("data.aws_subnets.all", "ids.#", "0"), resource.TestCheckResourceAttr("data.aws_subnets.none", "ids.#", "0"), ), }, diff --git a/internal/service/ec2/transit_gateway_route_tables_data_source_test.go b/internal/service/ec2/transit_gateway_route_tables_data_source_test.go index 4cd8ab8a19b..d33e61175dc 100644 --- a/internal/service/ec2/transit_gateway_route_tables_data_source_test.go +++ b/internal/service/ec2/transit_gateway_route_tables_data_source_test.go @@ -19,7 +19,7 @@ func testAccTransitGatewayRouteTablesDataSource_basic(t *testing.T) { { Config: testAccTransitGatewayRouteTablesDataSourceConfig, Check: resource.ComposeTestCheckFunc( - testCheckResourceAttrGreaterThanValue(dataSourceName, "ids.#", "0"), + acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "ids.#", "0"), ), }, }, @@ -37,7 +37,7 @@ func testAccTransitGatewayRouteTablesDataSource_Filter(t *testing.T) { { Config: testAccTransitGatewayRouteTablesTransitGatewayFilterDataSource, Check: resource.ComposeTestCheckFunc( - testCheckResourceAttrGreaterThanValue(dataSourceName, "ids.#", "0"), + acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "ids.#", "0"), ), }, }, diff --git a/internal/service/ec2/vpcs_data_source_test.go b/internal/service/ec2/vpcs_data_source_test.go index dc1aa069ffe..b618c63e87b 100644 --- a/internal/service/ec2/vpcs_data_source_test.go +++ b/internal/service/ec2/vpcs_data_source_test.go @@ -7,7 +7,6 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" 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" ) @@ -22,7 +21,7 @@ func TestAccEC2VPCsDataSource_basic(t *testing.T) { { Config: testAccVPCsDataSourceConfig(rName), Check: resource.ComposeTestCheckFunc( - testCheckResourceAttrGreaterThanValue("data.aws_vpcs.test", "ids.#", "0"), + acctest.CheckResourceAttrGreaterThanValue("data.aws_vpcs.test", "ids.#", "0"), ), }, }, @@ -58,7 +57,7 @@ func TestAccEC2VPCsDataSource_filters(t *testing.T) { { Config: testAccVPCsDataSourceConfig_filters(rName), Check: resource.ComposeTestCheckFunc( - testCheckResourceAttrGreaterThanValue("data.aws_vpcs.test", "ids.#", "0"), + acctest.CheckResourceAttrGreaterThanValue("data.aws_vpcs.test", "ids.#", "0"), ), }, }, @@ -83,26 +82,6 @@ func TestAccEC2VPCsDataSource_empty(t *testing.T) { }) } -func testCheckResourceAttrGreaterThanValue(n, key, value string) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("Not found: %s", n) - } - - if v, ok := rs.Primary.Attributes[key]; !ok || !(v > value) { - if !ok { - return fmt.Errorf("%s: Attribute %q not found", n, key) - } - - return fmt.Errorf("%s: Attribute %q is not greater than %q, got %q", n, key, value, v) - } - - return nil - - } -} - func testAccVPCsDataSourceConfig(rName string) string { return fmt.Sprintf(` resource "aws_vpc" "test" { From 810c9f3b47c7819a90fc7737df5bb34f55e0ea5c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Jan 2022 12:26:35 -0500 Subject: [PATCH 043/116] EKS: 'testCheckResourceAttrGreaterThanValue' -> 'acctest.CheckResourceAttrGreaterThanValue'. --- .../service/eks/cluster_data_source_test.go | 32 ------------------- .../service/eks/clusters_data_source_test.go | 2 +- 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/internal/service/eks/cluster_data_source_test.go b/internal/service/eks/cluster_data_source_test.go index 5e044e50f7a..999fc01ca4d 100644 --- a/internal/service/eks/cluster_data_source_test.go +++ b/internal/service/eks/cluster_data_source_test.go @@ -1,14 +1,12 @@ package eks_test import ( - "fmt" "regexp" "testing" "github.com/aws/aws-sdk-go/service/eks" 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" ) @@ -66,33 +64,3 @@ data "aws_eks_cluster" "test" { } `) } - -func testCheckResourceAttrGreaterThanValue(name, key, value string) resource.TestCheckFunc { - return func(s *terraform.State) error { - ms := s.RootModule() - rs, ok := ms.Resources[name] - if !ok { - return fmt.Errorf("Not found: %s in %s", name, ms.Path) - } - - is := rs.Primary - if is == nil { - return fmt.Errorf("No primary instance: %s in %s", name, ms.Path) - } - - if v, ok := is.Attributes[key]; !ok || !(v > value) { - if !ok { - return fmt.Errorf("%s: Attribute '%s' not found", name, key) - } - - return fmt.Errorf( - "%s: Attribute '%s' is not greater than %#v, got %#v", - name, - key, - value, - v) - } - return nil - - } -} diff --git a/internal/service/eks/clusters_data_source_test.go b/internal/service/eks/clusters_data_source_test.go index 70357deb036..535d778966a 100644 --- a/internal/service/eks/clusters_data_source_test.go +++ b/internal/service/eks/clusters_data_source_test.go @@ -22,7 +22,7 @@ func TestAccEKSClustersDataSource_basic(t *testing.T) { { Config: testAccClustersDataSourceConfig_Basic(rName), Check: resource.ComposeTestCheckFunc( - testCheckResourceAttrGreaterThanValue(dataSourceResourceName, "names.#", "0"), + acctest.CheckResourceAttrGreaterThanValue(dataSourceResourceName, "names.#", "0"), ), }, }, From 6d797fe5950ce7c46b5e179c5c6aeff77781b60c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Jan 2022 14:09:59 -0500 Subject: [PATCH 044/116] r/aws_default_subnet: Add 'testAccEC2DefaultSubnet_privateDnsNameOptionsOnLaunch'. % make testacc TESTS=TestAccEC2DefaultVPCAndSubnet_serial/Subnet/privateDnsNameOptionsOnLaunch PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2DefaultVPCAndSubnet_serial/Subnet/privateDnsNameOptionsOnLaunch' -timeout 180m === RUN TestAccEC2DefaultVPCAndSubnet_serial === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/privateDnsNameOptionsOnLaunch --- PASS: TestAccEC2DefaultVPCAndSubnet_serial (48.51s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet (48.51s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/privateDnsNameOptionsOnLaunch (48.51s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 52.165s --- internal/service/ec2/default_subnet_test.go | 56 +++++++++++++++++++++ internal/service/ec2/default_vpc_test.go | 3 +- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/internal/service/ec2/default_subnet_test.go b/internal/service/ec2/default_subnet_test.go index 3f652ba42ea..04a5c1d11bc 100644 --- a/internal/service/ec2/default_subnet_test.go +++ b/internal/service/ec2/default_subnet_test.go @@ -1,9 +1,11 @@ package ec2_test import ( + "fmt" "testing" "github.com/aws/aws-sdk-go/service/ec2" + 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" @@ -70,6 +72,45 @@ func testAccEC2DefaultSubnet_basic(t *testing.T) { }) } +func testAccEC2DefaultSubnet_privateDnsNameOptionsOnLaunch(t *testing.T) { + var v ec2.Subnet + resourceName := "aws_default_subnet.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetAvailable(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckDefaultSubnetDestroyExists, + Steps: []resource.TestStep{ + { + Config: testAccDefaultSubnetPrivateDnsNameOptionsOnLaunchConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckSubnetExists(resourceName, &v), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttrSet(resourceName, "availability_zone"), + resource.TestCheckResourceAttrSet(resourceName, "availability_zone_id"), + resource.TestCheckResourceAttrSet(resourceName, "cidr_block"), + resource.TestCheckResourceAttr(resourceName, "customer_owned_ipv4_pool", ""), + resource.TestCheckResourceAttr(resourceName, "enable_dns64", "false"), + resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_aaaa_record_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_a_record_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "ipv6_cidr_block", ""), + resource.TestCheckResourceAttr(resourceName, "ipv6_native", "false"), + resource.TestCheckResourceAttr(resourceName, "map_customer_owned_ip_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "map_public_ip_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "outpost_arn", ""), + acctest.CheckResourceAttrAccountID(resourceName, "owner_id"), + resource.TestCheckResourceAttr(resourceName, "private_dns_hostname_type_on_launch", "resource-name"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), + resource.TestCheckResourceAttrSet(resourceName, "vpc_id"), + ), + }, + }, + }) +} + // testAccCheckDefaultSubnetDestroyExists runs after all resources are destroyed. // It verifies that the default subnet still exists. func testAccCheckDefaultSubnetDestroyExists(s *terraform.State) error { @@ -110,3 +151,18 @@ resource "aws_default_subnet" "test" { } `) } + +func testAccDefaultSubnetPrivateDnsNameOptionsOnLaunchConfig(rName string) string { + return acctest.ConfigCompose(testAccDefaultSubnetConfigBaseExisting, fmt.Sprintf(` +resource "aws_default_subnet" "test" { + availability_zone = data.aws_subnet.test.availability_zone + + map_public_ip_on_launch = false + private_dns_hostname_type_on_launch = "resource-name" + + tags = { + Name = %[1]q + } +} +`, rName)) +} diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index b35fd5e73d2..81f7acf733b 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -21,7 +21,8 @@ func TestAccEC2DefaultVPCAndSubnet_serial(t *testing.T) { "assignGeneratedIPv6CIDRBlock": testAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock, }, "Subnet": { - "basic": testAccEC2DefaultSubnet_basic, + "basic": testAccEC2DefaultSubnet_basic, + "privateDnsNameOptionsOnLaunch": testAccEC2DefaultSubnet_privateDnsNameOptionsOnLaunch, }, } From d094e9d475937f58bc75d145c967ba8e7c466871 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Jan 2022 15:19:18 -0500 Subject: [PATCH 045/116] r/aws_default_vpc: Add `force_destroy` and create new tests. % AWS_DEFAULT_REGION=eu-west-2 make testacc TESTS=TestAccEC2DefaultVPCAndSubnet_serial/VPC PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2DefaultVPCAndSubnet_serial/VPC' -timeout 180m === RUN TestAccEC2DefaultVPCAndSubnet_serial === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/existing.basic === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/existing.assignGeneratedIPv6CIDRBlock === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/existing.forceDestroy === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/notFound.basic default_vpc_test.go:56: Deleting existing default VPC: vpc-0952d31628cc2a7ba === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/notFound.assignGeneratedIPv6CIDRBlock default_vpc_test.go:56: Deleting existing default VPC: vpc-07b89ae85c358b75f === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/notFound.forceDestroy default_vpc_test.go:56: Deleting existing default VPC: vpc-0599d53adb4a24651 --- PASS: TestAccEC2DefaultVPCAndSubnet_serial (203.38s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC (203.38s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/existing.basic (22.97s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/existing.assignGeneratedIPv6CIDRBlock (33.03s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/existing.forceDestroy (50.79s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/notFound.basic (25.39s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/notFound.assignGeneratedIPv6CIDRBlock (36.82s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/notFound.forceDestroy (34.38s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 207.630s --- internal/service/ec2/default_vpc_test.go | 277 ++++++++++++++++++++++- internal/service/ec2/instance_test.go | 20 +- 2 files changed, 281 insertions(+), 16 deletions(-) diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index 81f7acf733b..f3311c18771 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -5,6 +5,7 @@ import ( "regexp" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -12,13 +13,18 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/acctest" "github.com/hashicorp/terraform-provider-aws/internal/conns" tfec2 "github.com/hashicorp/terraform-provider-aws/internal/service/ec2" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) func TestAccEC2DefaultVPCAndSubnet_serial(t *testing.T) { testCases := map[string]map[string]func(t *testing.T){ "VPC": { - "basic": testAccEC2DefaultVPC_basic, - "assignGeneratedIPv6CIDRBlock": testAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock, + "existing.basic": testAccEC2DefaultVPC_Existing_basic, + "existing.assignGeneratedIPv6CIDRBlock": testAccEC2DefaultVPC_Existing_assignGeneratedIPv6CIDRBlock, + "existing.forceDestroy": testAccEC2DefaultVPC_Existing_forceDestroy, + "notFound.basic": testAccEC2DefaultVPC_NotFound_basic, + "notFound.assignGeneratedIPv6CIDRBlock": testAccEC2DefaultVPC_NotFound_assignGeneratedIPv6CIDRBlock, + "notFound.forceDestroy": testAccEC2DefaultVPC_NotFound_forceDestroy, }, "Subnet": { "basic": testAccEC2DefaultSubnet_basic, @@ -39,18 +45,40 @@ func TestAccEC2DefaultVPCAndSubnet_serial(t *testing.T) { } } -func testAccPreCheckDefaultVPCAvailable(t *testing.T) { +func testAccPreCheckDefaultVPCExists(t *testing.T) { if !hasDefaultVPC(t) { - t.Skip("skipping since no default VPC is available") + t.Skip("skipping since no default VPC exists") } } -func testAccEC2DefaultVPC_basic(t *testing.T) { +func testAccPreCheckDefaultVPCNotFound(t *testing.T) { + if vpcID := defaultVPC(t); vpcID != "" { + t.Logf("Deleting existing default VPC: %s", vpcID) + + err := testAccEmptyDefaultVPC(vpcID) + + if err != nil { + t.Fatalf("error emptying default VPC: %s", err) + } + + r := tfec2.ResourceVPC() + d := r.Data(nil) + d.SetId(vpcID) + + err = acctest.DeleteResource(r, d, acctest.Provider.Meta()) + + if err != nil { + t.Fatalf("error deleting default VPC: %s", err) + } + } +} + +func testAccEC2DefaultVPC_Existing_basic(t *testing.T) { var v ec2.Vpc resourceName := "aws_default_vpc.test" resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCAvailable(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCExists(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultVPCDestroyExists, @@ -87,13 +115,13 @@ func testAccEC2DefaultVPC_basic(t *testing.T) { }) } -func testAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock(t *testing.T) { +func testAccEC2DefaultVPC_Existing_assignGeneratedIPv6CIDRBlock(t *testing.T) { var v ec2.Vpc resourceName := "aws_default_vpc.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCAvailable(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCExists(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultVPCDestroyExists, @@ -131,6 +159,136 @@ func testAccEC2DefaultVPC_assignGeneratedIPv6CIDRBlock(t *testing.T) { }) } +func testAccEC2DefaultVPC_Existing_forceDestroy(t *testing.T) { + var v ec2.Vpc + resourceName := "aws_default_vpc.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCExists(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckDefaultVPCDestroyNotFound, + Steps: []resource.TestStep{ + { + Config: testAccDefaultVPCForceDestroyConfig, + Check: resource.ComposeAggregateTestCheckFunc( + acctest.CheckVPCExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "force_destroy", "true"), + testAccCheckDefaultVPCEmpty(&v), + ), + }, + }, + }) +} + +func testAccEC2DefaultVPC_NotFound_basic(t *testing.T) { + var v ec2.Vpc + resourceName := "aws_default_vpc.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCNotFound(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckDefaultVPCDestroyExists, + Steps: []resource.TestStep{ + { + Config: testAccDefaultVPCConfig, + Check: resource.ComposeAggregateTestCheckFunc( + acctest.CheckVPCExists(resourceName, &v), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "assign_generated_ipv6_cidr_block", "false"), + resource.TestCheckResourceAttr(resourceName, "cidr_block", "172.31.0.0/16"), + resource.TestCheckResourceAttrSet(resourceName, "default_network_acl_id"), + resource.TestCheckResourceAttrSet(resourceName, "default_route_table_id"), + resource.TestCheckResourceAttrSet(resourceName, "default_security_group_id"), + resource.TestCheckResourceAttrSet(resourceName, "dhcp_options_id"), + resource.TestCheckResourceAttr(resourceName, "enable_classiclink", "false"), + resource.TestCheckResourceAttr(resourceName, "enable_classiclink_dns_support", "false"), + resource.TestCheckResourceAttr(resourceName, "enable_dns_hostnames", "true"), + resource.TestCheckResourceAttr(resourceName, "enable_dns_support", "true"), + resource.TestCheckResourceAttr(resourceName, "existing_default_vpc", "false"), + resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), + resource.TestCheckResourceAttr(resourceName, "instance_tenancy", "default"), + resource.TestCheckResourceAttr(resourceName, "ipv6_association_id", ""), + resource.TestCheckResourceAttr(resourceName, "ipv6_cidr_block", ""), + resource.TestCheckResourceAttr(resourceName, "ipv6_cidr_block_network_border_group", ""), + resource.TestCheckResourceAttr(resourceName, "ipv6_ipam_pool_id", ""), + resource.TestCheckResourceAttr(resourceName, "ipv6_netmask_length", "0"), + resource.TestCheckResourceAttrSet(resourceName, "main_route_table_id"), + acctest.CheckResourceAttrAccountID(resourceName, "owner_id"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + }, + }) +} + +func testAccEC2DefaultVPC_NotFound_assignGeneratedIPv6CIDRBlock(t *testing.T) { + var v ec2.Vpc + resourceName := "aws_default_vpc.test" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCNotFound(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckDefaultVPCDestroyExists, + Steps: []resource.TestStep{ + { + Config: testAccDefaultVPCAssignGeneratedIPv6CIDRBlockConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + acctest.CheckVPCExists(resourceName, &v), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "assign_generated_ipv6_cidr_block", "true"), + resource.TestCheckResourceAttr(resourceName, "cidr_block", "172.31.0.0/16"), + resource.TestCheckResourceAttrSet(resourceName, "default_network_acl_id"), + resource.TestCheckResourceAttrSet(resourceName, "default_route_table_id"), + resource.TestCheckResourceAttrSet(resourceName, "default_security_group_id"), + resource.TestCheckResourceAttrSet(resourceName, "dhcp_options_id"), + resource.TestCheckResourceAttr(resourceName, "enable_classiclink", "false"), + resource.TestCheckResourceAttr(resourceName, "enable_classiclink_dns_support", "false"), + resource.TestCheckResourceAttr(resourceName, "enable_dns_hostnames", "true"), + resource.TestCheckResourceAttr(resourceName, "enable_dns_support", "true"), + resource.TestCheckResourceAttr(resourceName, "existing_default_vpc", "false"), + resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), + resource.TestCheckResourceAttr(resourceName, "instance_tenancy", "default"), + resource.TestCheckResourceAttrSet(resourceName, "ipv6_association_id"), + resource.TestMatchResourceAttr(resourceName, "ipv6_cidr_block", regexp.MustCompile(`/56$`)), + resource.TestCheckResourceAttr(resourceName, "ipv6_cidr_block_network_border_group", acctest.Region()), + resource.TestCheckResourceAttr(resourceName, "ipv6_ipam_pool_id", ""), + resource.TestCheckResourceAttr(resourceName, "ipv6_netmask_length", "0"), + resource.TestCheckResourceAttrSet(resourceName, "main_route_table_id"), + acctest.CheckResourceAttrAccountID(resourceName, "owner_id"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.Name", rName), + ), + }, + }, + }) +} + +func testAccEC2DefaultVPC_NotFound_forceDestroy(t *testing.T) { + var v ec2.Vpc + resourceName := "aws_default_vpc.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCNotFound(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckDefaultVPCDestroyNotFound, + Steps: []resource.TestStep{ + { + Config: testAccDefaultVPCForceDestroyConfig, + Check: resource.ComposeAggregateTestCheckFunc( + acctest.CheckVPCExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "force_destroy", "true"), + testAccCheckDefaultVPCEmpty(&v), + ), + }, + }, + }) +} + // testAccCheckDefaultVPCDestroyExists runs after all resources are destroyed. // It verifies that the default VPC still exists. func testAccCheckDefaultVPCDestroyExists(s *terraform.State) error { @@ -151,10 +309,113 @@ func testAccCheckDefaultVPCDestroyExists(s *terraform.State) error { return nil } +// testAccCheckDefaultVPCDestroyNotFound runs after all resources are destroyed. +// It verifies that the default VPC does not exist. +// A new default VPC is then created. +func testAccCheckDefaultVPCDestroyNotFound(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_default_vpc" { + continue + } + + _, err := tfec2.FindVPCByID(conn, rs.Primary.ID) + + if tfresource.NotFound(err) { + continue + } + + if err != nil { + return err + } + + return fmt.Errorf("EC2 Default VPC %s still exists", rs.Primary.ID) + } + + _, err := conn.CreateDefaultVpc(&ec2.CreateDefaultVpcInput{}) + + if err != nil { + return fmt.Errorf("error creating new default VPC: %w", err) + } + + return nil +} + +// testAccCheckDefaultVPCEmpty returns a TestCheckFunc that empties the specified default VPC. +func testAccCheckDefaultVPCEmpty(v *ec2.Vpc) resource.TestCheckFunc { + return func(s *terraform.State) error { + return testAccEmptyDefaultVPC(aws.StringValue(v.VpcId)) + } +} + +// testAccEmptyDefaultVPC empties a default VPC so that it can be deleted. +func testAccEmptyDefaultVPC(vpcID string) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn + + // Delete the default IGW. + igw, err := tfec2.FindInternetGateway(conn, &ec2.DescribeInternetGatewaysInput{ + Filters: tfec2.BuildAttributeFilterList( + map[string]string{ + "attachment.state": "available", + "attachment.vpc-id": vpcID, + }, + ), + }) + + if err == nil { + r := tfec2.ResourceInternetGateway() + d := r.Data(nil) + d.SetId(aws.StringValue(igw.InternetGatewayId)) + d.Set("vpc_id", vpcID) + + err := acctest.DeleteResource(r, d, acctest.Provider.Meta()) + + if err != nil { + return err + } + } else if !tfresource.NotFound(err) { + return err + } + + // Delete default subnets. + subnets, err := tfec2.FindSubnets(conn, &ec2.DescribeSubnetsInput{ + Filters: tfec2.BuildAttributeFilterList( + map[string]string{ + "defaultForAz": "true", + }, + ), + }) + + if err != nil { + return err + } + + for _, v := range subnets { + r := tfec2.ResourceSubnet() + d := r.Data(nil) + d.SetId(aws.StringValue(v.SubnetId)) + + err := acctest.DeleteResource(r, d, acctest.Provider.Meta()) + + if err != nil { + return err + } + } + + return nil +} + const testAccDefaultVPCConfig = ` resource "aws_default_vpc" "test" {} ` +const testAccDefaultVPCForceDestroyConfig = ` +resource "aws_default_vpc" "test" { + force_destroy = true +} +` + func testAccDefaultVPCAssignGeneratedIPv6CIDRBlockConfig(rName string) string { return fmt.Sprintf(` resource "aws_default_vpc" "test" { diff --git a/internal/service/ec2/instance_test.go b/internal/service/ec2/instance_test.go index 44dc3aee530..00a0421f6bf 100644 --- a/internal/service/ec2/instance_test.go +++ b/internal/service/ec2/instance_test.go @@ -3987,8 +3987,8 @@ func testAccPreCheckEC2ClassicOrHasDefaultVPCWithDefaultSubnets(t *testing.T) { } } -// hasDefaultVPC returns whether the current AWS region has a default VPC. -func hasDefaultVPC(t *testing.T) bool { +// defaultVPC returns the ID of the default VPC for the current AWS Region, or "" if none exists. +func defaultVPC(t *testing.T) string { conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn output, err := conn.DescribeAccountAttributes(&ec2.DescribeAccountAttributesInput{ @@ -3996,20 +3996,24 @@ func hasDefaultVPC(t *testing.T) bool { }) if acctest.PreCheckSkipError(err) { - return false + return "" } if err != nil { t.Fatalf("error describing EC2 account attributes: %s", err) } - if len(output.AccountAttributes) == 0 || - len(output.AccountAttributes[0].AttributeValues) == 0 || - aws.StringValue(output.AccountAttributes[0].AttributeValues[0].AttributeValue) == "none" { - return false + if len(output.AccountAttributes) > 0 && len(output.AccountAttributes[0].AttributeValues) > 0 { + if v := aws.StringValue(output.AccountAttributes[0].AttributeValues[0].AttributeValue); v != "none" { + return v + } } - return true + return "" +} + +func hasDefaultVPC(t *testing.T) bool { + return defaultVPC(t) != "" } // defaultSubnetCount returns the number of default subnets in the current region's default VPC. From d16ad134462bb66e0806d7dfd9d16a360f090c54 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 20 Jan 2022 16:11:12 -0500 Subject: [PATCH 046/116] r/aws_default_subnet: Additional tests. % AWS_DEFAULT_REGION=eu-west-2 make testacc TESTS=TestAccEC2DefaultVPCAndSubnet_serial/Subnet PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2DefaultVPCAndSubnet_serial/Subnet' -timeout 180m === RUN TestAccEC2DefaultVPCAndSubnet_serial === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.privateDnsNameOptionsOnLaunch === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.basic === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.ipv6 --- PASS: TestAccEC2DefaultVPCAndSubnet_serial (150.53s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet (150.53s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.privateDnsNameOptionsOnLaunch (29.08s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.basic (28.64s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.ipv6 (92.81s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 154.075s --- internal/service/ec2/default_subnet_test.go | 68 +++++++++++++++++++-- internal/service/ec2/default_vpc_test.go | 5 +- 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/internal/service/ec2/default_subnet_test.go b/internal/service/ec2/default_subnet_test.go index 04a5c1d11bc..ab3c4401eaf 100644 --- a/internal/service/ec2/default_subnet_test.go +++ b/internal/service/ec2/default_subnet_test.go @@ -13,7 +13,7 @@ import ( tfec2 "github.com/hashicorp/terraform-provider-aws/internal/service/ec2" ) -func testAccPreCheckDefaultSubnetAvailable(t *testing.T) { +func testAccPreCheckDefaultSubnetExists(t *testing.T) { conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn input := &ec2.DescribeSubnetsInput{ @@ -35,12 +35,12 @@ func testAccPreCheckDefaultSubnetAvailable(t *testing.T) { } } -func testAccEC2DefaultSubnet_basic(t *testing.T) { +func testAccEC2DefaultSubnet_Existing_basic(t *testing.T) { var v ec2.Subnet resourceName := "aws_default_subnet.test" resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetAvailable(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetExists(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultSubnetDestroyExists, @@ -50,6 +50,7 @@ func testAccEC2DefaultSubnet_basic(t *testing.T) { Check: resource.ComposeAggregateTestCheckFunc( testAccCheckSubnetExists(resourceName, &v), resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "assign_ipv6_address_on_creation", "false"), resource.TestCheckResourceAttrSet(resourceName, "availability_zone"), resource.TestCheckResourceAttrSet(resourceName, "availability_zone_id"), resource.TestCheckResourceAttrSet(resourceName, "cidr_block"), @@ -63,6 +64,44 @@ func testAccEC2DefaultSubnet_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "map_public_ip_on_launch", "true"), resource.TestCheckResourceAttr(resourceName, "outpost_arn", ""), acctest.CheckResourceAttrAccountID(resourceName, "owner_id"), + resource.TestCheckResourceAttrSet(resourceName, "private_dns_hostname_type_on_launch"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttrSet(resourceName, "vpc_id"), + ), + }, + }, + }) +} + +func testAccEC2DefaultSubnet_Existing_ipv6(t *testing.T) { + var v ec2.Subnet + resourceName := "aws_default_subnet.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetExists(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckDefaultSubnetDestroyExists, + Steps: []resource.TestStep{ + { + Config: testAccDefaultSubnetIPv6Config(), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckSubnetExists(resourceName, &v), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "assign_ipv6_address_on_creation", "true"), + resource.TestCheckResourceAttrSet(resourceName, "availability_zone"), + resource.TestCheckResourceAttrSet(resourceName, "availability_zone_id"), + resource.TestCheckResourceAttrSet(resourceName, "cidr_block"), + resource.TestCheckResourceAttr(resourceName, "customer_owned_ipv4_pool", ""), + resource.TestCheckResourceAttr(resourceName, "enable_dns64", "true"), + resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_aaaa_record_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_a_record_on_launch", "false"), + resource.TestCheckResourceAttrSet(resourceName, "ipv6_cidr_block"), + resource.TestCheckResourceAttr(resourceName, "ipv6_native", "false"), + resource.TestCheckResourceAttr(resourceName, "map_customer_owned_ip_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "map_public_ip_on_launch", "true"), + resource.TestCheckResourceAttr(resourceName, "outpost_arn", ""), + acctest.CheckResourceAttrAccountID(resourceName, "owner_id"), resource.TestCheckResourceAttr(resourceName, "private_dns_hostname_type_on_launch", "ip-name"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), resource.TestCheckResourceAttrSet(resourceName, "vpc_id"), @@ -72,13 +111,13 @@ func testAccEC2DefaultSubnet_basic(t *testing.T) { }) } -func testAccEC2DefaultSubnet_privateDnsNameOptionsOnLaunch(t *testing.T) { +func testAccEC2DefaultSubnet_Existing_privateDnsNameOptionsOnLaunch(t *testing.T) { var v ec2.Subnet resourceName := "aws_default_subnet.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetAvailable(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetExists(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultSubnetDestroyExists, @@ -88,6 +127,7 @@ func testAccEC2DefaultSubnet_privateDnsNameOptionsOnLaunch(t *testing.T) { Check: resource.ComposeAggregateTestCheckFunc( testAccCheckSubnetExists(resourceName, &v), resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "assign_ipv6_address_on_creation", "false"), resource.TestCheckResourceAttrSet(resourceName, "availability_zone"), resource.TestCheckResourceAttrSet(resourceName, "availability_zone_id"), resource.TestCheckResourceAttrSet(resourceName, "cidr_block"), @@ -152,6 +192,24 @@ resource "aws_default_subnet" "test" { `) } +func testAccDefaultSubnetIPv6Config() string { + return acctest.ConfigCompose(testAccDefaultSubnetConfigBaseExisting, ` +resource "aws_default_vpc" "test" { + assign_generated_ipv6_cidr_block = true +} + +resource "aws_default_subnet" "test" { + availability_zone = data.aws_subnet.test.availability_zone + + ipv6_cidr_block = cidrsubnet(aws_default_vpc.test.ipv6_cidr_block, 8, 1) + assign_ipv6_address_on_creation = true + enable_dns64 = true + + private_dns_hostname_type_on_launch = "ip-name" +} +`) +} + func testAccDefaultSubnetPrivateDnsNameOptionsOnLaunchConfig(rName string) string { return acctest.ConfigCompose(testAccDefaultSubnetConfigBaseExisting, fmt.Sprintf(` resource "aws_default_subnet" "test" { diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index f3311c18771..5cd0d18047f 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -27,8 +27,9 @@ func TestAccEC2DefaultVPCAndSubnet_serial(t *testing.T) { "notFound.forceDestroy": testAccEC2DefaultVPC_NotFound_forceDestroy, }, "Subnet": { - "basic": testAccEC2DefaultSubnet_basic, - "privateDnsNameOptionsOnLaunch": testAccEC2DefaultSubnet_privateDnsNameOptionsOnLaunch, + "existing.basic": testAccEC2DefaultSubnet_Existing_basic, + "existing.ipv6": testAccEC2DefaultSubnet_Existing_ipv6, + "existing.privateDnsNameOptionsOnLaunch": testAccEC2DefaultSubnet_Existing_privateDnsNameOptionsOnLaunch, }, } From b69e4c88a6a0fbfb38a0ff70e30a6f88dfa0b560 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 21 Jan 2022 09:20:56 -0500 Subject: [PATCH 047/116] r/aws_default_subnet: Ensure default subnets are recreated. % AWS_DEFAULT_REGION=eu-west-2 make testacc TESTS=TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing' -timeout 180m === RUN TestAccEC2DefaultVPCAndSubnet_serial === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.privateDnsNameOptionsOnLaunch === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.basic === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.forceDestroy === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.ipv6 --- PASS: TestAccEC2DefaultVPCAndSubnet_serial (192.57s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet (192.57s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.privateDnsNameOptionsOnLaunch (49.32s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.basic (33.13s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.forceDestroy (19.62s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.ipv6 (90.50s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 199.777s --- internal/service/ec2/default_subnet.go | 28 ++- internal/service/ec2/default_subnet_test.go | 266 +++++++++++++++++++- internal/service/ec2/default_vpc_test.go | 5 + internal/service/ec2/errors.go | 1 + internal/service/ec2/subnet.go | 48 ++-- internal/service/ec2/vpc.go | 2 +- 6 files changed, 329 insertions(+), 21 deletions(-) diff --git a/internal/service/ec2/default_subnet.go b/internal/service/ec2/default_subnet.go index ecba2ee81ef..d3026f0cb9e 100644 --- a/internal/service/ec2/default_subnet.go +++ b/internal/service/ec2/default_subnet.go @@ -41,6 +41,7 @@ func ResourceDefaultSubnet() *schema.Resource { // - availability_zone is Required/ForceNew // - availability_zone_id is Computed-only // - cidr_block is Computed-only + // - ipv6_cidr_block is Optional/Computed as it's automatically assigned if ipv6_native = true // - map_public_ip_on_launch has a Default of true // - outpost_arn is Computed-only // - vpc_id is Computed-only @@ -102,6 +103,7 @@ func ResourceDefaultSubnet() *schema.Resource { "ipv6_cidr_block": { Type: schema.TypeString, Optional: true, + Computed: true, ValidateFunc: verify.ValidIPv6CIDRNetworkAddress, }, "ipv6_cidr_block_association_id": { @@ -161,6 +163,7 @@ func resourceDefaultSubnetCreate(d *schema.ResourceData, meta interface{}) error ), } + var computedIPv6CIDRBlock bool subnet, err := FindSubnet(conn, input) if err == nil { @@ -172,8 +175,10 @@ func resourceDefaultSubnetCreate(d *schema.ResourceData, meta interface{}) error AvailabilityZone: aws.String(availabilityZone), } + var ipv6Native bool if v, ok := d.GetOk("ipv6_native"); ok { - input.Ipv6Native = aws.Bool(v.(bool)) + ipv6Native = v.(bool) + input.Ipv6Native = aws.Bool(ipv6Native) } log.Printf("[DEBUG] Creating EC2 Default Subnet: %s", input) @@ -188,16 +193,33 @@ func resourceDefaultSubnetCreate(d *schema.ResourceData, meta interface{}) error d.SetId(aws.StringValue(subnet.SubnetId)) d.Set("existing_default_subnet", false) - _, err = WaitSubnetAvailable(conn, d.Id(), d.Timeout(schema.TimeoutCreate)) + subnet, err = WaitSubnetAvailable(conn, d.Id(), d.Timeout(schema.TimeoutCreate)) if err != nil { return fmt.Errorf("error waiting for EC2 Default Subnet (%s) create: %w", d.Id(), err) } + + // Creating an IPv6-native default subnets associates an IPv6 CIDR block. + for _, v := range subnet.Ipv6CidrBlockAssociationSet { + if aws.StringValue(v.Ipv6CidrBlockState.State) == ec2.SubnetCidrBlockStateCodeAssociating { //we can only ever have 1 IPv6 block associated at once + associationID := aws.StringValue(v.AssociationId) + + _, err = WaitSubnetIPv6CIDRBlockAssociationCreated(conn, associationID) + + if err != nil { + return fmt.Errorf("error waiting for EC2 Default Subnet (%s) IPv6 CIDR block (%s) to become associated: %w", d.Id(), associationID, err) + } + } + } + + if ipv6Native { + computedIPv6CIDRBlock = true + } } else { return fmt.Errorf("error reading EC2 Default Subnet (%s): %w", d.Id(), err) } - if err := modifySubnetAttributesOnCreate(conn, d, subnet); err != nil { + if err := modifySubnetAttributesOnCreate(conn, d, subnet, computedIPv6CIDRBlock); err != nil { return err } diff --git a/internal/service/ec2/default_subnet_test.go b/internal/service/ec2/default_subnet_test.go index ab3c4401eaf..65ad4fe81ec 100644 --- a/internal/service/ec2/default_subnet_test.go +++ b/internal/service/ec2/default_subnet_test.go @@ -4,13 +4,16 @@ import ( "fmt" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" + "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" tfec2 "github.com/hashicorp/terraform-provider-aws/internal/service/ec2" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) func testAccPreCheckDefaultSubnetExists(t *testing.T) { @@ -35,6 +38,40 @@ func testAccPreCheckDefaultSubnetExists(t *testing.T) { } } +func testAccPreCheckDefaultSubnetNotFound(t *testing.T) { + conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn + + input := &ec2.DescribeSubnetsInput{ + Filters: tfec2.BuildAttributeFilterList( + map[string]string{ + "defaultForAz": "true", + }, + ), + } + + subnets, err := tfec2.FindSubnets(conn, input) + + if err != nil { + t.Fatalf("error listing default subnets: %s", err) + } + + for _, v := range subnets { + subnetID := aws.StringValue(v.SubnetId) + + t.Logf("Deleting existing default subnet: %s", subnetID) + + r := tfec2.ResourceSubnet() + d := r.Data(nil) + d.SetId(subnetID) + + err := acctest.DeleteResource(r, d, acctest.Provider.Meta()) + + if err != nil { + t.Fatalf("error deleting default subnet: %s", err) + } + } +} + func testAccEC2DefaultSubnet_Existing_basic(t *testing.T) { var v ec2.Subnet resourceName := "aws_default_subnet.test" @@ -58,6 +95,8 @@ func testAccEC2DefaultSubnet_Existing_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "enable_dns64", "false"), resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_aaaa_record_on_launch", "false"), resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_a_record_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "existing_default_subnet", "true"), + resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), resource.TestCheckResourceAttr(resourceName, "ipv6_cidr_block", ""), resource.TestCheckResourceAttr(resourceName, "ipv6_native", "false"), resource.TestCheckResourceAttr(resourceName, "map_customer_owned_ip_on_launch", "false"), @@ -73,6 +112,28 @@ func testAccEC2DefaultSubnet_Existing_basic(t *testing.T) { }) } +func testAccEC2DefaultSubnet_Existing_forceDestroy(t *testing.T) { + var v ec2.Subnet + resourceName := "aws_default_subnet.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetExists(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckDefaultSubnetDestroyNotFound, + Steps: []resource.TestStep{ + { + Config: testAccDefaultSubnetForceDestroyConfig(), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckSubnetExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "existing_default_subnet", "true"), + resource.TestCheckResourceAttr(resourceName, "force_destroy", "true"), + ), + }, + }, + }) +} + func testAccEC2DefaultSubnet_Existing_ipv6(t *testing.T) { var v ec2.Subnet resourceName := "aws_default_subnet.test" @@ -81,7 +142,7 @@ func testAccEC2DefaultSubnet_Existing_ipv6(t *testing.T) { PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetExists(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckDefaultSubnetDestroyExists, + CheckDestroy: testAccCheckDefaultSubnetDestroyNotFound, Steps: []resource.TestStep{ { Config: testAccDefaultSubnetIPv6Config(), @@ -96,6 +157,8 @@ func testAccEC2DefaultSubnet_Existing_ipv6(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "enable_dns64", "true"), resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_aaaa_record_on_launch", "false"), resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_a_record_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "existing_default_subnet", "true"), + resource.TestCheckResourceAttr(resourceName, "force_destroy", "true"), resource.TestCheckResourceAttrSet(resourceName, "ipv6_cidr_block"), resource.TestCheckResourceAttr(resourceName, "ipv6_native", "false"), resource.TestCheckResourceAttr(resourceName, "map_customer_owned_ip_on_launch", "false"), @@ -135,6 +198,8 @@ func testAccEC2DefaultSubnet_Existing_privateDnsNameOptionsOnLaunch(t *testing.T resource.TestCheckResourceAttr(resourceName, "enable_dns64", "false"), resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_aaaa_record_on_launch", "false"), resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_a_record_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "existing_default_subnet", "true"), + resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), resource.TestCheckResourceAttr(resourceName, "ipv6_cidr_block", ""), resource.TestCheckResourceAttr(resourceName, "ipv6_native", "false"), resource.TestCheckResourceAttr(resourceName, "map_customer_owned_ip_on_launch", "false"), @@ -151,8 +216,89 @@ func testAccEC2DefaultSubnet_Existing_privateDnsNameOptionsOnLaunch(t *testing.T }) } +func testAccEC2DefaultSubnet_NotFound_basic(t *testing.T) { + var v ec2.Subnet + resourceName := "aws_default_subnet.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetNotFound(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckDefaultSubnetDestroyExists, + Steps: []resource.TestStep{ + { + Config: testAccDefaultSubnetNotFoundConfig(), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckSubnetExists(resourceName, &v), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "assign_ipv6_address_on_creation", "false"), + resource.TestCheckResourceAttrSet(resourceName, "availability_zone"), + resource.TestCheckResourceAttrSet(resourceName, "availability_zone_id"), + resource.TestCheckResourceAttrSet(resourceName, "cidr_block"), + resource.TestCheckResourceAttr(resourceName, "customer_owned_ipv4_pool", ""), + resource.TestCheckResourceAttr(resourceName, "enable_dns64", "false"), + resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_aaaa_record_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_a_record_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "existing_default_subnet", "false"), + resource.TestCheckResourceAttr(resourceName, "force_destroy", "false"), + resource.TestCheckResourceAttr(resourceName, "ipv6_cidr_block", ""), + resource.TestCheckResourceAttr(resourceName, "ipv6_native", "false"), + resource.TestCheckResourceAttr(resourceName, "map_customer_owned_ip_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "map_public_ip_on_launch", "true"), + resource.TestCheckResourceAttr(resourceName, "outpost_arn", ""), + acctest.CheckResourceAttrAccountID(resourceName, "owner_id"), + resource.TestCheckResourceAttrSet(resourceName, "private_dns_hostname_type_on_launch"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttrSet(resourceName, "vpc_id"), + ), + }, + }, + }) +} + +func testAccEC2DefaultSubnet_NotFound_ipv6Native(t *testing.T) { + var v ec2.Subnet + resourceName := "aws_default_subnet.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetNotFound(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckDefaultSubnetDestroyNotFound, + Steps: []resource.TestStep{ + { + Config: testAccDefaultSubnetIPv6NativeConfig(), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckSubnetExists(resourceName, &v), + resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttr(resourceName, "assign_ipv6_address_on_creation", "true"), + resource.TestCheckResourceAttrSet(resourceName, "availability_zone"), + resource.TestCheckResourceAttrSet(resourceName, "availability_zone_id"), + resource.TestCheckResourceAttr(resourceName, "cidr_block", ""), + resource.TestCheckResourceAttr(resourceName, "customer_owned_ipv4_pool", ""), + resource.TestCheckResourceAttr(resourceName, "enable_dns64", "true"), + resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_aaaa_record_on_launch", "true"), + resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_a_record_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "existing_default_subnet", "true"), + resource.TestCheckResourceAttr(resourceName, "force_destroy", "true"), + resource.TestCheckResourceAttrSet(resourceName, "ipv6_cidr_block"), + resource.TestCheckResourceAttr(resourceName, "ipv6_native", "true"), + resource.TestCheckResourceAttr(resourceName, "map_customer_owned_ip_on_launch", "false"), + resource.TestCheckResourceAttr(resourceName, "map_public_ip_on_launch", "true"), + resource.TestCheckResourceAttr(resourceName, "outpost_arn", ""), + acctest.CheckResourceAttrAccountID(resourceName, "owner_id"), + resource.TestCheckResourceAttrSet(resourceName, "private_dns_hostname_type_on_launch"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttrSet(resourceName, "vpc_id"), + ), + }, + }, + }) +} + // testAccCheckDefaultSubnetDestroyExists runs after all resources are destroyed. // It verifies that the default subnet still exists. +// Any missing default subnets are then created. func testAccCheckDefaultSubnetDestroyExists(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn @@ -168,6 +314,80 @@ func testAccCheckDefaultSubnetDestroyExists(s *terraform.State) error { } } + err := testAccCreateMissingDefaultSubnets() + + if err != nil { + return err + } + + return nil +} + +// testAccCheckDefaultSubnetDestroyNotFound runs after all resources are destroyed. +// It verifies that the default subnet does not exist. +// Any missing default subnets are then created. +func testAccCheckDefaultSubnetDestroyNotFound(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_subnet" { + continue + } + + _, err := tfec2.FindSubnetByID(conn, rs.Primary.ID) + + if tfresource.NotFound(err) { + continue + } + + if err != nil { + return err + } + + return fmt.Errorf("EC2 Default Subnet %s still exists", rs.Primary.ID) + } + + err := testAccCreateMissingDefaultSubnets() + + if err != nil { + return err + } + + return nil +} + +func testAccCreateMissingDefaultSubnets() error { + conn := acctest.Provider.Meta().(*conns.AWSClient).EC2Conn + + output, err := conn.DescribeAvailabilityZones(&ec2.DescribeAvailabilityZonesInput{ + Filters: tfec2.BuildAttributeFilterList( + map[string]string{ + "opt-in-status": "opt-in-not-required", + "state": "available", + }, + ), + }) + + if err != nil { + return err + } + + for _, v := range output.AvailabilityZones { + availabilityZone := aws.StringValue(v.ZoneName) + + _, err := conn.CreateDefaultSubnet(&ec2.CreateDefaultSubnetInput{ + AvailabilityZone: aws.String(availabilityZone), + }) + + if tfawserr.ErrCodeEquals(err, tfec2.ErrCodeDefaultSubnetAlreadyExistsInAvailabilityZone) { + continue + } + + if err != nil { + return fmt.Errorf("error creating new default subnet (%s): %w", availabilityZone, err) + } + } + return nil } @@ -192,6 +412,23 @@ resource "aws_default_subnet" "test" { `) } +func testAccDefaultSubnetNotFoundConfig() string { + return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), ` +resource "aws_default_subnet" "test" { + availability_zone = data.aws_availability_zones.available.names[0] +} +`) +} + +func testAccDefaultSubnetForceDestroyConfig() string { + return acctest.ConfigCompose(testAccDefaultSubnetConfigBaseExisting, ` +resource "aws_default_subnet" "test" { + availability_zone = data.aws_subnet.test.availability_zone + force_destroy = true +} +`) +} + func testAccDefaultSubnetIPv6Config() string { return acctest.ConfigCompose(testAccDefaultSubnetConfigBaseExisting, ` resource "aws_default_vpc" "test" { @@ -206,6 +443,33 @@ resource "aws_default_subnet" "test" { enable_dns64 = true private_dns_hostname_type_on_launch = "ip-name" + + # force-destroy so that the default VPC can have IPv6 disabled. + force_destroy = true + + depends_on = [aws_default_vpc.test] +} +`) +} + +func testAccDefaultSubnetIPv6NativeConfig() string { + return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), ` +resource "aws_default_vpc" "test" { + assign_generated_ipv6_cidr_block = true +} + +resource "aws_default_subnet" "test" { + availability_zone = data.aws_availability_zones.available.names[0] + + assign_ipv6_address_on_creation = true + ipv6_native = true + + enable_resource_name_dns_aaaa_record_on_launch = true + + # force-destroy so that the default VPC can have IPv6 disabled. + force_destroy = true + + depends_on = [aws_default_vpc.test] } `) } diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index 5cd0d18047f..eb04a72430b 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -28,8 +28,11 @@ func TestAccEC2DefaultVPCAndSubnet_serial(t *testing.T) { }, "Subnet": { "existing.basic": testAccEC2DefaultSubnet_Existing_basic, + "existing.forceDestroy": testAccEC2DefaultSubnet_Existing_forceDestroy, "existing.ipv6": testAccEC2DefaultSubnet_Existing_ipv6, "existing.privateDnsNameOptionsOnLaunch": testAccEC2DefaultSubnet_Existing_privateDnsNameOptionsOnLaunch, + "notFound.basic": testAccEC2DefaultSubnet_NotFound_basic, + "notFound.ipv6Native": testAccEC2DefaultSubnet_NotFound_ipv6Native, }, } @@ -174,6 +177,7 @@ func testAccEC2DefaultVPC_Existing_forceDestroy(t *testing.T) { Config: testAccDefaultVPCForceDestroyConfig, Check: resource.ComposeAggregateTestCheckFunc( acctest.CheckVPCExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "existing_default_vpc", "true"), resource.TestCheckResourceAttr(resourceName, "force_destroy", "true"), testAccCheckDefaultVPCEmpty(&v), ), @@ -282,6 +286,7 @@ func testAccEC2DefaultVPC_NotFound_forceDestroy(t *testing.T) { Config: testAccDefaultVPCForceDestroyConfig, Check: resource.ComposeAggregateTestCheckFunc( acctest.CheckVPCExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "existing_default_vpc", "false"), resource.TestCheckResourceAttr(resourceName, "force_destroy", "true"), testAccCheckDefaultVPCEmpty(&v), ), diff --git a/internal/service/ec2/errors.go b/internal/service/ec2/errors.go index 8ea1126c475..1a1bde9e86f 100644 --- a/internal/service/ec2/errors.go +++ b/internal/service/ec2/errors.go @@ -12,6 +12,7 @@ import ( const ( ErrCodeAuthFailure = "AuthFailure" ErrCodeClientInvalidHostIDNotFound = "Client.InvalidHostID.NotFound" + ErrCodeDefaultSubnetAlreadyExistsInAvailabilityZone = "DefaultSubnetAlreadyExistsInAvailabilityZone" ErrCodeDependencyViolation = "DependencyViolation" ErrCodeGatewayNotAttached = "Gateway.NotAttached" ErrCodeIncorrectState = "IncorrectState" diff --git a/internal/service/ec2/subnet.go b/internal/service/ec2/subnet.go index c19d2ca08bd..66182c22684 100644 --- a/internal/service/ec2/subnet.go +++ b/internal/service/ec2/subnet.go @@ -190,7 +190,19 @@ func resourceSubnetCreate(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("error waiting for EC2 Subnet (%s) create: %w", d.Id(), err) } - if err := modifySubnetAttributesOnCreate(conn, d, subnet); err != nil { + for _, v := range subnet.Ipv6CidrBlockAssociationSet { + if aws.StringValue(v.Ipv6CidrBlockState.State) == ec2.SubnetCidrBlockStateCodeAssociating { //we can only ever have 1 IPv6 block associated at once + associationID := aws.StringValue(v.AssociationId) + + _, err = WaitSubnetIPv6CIDRBlockAssociationCreated(conn, associationID) + + if err != nil { + return fmt.Errorf("error waiting for EC2 Subnet (%s) IPv6 CIDR block (%s) to become associated: %w", d.Id(), associationID, err) + } + } + } + + if err := modifySubnetAttributesOnCreate(conn, d, subnet, false); err != nil { return err } @@ -370,7 +382,7 @@ func resourceSubnetDelete(d *schema.ResourceData, meta interface{}) error { // modifySubnetAttributesOnCreate sets subnet attributes on resource Create. // Called after new subnet creation or existing default subnet adoption. -func modifySubnetAttributesOnCreate(conn *ec2.EC2, d *schema.ResourceData, subnet *ec2.Subnet) error { +func modifySubnetAttributesOnCreate(conn *ec2.EC2, d *schema.ResourceData, subnet *ec2.Subnet, computedIPv6CidrBlock bool) error { // If we're disabling IPv6 assignment for new ENIs, do that before modifying the IPv6 CIDR block. if new, old := d.Get("assign_ipv6_address_on_creation").(bool), aws.BoolValue(subnet.AssignIpv6AddressOnCreation); old != new && !new { if err := modifySubnetAssignIpv6AddressOnCreation(conn, d.Id(), false); err != nil { @@ -385,18 +397,22 @@ func modifySubnetAttributesOnCreate(conn *ec2.EC2, d *schema.ResourceData, subne } } - var oldAssociationID, oldIPv6CIDRBlock string - for _, v := range subnet.Ipv6CidrBlockAssociationSet { - if aws.StringValue(v.Ipv6CidrBlockState.State) == ec2.SubnetCidrBlockStateCodeAssociated { //we can only ever have 1 IPv6 block associated at once - oldAssociationID = aws.StringValue(v.AssociationId) - oldIPv6CIDRBlock = aws.StringValue(v.Ipv6CidrBlock) + // Creating a new IPv6-native default subnet assigns a computed IPv6 CIDR block. + // Don't attempt to do anything with it. + if !computedIPv6CidrBlock { + var oldAssociationID, oldIPv6CIDRBlock string + for _, v := range subnet.Ipv6CidrBlockAssociationSet { + if aws.StringValue(v.Ipv6CidrBlockState.State) == ec2.SubnetCidrBlockStateCodeAssociated { //we can only ever have 1 IPv6 block associated at once + oldAssociationID = aws.StringValue(v.AssociationId) + oldIPv6CIDRBlock = aws.StringValue(v.Ipv6CidrBlock) - break + break + } } - } - if new := d.Get("ipv6_cidr_block").(string); oldIPv6CIDRBlock != new { - if err := modifySubnetIPv6CIDRBlockAssociation(conn, d.Id(), oldAssociationID, new); err != nil { - return err + if new := d.Get("ipv6_cidr_block").(string); oldIPv6CIDRBlock != new { + if err := modifySubnetIPv6CIDRBlockAssociation(conn, d.Id(), oldAssociationID, new); err != nil { + return err + } } } @@ -539,13 +555,13 @@ func modifySubnetIPv6CIDRBlockAssociation(conn *ec2.EC2, subnetID, associationID _, err := conn.DisassociateSubnetCidrBlock(input) if err != nil { - return fmt.Errorf("error disassociating EC2 Subnet (%s) CIDR block (%s): %w", subnetID, associationID, err) + return fmt.Errorf("error disassociating EC2 Subnet (%s) IPv6 CIDR block (%s): %w", subnetID, associationID, err) } _, err = WaitSubnetIPv6CIDRBlockAssociationDeleted(conn, associationID) if err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) CIDR block (%s) to become disassociated: %w", subnetID, associationID, err) + return fmt.Errorf("error waiting for EC2 Subnet (%s) IPv6 CIDR block (%s) to become disassociated: %w", subnetID, associationID, err) } } @@ -560,7 +576,7 @@ func modifySubnetIPv6CIDRBlockAssociation(conn *ec2.EC2, subnetID, associationID if err != nil { //The big question here is, do we want to try to reassociate the old one?? //If we have a failure here, then we may be in a situation that we have nothing associated - return fmt.Errorf("error associating EC2 Subnet (%s) CIDR block (%s): %w", subnetID, cidrBlock, err) + return fmt.Errorf("error associating EC2 Subnet (%s) IPv6 CIDR block (%s): %w", subnetID, cidrBlock, err) } associationID := aws.StringValue(output.Ipv6CidrBlockAssociation.AssociationId) @@ -568,7 +584,7 @@ func modifySubnetIPv6CIDRBlockAssociation(conn *ec2.EC2, subnetID, associationID _, err = WaitSubnetIPv6CIDRBlockAssociationCreated(conn, associationID) if err != nil { - return fmt.Errorf("error waiting for EC2 Subnet (%s) CIDR block (%s) to become associated: %w", subnetID, associationID, err) + return fmt.Errorf("error waiting for EC2 Subnet (%s) IPv6 CIDR block (%s) to become associated: %w", subnetID, associationID, err) } } diff --git a/internal/service/ec2/vpc.go b/internal/service/ec2/vpc.go index 16b7c0321ad..ce91cf44317 100644 --- a/internal/service/ec2/vpc.go +++ b/internal/service/ec2/vpc.go @@ -668,7 +668,7 @@ func modifyVPCIPv6CIDRBlockAssociation(conn *ec2.EC2, vpcID, associationID strin _, err := conn.DisassociateVpcCidrBlock(input) if err != nil { - return "", fmt.Errorf("error disassociating EC2 VPC (%s) CIDR block (%s): %w", vpcID, associationID, err) + return "", fmt.Errorf("error disassociating EC2 VPC (%s) IPv6 CIDR block (%s): %w", vpcID, associationID, err) } _, err = WaitVPCIPv6CIDRBlockAssociationDeleted(conn, associationID, vpcIPv6CIDRBlockAssociationDeletedTimeout) From de1d44ff5d476eaa7652aec290f731e470f4ebb1 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 21 Jan 2022 13:24:23 -0500 Subject: [PATCH 048/116] r/aws_default_subnet & r/aws_default_vpc: Don't run acceptance tests in the standard region(s) as other resources' tests (e.g. aws_instance) implicitly use default subnets. Acceptance test output: % AWS_DEFAULT_REGION=eu-west-2 make testacc TESTS=TestAccEC2DefaultVPCAndSubnet_serial PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2DefaultVPCAndSubnet_serial' -timeout 180m === RUN TestAccEC2DefaultVPCAndSubnet_serial === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/existing.basic === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/existing.assignGeneratedIPv6CIDRBlock === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/existing.forceDestroy === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/notFound.basic default_vpc_test.go:61: Deleting existing default VPC: vpc-070f87de6a2504c87 === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/notFound.assignGeneratedIPv6CIDRBlock default_vpc_test.go:61: Deleting existing default VPC: vpc-08068b0353ebbae41 === RUN TestAccEC2DefaultVPCAndSubnet_serial/VPC/notFound.forceDestroy default_vpc_test.go:61: Deleting existing default VPC: vpc-09610d2f3e1ffba00 === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.forceDestroy === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.ipv6 === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.privateDnsNameOptionsOnLaunch === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/notFound.basic default_subnet_test.go:62: Deleting existing default subnet: subnet-0a60a9666d2edfb92 default_subnet_test.go:62: Deleting existing default subnet: subnet-0d5b5572150325e38 default_subnet_test.go:62: Deleting existing default subnet: subnet-055f31bb2650e3b86 === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/notFound.ipv6Native default_subnet_test.go:62: Deleting existing default subnet: subnet-07b62a14e35e531c8 default_subnet_test.go:62: Deleting existing default subnet: subnet-03e145e9e3a5db6e6 default_subnet_test.go:62: Deleting existing default subnet: subnet-0e2ba115852876dc6 === RUN TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.basic --- PASS: TestAccEC2DefaultVPCAndSubnet_serial (467.10s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC (233.68s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/existing.basic (46.26s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/existing.assignGeneratedIPv6CIDRBlock (32.89s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/existing.forceDestroy (52.24s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/notFound.basic (27.52s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/notFound.assignGeneratedIPv6CIDRBlock (40.93s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/VPC/notFound.forceDestroy (33.84s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet (233.42s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.forceDestroy (22.89s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.ipv6 (64.95s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.privateDnsNameOptionsOnLaunch (41.24s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/notFound.basic (21.50s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/notFound.ipv6Native (64.50s) --- PASS: TestAccEC2DefaultVPCAndSubnet_serial/Subnet/existing.basic (18.33s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 470.792s --- internal/acctest/acctest.go | 9 ++++ internal/service/ec2/default_subnet_test.go | 48 ++++++++++++++++----- internal/service/ec2/default_vpc_test.go | 37 +++++++++++++--- 3 files changed, 77 insertions(+), 17 deletions(-) diff --git a/internal/acctest/acctest.go b/internal/acctest/acctest.go index 36b2c1d6d1f..1e0a11e2c84 100644 --- a/internal/acctest/acctest.go +++ b/internal/acctest/acctest.go @@ -652,6 +652,15 @@ func PreCheckRegion(t *testing.T, region string) { } } +// PreCheckRegionNot checks that the test region is not one of the specified regions. +func PreCheckRegionNot(t *testing.T, regions ...string) { + for _, region := range regions { + if Region() == region { + t.Skipf("skipping tests; %s (%s) not supported", conns.EnvVarDefaultRegion, region) + } + } +} + // PreCheckPartition checks that the test partition is the specified partition. func PreCheckPartition(partition string, t *testing.T) { if Partition() != partition { diff --git a/internal/service/ec2/default_subnet_test.go b/internal/service/ec2/default_subnet_test.go index 65ad4fe81ec..a33201dab55 100644 --- a/internal/service/ec2/default_subnet_test.go +++ b/internal/service/ec2/default_subnet_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/aws-sdk-go-base/tfawserr" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" @@ -77,7 +78,11 @@ func testAccEC2DefaultSubnet_Existing_basic(t *testing.T) { resourceName := "aws_default_subnet.test" resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetExists(t) }, + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckRegionNot(t, endpoints.UsWest2RegionID, endpoints.UsGovWest1RegionID) + testAccPreCheckDefaultSubnetExists(t) + }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultSubnetDestroyExists, @@ -117,7 +122,11 @@ func testAccEC2DefaultSubnet_Existing_forceDestroy(t *testing.T) { resourceName := "aws_default_subnet.test" resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetExists(t) }, + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckRegionNot(t, endpoints.UsWest2RegionID, endpoints.UsGovWest1RegionID) + testAccPreCheckDefaultSubnetExists(t) + }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultSubnetDestroyNotFound, @@ -139,7 +148,11 @@ func testAccEC2DefaultSubnet_Existing_ipv6(t *testing.T) { resourceName := "aws_default_subnet.test" resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetExists(t) }, + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckRegionNot(t, endpoints.UsWest2RegionID, endpoints.UsGovWest1RegionID) + testAccPreCheckDefaultSubnetExists(t) + }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultSubnetDestroyNotFound, @@ -180,7 +193,11 @@ func testAccEC2DefaultSubnet_Existing_privateDnsNameOptionsOnLaunch(t *testing.T rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetExists(t) }, + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckRegionNot(t, endpoints.UsWest2RegionID, endpoints.UsGovWest1RegionID) + testAccPreCheckDefaultSubnetExists(t) + }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultSubnetDestroyExists, @@ -221,7 +238,11 @@ func testAccEC2DefaultSubnet_NotFound_basic(t *testing.T) { resourceName := "aws_default_subnet.test" resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetNotFound(t) }, + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckRegionNot(t, endpoints.UsWest2RegionID, endpoints.UsGovWest1RegionID) + testAccPreCheckDefaultSubnetNotFound(t) + }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultSubnetDestroyExists, @@ -261,7 +282,11 @@ func testAccEC2DefaultSubnet_NotFound_ipv6Native(t *testing.T) { resourceName := "aws_default_subnet.test" resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultSubnetNotFound(t) }, + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckRegionNot(t, endpoints.UsWest2RegionID, endpoints.UsGovWest1RegionID) + testAccPreCheckDefaultSubnetNotFound(t) + }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultSubnetDestroyNotFound, @@ -276,15 +301,15 @@ func testAccEC2DefaultSubnet_NotFound_ipv6Native(t *testing.T) { resource.TestCheckResourceAttrSet(resourceName, "availability_zone_id"), resource.TestCheckResourceAttr(resourceName, "cidr_block", ""), resource.TestCheckResourceAttr(resourceName, "customer_owned_ipv4_pool", ""), - resource.TestCheckResourceAttr(resourceName, "enable_dns64", "true"), + resource.TestCheckResourceAttr(resourceName, "enable_dns64", "false"), resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_aaaa_record_on_launch", "true"), resource.TestCheckResourceAttr(resourceName, "enable_resource_name_dns_a_record_on_launch", "false"), - resource.TestCheckResourceAttr(resourceName, "existing_default_subnet", "true"), + resource.TestCheckResourceAttr(resourceName, "existing_default_subnet", "false"), resource.TestCheckResourceAttr(resourceName, "force_destroy", "true"), resource.TestCheckResourceAttrSet(resourceName, "ipv6_cidr_block"), resource.TestCheckResourceAttr(resourceName, "ipv6_native", "true"), resource.TestCheckResourceAttr(resourceName, "map_customer_owned_ip_on_launch", "false"), - resource.TestCheckResourceAttr(resourceName, "map_public_ip_on_launch", "true"), + resource.TestCheckResourceAttr(resourceName, "map_public_ip_on_launch", "false"), resource.TestCheckResourceAttr(resourceName, "outpost_arn", ""), acctest.CheckResourceAttrAccountID(resourceName, "owner_id"), resource.TestCheckResourceAttrSet(resourceName, "private_dns_hostname_type_on_launch"), @@ -444,7 +469,7 @@ resource "aws_default_subnet" "test" { private_dns_hostname_type_on_launch = "ip-name" - # force-destroy so that the default VPC can have IPv6 disabled. + # force_destroy so that the default VPC can have IPv6 disabled. force_destroy = true depends_on = [aws_default_vpc.test] @@ -463,10 +488,11 @@ resource "aws_default_subnet" "test" { assign_ipv6_address_on_creation = true ipv6_native = true + map_public_ip_on_launch = false enable_resource_name_dns_aaaa_record_on_launch = true - # force-destroy so that the default VPC can have IPv6 disabled. + # force_destroy so that the default VPC can have IPv6 disabled. force_destroy = true depends_on = [aws_default_vpc.test] diff --git a/internal/service/ec2/default_vpc_test.go b/internal/service/ec2/default_vpc_test.go index eb04a72430b..de454c920c0 100644 --- a/internal/service/ec2/default_vpc_test.go +++ b/internal/service/ec2/default_vpc_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/service/ec2" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -82,7 +83,11 @@ func testAccEC2DefaultVPC_Existing_basic(t *testing.T) { resourceName := "aws_default_vpc.test" resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCExists(t) }, + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckRegionNot(t, endpoints.UsWest2RegionID, endpoints.UsGovWest1RegionID) + testAccPreCheckDefaultVPCExists(t) + }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultVPCDestroyExists, @@ -125,7 +130,11 @@ func testAccEC2DefaultVPC_Existing_assignGeneratedIPv6CIDRBlock(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCExists(t) }, + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckRegionNot(t, endpoints.UsWest2RegionID, endpoints.UsGovWest1RegionID) + testAccPreCheckDefaultVPCExists(t) + }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultVPCDestroyExists, @@ -168,7 +177,11 @@ func testAccEC2DefaultVPC_Existing_forceDestroy(t *testing.T) { resourceName := "aws_default_vpc.test" resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCExists(t) }, + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckRegionNot(t, endpoints.UsWest2RegionID, endpoints.UsGovWest1RegionID) + testAccPreCheckDefaultVPCExists(t) + }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultVPCDestroyNotFound, @@ -191,7 +204,11 @@ func testAccEC2DefaultVPC_NotFound_basic(t *testing.T) { resourceName := "aws_default_vpc.test" resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCNotFound(t) }, + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckRegionNot(t, endpoints.UsWest2RegionID, endpoints.UsGovWest1RegionID) + testAccPreCheckDefaultVPCNotFound(t) + }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultVPCDestroyExists, @@ -234,7 +251,11 @@ func testAccEC2DefaultVPC_NotFound_assignGeneratedIPv6CIDRBlock(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCNotFound(t) }, + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckRegionNot(t, endpoints.UsWest2RegionID, endpoints.UsGovWest1RegionID) + testAccPreCheckDefaultVPCNotFound(t) + }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultVPCDestroyExists, @@ -277,7 +298,11 @@ func testAccEC2DefaultVPC_NotFound_forceDestroy(t *testing.T) { resourceName := "aws_default_vpc.test" resource.Test(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckDefaultVPCNotFound(t) }, + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckRegionNot(t, endpoints.UsWest2RegionID, endpoints.UsGovWest1RegionID) + testAccPreCheckDefaultVPCNotFound(t) + }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, CheckDestroy: testAccCheckDefaultVPCDestroyNotFound, From b6024431eee287a014c97dd947882d128d7a2b5a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 21 Jan 2022 14:05:58 -0500 Subject: [PATCH 049/116] Documentation updates. --- website/docs/r/default_subnet.html.markdown | 34 ++++++------ website/docs/r/default_vpc.html.markdown | 59 ++++++--------------- 2 files changed, 32 insertions(+), 61 deletions(-) diff --git a/website/docs/r/default_subnet.html.markdown b/website/docs/r/default_subnet.html.markdown index 719b3e24900..40333fffc8b 100644 --- a/website/docs/r/default_subnet.html.markdown +++ b/website/docs/r/default_subnet.html.markdown @@ -3,16 +3,19 @@ subcategory: "VPC" layout: "aws" page_title: "AWS: aws_default_subnet" description: |- - Manage a default VPC subnet resource. + Manage a default subnet resource. --- # Resource: aws_default_subnet -Provides a resource to manage a [default AWS VPC subnet](http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/default-vpc.html#default-vpc-basics) in the current region. +Provides a resource to manage a [default subnet](http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/default-vpc.html#default-vpc-basics) in the current region. -The `aws_default_subnet` behaves differently from normal resources, in that Terraform does not _create_ this resource but instead "adopts" it into management. +**This is an advanced resource** and has special caveats to be aware of when using it. Please read this document in its entirety before using this resource. -The `aws_default_subnet` resource allows you to manage a region's default VPC subnet but Terraform cannot destroy it. Removing this resource from your configuration will remove it from your statefile and Terraform management. +The `aws_default_subnet` resource behaves differently from normal resources in that if a default subnet exists in the specified Availability Zone, Terraform does not _create_ this resource, but instead "adopts" it into management. +If no default subnet exists, Terraform creates a new default subnet. +By default, `terraform destroy` does not delete the default subnet but does remove the resource from Terraform state. +Set the `force_destroy` argument to `true` to delete the default subnet. ## Example Usage @@ -28,28 +31,23 @@ resource "aws_default_subnet" "default_az1" { ## Argument Reference -The following argument is required: +The arguments of an `aws_default_subnet` differ slightly from those of [`aws_subnet`](subnet.html): -* `availability_zone`- (Required) AZ for the subnet. +* `availability_zone` is required +* The `availability_zone_id`, `cidr_block` and `vpc_id` arguments become computed attributes +* The default value for `map_public_ip_on_launch` is `true` -The following arguments are optional: +The following additional arguments are supported: -* `map_public_ip_on_launch` - (Optional) Whether instances launched into the subnet should be assigned a public IP address. -* `tags` - (Optional) Map of tags to assign to the resource. +* `force_destroy` - (Optional) Whether destroying the resource deletes the default subnet. Default: `false` ## Attributes Reference In addition to all arguments above, the following attributes are exported: -* `arn` - ARN for the subnet. -* `assign_ipv6_address_on_creation` - Whether IPv6 addresses are assigned on creation. -* `availability_zone_id`- AZ ID of the subnet. -* `cidr_block` - CIDR block for the subnet. -* `id` - ID of the subnet -* `ipv6_association_id` - Association ID for the IPv6 CIDR block. -* `ipv6_cidr_block` - IPv6 CIDR block. -* `owner_id` - ID of the AWS account that owns the subnet. -* `vpc_id` - VPC ID. +* `availability_zone_id` - The AZ ID of the subnet +* `cidr_block` - The IPv4 CIDR block assigned to the subnet +* `vpc_id` - The ID of the VPC the subnet is in ## Import diff --git a/website/docs/r/default_vpc.html.markdown b/website/docs/r/default_vpc.html.markdown index 26030ae3f2f..9782836acaa 100644 --- a/website/docs/r/default_vpc.html.markdown +++ b/website/docs/r/default_vpc.html.markdown @@ -3,21 +3,22 @@ subcategory: "VPC" layout: "aws" page_title: "AWS: aws_default_vpc" description: |- - Manage the default VPC resource. + Manage a default VPC resource. --- # Resource: aws_default_vpc Provides a resource to manage the [default AWS VPC](http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/default-vpc.html) -in the current region. +in the current AWS Region. -For AWS accounts created after 2013-12-04, each region comes with a Default VPC. -**This is an advanced resource**, and has special caveats to be aware of when -using it. Please read this document in its entirety before using this resource. +If you created your AWS account after 2013-12-04 you have a default VPC in each AWS Region. -The `aws_default_vpc` behaves differently from normal resources, in that -Terraform does not _create_ this resource, but instead "adopts" it -into management. +**This is an advanced resource** and has special caveats to be aware of when using it. Please read this document in its entirety before using this resource. + +The `aws_default_vpc` resource behaves differently from normal resources in that if a default VPC exists, Terraform does not _create_ this resource, but instead "adopts" it into management. +If no default VPC exists, Terraform creates a new default VPC, which leads to the implicit creation of [other resources](https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html#default-vpc-components). +By default, `terraform destroy` does not delete the default VPC but does remove the resource from Terraform state. +Set the `force_destroy` argument to `true` to delete the default VPC. ## Example Usage @@ -33,49 +34,21 @@ resource "aws_default_vpc" "default" { ## Argument Reference -The arguments of an `aws_default_vpc` differ slightly from `aws_vpc` -resources. Namely, the `cidr_block`, `instance_tenancy` and `assign_generated_ipv6_cidr_block` -arguments are computed. The following arguments are still supported: +The arguments of an `aws_default_vpc` differ slightly from those of [`aws_vpc`](vpc.html): -* `enable_dns_support` - (Optional) A boolean flag to enable/disable DNS support in the VPC. Defaults true. -* `enable_dns_hostnames` - (Optional) A boolean flag to enable/disable DNS hostnames in the VPC. Defaults false. -* `enable_classiclink` - (Optional) A boolean flag to enable/disable ClassicLink - for the VPC. Only valid in regions and accounts that support EC2 Classic. - See the [ClassicLink documentation][1] for more information. Defaults false. -* `tags` - (Optional) A map of tags to assign to the resource. +* The `cidr_block` and `instance_tenancy` arguments become computed attributes +* The default value for `enable_dns_hostnames` is `true` -### Removing `aws_default_vpc` from your configuration +The following additional arguments are supported: -The `aws_default_vpc` resource allows you to manage a region's default VPC, -but Terraform cannot destroy it. Removing this resource from your configuration -will remove it from your statefile and management, but will not destroy the VPC. -You can resume managing the VPC via the AWS Console. +* `force_destroy` - (Optional) Whether destroying the resource deletes the default VPC. Default: `false` ## Attributes Reference In addition to all arguments above, the following attributes are exported: -* `arn` - Amazon Resource Name (ARN) of VPC -* `id` - The ID of the VPC -* `cidr_block` - The CIDR block of the VPC -* `instance_tenancy` - Tenancy of instances spin up within VPC. -* `enable_dns_support` - Whether or not the VPC has DNS support -* `enable_dns_hostnames` - Whether or not the VPC has DNS hostname support -* `enable_classiclink` - Whether or not the VPC has Classiclink enabled -* `assign_generated_ipv6_cidr_block` - Whether or not an Amazon-provided IPv6 CIDR -block with a /56 prefix length for the VPC was assigned -* `main_route_table_id` - The ID of the main route table associated with - this VPC. Note that you can change a VPC's main route table by using an - [`aws_main_route_table_association`](/docs/providers/aws/r/main_route_table_association.html) -* `default_network_acl_id` - The ID of the network ACL created by default on VPC creation -* `default_security_group_id` - The ID of the security group created by default on VPC creation -* `default_route_table_id` - The ID of the route table created by default on VPC creation -* `ipv6_association_id` - The association ID for the IPv6 CIDR block of the VPC -* `ipv6_cidr_block` - The IPv6 CIDR block of the VPC -* `owner_id` - The ID of the AWS account that owns the VPC. - - -[1]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html +* `cidr_block` - The primary IPv4 CIDR block for the VPC +* `instance_tenancy` - The allowed tenancy of instances launched into the VPC ## Import From cccf81ca65b3c900ac2ccf4ea437be4d42d35845 Mon Sep 17 00:00:00 2001 From: Ben Dean Date: Thu, 22 Oct 2020 17:35:55 -0400 Subject: [PATCH 050/116] aws_vpn_connection resource's customer_gateway_configuration should be sensitive because the xml contains tunnel psk Signed-off-by: Ben Dean --- internal/service/ec2/vpn_connection.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/service/ec2/vpn_connection.go b/internal/service/ec2/vpn_connection.go index abce1fb2765..2db39599286 100644 --- a/internal/service/ec2/vpn_connection.go +++ b/internal/service/ec2/vpn_connection.go @@ -37,8 +37,9 @@ func ResourceVPNConnection() *schema.Resource { Computed: true, }, "customer_gateway_configuration": { - Type: schema.TypeString, - Computed: true, + Type: schema.TypeString, + Sensitive: true, + Computed: true, }, "customer_gateway_id": { Type: schema.TypeString, From dac007724ea5b652bb2cfd9ac400e5471e8b224e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 24 Jan 2022 07:59:31 -0500 Subject: [PATCH 051/116] Add CHANGELOG entry. --- .changelog/15806.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/15806.txt diff --git a/.changelog/15806.txt b/.changelog/15806.txt new file mode 100644 index 00000000000..78b8e24ec1a --- /dev/null +++ b/.changelog/15806.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_vpn_connection: Mark `customer_gateway_configuration` as [`Sensitive`](https://www.terraform.io/plugin/sdkv2/best-practices/sensitive-state#using-the-sensitive-flag) +``` \ No newline at end of file From 6f3726655630ca0f2c6449a84bf0e55e61a93244 Mon Sep 17 00:00:00 2001 From: Dchamard Date: Tue, 25 Jan 2022 08:01:24 -0800 Subject: [PATCH 052/116] Added data source 'aws_eips'. (#7537) Co-authored-by: David Chamard --- .changelog/7537.txt | 3 + internal/provider/provider.go | 1 + internal/service/ec2/eips_data_source.go | 76 +++++++++++++ internal/service/ec2/eips_data_source_test.go | 100 ++++++++++++++++++ internal/service/ec2/errors.go | 2 + internal/service/ec2/find.go | 25 +++++ website/docs/d/eips.html.markdown | 50 +++++++++ 7 files changed, 257 insertions(+) create mode 100644 .changelog/7537.txt create mode 100644 internal/service/ec2/eips_data_source.go create mode 100644 internal/service/ec2/eips_data_source_test.go create mode 100644 website/docs/d/eips.html.markdown diff --git a/.changelog/7537.txt b/.changelog/7537.txt new file mode 100644 index 00000000000..1cd879dd11e --- /dev/null +++ b/.changelog/7537.txt @@ -0,0 +1,3 @@ +```release-note:new-data-source +aws_eips +``` \ No newline at end of file diff --git a/internal/provider/provider.go b/internal/provider/provider.go index ddf46311474..95781614b62 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -474,6 +474,7 @@ func Provider() *schema.Provider { "aws_ec2_transit_gateway_vpc_attachment": ec2.DataSourceTransitGatewayVPCAttachment(), "aws_ec2_transit_gateway_vpn_attachment": ec2.DataSourceTransitGatewayVPNAttachment(), "aws_eip": ec2.DataSourceEIP(), + "aws_eips": ec2.DataSourceEIPs(), "aws_instance": ec2.DataSourceInstance(), "aws_instances": ec2.DataSourceInstances(), "aws_internet_gateway": ec2.DataSourceInternetGateway(), diff --git a/internal/service/ec2/eips_data_source.go b/internal/service/ec2/eips_data_source.go new file mode 100644 index 00000000000..9bfedc10694 --- /dev/null +++ b/internal/service/ec2/eips_data_source.go @@ -0,0 +1,76 @@ +package ec2 + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" +) + +func DataSourceEIPs() *schema.Resource { + return &schema.Resource{ + Read: dataSourceEIPsRead, + + Schema: map[string]*schema.Schema{ + "allocation_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "filter": DataSourceFiltersSchema(), + "public_ips": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "tags": tftags.TagsSchemaComputed(), + }, + } +} + +func dataSourceEIPsRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).EC2Conn + + input := &ec2.DescribeAddressesInput{} + + if tags, tagsOk := d.GetOk("tags"); tagsOk { + input.Filters = append(input.Filters, BuildTagFilterList( + Tags(tftags.New(tags.(map[string]interface{}))), + )...) + } + + if filters, filtersOk := d.GetOk("filter"); filtersOk { + input.Filters = append(input.Filters, + BuildFiltersDataSource(filters.(*schema.Set))...) + } + + if len(input.Filters) == 0 { + input.Filters = nil + } + + output, err := FindEIPs(conn, input) + + if err != nil { + return fmt.Errorf("error reading EC2 EIPs: %w", err) + } + + var allocationIDs []string + var publicIPs []string + + for _, v := range output { + if aws.StringValue(v.Domain) == ec2.DomainTypeVpc { + allocationIDs = append(allocationIDs, aws.StringValue(v.AllocationId)) + } else { + publicIPs = append(publicIPs, aws.StringValue(v.PublicIp)) + } + } + + d.SetId(meta.(*conns.AWSClient).Region) + d.Set("allocation_ids", allocationIDs) + d.Set("public_ips", publicIPs) + + return nil +} diff --git a/internal/service/ec2/eips_data_source_test.go b/internal/service/ec2/eips_data_source_test.go new file mode 100644 index 00000000000..108ae41d3c0 --- /dev/null +++ b/internal/service/ec2/eips_data_source_test.go @@ -0,0 +1,100 @@ +package ec2_test + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/ec2" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" +) + +func TestAccEC2EIPsDataSource_vpcDomain(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccEIPsVPCDomainDataSourceConfig(rName), + Check: resource.ComposeTestCheckFunc( + acctest.CheckResourceAttrGreaterThanValue("data.aws_eips.all", "allocation_ids.#", "1"), + resource.TestCheckResourceAttr("data.aws_eips.by_tags", "allocation_ids.#", "1"), + resource.TestCheckResourceAttr("data.aws_eips.by_tags", "public_ips.#", "0"), + resource.TestCheckResourceAttr("data.aws_eips.none", "allocation_ids.#", "0"), + resource.TestCheckResourceAttr("data.aws_eips.none", "public_ips.#", "0"), + ), + }, + }, + }) +} + +func TestAccEC2EIPsDataSource_standardDomain(t *testing.T) { + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); acctest.PreCheckEC2Classic(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccEIPsStandardDomainDataSourceConfig(), + Check: resource.ComposeTestCheckFunc( + acctest.CheckResourceAttrGreaterThanValue("data.aws_eips.all", "public_ips.#", "0"), + ), + }, + }, + }) +} + +func testAccEIPsVPCDomainDataSourceConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_eip" "test1" { + vpc = true + + tags = { + Name = "%[1]s-1" + } +} + +resource "aws_eip" "test2" { + vpc = true + + tags = { + Name = "%[1]s-2" + } +} + +data "aws_eips" "all" { + depends_on = [aws_eip.test1, aws_eip.test2] +} + +data "aws_eips" "by_tags" { + tags = { + Name = "%[1]s-1" + } + + depends_on = [aws_eip.test1, aws_eip.test2] +} + +data "aws_eips" "none" { + filter { + name = "tag-key" + values = ["%[1]s-3"] + } + + depends_on = [aws_eip.test1, aws_eip.test2] +} +`, rName) +} + +func testAccEIPsStandardDomainDataSourceConfig() string { + return acctest.ConfigCompose(acctest.ConfigEC2ClassicRegionProvider(), ` +resource "aws_eip" "test" {} + +data "aws_eips" "all" { + depends_on = [aws_eip.test] +} +`) +} diff --git a/internal/service/ec2/errors.go b/internal/service/ec2/errors.go index 1a1bde9e86f..d30d6e33e22 100644 --- a/internal/service/ec2/errors.go +++ b/internal/service/ec2/errors.go @@ -16,6 +16,8 @@ const ( ErrCodeDependencyViolation = "DependencyViolation" ErrCodeGatewayNotAttached = "Gateway.NotAttached" ErrCodeIncorrectState = "IncorrectState" + ErrCodeInvalidAddressNotFound = "InvalidAddress.NotFound" + ErrCodeInvalidAllocationIDNotFound = "InvalidAllocationID.NotFound" ErrCodeInvalidAssociationIDNotFound = "InvalidAssociationID.NotFound" ErrCodeInvalidAttachmentIDNotFound = "InvalidAttachmentID.NotFound" ErrCodeInvalidCarrierGatewayIDNotFound = "InvalidCarrierGatewayID.NotFound" diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index 179ad17e666..52467812eec 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -172,6 +172,31 @@ func FindClientVPNRouteByID(conn *ec2.EC2, routeID string) (*ec2.DescribeClientV return FindClientVPNRoute(conn, endpointID, targetSubnetID, destinationCidr) } +func FindEIPs(conn *ec2.EC2, input *ec2.DescribeAddressesInput) ([]*ec2.Address, error) { + var addresses []*ec2.Address + + output, err := conn.DescribeAddresses(input) + + if tfawserr.ErrCodeEquals(err, ErrCodeInvalidAddressNotFound, ErrCodeInvalidAllocationIDNotFound) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + for _, v := range output.Addresses { + if v != nil { + addresses = append(addresses, v) + } + } + + return addresses, nil +} + func FindHostByID(conn *ec2.EC2, id string) (*ec2.Host, error) { input := &ec2.DescribeHostsInput{ HostIds: aws.StringSlice([]string{id}), diff --git a/website/docs/d/eips.html.markdown b/website/docs/d/eips.html.markdown new file mode 100644 index 00000000000..e974cbf7e84 --- /dev/null +++ b/website/docs/d/eips.html.markdown @@ -0,0 +1,50 @@ +--- +subcategory: "VPC" +layout: "aws" +page_title: "AWS: aws_eips" +description: |- + Provides a list of Elastic IPs in a region +--- + +# Data Source: aws_eips + +Provides a list of Elastic IPs in a region. + +## Example Usage + +The following shows outputing all Elastic IPs with the a specific tag value. + +```terraform +data "aws_eips" "example" { + tags = { + Env = "dev" + } +} + +# VPC EIPs. +output "allocation_ids" { + value = data.aws_eips.example.allocation_ids +} + +# EC2-Classic EIPs. +output "public_ips" { + value = data.aws_eips.example.public_ips +} +``` + +## Argument Reference + +* `filter` - (Optional) Custom filter block as described below. +* `tags` - (Optional) A map of tags, each pair of which must exactly match a pair on the desired Elastic IPs. + +More complex filters can be expressed using one or more `filter` sub-blocks, which take the following arguments: + +* `name` - (Required) The name of the field to filter by, as defined by + [the underlying AWS API](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeAddresses.html). +* `values` - (Required) Set of values that are accepted for the given field. An Elastic IP will be selected if any one of the given values matches. + +## Attributes Reference + +* `id` - AWS Region. +* `allocation_ids` - A list of all the allocation IDs for address for use with EC2-VPC. +* `public_ips` - A list of all the Elastic IP addresses for use with EC2-Classic. From 0f2112077908b2ee0e7e42a0d549d68731906296 Mon Sep 17 00:00:00 2001 From: Stephen Hoekstra Date: Wed, 26 Jan 2022 15:23:10 +0100 Subject: [PATCH 053/116] Add default values to aws_vpn_connection (#17031) * Add default values to aws_vpn_connection This fixes a bug where removing fields from the resource should revert them to their default value, but instead sets them to their empty value (in this case 0). When this happens the provider attempts to use these 0 values to update the VPN connection which results in an error, forcing the user to specify these fields and their default values. Signed-off-by: Stephen Hoekstra --- .changelog/17031.txt | 3 + internal/service/ec2/enum.go | 102 +++++ internal/service/ec2/vpn_connection.go | 416 ++++++++++++++------ internal/service/ec2/vpn_connection_test.go | 84 ++-- 4 files changed, 458 insertions(+), 147 deletions(-) create mode 100644 .changelog/17031.txt diff --git a/.changelog/17031.txt b/.changelog/17031.txt new file mode 100644 index 00000000000..3d63f7be1cb --- /dev/null +++ b/.changelog/17031.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_vpn_connection: Add the ability to revert changes to unconfigured tunnel options made outside of Terraform to their (documented default values)[(https://docs.aws.amazon.com/vpn/latest/s2svpn/VPNTunnels.html)] +``` \ No newline at end of file diff --git a/internal/service/ec2/enum.go b/internal/service/ec2/enum.go index 468f225cea4..da23215e138 100644 --- a/internal/service/ec2/enum.go +++ b/internal/service/ec2/enum.go @@ -58,6 +58,108 @@ const ( CustomerGatewayStatePending = "pending" ) +const ( + VpnTunnelOptionsDPDTimeoutActionClear = "clear" + VpnTunnelOptionsDPDTimeoutActionNone = "none" + VpnTunnelOptionsDPDTimeoutActionRestart = "restart" +) + +func VpnTunnelOptionsDPDTimeoutAction_Values() []string { + return []string{ + VpnTunnelOptionsDPDTimeoutActionClear, + VpnTunnelOptionsDPDTimeoutActionNone, + VpnTunnelOptionsDPDTimeoutActionRestart, + } +} + +const ( + VpnTunnelOptionsIKEVersion1 = "ikev1" + VpnTunnelOptionsIKEVersion2 = "ikev2" +) + +func VpnTunnelOptionsIKEVersion_Values() []string { + return []string{ + VpnTunnelOptionsIKEVersion1, + VpnTunnelOptionsIKEVersion2, + } +} + +const ( + VpnTunnelOptionsPhase1EncryptionAlgorithmAES128 = "AES128" + VpnTunnelOptionsPhase1EncryptionAlgorithmAES256 = "AES256" + VpnTunnelOptionsPhase1EncryptionAlgorithmAES128_GCM_16 = "AES128-GCM-16" + VpnTunnelOptionsPhase1EncryptionAlgorithmAES256_GCM_16 = "AES256-GCM-16" +) + +func VpnTunnelOptionsPhase1EncryptionAlgorithm_Values() []string { + return []string{ + VpnTunnelOptionsPhase1EncryptionAlgorithmAES128, + VpnTunnelOptionsPhase1EncryptionAlgorithmAES256, + VpnTunnelOptionsPhase1EncryptionAlgorithmAES128_GCM_16, + VpnTunnelOptionsPhase1EncryptionAlgorithmAES256_GCM_16, + } +} + +const ( + VpnTunnelOptionsPhase1IntegrityAlgorithmSHA1 = "SHA1" + VpnTunnelOptionsPhase1IntegrityAlgorithmSHA2_256 = "SHA2-256" + VpnTunnelOptionsPhase1IntegrityAlgorithmSHA2_384 = "SHA2-384" + VpnTunnelOptionsPhase1IntegrityAlgorithmSHA2_512 = "SHA2-512" +) + +func VpnTunnelOptionsPhase1IntegrityAlgorithm_Values() []string { + return []string{ + VpnTunnelOptionsPhase1IntegrityAlgorithmSHA1, + VpnTunnelOptionsPhase1IntegrityAlgorithmSHA2_256, + VpnTunnelOptionsPhase1IntegrityAlgorithmSHA2_384, + VpnTunnelOptionsPhase1IntegrityAlgorithmSHA2_512, + } +} + +const ( + VpnTunnelOptionsPhase2EncryptionAlgorithmAES128 = "AES128" + VpnTunnelOptionsPhase2EncryptionAlgorithmAES256 = "AES256" + VpnTunnelOptionsPhase2EncryptionAlgorithmAES128_GCM_16 = "AES128-GCM-16" + VpnTunnelOptionsPhase2EncryptionAlgorithmAES256_GCM_16 = "AES256-GCM-16" +) + +func VpnTunnelOptionsPhase2EncryptionAlgorithm_Values() []string { + return []string{ + VpnTunnelOptionsPhase2EncryptionAlgorithmAES128, + VpnTunnelOptionsPhase2EncryptionAlgorithmAES256, + VpnTunnelOptionsPhase2EncryptionAlgorithmAES128_GCM_16, + VpnTunnelOptionsPhase2EncryptionAlgorithmAES256_GCM_16, + } +} + +const ( + VpnTunnelOptionsPhase2IntegrityAlgorithmSHA1 = "SHA1" + VpnTunnelOptionsPhase2IntegrityAlgorithmSHA2_256 = "SHA2-256" + VpnTunnelOptionsPhase2IntegrityAlgorithmSHA2_384 = "SHA2-384" + VpnTunnelOptionsPhase2IntegrityAlgorithmSHA2_512 = "SHA2-512" +) + +func VpnTunnelOptionsPhase2IntegrityAlgorithm_Values() []string { + return []string{ + VpnTunnelOptionsPhase2IntegrityAlgorithmSHA1, + VpnTunnelOptionsPhase2IntegrityAlgorithmSHA2_256, + VpnTunnelOptionsPhase2IntegrityAlgorithmSHA2_384, + VpnTunnelOptionsPhase2IntegrityAlgorithmSHA2_512, + } +} + +const ( + VpnTunnelOptionsStartupActionAdd = "add" + VpnTunnelOptionsStartupActionStart = "start" +) + +func VpnTunnelOptionsStartupAction_Values() []string { + return []string{ + VpnTunnelOptionsStartupActionAdd, + VpnTunnelOptionsStartupActionStart, + } +} + const ( VpnConnectionTypeIpsec1 = "ipsec.1" ) diff --git a/internal/service/ec2/vpn_connection.go b/internal/service/ec2/vpn_connection.go index 2db39599286..ceaf071d9bb 100644 --- a/internal/service/ec2/vpn_connection.go +++ b/internal/service/ec2/vpn_connection.go @@ -7,6 +7,7 @@ import ( "net" "regexp" "sort" + "strconv" "time" "github.com/aws/aws-sdk-go/aws" @@ -56,26 +57,26 @@ func ResourceVPNConnection() *schema.Resource { Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: validateLocalIpv4NetworkCidr(), + ValidateFunc: validation.IsCIDRNetwork(0, 32), }, "local_ipv6_network_cidr": { Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: validateLocalIpv6NetworkCidr(), + ValidateFunc: validation.IsCIDRNetwork(0, 128), RequiredWith: []string{"transit_gateway_id"}, }, "remote_ipv4_network_cidr": { Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: validateLocalIpv4NetworkCidr(), + ValidateFunc: validation.IsCIDRNetwork(0, 32), }, "remote_ipv6_network_cidr": { Type: schema.TypeString, Optional: true, Computed: true, - ValidateFunc: validateLocalIpv6NetworkCidr(), + ValidateFunc: validation.IsCIDRNetwork(0, 128), RequiredWith: []string{"transit_gateway_id"}, }, "routes": { @@ -141,17 +142,32 @@ func ResourceVPNConnection() *schema.Resource { "tunnel1_dpd_timeout_action": { Type: schema.TypeString, Optional: true, - ValidateFunc: validateVpnConnectionTunnelDpdTimeoutAction(), + ValidateFunc: validation.StringInSlice(VpnTunnelOptionsDPDTimeoutAction_Values(), false), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == defaultVpnTunnelOptionsDPDTimeoutAction && new == "" { + return true + } + return false + }, }, "tunnel1_dpd_timeout_seconds": { Type: schema.TypeInt, Optional: true, - ValidateFunc: validateVpnConnectionTunnelDpdTimeoutSeconds(), + ValidateFunc: validation.IntAtLeast(30), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == strconv.Itoa(defaultVpnTunnelOptionsDPDTimeoutSeconds) && new == "0" { + return true + } + return false + }, }, "tunnel1_ike_versions": { Type: schema.TypeSet, Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice(VpnTunnelOptionsIKEVersion_Values(), false), + }, }, "tunnel1_inside_cidr": { Type: schema.TypeString, @@ -176,17 +192,29 @@ func ResourceVPNConnection() *schema.Resource { "tunnel1_phase1_encryption_algorithms": { Type: schema.TypeSet, Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice(VpnTunnelOptionsPhase1EncryptionAlgorithm_Values(), false), + }, }, "tunnel1_phase1_integrity_algorithms": { Type: schema.TypeSet, Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice(VpnTunnelOptionsPhase1IntegrityAlgorithm_Values(), false), + }, }, "tunnel1_phase1_lifetime_seconds": { Type: schema.TypeInt, Optional: true, - ValidateFunc: validateVpnConnectionTunnelPhase1LifetimeSeconds(), + ValidateFunc: validation.IntBetween(900, 28800), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == strconv.Itoa(defaultVpnTunnelOptionsPhase1LifetimeSeconds) && new == "0" { + return true + } + return false + }, }, "tunnel1_phase2_dh_group_numbers": { Type: schema.TypeSet, @@ -196,17 +224,29 @@ func ResourceVPNConnection() *schema.Resource { "tunnel1_phase2_encryption_algorithms": { Type: schema.TypeSet, Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice(VpnTunnelOptionsPhase2EncryptionAlgorithm_Values(), false), + }, }, "tunnel1_phase2_integrity_algorithms": { Type: schema.TypeSet, Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice(VpnTunnelOptionsPhase2IntegrityAlgorithm_Values(), false), + }, }, "tunnel1_phase2_lifetime_seconds": { Type: schema.TypeInt, Optional: true, - ValidateFunc: validateVpnConnectionTunnelPhase2LifetimeSeconds(), + ValidateFunc: validation.IntBetween(900, 3600), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == strconv.Itoa(defaultVpnTunnelOptionsPhase2LifetimeSeconds) && new == "0" { + return true + } + return false + }, }, "tunnel1_preshared_key": { Type: schema.TypeString, @@ -218,22 +258,46 @@ func ResourceVPNConnection() *schema.Resource { "tunnel1_rekey_fuzz_percentage": { Type: schema.TypeInt, Optional: true, - ValidateFunc: validateVpnConnectionTunnelRekeyFuzzPercentage(), + ValidateFunc: validation.IntBetween(0, 100), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == strconv.Itoa(defaultVpnTunnelOptionsRekeyFuzzPercentage) && new == "0" { + return true + } + return false + }, }, "tunnel1_rekey_margin_time_seconds": { Type: schema.TypeInt, Optional: true, - ValidateFunc: validateVpnConnectionTunnelRekeyMarginTimeSeconds(), + ValidateFunc: validation.IntBetween(60, 1800), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == strconv.Itoa(defaultVpnTunnelOptionsRekeyMarginTimeSeconds) && new == "0" { + return true + } + return false + }, }, "tunnel1_replay_window_size": { Type: schema.TypeInt, Optional: true, - ValidateFunc: validateVpnConnectionTunnelReplayWindowSize(), + ValidateFunc: validation.IntBetween(64, 2048), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == strconv.Itoa(defaultVpnTunnelOptionsReplayWindowSize) && new == "0" { + return true + } + return false + }, }, "tunnel1_startup_action": { Type: schema.TypeString, Optional: true, - ValidateFunc: validateVpnConnectionTunnelStartupAction(), + ValidateFunc: validation.StringInSlice(VpnTunnelOptionsStartupAction_Values(), false), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == defaultVpnTunnelOptionsStartupAction && new == "" { + return true + } + return false + }, }, "tunnel1_vgw_inside_address": { Type: schema.TypeString, @@ -258,17 +322,32 @@ func ResourceVPNConnection() *schema.Resource { "tunnel2_dpd_timeout_action": { Type: schema.TypeString, Optional: true, - ValidateFunc: validateVpnConnectionTunnelDpdTimeoutAction(), + ValidateFunc: validation.StringInSlice(VpnTunnelOptionsDPDTimeoutAction_Values(), false), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == defaultVpnTunnelOptionsDPDTimeoutAction && new == "" { + return true + } + return false + }, }, "tunnel2_dpd_timeout_seconds": { Type: schema.TypeInt, Optional: true, - ValidateFunc: validateVpnConnectionTunnelDpdTimeoutSeconds(), + ValidateFunc: validation.IntAtLeast(30), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == strconv.Itoa(defaultVpnTunnelOptionsDPDTimeoutSeconds) && new == "0" { + return true + } + return false + }, }, "tunnel2_ike_versions": { Type: schema.TypeSet, Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice(VpnTunnelOptionsIKEVersion_Values(), false), + }, }, "tunnel2_inside_cidr": { Type: schema.TypeString, @@ -293,17 +372,29 @@ func ResourceVPNConnection() *schema.Resource { "tunnel2_phase1_encryption_algorithms": { Type: schema.TypeSet, Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice(VpnTunnelOptionsPhase1EncryptionAlgorithm_Values(), false), + }, }, "tunnel2_phase1_integrity_algorithms": { Type: schema.TypeSet, Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice(VpnTunnelOptionsPhase1IntegrityAlgorithm_Values(), false), + }, }, "tunnel2_phase1_lifetime_seconds": { Type: schema.TypeInt, Optional: true, - ValidateFunc: validateVpnConnectionTunnelPhase1LifetimeSeconds(), + ValidateFunc: validation.IntBetween(900, 28800), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == strconv.Itoa(defaultVpnTunnelOptionsPhase1LifetimeSeconds) && new == "0" { + return true + } + return false + }, }, "tunnel2_phase2_dh_group_numbers": { Type: schema.TypeSet, @@ -313,17 +404,29 @@ func ResourceVPNConnection() *schema.Resource { "tunnel2_phase2_encryption_algorithms": { Type: schema.TypeSet, Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice(VpnTunnelOptionsPhase2EncryptionAlgorithm_Values(), false), + }, }, "tunnel2_phase2_integrity_algorithms": { Type: schema.TypeSet, Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice(VpnTunnelOptionsPhase2IntegrityAlgorithm_Values(), false), + }, }, "tunnel2_phase2_lifetime_seconds": { Type: schema.TypeInt, Optional: true, - ValidateFunc: validateVpnConnectionTunnelPhase2LifetimeSeconds(), + ValidateFunc: validation.IntBetween(900, 3600), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == strconv.Itoa(defaultVpnTunnelOptionsPhase2LifetimeSeconds) && new == "0" { + return true + } + return false + }, }, "tunnel2_preshared_key": { Type: schema.TypeString, @@ -335,22 +438,46 @@ func ResourceVPNConnection() *schema.Resource { "tunnel2_rekey_fuzz_percentage": { Type: schema.TypeInt, Optional: true, - ValidateFunc: validateVpnConnectionTunnelRekeyFuzzPercentage(), + ValidateFunc: validation.IntBetween(0, 100), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == strconv.Itoa(defaultVpnTunnelOptionsRekeyFuzzPercentage) && new == "0" { + return true + } + return false + }, }, "tunnel2_rekey_margin_time_seconds": { Type: schema.TypeInt, Optional: true, - ValidateFunc: validateVpnConnectionTunnelRekeyMarginTimeSeconds(), + ValidateFunc: validation.IntBetween(60, 1800), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == strconv.Itoa(defaultVpnTunnelOptionsRekeyMarginTimeSeconds) && new == "0" { + return true + } + return false + }, }, "tunnel2_replay_window_size": { Type: schema.TypeInt, Optional: true, - ValidateFunc: validateVpnConnectionTunnelReplayWindowSize(), + ValidateFunc: validation.IntBetween(64, 2048), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == strconv.Itoa(defaultVpnTunnelOptionsReplayWindowSize) && new == "0" { + return true + } + return false + }, }, "tunnel2_startup_action": { Type: schema.TypeString, Optional: true, - ValidateFunc: validateVpnConnectionTunnelStartupAction(), + ValidateFunc: validation.StringInSlice(VpnTunnelOptionsStartupAction_Values(), false), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == defaultVpnTunnelOptionsStartupAction && new == "" { + return true + } + return false + }, }, "tunnel2_vgw_inside_address": { Type: schema.TypeString, @@ -405,6 +532,45 @@ func ResourceVPNConnection() *schema.Resource { } } +// https://docs.aws.amazon.com/vpn/latest/s2svpn/VPNTunnels.html. +var ( + defaultVpnTunnelOptionsDPDTimeoutAction = VpnTunnelOptionsDPDTimeoutActionClear + defaultVpnTunnelOptionsDPDTimeoutSeconds = 30 + defaultVpnTunnelOptionsIKEVersions = []string{VpnTunnelOptionsIKEVersion1, VpnTunnelOptionsIKEVersion2} + defaultVpnTunnelOptionsPhase1DHGroupNumbers = []int{2, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24} + defaultVpnTunnelOptionsPhase1EncryptionAlgorithms = []string{ + VpnTunnelOptionsPhase1EncryptionAlgorithmAES128, + VpnTunnelOptionsPhase1EncryptionAlgorithmAES256, + VpnTunnelOptionsPhase1EncryptionAlgorithmAES128_GCM_16, + VpnTunnelOptionsPhase1EncryptionAlgorithmAES256_GCM_16, + } + defaultVpnTunnelOptionsPhase1IntegrityAlgorithms = []string{ + VpnTunnelOptionsPhase1IntegrityAlgorithmSHA1, + VpnTunnelOptionsPhase1IntegrityAlgorithmSHA2_256, + VpnTunnelOptionsPhase1IntegrityAlgorithmSHA2_384, + VpnTunnelOptionsPhase1IntegrityAlgorithmSHA2_512, + } + defaultVpnTunnelOptionsPhase1LifetimeSeconds = 28800 + defaultVpnTunnelOptionsPhase2DHGroupNumbers = []int{2, 5, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24} + defaultVpnTunnelOptionsPhase2EncryptionAlgorithms = []string{ + VpnTunnelOptionsPhase2EncryptionAlgorithmAES128, + VpnTunnelOptionsPhase2EncryptionAlgorithmAES256, + VpnTunnelOptionsPhase2EncryptionAlgorithmAES128_GCM_16, + VpnTunnelOptionsPhase2EncryptionAlgorithmAES256_GCM_16, + } + defaultVpnTunnelOptionsPhase2IntegrityAlgorithms = []string{ + VpnTunnelOptionsPhase2IntegrityAlgorithmSHA1, + VpnTunnelOptionsPhase2IntegrityAlgorithmSHA2_256, + VpnTunnelOptionsPhase2IntegrityAlgorithmSHA2_384, + VpnTunnelOptionsPhase2IntegrityAlgorithmSHA2_512, + } + defaultVpnTunnelOptionsPhase2LifetimeSeconds = 3600 + defaultVpnTunnelOptionsRekeyFuzzPercentage = 100 + defaultVpnTunnelOptionsRekeyMarginTimeSeconds = 540 + defaultVpnTunnelOptionsReplayWindowSize = 1024 + defaultVpnTunnelOptionsStartupAction = VpnTunnelOptionsStartupActionAdd +) + func resourceVPNConnectionCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig @@ -837,81 +1003,139 @@ func expandModifyVpnTunnelOptionsSpecification(d *schema.ResourceData, prefix st hasChange := false if key := prefix + "dpd_timeout_action"; d.HasChange(key) { - apiObject.DPDTimeoutAction = aws.String(d.Get(key).(string)) + if v, ok := d.GetOk(key); ok { + apiObject.DPDTimeoutAction = aws.String(v.(string)) + } else { + apiObject.DPDTimeoutAction = aws.String(defaultVpnTunnelOptionsDPDTimeoutAction) + } hasChange = true } if key := prefix + "dpd_timeout_seconds"; d.HasChange(key) { - apiObject.DPDTimeoutSeconds = aws.Int64(int64(d.Get(key).(int))) + if v, ok := d.GetOk(key); ok { + apiObject.DPDTimeoutSeconds = aws.Int64(int64(v.(int))) + } else { + apiObject.DPDTimeoutSeconds = aws.Int64(int64(defaultVpnTunnelOptionsDPDTimeoutSeconds)) + } hasChange = true } if key := prefix + "ike_versions"; d.HasChange(key) { - for _, v := range d.Get(key).(*schema.Set).List() { - apiObject.IKEVersions = append(apiObject.IKEVersions, &ec2.IKEVersionsRequestListValue{Value: aws.String(v.(string))}) + if v, ok := d.GetOk(key); ok && v.(*schema.Set).Len() > 0 { + for _, v := range d.Get(key).(*schema.Set).List() { + apiObject.IKEVersions = append(apiObject.IKEVersions, &ec2.IKEVersionsRequestListValue{Value: aws.String(v.(string))}) + } + } else { + for _, v := range defaultVpnTunnelOptionsIKEVersions { + apiObject.IKEVersions = append(apiObject.IKEVersions, &ec2.IKEVersionsRequestListValue{Value: aws.String(v)}) + } } hasChange = true } if key := prefix + "phase1_dh_group_numbers"; d.HasChange(key) { - for _, v := range d.Get(key).(*schema.Set).List() { - apiObject.Phase1DHGroupNumbers = append(apiObject.Phase1DHGroupNumbers, &ec2.Phase1DHGroupNumbersRequestListValue{Value: aws.Int64(int64(v.(int)))}) + if v, ok := d.GetOk(key); ok && v.(*schema.Set).Len() > 0 { + for _, v := range d.Get(key).(*schema.Set).List() { + apiObject.Phase1DHGroupNumbers = append(apiObject.Phase1DHGroupNumbers, &ec2.Phase1DHGroupNumbersRequestListValue{Value: aws.Int64(int64(v.(int)))}) + } + } else { + for _, v := range defaultVpnTunnelOptionsPhase1DHGroupNumbers { + apiObject.Phase1DHGroupNumbers = append(apiObject.Phase1DHGroupNumbers, &ec2.Phase1DHGroupNumbersRequestListValue{Value: aws.Int64(int64(v))}) + } } hasChange = true } if key := prefix + "phase1_encryption_algorithms"; d.HasChange(key) { - for _, v := range d.Get(key).(*schema.Set).List() { - apiObject.Phase1EncryptionAlgorithms = append(apiObject.Phase1EncryptionAlgorithms, &ec2.Phase1EncryptionAlgorithmsRequestListValue{Value: aws.String(v.(string))}) + if v, ok := d.GetOk(key); ok && v.(*schema.Set).Len() > 0 { + for _, v := range d.Get(key).(*schema.Set).List() { + apiObject.Phase1EncryptionAlgorithms = append(apiObject.Phase1EncryptionAlgorithms, &ec2.Phase1EncryptionAlgorithmsRequestListValue{Value: aws.String(v.(string))}) + } + } else { + for _, v := range defaultVpnTunnelOptionsPhase1EncryptionAlgorithms { + apiObject.Phase1EncryptionAlgorithms = append(apiObject.Phase1EncryptionAlgorithms, &ec2.Phase1EncryptionAlgorithmsRequestListValue{Value: aws.String(v)}) + } } hasChange = true } if key := prefix + "phase1_integrity_algorithms"; d.HasChange(key) { - for _, v := range d.Get(key).(*schema.Set).List() { - apiObject.Phase1IntegrityAlgorithms = append(apiObject.Phase1IntegrityAlgorithms, &ec2.Phase1IntegrityAlgorithmsRequestListValue{Value: aws.String(v.(string))}) + if v, ok := d.GetOk(key); ok && v.(*schema.Set).Len() > 0 { + for _, v := range d.Get(key).(*schema.Set).List() { + apiObject.Phase1IntegrityAlgorithms = append(apiObject.Phase1IntegrityAlgorithms, &ec2.Phase1IntegrityAlgorithmsRequestListValue{Value: aws.String(v.(string))}) + } + } else { + for _, v := range defaultVpnTunnelOptionsPhase1IntegrityAlgorithms { + apiObject.Phase1IntegrityAlgorithms = append(apiObject.Phase1IntegrityAlgorithms, &ec2.Phase1IntegrityAlgorithmsRequestListValue{Value: aws.String(v)}) + } } hasChange = true } if key := prefix + "phase1_lifetime_seconds"; d.HasChange(key) { - apiObject.Phase1LifetimeSeconds = aws.Int64(int64(d.Get(key).(int))) + if v, ok := d.GetOk(key); ok { + apiObject.Phase1LifetimeSeconds = aws.Int64(int64(v.(int))) + } else { + apiObject.Phase1LifetimeSeconds = aws.Int64(int64(defaultVpnTunnelOptionsPhase1LifetimeSeconds)) + } hasChange = true } if key := prefix + "phase2_dh_group_numbers"; d.HasChange(key) { - for _, v := range d.Get(key).(*schema.Set).List() { - apiObject.Phase2DHGroupNumbers = append(apiObject.Phase2DHGroupNumbers, &ec2.Phase2DHGroupNumbersRequestListValue{Value: aws.Int64(int64(v.(int)))}) + if v, ok := d.GetOk(key); ok && v.(*schema.Set).Len() > 0 { + for _, v := range d.Get(key).(*schema.Set).List() { + apiObject.Phase2DHGroupNumbers = append(apiObject.Phase2DHGroupNumbers, &ec2.Phase2DHGroupNumbersRequestListValue{Value: aws.Int64(int64(v.(int)))}) + } + } else { + for _, v := range defaultVpnTunnelOptionsPhase2DHGroupNumbers { + apiObject.Phase2DHGroupNumbers = append(apiObject.Phase2DHGroupNumbers, &ec2.Phase2DHGroupNumbersRequestListValue{Value: aws.Int64(int64(v))}) + } } hasChange = true } if key := prefix + "phase2_encryption_algorithms"; d.HasChange(key) { - for _, v := range d.Get(key).(*schema.Set).List() { - apiObject.Phase2EncryptionAlgorithms = append(apiObject.Phase2EncryptionAlgorithms, &ec2.Phase2EncryptionAlgorithmsRequestListValue{Value: aws.String(v.(string))}) + if v, ok := d.GetOk(key); ok && v.(*schema.Set).Len() > 0 { + for _, v := range d.Get(key).(*schema.Set).List() { + apiObject.Phase2EncryptionAlgorithms = append(apiObject.Phase2EncryptionAlgorithms, &ec2.Phase2EncryptionAlgorithmsRequestListValue{Value: aws.String(v.(string))}) + } + } else { + for _, v := range defaultVpnTunnelOptionsPhase2EncryptionAlgorithms { + apiObject.Phase2EncryptionAlgorithms = append(apiObject.Phase2EncryptionAlgorithms, &ec2.Phase2EncryptionAlgorithmsRequestListValue{Value: aws.String(v)}) + } } hasChange = true } if key := prefix + "phase2_integrity_algorithms"; d.HasChange(key) { - for _, v := range d.Get(key).(*schema.Set).List() { - apiObject.Phase2IntegrityAlgorithms = append(apiObject.Phase2IntegrityAlgorithms, &ec2.Phase2IntegrityAlgorithmsRequestListValue{Value: aws.String(v.(string))}) + if v, ok := d.GetOk(key); ok && v.(*schema.Set).Len() > 0 { + for _, v := range d.Get(key).(*schema.Set).List() { + apiObject.Phase2IntegrityAlgorithms = append(apiObject.Phase2IntegrityAlgorithms, &ec2.Phase2IntegrityAlgorithmsRequestListValue{Value: aws.String(v.(string))}) + } + } else { + for _, v := range defaultVpnTunnelOptionsPhase2IntegrityAlgorithms { + apiObject.Phase2IntegrityAlgorithms = append(apiObject.Phase2IntegrityAlgorithms, &ec2.Phase2IntegrityAlgorithmsRequestListValue{Value: aws.String(v)}) + } } hasChange = true } if key := prefix + "phase2_lifetime_seconds"; d.HasChange(key) { - apiObject.Phase2LifetimeSeconds = aws.Int64(int64(d.Get(key).(int))) + if v, ok := d.GetOk(key); ok { + apiObject.Phase2LifetimeSeconds = aws.Int64(int64(v.(int))) + } else { + apiObject.Phase2LifetimeSeconds = aws.Int64(int64(defaultVpnTunnelOptionsPhase2LifetimeSeconds)) + } hasChange = true } @@ -923,25 +1147,41 @@ func expandModifyVpnTunnelOptionsSpecification(d *schema.ResourceData, prefix st } if key := prefix + "rekey_fuzz_percentage"; d.HasChange(key) { - apiObject.RekeyFuzzPercentage = aws.Int64(int64(d.Get(key).(int))) + if v, ok := d.GetOk(key); ok { + apiObject.RekeyFuzzPercentage = aws.Int64(int64(v.(int))) + } else { + apiObject.RekeyFuzzPercentage = aws.Int64(int64(defaultVpnTunnelOptionsRekeyFuzzPercentage)) + } hasChange = true } if key := prefix + "rekey_margin_time_seconds"; d.HasChange(key) { - apiObject.RekeyMarginTimeSeconds = aws.Int64(int64(d.Get(key).(int))) + if v, ok := d.GetOk(key); ok { + apiObject.RekeyMarginTimeSeconds = aws.Int64(int64(v.(int))) + } else { + apiObject.RekeyMarginTimeSeconds = aws.Int64(int64(defaultVpnTunnelOptionsRekeyMarginTimeSeconds)) + } hasChange = true } if key := prefix + "replay_window_size"; d.HasChange(key) { - apiObject.ReplayWindowSize = aws.Int64(int64(d.Get(key).(int))) + if v, ok := d.GetOk(key); ok { + apiObject.ReplayWindowSize = aws.Int64(int64(v.(int))) + } else { + apiObject.ReplayWindowSize = aws.Int64(int64(defaultVpnTunnelOptionsReplayWindowSize)) + } hasChange = true } if key := prefix + "startup_action"; d.HasChange(key) { - apiObject.StartupAction = aws.String(d.Get(key).(string)) + if v, ok := d.GetOk(key); ok { + apiObject.StartupAction = aws.String(v.(string)) + } else { + apiObject.StartupAction = aws.String(defaultVpnTunnelOptionsStartupAction) + } hasChange = true } @@ -1242,75 +1482,3 @@ func validateVpnConnectionTunnelInsideIpv6CIDR() schema.SchemaValidateFunc { validation.StringMatch(regexp.MustCompile(`^fd00:`), "must be within fd00::/8"), ) } - -func validateLocalIpv4NetworkCidr() schema.SchemaValidateFunc { - return validation.All( - validation.IsCIDRNetwork(0, 32), - ) -} - -func validateLocalIpv6NetworkCidr() schema.SchemaValidateFunc { - return validation.All( - validation.IsCIDRNetwork(0, 128), - ) -} - -func validateVpnConnectionTunnelDpdTimeoutAction() schema.SchemaValidateFunc { - allowedDpdTimeoutActions := []string{ - "clear", - "none", - "restart", - } - - return validation.All( - validation.StringInSlice(allowedDpdTimeoutActions, false), - ) -} - -func validateVpnConnectionTunnelDpdTimeoutSeconds() schema.SchemaValidateFunc { - return validation.All( - //validation.IntBetween(0, 30) - validation.IntAtLeast(30), // Must be 30 or higher - ) -} - -func validateVpnConnectionTunnelPhase1LifetimeSeconds() schema.SchemaValidateFunc { - return validation.All( - validation.IntBetween(900, 28800), - ) -} - -func validateVpnConnectionTunnelPhase2LifetimeSeconds() schema.SchemaValidateFunc { - return validation.All( - validation.IntBetween(900, 3600), - ) -} - -func validateVpnConnectionTunnelRekeyFuzzPercentage() schema.SchemaValidateFunc { - return validation.All( - validation.IntBetween(0, 100), - ) -} - -func validateVpnConnectionTunnelRekeyMarginTimeSeconds() schema.SchemaValidateFunc { - return validation.All( - validation.IntBetween(60, 1800), - ) -} - -func validateVpnConnectionTunnelReplayWindowSize() schema.SchemaValidateFunc { - return validation.All( - validation.IntBetween(64, 2048), - ) -} - -func validateVpnConnectionTunnelStartupAction() schema.SchemaValidateFunc { - allowedStartupAction := []string{ - "add", - "start", - } - - return validation.All( - validation.StringInSlice(allowedStartupAction, false), - ) -} diff --git a/internal/service/ec2/vpn_connection_test.go b/internal/service/ec2/vpn_connection_test.go index 366afd7a441..085e898b506 100644 --- a/internal/service/ec2/vpn_connection_test.go +++ b/internal/service/ec2/vpn_connection_test.go @@ -402,7 +402,6 @@ func TestAccEC2VPNConnection_tunnelOptions(t *testing.T) { Providers: acctest.Providers, CheckDestroy: testAccVPNConnectionDestroy, Steps: []resource.TestStep{ - // Checking CIDR blocks { Config: testAccVPNConnectionSingleTunnelOptionsConfig(rName, rBgpAsn, "12345678", "not-a-cidr"), ExpectError: regexp.MustCompile(`invalid CIDR address: not-a-cidr`), @@ -443,8 +442,6 @@ func TestAccEC2VPNConnection_tunnelOptions(t *testing.T) { Config: testAccVPNConnectionSingleTunnelOptionsConfig(rName, rBgpAsn, "12345678", "169.254.169.252/30"), ExpectError: badCidrRangeErr, }, - - // Checking PreShared Key { Config: testAccVPNConnectionSingleTunnelOptionsConfig(rName, rBgpAsn, "1234567", "169.254.254.0/30"), ExpectError: regexp.MustCompile(`expected length of \w+ to be in the range \(8 - 64\)`), @@ -461,25 +458,6 @@ func TestAccEC2VPNConnection_tunnelOptions(t *testing.T) { Config: testAccVPNConnectionSingleTunnelOptionsConfig(rName, rBgpAsn, "1234567!", "169.254.254.0/30"), ExpectError: regexp.MustCompile(`can only contain alphanumeric, period and underscore characters`), }, - - // Should pre-check: - // - local_ipv4_network_cidr - // - local_ipv6_network_cidr - // - remote_ipv4_network_cidr - // - remote_ipv6_network_cidr - // - tunnel_inside_ip_version - // - tunnel1_dpd_timeout_action - // - tunnel1_dpd_timeout_seconds - // - tunnel1_phase1_lifetime_seconds - // - tunnel1_phase2_lifetime_seconds - // - tunnel1_rekey_fuzz_percentage - // - tunnel1_rekey_margin_time_seconds - // - tunnel1_replay_window_size - // - tunnel1_startup_action - // - tunnel1_inside_cidr - // - tunnel1_inside_ipv6_cidr - - //Try actual building { Config: testAccVPNConnectionTunnelOptionsConfig(rName, rBgpAsn, "192.168.1.1/32", "192.168.1.2/32", tunnel1, tunnel2), Check: resource.ComposeTestCheckFunc( @@ -507,7 +485,7 @@ func TestAccEC2VPNConnection_tunnelOptionsLesser(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) rBgpAsn := sdkacctest.RandIntRange(64512, 65534) resourceName := "aws_vpn_connection.test" - var vpn1, vpn2, vpn3, vpn4 ec2.VpnConnection + var vpn1, vpn2, vpn3, vpn4, vpn5 ec2.VpnConnection tunnel1 := TunnelOptions{ psk: "12345678", @@ -988,6 +966,66 @@ func TestAccEC2VPNConnection_tunnelOptionsLesser(t *testing.T) { resource.TestCheckResourceAttrSet(resourceName, "tunnel2_vgw_inside_address"), ), }, + // Test resetting to defaults. + // [local|remote]_ipv[4|6]_network_cidr, tunnel[1|2]_inside_[ipv6_]cidr and tunnel[1|2]_preshared_key are Computed so no diffs will be detected. + { + Config: testAccVPNConnectionConfig(rName, rBgpAsn), + Check: resource.ComposeAggregateTestCheckFunc( + testAccVPNConnectionExists(resourceName, &vpn5), + testAccCheckVPNConnectionNotRecreated(&vpn4, &vpn5), + resource.TestCheckResourceAttrSet(resourceName, "tunnel1_address"), + resource.TestCheckResourceAttrSet(resourceName, "tunnel1_bgp_asn"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_bgp_holdtime", "30"), + resource.TestCheckResourceAttrSet(resourceName, "tunnel1_cgw_inside_address"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_dpd_timeout_action", "clear"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_dpd_timeout_seconds", "30"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_ike_versions.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_inside_cidr", "169.254.8.0/30"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_inside_ipv6_cidr", ""), + resource.TestCheckNoResourceAttr(resourceName, "tunnel1_phase1_dh_group_numbers"), + resource.TestCheckNoResourceAttr(resourceName, "tunnel1_phase1_encryption_algorithms"), + resource.TestCheckNoResourceAttr(resourceName, "tunnel1_phase1_integrity_algorithms"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_phase1_lifetime_seconds", "28800"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_phase1_dh_group_numbers.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_phase1_encryption_algorithms.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_phase1_integrity_algorithms.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_phase2_dh_group_numbers.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_phase2_encryption_algorithms.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_phase2_integrity_algorithms.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_phase2_lifetime_seconds", "3600"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_preshared_key", "12345678"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_rekey_fuzz_percentage", "100"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_rekey_margin_time_seconds", "540"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_replay_window_size", "1024"), + resource.TestCheckResourceAttr(resourceName, "tunnel1_startup_action", "add"), + resource.TestCheckResourceAttrSet(resourceName, "tunnel1_vgw_inside_address"), + resource.TestCheckResourceAttrSet(resourceName, "tunnel2_address"), + resource.TestCheckResourceAttrSet(resourceName, "tunnel2_bgp_asn"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_bgp_holdtime", "30"), + resource.TestCheckResourceAttrSet(resourceName, "tunnel2_cgw_inside_address"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_dpd_timeout_action", "clear"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_dpd_timeout_seconds", "30"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_ike_versions.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_inside_cidr", "169.254.9.0/30"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_inside_ipv6_cidr", ""), + resource.TestCheckResourceAttr(resourceName, "tunnel2_phase1_dh_group_numbers.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_phase1_encryption_algorithms.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_phase1_integrity_algorithms.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_phase2_dh_group_numbers.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_phase2_encryption_algorithms.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_phase2_integrity_algorithms.#", "0"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_phase2_lifetime_seconds", "3600"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_preshared_key", "abcdefgh"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_rekey_fuzz_percentage", "100"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_rekey_margin_time_seconds", "540"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_replay_window_size", "1024"), + resource.TestCheckResourceAttr(resourceName, "tunnel2_startup_action", "add"), + resource.TestCheckResourceAttrSet(resourceName, "tunnel2_vgw_inside_address"), + resource.TestCheckResourceAttr(resourceName, "tunnel_inside_ip_version", "ipv4"), + resource.TestCheckResourceAttr(resourceName, "vgw_telemetry.#", "2"), + ), + ExpectNonEmptyPlan: true, + }, }, }) } From ea9c5a1586a83c1c85ae2b996914ab2a6f15fac6 Mon Sep 17 00:00:00 2001 From: dirk39 Date: Sat, 13 Nov 2021 16:23:01 +0100 Subject: [PATCH 054/116] removed field instance_interruption_behaviour from spot_instance_request Signed-off-by: dirk39 --- internal/service/ec2/spot_instance_request.go | 38 +----- .../service/ec2/spot_instance_request_test.go | 112 ------------------ .../r/spot_instance_request.html.markdown | 1 - 3 files changed, 5 insertions(+), 146 deletions(-) diff --git a/internal/service/ec2/spot_instance_request.go b/internal/service/ec2/spot_instance_request.go index 410975543e6..a4d2d71998d 100644 --- a/internal/service/ec2/spot_instance_request.go +++ b/internal/service/ec2/spot_instance_request.go @@ -1,7 +1,6 @@ package ec2 import ( - "context" "fmt" "log" "math/big" @@ -101,23 +100,12 @@ func ResourceSpotInstanceRequest() *schema.Resource { ForceNew: true, ValidateFunc: validation.IntDivisibleBy(60), } - s["instance_interruption_behaviour"] = &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ValidateFunc: validation.StringInSlice(ec2.InstanceInterruptionBehavior_Values(), false), - Deprecated: "Use the parameter \"instance_interruption_behavior\" instead.", - ConflictsWith: []string{"instance_interruption_behavior"}, - } s["instance_interruption_behavior"] = &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Computed: true, // Only during `instance_interruption_behaviour` deprecation period - // Default: ec2.InstanceInterruptionBehaviorTerminate, - ForceNew: true, - ValidateFunc: validation.StringInSlice(ec2.InstanceInterruptionBehavior_Values(), false), - ConflictsWith: []string{"instance_interruption_behaviour"}, + Type: schema.TypeString, + Optional: true, + Default: ec2.InstanceInterruptionBehaviorTerminate, + ForceNew: true, + ValidateFunc: validation.StringInSlice(ec2.InstanceInterruptionBehavior_Values(), false), } s["valid_from"] = &schema.Schema{ Type: schema.TypeString, @@ -138,21 +126,6 @@ func ResourceSpotInstanceRequest() *schema.Resource { CustomizeDiff: customdiff.All( verify.SetTagsDiff, - // This function exists to apply a default value to `instance_interruption_behavior` while - // accounting for the deprecated parameter `instance_interruption_behaviour`. It can be removed - // in favor of setting a `Default` on the parameter once `instance_interruption_behaviour` is removed. - // https://github.com/hashicorp/terraform-provider-aws/issues/20101 - func(_ context.Context, diff *schema.ResourceDiff, meta interface{}) error { - if v, ok := diff.GetOk("instance_interruption_behavior"); ok && v != "" { - return nil - } - if v, ok := diff.GetOk("instance_interruption_behaviour"); ok && v != "" { - diff.SetNew("instance_interruption_behavior", v) - return nil - } - diff.SetNew("instance_interruption_behavior", ec2.InstanceInterruptionBehaviorTerminate) - return nil - }, ), } } @@ -373,7 +346,6 @@ func resourceSpotInstanceRequestRead(d *schema.ResourceData, meta interface{}) e } d.Set("instance_interruption_behavior", request.InstanceInterruptionBehavior) - d.Set("instance_interruption_behaviour", request.InstanceInterruptionBehavior) d.Set("valid_from", aws.TimeValue(request.ValidFrom).Format(time.RFC3339)) d.Set("valid_until", aws.TimeValue(request.ValidUntil).Format(time.RFC3339)) d.Set("spot_type", request.Type) diff --git a/internal/service/ec2/spot_instance_request_test.go b/internal/service/ec2/spot_instance_request_test.go index 33a122c7c50..99cc95f7e85 100644 --- a/internal/service/ec2/spot_instance_request_test.go +++ b/internal/service/ec2/spot_instance_request_test.go @@ -34,7 +34,6 @@ func TestAccEC2SpotInstanceRequest_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spot_bid_status", "fulfilled"), resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "instance_interruption_behavior", "terminate"), - resource.TestCheckResourceAttr(resourceName, "instance_interruption_behaviour", "terminate"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, @@ -616,7 +615,6 @@ func TestAccEC2SpotInstanceRequest_interruptStop(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spot_bid_status", "fulfilled"), resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "instance_interruption_behavior", "stop"), - resource.TestCheckResourceAttr(resourceName, "instance_interruption_behaviour", "stop"), ), }, { @@ -646,7 +644,6 @@ func TestAccEC2SpotInstanceRequest_interruptHibernate(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spot_bid_status", "fulfilled"), resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), resource.TestCheckResourceAttr(resourceName, "instance_interruption_behavior", "hibernate"), - resource.TestCheckResourceAttr(resourceName, "instance_interruption_behaviour", "hibernate"), ), }, { @@ -674,7 +671,6 @@ func TestAccEC2SpotInstanceRequest_interruptUpdate(t *testing.T) { Check: resource.ComposeAggregateTestCheckFunc( testAccCheckSpotInstanceRequestExists(resourceName, &sir1), resource.TestCheckResourceAttr(resourceName, "instance_interruption_behavior", "hibernate"), - resource.TestCheckResourceAttr(resourceName, "instance_interruption_behaviour", "hibernate"), ), }, { @@ -683,99 +679,6 @@ func TestAccEC2SpotInstanceRequest_interruptUpdate(t *testing.T) { testAccCheckSpotInstanceRequestExists(resourceName, &sir2), testAccCheckSpotInstanceRequestRecreated(&sir1, &sir2), resource.TestCheckResourceAttr(resourceName, "instance_interruption_behavior", "terminate"), - resource.TestCheckResourceAttr(resourceName, "instance_interruption_behaviour", "terminate"), - ), - }, - }, - }) -} - -func TestAccEC2SpotInstanceRequest_interruptDeprecated(t *testing.T) { - var sir ec2.SpotInstanceRequest - resourceName := "aws_spot_instance_request.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t) }, - ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), - Providers: acctest.Providers, - CheckDestroy: testAccCheckSpotInstanceRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccSpotInstanceRequestInterruptConfig_Deprecated("hibernate"), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckSpotInstanceRequestExists(resourceName, &sir), - resource.TestCheckResourceAttr(resourceName, "spot_bid_status", "fulfilled"), - resource.TestCheckResourceAttr(resourceName, "spot_request_state", "active"), - resource.TestCheckResourceAttr(resourceName, "instance_interruption_behavior", "hibernate"), - resource.TestCheckResourceAttr(resourceName, "instance_interruption_behaviour", "hibernate"), - ), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateVerify: true, - ImportStateVerifyIgnore: []string{"wait_for_fulfillment"}, - }, - }, - }) -} - -func TestAccEC2SpotInstanceRequest_interruptFixDeprecated(t *testing.T) { - var sir1, sir2 ec2.SpotInstanceRequest - resourceName := "aws_spot_instance_request.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t) }, - ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), - Providers: acctest.Providers, - CheckDestroy: testAccCheckSpotInstanceRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccSpotInstanceRequestInterruptConfig_Deprecated("hibernate"), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckSpotInstanceRequestExists(resourceName, &sir1), - resource.TestCheckResourceAttr(resourceName, "instance_interruption_behavior", "hibernate"), - resource.TestCheckResourceAttr(resourceName, "instance_interruption_behaviour", "hibernate"), - ), - }, - { - Config: testAccSpotInstanceRequestInterruptConfig("hibernate"), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckSpotInstanceRequestExists(resourceName, &sir2), - testAccCheckSpotInstanceRequestNotRecreated(&sir1, &sir2), - resource.TestCheckResourceAttr(resourceName, "instance_interruption_behavior", "hibernate"), - resource.TestCheckResourceAttr(resourceName, "instance_interruption_behaviour", "hibernate"), - ), - }, - }, - }) -} - -func TestAccEC2SpotInstanceRequest_interruptUpdateFromDeprecated(t *testing.T) { - var sir1, sir2 ec2.SpotInstanceRequest - resourceName := "aws_spot_instance_request.test" - - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t) }, - ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), - Providers: acctest.Providers, - CheckDestroy: testAccCheckSpotInstanceRequestDestroy, - Steps: []resource.TestStep{ - { - Config: testAccSpotInstanceRequestInterruptConfig_Deprecated("hibernate"), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckSpotInstanceRequestExists(resourceName, &sir1), - resource.TestCheckResourceAttr(resourceName, "instance_interruption_behavior", "hibernate"), - resource.TestCheckResourceAttr(resourceName, "instance_interruption_behaviour", "hibernate"), - ), - }, - { - Config: testAccSpotInstanceRequestInterruptConfig("stop"), - Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckSpotInstanceRequestExists(resourceName, &sir2), - testAccCheckSpotInstanceRequestRecreated(&sir1, &sir2), - resource.TestCheckResourceAttr(resourceName, "instance_interruption_behavior", "stop"), - resource.TestCheckResourceAttr(resourceName, "instance_interruption_behaviour", "stop"), ), }, }, @@ -1079,18 +982,3 @@ resource "aws_spot_instance_request" "test" { } `, interruptionBehavior)) } - -func testAccSpotInstanceRequestInterruptConfig_Deprecated(interruptionBehavior string) string { - return acctest.ConfigCompose( - acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), - acctest.AvailableEC2InstanceTypeForRegion("c5.large", "c4.large"), - fmt.Sprintf(` -resource "aws_spot_instance_request" "test" { - ami = data.aws_ami.amzn-ami-minimal-hvm-ebs.id - instance_type = data.aws_ec2_instance_type_offering.available.instance_type - spot_price = "0.07" - wait_for_fulfillment = true - instance_interruption_behaviour = %[1]q -} -`, interruptionBehavior)) -} diff --git a/website/docs/r/spot_instance_request.html.markdown b/website/docs/r/spot_instance_request.html.markdown index 35f61ec88fe..ce75d2cc733 100644 --- a/website/docs/r/spot_instance_request.html.markdown +++ b/website/docs/r/spot_instance_request.html.markdown @@ -64,7 +64,6 @@ Spot Instance Requests support all the same arguments as The duration period starts as soon as your Spot instance receives its instance ID. At the end of the duration period, Amazon EC2 marks the Spot instance for termination and provides a Spot instance termination notice, which gives the instance a two-minute warning before it terminates. Note that you can't specify an Availability Zone group or a launch group if you specify a duration. * `instance_interruption_behavior` - (Optional) Indicates Spot instance behavior when it is interrupted. Valid values are `terminate`, `stop`, or `hibernate`. Default value is `terminate`. -* `instance_interruption_behaviour` - (Optional, **Deprecated**) Indicates Spot instance behavior when it is interrupted. Valid values are `terminate`, `stop`, or `hibernate`. Default value is `terminate`. Use the argument `instance_interruption_behavior` instead. * `valid_until` - (Optional) The end date and time of the request, in UTC [RFC3339](https://tools.ietf.org/html/rfc3339#section-5.8) format(for example, YYYY-MM-DDTHH:MM:SSZ). At this point, no new Spot instance requests are placed or enabled to fulfill the request. The default end date is 7 days from the current date. * `valid_from` - (Optional) The start date and time of the request, in UTC [RFC3339](https://tools.ietf.org/html/rfc3339#section-5.8) format(for example, YYYY-MM-DDTHH:MM:SSZ). The default is to start fulfilling the request immediately. * `tags` - (Optional) A map of tags to assign to the Spot Instance Request. These tags are not automatically applied to the launched Instance. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. From 5b547b861612e710747017b2db32f8cef954218f Mon Sep 17 00:00:00 2001 From: dirk39 Date: Sun, 14 Nov 2021 23:21:49 +0100 Subject: [PATCH 055/116] removed unused function Signed-off-by: dirk39 --- internal/service/ec2/spot_instance_request_test.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/internal/service/ec2/spot_instance_request_test.go b/internal/service/ec2/spot_instance_request_test.go index 99cc95f7e85..ed176ee1144 100644 --- a/internal/service/ec2/spot_instance_request_test.go +++ b/internal/service/ec2/spot_instance_request_test.go @@ -695,16 +695,6 @@ func testAccCheckSpotInstanceRequestRecreated(before, after *ec2.SpotInstanceReq } } -func testAccCheckSpotInstanceRequestNotRecreated(before, after *ec2.SpotInstanceRequest) resource.TestCheckFunc { - return func(s *terraform.State) error { - if before, after := aws.StringValue(before.InstanceId), aws.StringValue(after.InstanceId); before != after { - return fmt.Errorf("Spot Instance (%s/%s) recreated", before, after) - } - - return nil - } -} - func testAccSpotInstanceRequestConfig() string { return acctest.ConfigCompose( acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), From 99d0e835ac69243dac314c43969a692f5e76d641 Mon Sep 17 00:00:00 2001 From: maquessime Date: Fri, 3 Dec 2021 16:19:05 -0500 Subject: [PATCH 056/116] remove :* suffix --- internal/service/cloudwatchlogs/group_data_source.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/cloudwatchlogs/group_data_source.go b/internal/service/cloudwatchlogs/group_data_source.go index 5432a1950c2..3a0df3d2f94 100644 --- a/internal/service/cloudwatchlogs/group_data_source.go +++ b/internal/service/cloudwatchlogs/group_data_source.go @@ -52,7 +52,7 @@ func dataSourceGroupRead(d *schema.ResourceData, meta interface{}) error { } d.SetId(name) - d.Set("arn", logGroup.Arn) + d.Set("arn", TrimLogGroupARNWildcardSuffix(aws.StringValue(logGroup.Arn))) d.Set("creation_time", logGroup.CreationTime) d.Set("retention_in_days", logGroup.RetentionInDays) d.Set("kms_key_id", logGroup.KmsKeyId) From 2de9a9abed0322ad63e96d7828115fe52e358ad1 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Wed, 26 Jan 2022 16:28:25 -0500 Subject: [PATCH 057/116] add missing import and update data source tests --- .../cloudwatchlogs/group_data_source.go | 1 + .../cloudwatchlogs/group_data_source_test.go | 31 +++++++++---------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/internal/service/cloudwatchlogs/group_data_source.go b/internal/service/cloudwatchlogs/group_data_source.go index 3a0df3d2f94..a3df9461871 100644 --- a/internal/service/cloudwatchlogs/group_data_source.go +++ b/internal/service/cloudwatchlogs/group_data_source.go @@ -3,6 +3,7 @@ package cloudwatchlogs import ( "fmt" + "github.com/aws/aws-sdk-go/aws" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" diff --git a/internal/service/cloudwatchlogs/group_data_source_test.go b/internal/service/cloudwatchlogs/group_data_source_test.go index 50698853fbc..396a7e299c0 100644 --- a/internal/service/cloudwatchlogs/group_data_source_test.go +++ b/internal/service/cloudwatchlogs/group_data_source_test.go @@ -22,10 +22,10 @@ func TestAccCloudWatchLogsGroupDataSource_basic(t *testing.T) { { Config: testAccCheckGroupDataSourceConfig(rName), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", rName), - resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttrPair(resourceName, "name", "aws_cloudwatch_log_group.test", "name"), + resource.TestCheckResourceAttrPair(resourceName, "arn", "aws_cloudwatch_log_group.test", "arn"), resource.TestCheckResourceAttrSet(resourceName, "creation_time"), - resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttrPair(resourceName, "tags", "aws_cloudwatch_log_group.test", "tags"), ), }, }, @@ -44,13 +44,10 @@ func TestAccCloudWatchLogsGroupDataSource_tags(t *testing.T) { { Config: testAccCheckGroupTagsDataSourceConfig(rName), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", rName), - resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttrPair(resourceName, "name", "aws_cloudwatch_log_group.test", "name"), + resource.TestCheckResourceAttrPair(resourceName, "arn", "aws_cloudwatch_log_group.test", "arn"), resource.TestCheckResourceAttrSet(resourceName, "creation_time"), - resource.TestCheckResourceAttr(resourceName, "tags.%", "3"), - resource.TestCheckResourceAttr(resourceName, "tags.Environment", "Production"), - resource.TestCheckResourceAttr(resourceName, "tags.Foo", "Bar"), - resource.TestCheckResourceAttr(resourceName, "tags.Empty", ""), + resource.TestCheckResourceAttrPair(resourceName, "tags", "aws_cloudwatch_log_group.test", "tags"), ), }, }, @@ -69,11 +66,11 @@ func TestAccCloudWatchLogsGroupDataSource_kms(t *testing.T) { { Config: testAccCheckGroupKMSDataSourceConfig(rName), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", rName), - resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttrPair(resourceName, "name", "aws_cloudwatch_log_group.test", "name"), + resource.TestCheckResourceAttrPair(resourceName, "arn", "aws_cloudwatch_log_group.test", "arn"), resource.TestCheckResourceAttrSet(resourceName, "creation_time"), - resource.TestCheckResourceAttrSet(resourceName, "kms_key_id"), - resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + resource.TestCheckResourceAttrPair(resourceName, "kms_key_id", "aws_cloudwatch_log_group.test", "kms_key_id"), + resource.TestCheckResourceAttrPair(resourceName, "tags", "aws_cloudwatch_log_group.test", "tags"), ), }, }, @@ -92,11 +89,11 @@ func TestAccCloudWatchLogsGroupDataSource_retention(t *testing.T) { { Config: testAccCheckGroupRetentionDataSourceConfig(rName), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(resourceName, "name", rName), - resource.TestCheckResourceAttrSet(resourceName, "arn"), + resource.TestCheckResourceAttrPair(resourceName, "name", "aws_cloudwatch_log_group.test", "name"), + resource.TestCheckResourceAttrPair(resourceName, "arn", "aws_cloudwatch_log_group.test", "arn"), resource.TestCheckResourceAttrSet(resourceName, "creation_time"), - resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), - resource.TestCheckResourceAttr(resourceName, "retention_in_days", "365"), + resource.TestCheckResourceAttrPair(resourceName, "tags", "aws_cloudwatch_log_group.test", "tags"), + resource.TestCheckResourceAttrPair(resourceName, "retention_in_days", "aws_cloudwatch_log_group.test", "retention_in_days"), ), }, }, From 73acefdb8ec25e98b91eb1fd2eddc7518e78bfc4 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Wed, 26 Jan 2022 16:28:30 -0500 Subject: [PATCH 058/116] Update CHANGELOG for #22043 --- .changelog/22043.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/22043.txt diff --git a/.changelog/22043.txt b/.changelog/22043.txt new file mode 100644 index 00000000000..972b7c83293 --- /dev/null +++ b/.changelog/22043.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +data-source/aws_cloudwatch_log_group: Automatically trim `:*` suffix from `arn` attribute +``` \ No newline at end of file From 33621ddbee0a9e89cc3d91a447c74905759c7d17 Mon Sep 17 00:00:00 2001 From: "Prats, Jordi" Date: Wed, 20 Oct 2021 22:09:36 +0200 Subject: [PATCH 059/116] Return empty list when aws_security_groups doesnt match any SG --- .../ec2/security_groups_data_source.go | 4 --- .../ec2/security_groups_data_source_test.go | 30 +++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/internal/service/ec2/security_groups_data_source.go b/internal/service/ec2/security_groups_data_source.go index f651645efb0..a3beae08d83 100644 --- a/internal/service/ec2/security_groups_data_source.go +++ b/internal/service/ec2/security_groups_data_source.go @@ -90,10 +90,6 @@ func dataSourceSecurityGroupsRead(d *schema.ResourceData, meta interface{}) erro req.NextToken = resp.NextToken } - if len(ids) < 1 { - return fmt.Errorf("Your query returned no results. Please change your search criteria and try again.") - } - log.Printf("[DEBUG] Found %d security groups via given filter: %s", len(ids), req) d.SetId(meta.(*conns.AWSClient).Region) diff --git a/internal/service/ec2/security_groups_data_source_test.go b/internal/service/ec2/security_groups_data_source_test.go index fba42a1bf1e..709d6af59f3 100644 --- a/internal/service/ec2/security_groups_data_source_test.go +++ b/internal/service/ec2/security_groups_data_source_test.go @@ -50,6 +50,26 @@ func TestAccEC2SecurityGroupsDataSource_filter(t *testing.T) { }) } +func TestAccDataSourceAwsSecurityGroups_empty(t *testing.T) { + rInt := acctest.RandInt() + dataSourceName := "data.aws_security_groups.empty" + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAwsSecurityGroupsConfig_empty(rInt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "ids.#", "0"), + resource.TestCheckResourceAttr(dataSourceName, "vpc_ids.#", "0"), + resource.TestCheckResourceAttr(dataSourceName, "arns.#", "0"), + ), + }, + }, + }) +} + func testAccSecurityGroupsDataSourceConfig_tag(rInt int) string { return fmt.Sprintf(` resource "aws_vpc" "test_tag" { @@ -111,3 +131,13 @@ data "aws_security_groups" "by_filter" { } `, rInt) } + +func testAccDataSourceAwsSecurityGroupsConfig_empty(rInt int) string { + return fmt.Sprintf(` +data "aws_security_groups" "empty" { + tags = { + Random = "%[1]d" + } +} +`, rInt) +} From a20b0bfbf79ddd85c6c4cbdaa38d37596e2d7eae Mon Sep 17 00:00:00 2001 From: Matt Cooper Date: Tue, 3 Jul 2018 11:55:55 +1200 Subject: [PATCH 060/116] Add option to allow no results when querying for instances data --- aws/data_source_aws_instances_test.go | 0 internal/service/ec2/instances_data_source.go | 8 +++++++- website/docs/d/instances.html.markdown | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 aws/data_source_aws_instances_test.go diff --git a/aws/data_source_aws_instances_test.go b/aws/data_source_aws_instances_test.go new file mode 100644 index 00000000000..e69de29bb2d diff --git a/internal/service/ec2/instances_data_source.go b/internal/service/ec2/instances_data_source.go index b318933eae9..b58a0fcc271 100644 --- a/internal/service/ec2/instances_data_source.go +++ b/internal/service/ec2/instances_data_source.go @@ -51,6 +51,11 @@ func DataSourceInstances() *schema.Resource { Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, + "allow_no_results": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, }, } } @@ -60,6 +65,7 @@ func dataSourceInstancesRead(d *schema.ResourceData, meta interface{}) error { filters, filtersOk := d.GetOk("filter") tags, tagsOk := d.GetOk("instance_tags") + allowNoResults := d.Get("allow_no_results").(bool) if !filtersOk && !tagsOk { return fmt.Errorf("One of filters or instance_tags must be assigned") @@ -109,7 +115,7 @@ func dataSourceInstancesRead(d *schema.ResourceData, meta interface{}) error { return err } - if len(instanceIds) < 1 { + if len(instanceIds) < 1 && allowNoResults == false { return fmt.Errorf("Your query returned no results. Please change your search criteria and try again.") } diff --git a/website/docs/d/instances.html.markdown b/website/docs/d/instances.html.markdown index 0ca6f9cc510..90c2f259dc4 100644 --- a/website/docs/d/instances.html.markdown +++ b/website/docs/d/instances.html.markdown @@ -54,6 +54,8 @@ exactly match a pair on desired instances. several valid keys, for a full reference, check out [describe-instances in the AWS CLI reference][1]. +* `allow_no_results` - (Optional) Defaults to false. If true, empty lists could be returned for `ids`, `private_ips` and `public_ips`. This is useful when querying the count of ephemeral instances (e.g. managed via autoscaling group) which may not be created yet. + ## Attributes Reference * `id` - AWS Region. From 2ad066a954a21c4e2b39fd76c28372c53fb997f4 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 25 Jan 2022 11:08:12 -0500 Subject: [PATCH 061/116] Revert "Add option to allow no results when querying for instances data" This reverts commit 9c81e9debb19f759f35fd6f4c039bcdc586bff92. --- internal/service/ec2/instances_data_source.go | 8 +------- website/docs/d/instances.html.markdown | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/internal/service/ec2/instances_data_source.go b/internal/service/ec2/instances_data_source.go index b58a0fcc271..b318933eae9 100644 --- a/internal/service/ec2/instances_data_source.go +++ b/internal/service/ec2/instances_data_source.go @@ -51,11 +51,6 @@ func DataSourceInstances() *schema.Resource { Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, - "allow_no_results": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, }, } } @@ -65,7 +60,6 @@ func dataSourceInstancesRead(d *schema.ResourceData, meta interface{}) error { filters, filtersOk := d.GetOk("filter") tags, tagsOk := d.GetOk("instance_tags") - allowNoResults := d.Get("allow_no_results").(bool) if !filtersOk && !tagsOk { return fmt.Errorf("One of filters or instance_tags must be assigned") @@ -115,7 +109,7 @@ func dataSourceInstancesRead(d *schema.ResourceData, meta interface{}) error { return err } - if len(instanceIds) < 1 && allowNoResults == false { + if len(instanceIds) < 1 { return fmt.Errorf("Your query returned no results. Please change your search criteria and try again.") } diff --git a/website/docs/d/instances.html.markdown b/website/docs/d/instances.html.markdown index 90c2f259dc4..0ca6f9cc510 100644 --- a/website/docs/d/instances.html.markdown +++ b/website/docs/d/instances.html.markdown @@ -54,8 +54,6 @@ exactly match a pair on desired instances. several valid keys, for a full reference, check out [describe-instances in the AWS CLI reference][1]. -* `allow_no_results` - (Optional) Defaults to false. If true, empty lists could be returned for `ids`, `private_ips` and `public_ips`. This is useful when querying the count of ephemeral instances (e.g. managed via autoscaling group) which may not be created yet. - ## Attributes Reference * `id` - AWS Region. From 46b20b409af3afa78860eeda0f025c81dc1ab70d Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 25 Jan 2022 11:13:04 -0500 Subject: [PATCH 062/116] d/aws_security_groups: Alphabetize attributes. --- internal/service/ec2/security_groups_data_source.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/internal/service/ec2/security_groups_data_source.go b/internal/service/ec2/security_groups_data_source.go index a3beae08d83..b1e43501c7e 100644 --- a/internal/service/ec2/security_groups_data_source.go +++ b/internal/service/ec2/security_groups_data_source.go @@ -17,20 +17,19 @@ func DataSourceSecurityGroups() *schema.Resource { Read: dataSourceSecurityGroupsRead, Schema: map[string]*schema.Schema{ - "filter": DataSourceFiltersSchema(), - "tags": tftags.TagsSchemaComputed(), - - "ids": { + "arns": { Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, - "vpc_ids": { + "filter": DataSourceFiltersSchema(), + "ids": { Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, - "arns": { + "tags": tftags.TagsSchemaComputed(), + "vpc_ids": { Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, From 4f64a372adad314eaad04bd71699bfe58dccb445 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 25 Jan 2022 11:34:00 -0500 Subject: [PATCH 063/116] d/aws_security_groups: Use `FindSecurityGroups`. Acceptance test output: % make testacc TESTS=TestAccEC2SecurityGroupsDataSource_ PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2SecurityGroupsDataSource_' -timeout 180m === RUN TestAccEC2SecurityGroupsDataSource_tag === PAUSE TestAccEC2SecurityGroupsDataSource_tag === RUN TestAccEC2SecurityGroupsDataSource_filter === PAUSE TestAccEC2SecurityGroupsDataSource_filter === RUN TestAccEC2SecurityGroupsDataSource_empty === PAUSE TestAccEC2SecurityGroupsDataSource_empty === CONT TestAccEC2SecurityGroupsDataSource_tag === CONT TestAccEC2SecurityGroupsDataSource_empty === CONT TestAccEC2SecurityGroupsDataSource_filter --- PASS: TestAccEC2SecurityGroupsDataSource_empty (12.98s) --- PASS: TestAccEC2SecurityGroupsDataSource_filter (29.08s) --- PASS: TestAccEC2SecurityGroupsDataSource_tag (29.57s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 34.934s --- .../ec2/security_groups_data_source.go | 79 ++++++----------- .../ec2/security_groups_data_source_test.go | 88 ++++++++++--------- 2 files changed, 74 insertions(+), 93 deletions(-) diff --git a/internal/service/ec2/security_groups_data_source.go b/internal/service/ec2/security_groups_data_source.go index b1e43501c7e..df49fdad6ab 100644 --- a/internal/service/ec2/security_groups_data_source.go +++ b/internal/service/ec2/security_groups_data_source.go @@ -2,7 +2,6 @@ package ec2 import ( "fmt" - "log" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/arn" @@ -40,71 +39,49 @@ func DataSourceSecurityGroups() *schema.Resource { func dataSourceSecurityGroupsRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - req := &ec2.DescribeSecurityGroupsInput{} - filters, filtersOk := d.GetOk("filter") - tags, tagsOk := d.GetOk("tags") + input := &ec2.DescribeSecurityGroupsInput{} - if !filtersOk && !tagsOk { - return fmt.Errorf("One of filters or tags must be assigned") - } - - if filtersOk { - req.Filters = append(req.Filters, - BuildFiltersDataSource(filters.(*schema.Set))...) - } - if tagsOk { - req.Filters = append(req.Filters, BuildTagFilterList( + if tags, tagsOk := d.GetOk("tags"); tagsOk { + input.Filters = append(input.Filters, BuildTagFilterList( Tags(tftags.New(tags.(map[string]interface{}))), )...) } - log.Printf("[DEBUG] Reading Security Groups with request: %s", req) - - var ids, vpcIds, arns []string - for { - resp, err := conn.DescribeSecurityGroups(req) - if err != nil { - return fmt.Errorf("error reading security groups: %w", err) - } - - for _, sg := range resp.SecurityGroups { - ids = append(ids, aws.StringValue(sg.GroupId)) - vpcIds = append(vpcIds, aws.StringValue(sg.VpcId)) - - arn := arn.ARN{ - Partition: meta.(*conns.AWSClient).Partition, - Service: ec2.ServiceName, - Region: meta.(*conns.AWSClient).Region, - AccountID: aws.StringValue(sg.OwnerId), - Resource: fmt.Sprintf("security-group/%s", aws.StringValue(sg.GroupId)), - }.String() - - arns = append(arns, arn) - } + if filters, filtersOk := d.GetOk("filter"); filtersOk { + input.Filters = append(input.Filters, + BuildFiltersDataSource(filters.(*schema.Set))...) + } - if resp.NextToken == nil { - break - } - req.NextToken = resp.NextToken + if len(input.Filters) == 0 { + input.Filters = nil } - log.Printf("[DEBUG] Found %d security groups via given filter: %s", len(ids), req) + output, err := FindSecurityGroups(conn, input) - d.SetId(meta.(*conns.AWSClient).Region) - - err := d.Set("ids", ids) if err != nil { - return err + return fmt.Errorf("error reading EC2 Security Groups: %w", err) } - if err = d.Set("vpc_ids", vpcIds); err != nil { - return fmt.Errorf("error setting vpc_ids: %s", err) + var arns, securityGroupIDs, vpcIDs []string + + for _, v := range output { + arn := arn.ARN{ + Partition: meta.(*conns.AWSClient).Partition, + Service: ec2.ServiceName, + Region: meta.(*conns.AWSClient).Region, + AccountID: aws.StringValue(v.OwnerId), + Resource: fmt.Sprintf("security-group/%s", aws.StringValue(v.GroupId)), + }.String() + arns = append(arns, arn) + securityGroupIDs = append(securityGroupIDs, aws.StringValue(v.GroupId)) + vpcIDs = append(vpcIDs, aws.StringValue(v.VpcId)) } - if err = d.Set("arns", arns); err != nil { - return fmt.Errorf("error setting arns: %s", err) - } + d.SetId(meta.(*conns.AWSClient).Region) + d.Set("arns", arns) + d.Set("ids", securityGroupIDs) + d.Set("vpc_ids", vpcIDs) return nil } diff --git a/internal/service/ec2/security_groups_data_source_test.go b/internal/service/ec2/security_groups_data_source_test.go index 709d6af59f3..803b3139f5d 100644 --- a/internal/service/ec2/security_groups_data_source_test.go +++ b/internal/service/ec2/security_groups_data_source_test.go @@ -11,19 +11,20 @@ import ( ) func TestAccEC2SecurityGroupsDataSource_tag(t *testing.T) { - rInt := sdkacctest.RandInt() - dataSourceName := "data.aws_security_groups.by_tag" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + dataSourceName := "data.aws_security_groups.test" + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, Steps: []resource.TestStep{ { - Config: testAccSecurityGroupsDataSourceConfig_tag(rInt), + Config: testAccSecurityGroupsDataSourceConfig_tag(rName), Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "arns.#", "3"), resource.TestCheckResourceAttr(dataSourceName, "ids.#", "3"), resource.TestCheckResourceAttr(dataSourceName, "vpc_ids.#", "3"), - resource.TestCheckResourceAttr(dataSourceName, "arns.#", "3"), ), }, }, @@ -31,113 +32,116 @@ func TestAccEC2SecurityGroupsDataSource_tag(t *testing.T) { } func TestAccEC2SecurityGroupsDataSource_filter(t *testing.T) { - rInt := sdkacctest.RandInt() - dataSourceName := "data.aws_security_groups.by_filter" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + dataSourceName := "data.aws_security_groups.test" + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), Providers: acctest.Providers, Steps: []resource.TestStep{ { - Config: testAccSecurityGroupsDataSourceConfig_filter(rInt), + Config: testAccSecurityGroupsDataSourceConfig_filter(rName), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr(dataSourceName, "ids.#", "3"), - resource.TestCheckResourceAttr(dataSourceName, "vpc_ids.#", "3"), - resource.TestCheckResourceAttr(dataSourceName, "arns.#", "3"), + resource.TestCheckResourceAttr(dataSourceName, "arns.#", "1"), + resource.TestCheckResourceAttr(dataSourceName, "ids.#", "1"), + resource.TestCheckResourceAttr(dataSourceName, "vpc_ids.#", "1"), ), }, }, }) } -func TestAccDataSourceAwsSecurityGroups_empty(t *testing.T) { - rInt := acctest.RandInt() - dataSourceName := "data.aws_security_groups.empty" +func TestAccEC2SecurityGroupsDataSource_empty(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + dataSourceName := "data.aws_security_groups.test" + resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), - Providers: testAccProviders, + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, Steps: []resource.TestStep{ { - Config: testAccDataSourceAwsSecurityGroupsConfig_empty(rInt), + Config: testAccDataSourceAwsSecurityGroupsConfig_empty(rName), Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "arns.#", "0"), resource.TestCheckResourceAttr(dataSourceName, "ids.#", "0"), resource.TestCheckResourceAttr(dataSourceName, "vpc_ids.#", "0"), - resource.TestCheckResourceAttr(dataSourceName, "arns.#", "0"), ), }, }, }) } -func testAccSecurityGroupsDataSourceConfig_tag(rInt int) string { +func testAccSecurityGroupsDataSourceConfig_tag(rName string) string { return fmt.Sprintf(` -resource "aws_vpc" "test_tag" { +resource "aws_vpc" "test" { cidr_block = "172.16.0.0/16" tags = { - Name = "terraform-testacc-security-group-data-source" + Name = %[1]q } } resource "aws_security_group" "test" { count = 3 - vpc_id = aws_vpc.test_tag.id - name = "tf-%[1]d-${count.index}" + vpc_id = aws_vpc.test.id + name = "%[1]s-${count.index}" tags = { - Seed = "%[1]d" + Name = %[1]q } } -data "aws_security_groups" "by_tag" { +data "aws_security_groups" "test" { tags = { - Seed = aws_security_group.test[0].tags["Seed"] + Name = %[1]q } + + depends_on = [aws_security_group.test[0], aws_security_group.test[1], aws_security_group.test[2]] } -`, rInt) +`, rName) } -func testAccSecurityGroupsDataSourceConfig_filter(rInt int) string { +func testAccSecurityGroupsDataSourceConfig_filter(rName string) string { return fmt.Sprintf(` -resource "aws_vpc" "test_filter" { +resource "aws_vpc" "test" { cidr_block = "172.16.0.0/16" tags = { - Name = "terraform-testacc-security-group-data-source" + Name = %[1]q } } resource "aws_security_group" "test" { - count = 3 - vpc_id = aws_vpc.test_filter.id - name = "tf-%[1]d-${count.index}" + vpc_id = aws_vpc.test.id + name = %[1]q tags = { - Seed = "%[1]d" + Name = %[1]q } } -data "aws_security_groups" "by_filter" { +data "aws_security_groups" "test" { filter { name = "vpc-id" - values = [aws_vpc.test_filter.id] + values = [aws_vpc.test.id] } filter { name = "group-name" - values = ["tf-${aws_security_group.test[0].tags["Seed"]}-*"] + values = [aws_security_group.test.name] } } -`, rInt) +`, rName) } -func testAccDataSourceAwsSecurityGroupsConfig_empty(rInt int) string { +func testAccDataSourceAwsSecurityGroupsConfig_empty(rName string) string { return fmt.Sprintf(` -data "aws_security_groups" "empty" { +data "aws_security_groups" "test" { tags = { - Random = "%[1]d" + Name = %[1]q } } -`, rInt) +`, rName) } From d017930d6b0880da7a265f1d04c6a4b59d0af3b7 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 25 Jan 2022 11:38:17 -0500 Subject: [PATCH 064/116] Add CHANGELOG entry. --- .changelog/21219.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/21219.txt diff --git a/.changelog/21219.txt b/.changelog/21219.txt new file mode 100644 index 00000000000..2b6a3914ff6 --- /dev/null +++ b/.changelog/21219.txt @@ -0,0 +1,3 @@ +```release-note:note +data-source/aws_security_groups: If no security groups match the specified criteria an empty list is returned (previously an error was raised) +``` \ No newline at end of file From dd301bb7be50b3a442f5ceae854016ae11a42a7a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 25 Jan 2022 12:08:12 -0500 Subject: [PATCH 065/116] Add and use 'FindInstances'. Acceptance test output: % make testacc TESTS=TestAccEC2Instance_instanceProfileChange PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2Instance_instanceProfileChange' -timeout 180m === RUN TestAccEC2Instance_instanceProfileChange === PAUSE TestAccEC2Instance_instanceProfileChange === CONT TestAccEC2Instance_instanceProfileChange --- PASS: TestAccEC2Instance_instanceProfileChange (313.72s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 317.907s --- internal/service/ec2/find.go | 72 +++++++++++++++++++++++++++++++--- internal/service/ec2/status.go | 6 +-- 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index 52467812eec..268c1019863 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -253,23 +253,85 @@ func FindHost(conn *ec2.EC2, input *ec2.DescribeHostsInput) (*ec2.Host, error) { return host, nil } -// FindInstanceByID looks up a Instance by ID. When not found, returns nil and potentially an API error. +func FindInstances(conn *ec2.EC2, input *ec2.DescribeInstancesInput) ([]*ec2.Instance, error) { + var output []*ec2.Instance + + err := conn.DescribeInstancesPages(input, func(page *ec2.DescribeInstancesOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.Reservations { + if v != nil { + for _, v := range v.Instances { + if v != nil { + output = append(output, v) + } + } + } + } + + return !lastPage + }) + + if tfawserr.ErrCodeEquals(err, ErrCodeInvalidInstanceIDNotFound) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + return output, nil +} + +func FindInstance(conn *ec2.EC2, input *ec2.DescribeInstancesInput) (*ec2.Instance, error) { + output, err := FindInstances(conn, input) + + if err != nil { + return nil, err + } + + if len(output) == 0 || output[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } + + return output[0], nil +} + func FindInstanceByID(conn *ec2.EC2, id string) (*ec2.Instance, error) { input := &ec2.DescribeInstancesInput{ InstanceIds: aws.StringSlice([]string{id}), } - output, err := conn.DescribeInstances(input) + output, err := FindInstance(conn, input) if err != nil { return nil, err } - if output == nil || len(output.Reservations) == 0 || output.Reservations[0] == nil || len(output.Reservations[0].Instances) == 0 || output.Reservations[0].Instances[0] == nil { - return nil, nil + if state := aws.StringValue(output.State.Name); state == ec2.InstanceStateNameTerminated { + return nil, &resource.NotFoundError{ + Message: state, + LastRequest: input, + } } - return output.Reservations[0].Instances[0], nil + // Eventual consistency check. + if aws.StringValue(output.InstanceId) != id { + return nil, &resource.NotFoundError{ + LastRequest: input, + } + } + + return output, nil } func FindNetworkACL(conn *ec2.EC2, input *ec2.DescribeNetworkAclsInput) (*ec2.NetworkAcl, error) { diff --git a/internal/service/ec2/status.go b/internal/service/ec2/status.go index 080f527a01c..ef7ed687207 100644 --- a/internal/service/ec2/status.go +++ b/internal/service/ec2/status.go @@ -218,7 +218,7 @@ func StatusInstanceIAMInstanceProfile(conn *ec2.EC2, id string) resource.StateRe return func() (interface{}, string, error) { instance, err := FindInstanceByID(conn, id) - if tfawserr.ErrCodeEquals(err, ErrCodeInvalidInstanceIDNotFound) { + if tfresource.NotFound(err) { return nil, "", nil } @@ -226,10 +226,6 @@ func StatusInstanceIAMInstanceProfile(conn *ec2.EC2, id string) resource.StateRe return nil, "", err } - if instance == nil { - return nil, "", nil - } - if instance.IamInstanceProfile == nil || instance.IamInstanceProfile.Arn == nil { return instance, "", nil } From f1e3bc4b390da8f145ca324187c7cf7e9bcf7f2c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 25 Jan 2022 12:35:24 -0500 Subject: [PATCH 066/116] d/aws_instances: Use 'FindInstances'. Acceptance test output: % make testacc TESTS=TestAccEC2InstancesDataSource_ PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2InstancesDataSource_' -timeout 180m === RUN TestAccEC2InstancesDataSource_basic === PAUSE TestAccEC2InstancesDataSource_basic === RUN TestAccEC2InstancesDataSource_tags === PAUSE TestAccEC2InstancesDataSource_tags === RUN TestAccEC2InstancesDataSource_instanceStateNames === PAUSE TestAccEC2InstancesDataSource_instanceStateNames === RUN TestAccEC2InstancesDataSource_empty === PAUSE TestAccEC2InstancesDataSource_empty === CONT TestAccEC2InstancesDataSource_basic === CONT TestAccEC2InstancesDataSource_instanceStateNames === CONT TestAccEC2InstancesDataSource_empty === CONT TestAccEC2InstancesDataSource_tags --- PASS: TestAccEC2InstancesDataSource_empty (13.42s) --- PASS: TestAccEC2InstancesDataSource_instanceStateNames (111.19s) --- PASS: TestAccEC2InstancesDataSource_basic (119.68s) --- PASS: TestAccEC2InstancesDataSource_tags (121.22s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 126.560s --- .changelog/5055.txt | 3 + internal/service/ec2/instances_data_source.go | 115 +++++++----------- .../service/ec2/instances_data_source_test.go | 34 +++++- 3 files changed, 77 insertions(+), 75 deletions(-) create mode 100644 .changelog/5055.txt diff --git a/.changelog/5055.txt b/.changelog/5055.txt new file mode 100644 index 00000000000..da9fa294d9c --- /dev/null +++ b/.changelog/5055.txt @@ -0,0 +1,3 @@ +```release-note:note +data-source/aws_instances: If no instances match the specified criteria an empty list is returned (previously an error was raised) +``` \ No newline at end of file diff --git a/internal/service/ec2/instances_data_source.go b/internal/service/ec2/instances_data_source.go index b318933eae9..bb12e16a4be 100644 --- a/internal/service/ec2/instances_data_source.go +++ b/internal/service/ec2/instances_data_source.go @@ -2,7 +2,6 @@ package ec2 import ( "fmt" - "log" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" @@ -18,29 +17,21 @@ func DataSourceInstances() *schema.Resource { Read: dataSourceInstancesRead, Schema: map[string]*schema.Schema{ - "filter": DataSourceFiltersSchema(), + "filter": DataSourceFiltersSchema(), + "ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "instance_tags": tftags.TagsSchemaComputed(), "instance_state_names": { Type: schema.TypeSet, Optional: true, Elem: &schema.Schema{ - Type: schema.TypeString, - ValidateFunc: validation.StringInSlice([]string{ - ec2.InstanceStateNamePending, - ec2.InstanceStateNameRunning, - ec2.InstanceStateNameShuttingDown, - ec2.InstanceStateNameStopped, - ec2.InstanceStateNameStopping, - ec2.InstanceStateNameTerminated, - }, false), + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice(ec2.InstanceStateName_Values(), false), }, }, - - "ids": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, "private_ips": { Type: schema.TypeList, Computed: true, @@ -58,75 +49,53 @@ func DataSourceInstances() *schema.Resource { func dataSourceInstancesRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - filters, filtersOk := d.GetOk("filter") - tags, tagsOk := d.GetOk("instance_tags") - - if !filtersOk && !tagsOk { - return fmt.Errorf("One of filters or instance_tags must be assigned") + input := &ec2.DescribeInstancesInput{} + + if v, ok := d.GetOk("instance_state_names"); ok && v.(*schema.Set).Len() > 0 { + input.Filters = append(input.Filters, &ec2.Filter{ + Name: aws.String("instance-state-name"), + Values: flex.ExpandStringSet(v.(*schema.Set)), + }) + } else { + input.Filters = append(input.Filters, &ec2.Filter{ + Name: aws.String("instance-state-name"), + Values: aws.StringSlice([]string{ec2.InstanceStateNameRunning}), + }) } - instanceStateNames := []*string{aws.String(ec2.InstanceStateNameRunning)} - if v, ok := d.GetOk("instance_state_names"); ok && len(v.(*schema.Set).List()) > 0 { - instanceStateNames = flex.ExpandStringSet(v.(*schema.Set)) - } - params := &ec2.DescribeInstancesInput{ - Filters: []*ec2.Filter{ - { - Name: aws.String("instance-state-name"), - Values: instanceStateNames, - }, - }, + if tags, tagsOk := d.GetOk("instance_tags"); tagsOk { + input.Filters = append(input.Filters, BuildTagFilterList( + Tags(tftags.New(tags.(map[string]interface{}))), + )...) } - if filtersOk { - params.Filters = append(params.Filters, + if filters, filtersOk := d.GetOk("filter"); filtersOk { + input.Filters = append(input.Filters, BuildFiltersDataSource(filters.(*schema.Set))...) } - if tagsOk { - params.Filters = append(params.Filters, BuildTagFilterList( - Tags(tftags.New(tags.(map[string]interface{}))), - )...) - } - log.Printf("[DEBUG] Reading EC2 instances: %s", params) + output, err := FindInstances(conn, input) - var instanceIds, privateIps, publicIps []string - err := conn.DescribeInstancesPages(params, func(resp *ec2.DescribeInstancesOutput, lastPage bool) bool { - for _, res := range resp.Reservations { - for _, instance := range res.Instances { - instanceIds = append(instanceIds, *instance.InstanceId) - if instance.PrivateIpAddress != nil { - privateIps = append(privateIps, *instance.PrivateIpAddress) - } - if instance.PublicIpAddress != nil { - publicIps = append(publicIps, *instance.PublicIpAddress) - } - } - } - return !lastPage - }) if err != nil { - return err - } - - if len(instanceIds) < 1 { - return fmt.Errorf("Your query returned no results. Please change your search criteria and try again.") + return fmt.Errorf("error reading EC2 Instances: %w", err) } - log.Printf("[DEBUG] Found %d instances via given filter", len(instanceIds)) + var instanceIDs, privateIPs, publicIPs []string - d.SetId(meta.(*conns.AWSClient).Region) - - err = d.Set("ids", instanceIds) - if err != nil { - return err + for _, v := range output { + instanceIDs = append(instanceIDs, aws.StringValue(v.InstanceId)) + if privateIP := aws.StringValue(v.PrivateIpAddress); privateIP != "" { + privateIPs = append(privateIPs, privateIP) + } + if publicIP := aws.StringValue(v.PublicIpAddress); publicIP != "" { + publicIPs = append(publicIPs, publicIP) + } } - err = d.Set("private_ips", privateIps) - if err != nil { - return err - } + d.SetId(meta.(*conns.AWSClient).Region) + d.Set("ids", instanceIDs) + d.Set("private_ips", privateIPs) + d.Set("public_ips", publicIPs) - err = d.Set("public_ips", publicIps) - return err + return nil } diff --git a/internal/service/ec2/instances_data_source_test.go b/internal/service/ec2/instances_data_source_test.go index 9f4c2ca7887..9a0d7e9a6dd 100644 --- a/internal/service/ec2/instances_data_source_test.go +++ b/internal/service/ec2/instances_data_source_test.go @@ -67,6 +67,26 @@ func TestAccEC2InstancesDataSource_instanceStateNames(t *testing.T) { }) } +func TestAccEC2InstancesDataSource_empty(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccInstancesDataSourceConfig_empty(rName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.aws_instances.test", "ids.#", "0"), + resource.TestCheckResourceAttr("data.aws_instances.test", "private_ips.#", "0"), + resource.TestCheckResourceAttr("data.aws_instances.test", "public_ips.#", "0"), + ), + }, + }, + }) +} + func testAccInstancesDataSourceConfig_ids(rName string) string { return acctest.ConfigCompose( acctest.ConfigLatestAmazonLinuxHvmEbsAmi(), @@ -78,7 +98,7 @@ resource "aws_instance" "test" { instance_type = data.aws_ec2_instance_type_offering.available.instance_type tags = { - Name = %q + Name = %[1]q } } @@ -129,7 +149,7 @@ resource "aws_instance" "test" { instance_type = data.aws_ec2_instance_type_offering.available.instance_type tags = { - Name = %q + Name = %[1]q } } @@ -143,3 +163,13 @@ data "aws_instances" "test" { } `, rName)) } + +func testAccInstancesDataSourceConfig_empty(rName string) string { + return fmt.Sprintf(` +data "aws_instances" "test" { + instance_tags = { + Name = %[1]q + } +} +`, rName) +} From 3c84e9e233f3c6b24ad5dec49109bb1bb97214d5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 25 Jan 2022 14:41:22 -0500 Subject: [PATCH 067/116] d/aws_route_tables: Call 'FindRouteTables'. Acceptance test output: % make testacc TESTS=TestAccEC2RouteTablesDataSource_ PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2RouteTablesDataSource_' -timeout 180m === RUN TestAccEC2RouteTablesDataSource_basic === PAUSE TestAccEC2RouteTablesDataSource_basic === CONT TestAccEC2RouteTablesDataSource_basic --- PASS: TestAccEC2RouteTablesDataSource_basic (26.72s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 32.176s --- .changelog/21219.txt | 4 + internal/service/ec2/instances_data_source.go | 17 +-- .../service/ec2/route_tables_data_source.go | 51 +++---- .../ec2/route_tables_data_source_test.go | 136 ++++++------------ .../ec2/security_groups_data_source.go | 15 +- 5 files changed, 85 insertions(+), 138 deletions(-) diff --git a/.changelog/21219.txt b/.changelog/21219.txt index 2b6a3914ff6..9c3e46a19cb 100644 --- a/.changelog/21219.txt +++ b/.changelog/21219.txt @@ -1,3 +1,7 @@ ```release-note:note data-source/aws_security_groups: If no security groups match the specified criteria an empty list is returned (previously an error was raised) +``` + +```release-note:note +data-source/aws_route_tables: The type of the `ids` attributes has changed from Set to List. If no route tables match the specified criteria an empty list is returned (previously an error was raised) ``` \ No newline at end of file diff --git a/internal/service/ec2/instances_data_source.go b/internal/service/ec2/instances_data_source.go index bb12e16a4be..13dd3204753 100644 --- a/internal/service/ec2/instances_data_source.go +++ b/internal/service/ec2/instances_data_source.go @@ -63,15 +63,16 @@ func dataSourceInstancesRead(d *schema.ResourceData, meta interface{}) error { }) } - if tags, tagsOk := d.GetOk("instance_tags"); tagsOk { - input.Filters = append(input.Filters, BuildTagFilterList( - Tags(tftags.New(tags.(map[string]interface{}))), - )...) - } + input.Filters = append(input.Filters, BuildTagFilterList( + Tags(tftags.New(d.Get("tags").(map[string]interface{}))), + )...) + + input.Filters = append(input.Filters, BuildFiltersDataSource( + d.Get("filter").(*schema.Set), + )...) - if filters, filtersOk := d.GetOk("filter"); filtersOk { - input.Filters = append(input.Filters, - BuildFiltersDataSource(filters.(*schema.Set))...) + if len(input.Filters) == 0 { + input.Filters = nil } output, err := FindInstances(conn, input) diff --git a/internal/service/ec2/route_tables_data_source.go b/internal/service/ec2/route_tables_data_source.go index f82bf0763ce..248f4b14bc2 100644 --- a/internal/service/ec2/route_tables_data_source.go +++ b/internal/service/ec2/route_tables_data_source.go @@ -2,7 +2,6 @@ package ec2 import ( "fmt" - "log" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" @@ -15,22 +14,17 @@ func DataSourceRouteTables() *schema.Resource { return &schema.Resource{ Read: dataSourceRouteTablesRead, Schema: map[string]*schema.Schema{ - - "filter": CustomFiltersSchema(), - + "filter": DataSourceFiltersSchema(), + "ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "tags": tftags.TagsSchemaComputed(), - "vpc_id": { Type: schema.TypeString, Optional: true, }, - - "ids": { - Type: schema.TypeSet, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, - }, }, } } @@ -38,45 +32,42 @@ func DataSourceRouteTables() *schema.Resource { func dataSourceRouteTablesRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - req := &ec2.DescribeRouteTablesInput{} + input := &ec2.DescribeRouteTablesInput{} if v, ok := d.GetOk("vpc_id"); ok { - req.Filters = BuildAttributeFilterList( + input.Filters = append(input.Filters, BuildAttributeFilterList( map[string]string{ "vpc-id": v.(string), }, - ) + )...) } - req.Filters = append(req.Filters, BuildTagFilterList( + input.Filters = append(input.Filters, BuildTagFilterList( Tags(tftags.New(d.Get("tags").(map[string]interface{}))), )...) - req.Filters = append(req.Filters, BuildCustomFilterList( + input.Filters = append(input.Filters, BuildFiltersDataSource( d.Get("filter").(*schema.Set), )...) - log.Printf("[DEBUG] DescribeRouteTables %s\n", req) - resp, err := conn.DescribeRouteTables(req) - if err != nil { - return err + if len(input.Filters) == 0 { + input.Filters = nil } - if resp == nil || len(resp.RouteTables) == 0 { - return fmt.Errorf("no matching route tables found for vpc with id %s", d.Get("vpc_id").(string)) + output, err := FindRouteTables(conn, input) + + if err != nil { + return fmt.Errorf("error reading EC2 Route Tables: %w", err) } - routeTables := make([]string, 0) + var routeTableIDs []string - for _, routeTable := range resp.RouteTables { - routeTables = append(routeTables, aws.StringValue(routeTable.RouteTableId)) + for _, v := range output { + routeTableIDs = append(routeTableIDs, aws.StringValue(v.RouteTableId)) } d.SetId(meta.(*conns.AWSClient).Region) - - if err = d.Set("ids", routeTables); err != nil { - return fmt.Errorf("error setting ids: %w", err) - } + d.Set("ids", routeTableIDs) return nil } diff --git a/internal/service/ec2/route_tables_data_source_test.go b/internal/service/ec2/route_tables_data_source_test.go index 49a36f2c6bb..5fad885e1ab 100644 --- a/internal/service/ec2/route_tables_data_source_test.go +++ b/internal/service/ec2/route_tables_data_source_test.go @@ -11,7 +11,8 @@ import ( ) func TestAccEC2RouteTablesDataSource_basic(t *testing.T) { - rInt := sdkacctest.RandIntRange(0, 256) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), @@ -19,154 +20,107 @@ func TestAccEC2RouteTablesDataSource_basic(t *testing.T) { CheckDestroy: testAccCheckVpcDestroy, Steps: []resource.TestStep{ { - Config: testAccRouteTablesDataSourceConfig(rInt), - }, - { - Config: testAccRouteTablesWithDataSourceDataSourceConfig(rInt), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("data.aws_route_tables.test", "ids.#", "5"), - resource.TestCheckResourceAttr("data.aws_route_tables.private", "ids.#", "3"), - resource.TestCheckResourceAttr("data.aws_route_tables.test2", "ids.#", "1"), - resource.TestCheckResourceAttr("data.aws_route_tables.filter_test", "ids.#", "2"), + Config: testAccRouteTablesDataSourceConfig(rName), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.aws_route_tables.by_vpc_id", "ids.#", "2"), // Add the default route table. + resource.TestCheckResourceAttr("data.aws_route_tables.by_tags", "ids.#", "2"), + resource.TestCheckResourceAttr("data.aws_route_tables.by_filter", "ids.#", "6"), // Add the default route tables. + resource.TestCheckResourceAttr("data.aws_route_tables.empty", "ids.#", "0"), ), }, }, }) } -func testAccRouteTablesWithDataSourceDataSourceConfig(rInt int) string { +func testAccRouteTablesDataSourceConfig(rName string) string { return fmt.Sprintf(` -resource "aws_vpc" "test" { - cidr_block = "172.%d.0.0/16" +resource "aws_vpc" "test1" { + cidr_block = "172.16.0.0/16" tags = { - Name = "terraform-testacc-route-tables-data-source" + Name = %[1]q } } resource "aws_vpc" "test2" { - cidr_block = "172.%d.0.0/16" + cidr_block = "172.16.0.0/16" tags = { - Name = "terraform-test2acc-route-tables-data-source" + Name = %[1]q } } -resource "aws_route_table" "test_public_a" { - vpc_id = aws_vpc.test.id +resource "aws_route_table" "test1_public" { + vpc_id = aws_vpc.test1.id tags = { - Name = "tf-acc-route-tables-data-source-public-a" + Name = %[1]q Tier = "Public" Component = "Frontend" } } -resource "aws_route_table" "test_private_a" { - vpc_id = aws_vpc.test.id +resource "aws_route_table" "test1_private1" { + vpc_id = aws_vpc.test1.id tags = { - Name = "tf-acc-route-tables-data-source-private-a" + Name = %[1]q Tier = "Private" Component = "Database" } } -resource "aws_route_table" "test_private_b" { - vpc_id = aws_vpc.test.id +resource "aws_route_table" "test1_private2" { + vpc_id = aws_vpc.test1.id tags = { - Name = "tf-acc-route-tables-data-source-private-b" + Name = %[1]q Tier = "Private" - Component = "Backend-1" + Component = "AppServer" } } -resource "aws_route_table" "test_private_c" { - vpc_id = aws_vpc.test.id - - tags = { - Name = "tf-acc-route-tables-data-source-private-c" - Tier = "Private" - Component = "Backend-2" - } -} - -data "aws_route_tables" "test" { - vpc_id = aws_vpc.test.id -} - -data "aws_route_tables" "test2" { +resource "aws_route_table" "test2_public" { vpc_id = aws_vpc.test2.id -} - -data "aws_route_tables" "private" { - vpc_id = aws_vpc.test.id tags = { - Tier = "Private" + Name = %[1]q + Tier = "Public" + Component = "Frontend" } } -data "aws_route_tables" "filter_test" { - vpc_id = aws_vpc.test.id +data "aws_route_tables" "by_vpc_id" { + vpc_id = aws_vpc.test2.id - filter { - name = "tag:Component" - values = ["Backend*"] - } + depends_on = [aws_route_table.test1_public, aws_route_table.test1_private1, aws_route_table.test1_private2, aws_route_table.test2_public] } -`, rInt, rInt) -} - -func testAccRouteTablesDataSourceConfig(rInt int) string { - return fmt.Sprintf(` -resource "aws_vpc" "test" { - cidr_block = "172.%d.0.0/16" +data "aws_route_tables" "by_tags" { tags = { - Name = "terraform-testacc-route-tables-data-source" + Tier = "Public" } -} - -resource "aws_route_table" "test_public_a" { - vpc_id = aws_vpc.test.id - tags = { - Name = "tf-acc-route-tables-data-source-public-a" - Tier = "Public" - Component = "Frontend" - } + depends_on = [aws_route_table.test1_public, aws_route_table.test1_private1, aws_route_table.test1_private2, aws_route_table.test2_public] } -resource "aws_route_table" "test_private_a" { - vpc_id = aws_vpc.test.id - - tags = { - Name = "tf-acc-route-tables-data-source-private-a" - Tier = "Private" - Component = "Database" +data "aws_route_tables" "by_filter" { + filter { + name = "vpc-id" + values = [aws_vpc.test1.id, aws_vpc.test2.id] } -} - -resource "aws_route_table" "test_private_b" { - vpc_id = aws_vpc.test.id - tags = { - Name = "tf-acc-route-tables-data-source-private-b" - Tier = "Private" - Component = "Backend-1" - } + depends_on = [aws_route_table.test1_public, aws_route_table.test1_private1, aws_route_table.test1_private2, aws_route_table.test2_public] } -resource "aws_route_table" "test_private_c" { - vpc_id = aws_vpc.test.id +data "aws_route_tables" "empty" { + vpc_id = aws_vpc.test2.id tags = { - Name = "tf-acc-route-tables-data-source-private-c" - Tier = "Private" - Component = "Backend-2" + Tier = "Private" } + + depends_on = [aws_route_table.test1_public, aws_route_table.test1_private1, aws_route_table.test1_private2, aws_route_table.test2_public] } -`, rInt) +`, rName) } diff --git a/internal/service/ec2/security_groups_data_source.go b/internal/service/ec2/security_groups_data_source.go index df49fdad6ab..8dc1cc5e8c5 100644 --- a/internal/service/ec2/security_groups_data_source.go +++ b/internal/service/ec2/security_groups_data_source.go @@ -42,16 +42,13 @@ func dataSourceSecurityGroupsRead(d *schema.ResourceData, meta interface{}) erro input := &ec2.DescribeSecurityGroupsInput{} - if tags, tagsOk := d.GetOk("tags"); tagsOk { - input.Filters = append(input.Filters, BuildTagFilterList( - Tags(tftags.New(tags.(map[string]interface{}))), - )...) - } + input.Filters = append(input.Filters, BuildTagFilterList( + Tags(tftags.New(d.Get("tags").(map[string]interface{}))), + )...) - if filters, filtersOk := d.GetOk("filter"); filtersOk { - input.Filters = append(input.Filters, - BuildFiltersDataSource(filters.(*schema.Set))...) - } + input.Filters = append(input.Filters, BuildFiltersDataSource( + d.Get("filter").(*schema.Set), + )...) if len(input.Filters) == 0 { input.Filters = nil From aef05f9a85bb41625b72272c4849e75a6077865a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 25 Jan 2022 14:59:02 -0500 Subject: [PATCH 068/116] d/aws_network_interfaces: Allow empty results. Acceptance test output: % make testacc TESTS=TestAccEC2NetworkInterfacesDataSource_ PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2NetworkInterfacesDataSource_' -timeout 180m === RUN TestAccEC2NetworkInterfacesDataSource_filter === PAUSE TestAccEC2NetworkInterfacesDataSource_filter === RUN TestAccEC2NetworkInterfacesDataSource_tags === PAUSE TestAccEC2NetworkInterfacesDataSource_tags === RUN TestAccEC2NetworkInterfacesDataSource_empty === PAUSE TestAccEC2NetworkInterfacesDataSource_empty === CONT TestAccEC2NetworkInterfacesDataSource_filter === CONT TestAccEC2NetworkInterfacesDataSource_empty === CONT TestAccEC2NetworkInterfacesDataSource_tags --- PASS: TestAccEC2NetworkInterfacesDataSource_empty (10.98s) --- PASS: TestAccEC2NetworkInterfacesDataSource_tags (28.43s) --- PASS: TestAccEC2NetworkInterfacesDataSource_filter (28.45s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 32.493s --- .changelog/21219.txt | 4 +++ .../ec2/network_interfaces_data_source.go | 32 ++++++------------- .../network_interfaces_data_source_test.go | 29 +++++++++++++++++ .../service/ec2/route_tables_data_source.go | 1 + .../docs/d/network_interfaces.html.markdown | 2 +- 5 files changed, 45 insertions(+), 23 deletions(-) diff --git a/.changelog/21219.txt b/.changelog/21219.txt index 9c3e46a19cb..a4a647a7813 100644 --- a/.changelog/21219.txt +++ b/.changelog/21219.txt @@ -4,4 +4,8 @@ data-source/aws_security_groups: If no security groups match the specified crite ```release-note:note data-source/aws_route_tables: The type of the `ids` attributes has changed from Set to List. If no route tables match the specified criteria an empty list is returned (previously an error was raised) +``` + +```release-note:note +data-source/aws_network_interfaces: The type of the `ids` attributes has changed from Set to List. If no network interfaces match the specified criteria an empty list is returned (previously an error was raised) ``` \ No newline at end of file diff --git a/internal/service/ec2/network_interfaces_data_source.go b/internal/service/ec2/network_interfaces_data_source.go index 129d92a48f5..fcbe3e8ecfb 100644 --- a/internal/service/ec2/network_interfaces_data_source.go +++ b/internal/service/ec2/network_interfaces_data_source.go @@ -1,7 +1,6 @@ package ec2 import ( - "errors" "fmt" "github.com/aws/aws-sdk-go/aws" @@ -14,13 +13,13 @@ import ( func DataSourceNetworkInterfaces() *schema.Resource { return &schema.Resource{ Read: dataSourceNetworkInterfacesRead, + Schema: map[string]*schema.Schema{ - "filter": CustomFiltersSchema(), + "filter": DataSourceFiltersSchema(), "ids": { - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, }, "tags": tftags.TagsSchemaComputed(), }, @@ -32,17 +31,13 @@ func dataSourceNetworkInterfacesRead(d *schema.ResourceData, meta interface{}) e input := &ec2.DescribeNetworkInterfacesInput{} - if v, ok := d.GetOk("tags"); ok { - input.Filters = BuildTagFilterList( - Tags(tftags.New(v.(map[string]interface{}))), - ) - } + input.Filters = append(input.Filters, BuildTagFilterList( + Tags(tftags.New(d.Get("tags").(map[string]interface{}))), + )...) - if v, ok := d.GetOk("filter"); ok { - input.Filters = append(input.Filters, BuildCustomFilterList( - v.(*schema.Set), - )...) - } + input.Filters = append(input.Filters, BuildFiltersDataSource( + d.Get("filter").(*schema.Set), + )...) if len(input.Filters) == 0 { input.Filters = nil @@ -56,19 +51,12 @@ func dataSourceNetworkInterfacesRead(d *schema.ResourceData, meta interface{}) e return fmt.Errorf("error reading EC2 Network Interfaces: %w", err) } - if len(output) == 0 { - return errors.New("no matching network interfaces found") - } - for _, v := range output { networkInterfaceIDs = append(networkInterfaceIDs, aws.StringValue(v.NetworkInterfaceId)) } d.SetId(meta.(*conns.AWSClient).Region) - - if err := d.Set("ids", networkInterfaceIDs); err != nil { - return fmt.Errorf("error setting ids: %w", err) - } + d.Set("ids", networkInterfaceIDs) return nil } diff --git a/internal/service/ec2/network_interfaces_data_source_test.go b/internal/service/ec2/network_interfaces_data_source_test.go index 81f7759999d..cb65c331c3b 100644 --- a/internal/service/ec2/network_interfaces_data_source_test.go +++ b/internal/service/ec2/network_interfaces_data_source_test.go @@ -48,6 +48,25 @@ func TestAccEC2NetworkInterfacesDataSource_tags(t *testing.T) { }) } +func TestAccEC2NetworkInterfacesDataSource_empty(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckVpcDestroy, + Steps: []resource.TestStep{ + { + Config: testAccNetworkInterfacesDataSourceConfig_Empty(rName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.aws_network_interfaces.test", "ids.#", "0"), + ), + }, + }, + }) +} + func testAccNetworkInterfacesDataSourceConfig_Base(rName string) string { return fmt.Sprintf(` resource "aws_vpc" "test" { @@ -105,3 +124,13 @@ data "aws_network_interfaces" "test" { } `) } + +func testAccNetworkInterfacesDataSourceConfig_Empty(rName string) string { + return fmt.Sprintf(` +data "aws_network_interfaces" "test" { + tags = { + Name = %[1]q + } +} +`, rName) +} diff --git a/internal/service/ec2/route_tables_data_source.go b/internal/service/ec2/route_tables_data_source.go index 248f4b14bc2..1779aa1e74b 100644 --- a/internal/service/ec2/route_tables_data_source.go +++ b/internal/service/ec2/route_tables_data_source.go @@ -13,6 +13,7 @@ import ( func DataSourceRouteTables() *schema.Resource { return &schema.Resource{ Read: dataSourceRouteTablesRead, + Schema: map[string]*schema.Schema{ "filter": DataSourceFiltersSchema(), "ids": { diff --git a/website/docs/d/network_interfaces.html.markdown b/website/docs/d/network_interfaces.html.markdown index 0a5a6ec6c6b..fd0be09ca7f 100644 --- a/website/docs/d/network_interfaces.html.markdown +++ b/website/docs/d/network_interfaces.html.markdown @@ -68,5 +68,5 @@ which take the following arguments: ## Attributes Reference * `id` - AWS Region. -* `ids` - A list of all the network interface ids found. This data source will fail if none are found. +* `ids` - A list of all the network interface ids found. From 94079f8e75069e96bde1c0bbefaf0d8fbc26f4d9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 25 Jan 2022 15:21:42 -0500 Subject: [PATCH 069/116] d/aws_network_acls: Use 'FindNetworkACLs'. Acceptance test output: % make testacc TESTS=TestAccEC2NetworkACLsDataSource_ PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2NetworkACLsDataSource_' -timeout 180m === RUN TestAccEC2NetworkACLsDataSource_basic === PAUSE TestAccEC2NetworkACLsDataSource_basic === RUN TestAccEC2NetworkACLsDataSource_filter === PAUSE TestAccEC2NetworkACLsDataSource_filter === RUN TestAccEC2NetworkACLsDataSource_tags === PAUSE TestAccEC2NetworkACLsDataSource_tags === RUN TestAccEC2NetworkACLsDataSource_vpcID === PAUSE TestAccEC2NetworkACLsDataSource_vpcID === RUN TestAccEC2NetworkACLsDataSource_empty === PAUSE TestAccEC2NetworkACLsDataSource_empty === CONT TestAccEC2NetworkACLsDataSource_basic === CONT TestAccEC2NetworkACLsDataSource_vpcID === CONT TestAccEC2NetworkACLsDataSource_empty === CONT TestAccEC2NetworkACLsDataSource_tags === CONT TestAccEC2NetworkACLsDataSource_filter --- PASS: TestAccEC2NetworkACLsDataSource_empty (12.47s) --- PASS: TestAccEC2NetworkACLsDataSource_basic (26.31s) --- PASS: TestAccEC2NetworkACLsDataSource_tags (26.82s) --- PASS: TestAccEC2NetworkACLsDataSource_filter (26.82s) --- PASS: TestAccEC2NetworkACLsDataSource_vpcID (26.82s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 30.300s --- .changelog/21219.txt | 4 + .../service/ec2/network_acls_data_source.go | 67 +++++---------- .../ec2/network_acls_data_source_test.go | 84 +++++++++++++------ website/docs/d/network_acls.html.markdown | 2 +- website/docs/d/route_tables.html.markdown | 2 +- website/docs/d/vpcs.html.markdown | 2 +- 6 files changed, 88 insertions(+), 73 deletions(-) diff --git a/.changelog/21219.txt b/.changelog/21219.txt index a4a647a7813..445dea86e5e 100644 --- a/.changelog/21219.txt +++ b/.changelog/21219.txt @@ -8,4 +8,8 @@ data-source/aws_route_tables: The type of the `ids` attributes has changed from ```release-note:note data-source/aws_network_interfaces: The type of the `ids` attributes has changed from Set to List. If no network interfaces match the specified criteria an empty list is returned (previously an error was raised) +``` + +```release-note:note +data-source/aws_network_acls: The type of the `ids` attributes has changed from Set to List. If no NACLs match the specified criteria an empty list is returned (previously an error was raised) ``` \ No newline at end of file diff --git a/internal/service/ec2/network_acls_data_source.go b/internal/service/ec2/network_acls_data_source.go index 26bd24308a3..7de247c6ace 100644 --- a/internal/service/ec2/network_acls_data_source.go +++ b/internal/service/ec2/network_acls_data_source.go @@ -1,9 +1,7 @@ package ec2 import ( - "errors" "fmt" - "log" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" @@ -16,21 +14,17 @@ func DataSourceNetworkACLs() *schema.Resource { return &schema.Resource{ Read: dataSourceNetworkACLsRead, Schema: map[string]*schema.Schema{ - "filter": CustomFiltersSchema(), - + "filter": DataSourceFiltersSchema(), + "ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, "tags": tftags.TagsSchemaComputed(), - "vpc_id": { Type: schema.TypeString, Optional: true, }, - - "ids": { - Type: schema.TypeSet, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, - }, }, } } @@ -38,57 +32,42 @@ func DataSourceNetworkACLs() *schema.Resource { func dataSourceNetworkACLsRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - req := &ec2.DescribeNetworkAclsInput{} + input := &ec2.DescribeNetworkAclsInput{} if v, ok := d.GetOk("vpc_id"); ok { - req.Filters = BuildAttributeFilterList( + input.Filters = append(input.Filters, BuildAttributeFilterList( map[string]string{ "vpc-id": v.(string), }, - ) + )...) } - filters, filtersOk := d.GetOk("filter") - tags, tagsOk := d.GetOk("tags") + input.Filters = append(input.Filters, BuildTagFilterList( + Tags(tftags.New(d.Get("tags").(map[string]interface{}))), + )...) - if tagsOk { - req.Filters = append(req.Filters, BuildTagFilterList( - Tags(tftags.New(tags.(map[string]interface{}))), - )...) - } + input.Filters = append(input.Filters, BuildFiltersDataSource( + d.Get("filter").(*schema.Set), + )...) - if filtersOk { - req.Filters = append(req.Filters, BuildCustomFilterList( - filters.(*schema.Set), - )...) + if len(input.Filters) == 0 { + input.Filters = nil } - if len(req.Filters) == 0 { - // Don't send an empty filters list; the EC2 API won't accept it. - req.Filters = nil - } + output, err := FindNetworkACLs(conn, input) - log.Printf("[DEBUG] DescribeNetworkAcls %s\n", req) - resp, err := conn.DescribeNetworkAcls(req) if err != nil { - return err - } - - if resp == nil || len(resp.NetworkAcls) == 0 { - return errors.New("no matching network ACLs found") + return fmt.Errorf("error reading EC2 Network ACLs: %w", err) } - networkAcls := make([]string, 0) + var naclIDs []string - for _, networkAcl := range resp.NetworkAcls { - networkAcls = append(networkAcls, aws.StringValue(networkAcl.NetworkAclId)) + for _, v := range output { + naclIDs = append(naclIDs, aws.StringValue(v.NetworkAclId)) } d.SetId(meta.(*conns.AWSClient).Region) - - if err := d.Set("ids", networkAcls); err != nil { - return fmt.Errorf("Error setting network ACL ids: %w", err) - } + d.Set("ids", naclIDs) return nil } diff --git a/internal/service/ec2/network_acls_data_source_test.go b/internal/service/ec2/network_acls_data_source_test.go index 59c76a62494..bb72cfbbc3b 100644 --- a/internal/service/ec2/network_acls_data_source_test.go +++ b/internal/service/ec2/network_acls_data_source_test.go @@ -2,7 +2,6 @@ package ec2_test import ( "fmt" - "regexp" "testing" "github.com/aws/aws-sdk-go/service/ec2" @@ -12,7 +11,7 @@ import ( ) func TestAccEC2NetworkACLsDataSource_basic(t *testing.T) { - rName := sdkacctest.RandString(5) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) dataSourceName := "data.aws_network_acls.test" resource.ParallelTest(t, resource.TestCase{ @@ -21,15 +20,10 @@ func TestAccEC2NetworkACLsDataSource_basic(t *testing.T) { Providers: acctest.Providers, CheckDestroy: testAccCheckVpcDestroy, Steps: []resource.TestStep{ - { - // Ensure at least 1 network ACL exists. We cannot use depends_on. - Config: testAccNetworkACLsDataSourceConfig_Base(rName), - }, { Config: testAccNetworkACLsDataSourceConfig_basic(rName), Check: resource.ComposeTestCheckFunc( - // At least 1 - resource.TestMatchResourceAttr(dataSourceName, "ids.#", regexp.MustCompile(`^[1-9][0-9]*`)), + testCheckResourceAttrGreaterThanValue(dataSourceName, "ids.#", "1"), ), }, }, @@ -37,7 +31,7 @@ func TestAccEC2NetworkACLsDataSource_basic(t *testing.T) { } func TestAccEC2NetworkACLsDataSource_filter(t *testing.T) { - rName := sdkacctest.RandString(5) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) dataSourceName := "data.aws_network_acls.test" resource.ParallelTest(t, resource.TestCase{ @@ -57,7 +51,7 @@ func TestAccEC2NetworkACLsDataSource_filter(t *testing.T) { } func TestAccEC2NetworkACLsDataSource_tags(t *testing.T) { - rName := sdkacctest.RandString(5) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) dataSourceName := "data.aws_network_acls.test" resource.ParallelTest(t, resource.TestCase{ @@ -77,7 +71,7 @@ func TestAccEC2NetworkACLsDataSource_tags(t *testing.T) { } func TestAccEC2NetworkACLsDataSource_vpcID(t *testing.T) { - rName := sdkacctest.RandString(5) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) dataSourceName := "data.aws_network_acls.test" resource.ParallelTest(t, resource.TestCase{ @@ -97,59 +91,97 @@ func TestAccEC2NetworkACLsDataSource_vpcID(t *testing.T) { }) } +func TestAccEC2NetworkACLsDataSource_empty(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + dataSourceName := "data.aws_network_acls.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckVpcDestroy, + Steps: []resource.TestStep{ + { + Config: testAccNetworkACLsDataSourceConfig_Empty(rName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "ids.#", "0"), + ), + }, + }, + }) +} + func testAccNetworkACLsDataSourceConfig_Base(rName string) string { return fmt.Sprintf(` resource "aws_vpc" "test" { cidr_block = "10.0.0.0/16" tags = { - Name = "testacc-acl-%[1]s" + Name = %[1]q } } -resource "aws_network_acl" "acl" { +resource "aws_network_acl" "test" { count = 2 vpc_id = aws_vpc.test.id tags = { - Name = "testacc-acl-%[1]s" + Name = %[1]q } } `, rName) } func testAccNetworkACLsDataSourceConfig_basic(rName string) string { - return testAccNetworkACLsDataSourceConfig_Base(rName) + ` -data "aws_network_acls" "test" {} -` + return acctest.ConfigCompose(testAccNetworkACLsDataSourceConfig_Base(rName), ` +data "aws_network_acls" "test" { + depends_on = [aws_network_acl.test[0], aws_network_acl.test[1]] +} +`) } func testAccNetworkACLsDataSourceConfig_Filter(rName string) string { - return testAccNetworkACLsDataSourceConfig_Base(rName) + ` + return acctest.ConfigCompose(testAccNetworkACLsDataSourceConfig_Base(rName), ` data "aws_network_acls" "test" { filter { name = "network-acl-id" - values = [aws_network_acl.acl[0].id] + values = [aws_network_acl.test[0].id] } + + depends_on = [aws_network_acl.test[0], aws_network_acl.test[1]] } -` +`) } func testAccNetworkACLsDataSourceConfig_Tags(rName string) string { - return testAccNetworkACLsDataSourceConfig_Base(rName) + ` + return acctest.ConfigCompose(testAccNetworkACLsDataSourceConfig_Base(rName), ` data "aws_network_acls" "test" { tags = { - Name = aws_network_acl.acl[0].tags.Name + Name = aws_network_acl.test[0].tags.Name } + + depends_on = [aws_network_acl.test[0], aws_network_acl.test[1]] } -` +`) } func testAccNetworkACLsDataSourceConfig_VPCID(rName string) string { - return testAccNetworkACLsDataSourceConfig_Base(rName) + ` + return acctest.ConfigCompose(testAccNetworkACLsDataSourceConfig_Base(rName), ` data "aws_network_acls" "test" { - vpc_id = aws_network_acl.acl[0].vpc_id + vpc_id = aws_network_acl.test[0].vpc_id + + depends_on = [aws_network_acl.test[0], aws_network_acl.test[1]] +} +`) } -` + +func testAccNetworkACLsDataSourceConfig_Empty(rName string) string { + return fmt.Sprintf(` +data "aws_network_acls" "test" { + tags = { + Name = %[1]q + } +} +`, rName) } diff --git a/website/docs/d/network_acls.html.markdown b/website/docs/d/network_acls.html.markdown index 5a0d21ce824..e53660d74e7 100644 --- a/website/docs/d/network_acls.html.markdown +++ b/website/docs/d/network_acls.html.markdown @@ -70,4 +70,4 @@ which take the following arguments: ## Attributes Reference * `id` - AWS Region. -* `ids` - A list of all the network ACL ids found. This data source will fail if none are found. +* `ids` - A list of all the network ACL ids found. diff --git a/website/docs/d/route_tables.html.markdown b/website/docs/d/route_tables.html.markdown index e874be58192..37e88521e60 100644 --- a/website/docs/d/route_tables.html.markdown +++ b/website/docs/d/route_tables.html.markdown @@ -55,4 +55,4 @@ which take the following arguments: ## Attributes Reference * `id` - AWS Region. -* `ids` - A set of all the route table ids found. This data source will fail if none are found. +* `ids` - A set of all the route table ids found. diff --git a/website/docs/d/vpcs.html.markdown b/website/docs/d/vpcs.html.markdown index 56b26fcc18a..8cd42429528 100644 --- a/website/docs/d/vpcs.html.markdown +++ b/website/docs/d/vpcs.html.markdown @@ -71,4 +71,4 @@ which take the following arguments: ## Attributes Reference * `id` - AWS Region. -* `ids` - A list of all the VPC Ids found. This data source will fail if none are found. +* `ids` - A list of all the VPC Ids found. From 74f416aab5ceb01b71f3549725521036fb8d27b3 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 25 Jan 2022 16:24:13 -0500 Subject: [PATCH 070/116] d/aws_ec2_transit_gateway_route_tables: Add and use 'FindTransitGatewayRouteTables'. Acceptance test output: % make testacc TESTS=TestAccEC2TransitGatewayDataSource_serial/RouteTables PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2TransitGatewayDataSource_serial/RouteTables' -timeout 180m === RUN TestAccEC2TransitGatewayDataSource_serial === RUN TestAccEC2TransitGatewayDataSource_serial/RouteTables === RUN TestAccEC2TransitGatewayDataSource_serial/RouteTables/Empty === RUN TestAccEC2TransitGatewayDataSource_serial/RouteTables/basic === RUN TestAccEC2TransitGatewayDataSource_serial/RouteTables/Filter === RUN TestAccEC2TransitGatewayDataSource_serial/RouteTables/Tags --- PASS: TestAccEC2TransitGatewayDataSource_serial (1087.03s) --- PASS: TestAccEC2TransitGatewayDataSource_serial/RouteTables (1087.03s) --- PASS: TestAccEC2TransitGatewayDataSource_serial/RouteTables/Empty (10.24s) --- PASS: TestAccEC2TransitGatewayDataSource_serial/RouteTables/basic (351.09s) --- PASS: TestAccEC2TransitGatewayDataSource_serial/RouteTables/Filter (340.75s) --- PASS: TestAccEC2TransitGatewayDataSource_serial/RouteTables/Tags (384.95s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 1090.624s --- .changelog/21219.txt | 4 + internal/service/ec2/find.go | 31 +++++ .../ec2/transit_gateway_data_source_test.go | 4 +- ...ransit_gateway_route_tables_data_source.go | 43 ++----- ...t_gateway_route_tables_data_source_test.go | 118 ++++++++++++++++-- 5 files changed, 155 insertions(+), 45 deletions(-) diff --git a/.changelog/21219.txt b/.changelog/21219.txt index 445dea86e5e..a345b0fbe3a 100644 --- a/.changelog/21219.txt +++ b/.changelog/21219.txt @@ -12,4 +12,8 @@ data-source/aws_network_interfaces: The type of the `ids` attributes has changed ```release-note:note data-source/aws_network_acls: The type of the `ids` attributes has changed from Set to List. If no NACLs match the specified criteria an empty list is returned (previously an error was raised) +``` + +```release-note:note +data-source/aws_ec2_transit_gateway_route_tables: The type of the `ids` attributes has changed from Set to List. If no transit gateway route tables match the specified criteria an empty list is returned (previously an error was raised) ``` \ No newline at end of file diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index 268c1019863..9a4a9f19d2d 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -1827,6 +1827,37 @@ func FindTransitGatewayAttachmentByID(conn *ec2.EC2, id string) (*ec2.TransitGat return output, nil } +func FindTransitGatewayRouteTables(conn *ec2.EC2, input *ec2.DescribeTransitGatewayRouteTablesInput) ([]*ec2.TransitGatewayRouteTable, error) { + var output []*ec2.TransitGatewayRouteTable + + err := conn.DescribeTransitGatewayRouteTablesPages(input, func(page *ec2.DescribeTransitGatewayRouteTablesOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.TransitGatewayRouteTables { + if v != nil { + output = append(output, v) + } + } + + return !lastPage + }) + + if tfawserr.ErrCodeEquals(err, ErrCodeInvalidRouteTableIDNotFound) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + return output, nil +} + func FindDHCPOptions(conn *ec2.EC2, input *ec2.DescribeDhcpOptionsInput) (*ec2.DhcpOptions, error) { output, err := FindDHCPOptionses(conn, input) diff --git a/internal/service/ec2/transit_gateway_data_source_test.go b/internal/service/ec2/transit_gateway_data_source_test.go index 9b3d5c800aa..8cafb8d3e57 100644 --- a/internal/service/ec2/transit_gateway_data_source_test.go +++ b/internal/service/ec2/transit_gateway_data_source_test.go @@ -31,7 +31,9 @@ func TestAccEC2TransitGatewayDataSource_serial(t *testing.T) { }, "RouteTables": { "basic": testAccTransitGatewayRouteTablesDataSource_basic, - "Filter": testAccTransitGatewayRouteTablesDataSource_Filter, + "Filter": testAccTransitGatewayRouteTablesDataSource_filter, + "Tags": testAccTransitGatewayRouteTablesDataSource_tags, + "Empty": testAccTransitGatewayRouteTablesDataSource_empty, }, "VpcAttachment": { "Filter": testAccTransitGatewayVPCAttachmentDataSource_Filter, diff --git a/internal/service/ec2/transit_gateway_route_tables_data_source.go b/internal/service/ec2/transit_gateway_route_tables_data_source.go index 294050898b8..be60da44063 100644 --- a/internal/service/ec2/transit_gateway_route_tables_data_source.go +++ b/internal/service/ec2/transit_gateway_route_tables_data_source.go @@ -15,15 +15,12 @@ func DataSourceTransitGatewayRouteTables() *schema.Resource { Read: dataSourceTransitGatewayRouteTablesRead, Schema: map[string]*schema.Schema{ - "filter": CustomFiltersSchema(), - + "filter": DataSourceFiltersSchema(), "ids": { - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, }, - "tags": tftags.TagsSchemaComputed(), }, } @@ -38,50 +35,28 @@ func dataSourceTransitGatewayRouteTablesRead(d *schema.ResourceData, meta interf Tags(tftags.New(d.Get("tags").(map[string]interface{}))), )...) - input.Filters = append(input.Filters, BuildCustomFilterList( + input.Filters = append(input.Filters, BuildFiltersDataSource( d.Get("filter").(*schema.Set), )...) if len(input.Filters) == 0 { - // Don't send an empty filters list; the EC2 API won't accept it. input.Filters = nil } - var transitGatewayRouteTables []*ec2.TransitGatewayRouteTable - - err := conn.DescribeTransitGatewayRouteTablesPages(input, func(page *ec2.DescribeTransitGatewayRouteTablesOutput, lastPage bool) bool { - if page == nil { - return !lastPage - } - - transitGatewayRouteTables = append(transitGatewayRouteTables, page.TransitGatewayRouteTables...) - - return !lastPage - }) + output, err := FindTransitGatewayRouteTables(conn, input) if err != nil { - return fmt.Errorf("error describing EC2 Transit Gateway Route Tables: %w", err) + return fmt.Errorf("error reading EC2 Transit Gateway Route Tables: %w", err) } - if len(transitGatewayRouteTables) == 0 { - return fmt.Errorf("no matching EC2 Transit Gateway Route Tables found") - } - - var ids []string - - for _, transitGatewayRouteTable := range transitGatewayRouteTables { - if transitGatewayRouteTable == nil { - continue - } + var routeTableIDs []string - ids = append(ids, aws.StringValue(transitGatewayRouteTable.TransitGatewayRouteTableId)) + for _, v := range output { + routeTableIDs = append(routeTableIDs, aws.StringValue(v.TransitGatewayRouteTableId)) } d.SetId(meta.(*conns.AWSClient).Region) - - if err = d.Set("ids", ids); err != nil { - return fmt.Errorf("error setting ids: %w", err) - } + d.Set("ids", routeTableIDs) return nil } diff --git a/internal/service/ec2/transit_gateway_route_tables_data_source_test.go b/internal/service/ec2/transit_gateway_route_tables_data_source_test.go index d33e61175dc..3e3bdfff874 100644 --- a/internal/service/ec2/transit_gateway_route_tables_data_source_test.go +++ b/internal/service/ec2/transit_gateway_route_tables_data_source_test.go @@ -1,14 +1,17 @@ package ec2_test import ( + "fmt" "testing" "github.com/aws/aws-sdk-go/service/ec2" + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-provider-aws/internal/acctest" ) func testAccTransitGatewayRouteTablesDataSource_basic(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) dataSourceName := "data.aws_ec2_transit_gateway_route_tables.test" resource.Test(t, resource.TestCase{ @@ -17,7 +20,7 @@ func testAccTransitGatewayRouteTablesDataSource_basic(t *testing.T) { Providers: acctest.Providers, Steps: []resource.TestStep{ { - Config: testAccTransitGatewayRouteTablesDataSourceConfig, + Config: testAccTransitGatewayRouteTablesDataSourceConfig(rName), Check: resource.ComposeTestCheckFunc( acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "ids.#", "0"), ), @@ -26,7 +29,8 @@ func testAccTransitGatewayRouteTablesDataSource_basic(t *testing.T) { }) } -func testAccTransitGatewayRouteTablesDataSource_Filter(t *testing.T) { +func testAccTransitGatewayRouteTablesDataSource_filter(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) dataSourceName := "data.aws_ec2_transit_gateway_route_tables.test" resource.Test(t, resource.TestCase{ @@ -35,32 +39,89 @@ func testAccTransitGatewayRouteTablesDataSource_Filter(t *testing.T) { Providers: acctest.Providers, Steps: []resource.TestStep{ { - Config: testAccTransitGatewayRouteTablesTransitGatewayFilterDataSource, + Config: testAccTransitGatewayRouteTablesTransitGatewayFilterDataSource(rName), Check: resource.ComposeTestCheckFunc( - acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "ids.#", "0"), + resource.TestCheckResourceAttr(dataSourceName, "ids.#", "2"), + ), + }, + }, + }) +} + +func testAccTransitGatewayRouteTablesDataSource_tags(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + dataSourceName := "data.aws_ec2_transit_gateway_route_tables.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckTransitGateway(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccTransitGatewayRouteTablesTransitGatewayTagsDataSource(rName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "ids.#", "1"), + ), + }, + }, + }) +} + +func testAccTransitGatewayRouteTablesDataSource_empty(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + dataSourceName := "data.aws_ec2_transit_gateway_route_tables.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckTransitGateway(t) }, + ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), + Providers: acctest.Providers, + Steps: []resource.TestStep{ + { + Config: testAccTransitGatewayRouteTablesTransitGatewayEmptyDataSource(rName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "ids.#", "0"), ), }, }, }) } -const testAccTransitGatewayRouteTablesDataSourceConfig = ` -resource "aws_ec2_transit_gateway" "test" {} +func testAccTransitGatewayRouteTablesDataSourceConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_ec2_transit_gateway" "test" { + tags = { + Name = %[1]q + } +} resource "aws_ec2_transit_gateway_route_table" "test" { transit_gateway_id = aws_ec2_transit_gateway.test.id + + tags = { + Name = %[1]q + } } data "aws_ec2_transit_gateway_route_tables" "test" { depends_on = [aws_ec2_transit_gateway_route_table.test] } -` +`, rName) +} -const testAccTransitGatewayRouteTablesTransitGatewayFilterDataSource = ` -resource "aws_ec2_transit_gateway" "test" {} +func testAccTransitGatewayRouteTablesTransitGatewayFilterDataSource(rName string) string { + return fmt.Sprintf(` +resource "aws_ec2_transit_gateway" "test" { + tags = { + Name = %[1]q + } +} resource "aws_ec2_transit_gateway_route_table" "test" { transit_gateway_id = aws_ec2_transit_gateway.test.id + + tags = { + Name = %[1]q + } } data "aws_ec2_transit_gateway_route_tables" "test" { @@ -71,4 +132,41 @@ data "aws_ec2_transit_gateway_route_tables" "test" { depends_on = [aws_ec2_transit_gateway_route_table.test] } -` +`, rName) +} + +func testAccTransitGatewayRouteTablesTransitGatewayTagsDataSource(rName string) string { + return fmt.Sprintf(` +resource "aws_ec2_transit_gateway" "test" { + tags = { + Name = %[1]q + } +} + +resource "aws_ec2_transit_gateway_route_table" "test" { + transit_gateway_id = aws_ec2_transit_gateway.test.id + + tags = { + Name = %[1]q + } +} + +data "aws_ec2_transit_gateway_route_tables" "test" { + tags = { + Name = %[1]q + } + + depends_on = [aws_ec2_transit_gateway_route_table.test] +} +`, rName) +} + +func testAccTransitGatewayRouteTablesTransitGatewayEmptyDataSource(rName string) string { + return fmt.Sprintf(` +data "aws_ec2_transit_gateway_route_tables" "test" { + tags = { + Name = %[1]q + } +} +`, rName) +} From d238e5fe2af8463e3042402e9c6c16bc0cb603b1 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 25 Jan 2022 16:46:12 -0500 Subject: [PATCH 071/116] d/aws_coip_pools: Add and use 'FindCOIPPools'. Acceptance test output: % aws ec2 describe-coip-pools --pool-ids ipv4pool-coip-123a45678b0001234 An error occurred (InvalidPoolID.NotFound) when calling the DescribeCoipPools operation: The pool ID 'ipv4pool-coip-123a45678b0001234' does not exist. ewbankkit@ewbankkit-C02F408DML85 terraform-provider-aws % make testacc TESTS=TestAccEC2CoIPPoolsDataSource_ PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2CoIPPoolsDataSource_' -timeout 180m === RUN TestAccEC2CoIPPoolsDataSource_basic === PAUSE TestAccEC2CoIPPoolsDataSource_basic === RUN TestAccEC2CoIPPoolsDataSource_filter === PAUSE TestAccEC2CoIPPoolsDataSource_filter === CONT TestAccEC2CoIPPoolsDataSource_basic === CONT TestAccEC2CoIPPoolsDataSource_filter acctest.go:1255: skipping since no Outposts found --- SKIP: TestAccEC2CoIPPoolsDataSource_filter (1.36s) === CONT TestAccEC2CoIPPoolsDataSource_basic acctest.go:1255: skipping since no Outposts found --- SKIP: TestAccEC2CoIPPoolsDataSource_basic (1.53s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 5.178s --- .changelog/21219.txt | 4 ++ .../service/ec2/coip_pools_data_source.go | 65 ++++++------------- internal/service/ec2/errors.go | 1 + internal/service/ec2/find.go | 42 +++++++++--- 4 files changed, 57 insertions(+), 55 deletions(-) diff --git a/.changelog/21219.txt b/.changelog/21219.txt index a345b0fbe3a..25df856ea6d 100644 --- a/.changelog/21219.txt +++ b/.changelog/21219.txt @@ -16,4 +16,8 @@ data-source/aws_network_acls: The type of the `ids` attributes has changed from ```release-note:note data-source/aws_ec2_transit_gateway_route_tables: The type of the `ids` attributes has changed from Set to List. If no transit gateway route tables match the specified criteria an empty list is returned (previously an error was raised) +``` + +```release-note:note +data-source/aws_ec2_coip_pools: The type of the `pool_ids` attributes has changed from Set to List. If no COIP pools match the specified criteria an empty list is returned (previously an error was raised) ``` \ No newline at end of file diff --git a/internal/service/ec2/coip_pools_data_source.go b/internal/service/ec2/coip_pools_data_source.go index e2d35941279..1c8a2848afd 100644 --- a/internal/service/ec2/coip_pools_data_source.go +++ b/internal/service/ec2/coip_pools_data_source.go @@ -13,17 +13,15 @@ import ( func DataSourceCoIPPools() *schema.Resource { return &schema.Resource{ Read: dataSourceCoIPPoolsRead, - Schema: map[string]*schema.Schema{ - "filter": CustomFiltersSchema(), - - "tags": tftags.TagsSchemaComputed(), + Schema: map[string]*schema.Schema{ + "filter": DataSourceFiltersSchema(), "pool_ids": { - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, }, + "tags": tftags.TagsSchemaComputed(), }, } } @@ -31,59 +29,34 @@ func DataSourceCoIPPools() *schema.Resource { func dataSourceCoIPPoolsRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - req := &ec2.DescribeCoipPoolsInput{} - - if tags, tagsOk := d.GetOk("tags"); tagsOk { - req.Filters = append(req.Filters, BuildTagFilterList( - Tags(tftags.New(tags.(map[string]interface{}))), - )...) - } - - if filters, filtersOk := d.GetOk("filter"); filtersOk { - req.Filters = append(req.Filters, BuildCustomFilterList( - filters.(*schema.Set), - )...) - } - if len(req.Filters) == 0 { - // Don't send an empty filters list; the EC2 API won't accept it. - req.Filters = nil - } + input := &ec2.DescribeCoipPoolsInput{} - var coipPools []*ec2.CoipPool + input.Filters = append(input.Filters, BuildTagFilterList( + Tags(tftags.New(d.Get("tags").(map[string]interface{}))), + )...) - err := conn.DescribeCoipPoolsPages(req, func(page *ec2.DescribeCoipPoolsOutput, lastPage bool) bool { - if page == nil { - return !lastPage - } + input.Filters = append(input.Filters, BuildFiltersDataSource( + d.Get("filter").(*schema.Set), + )...) - coipPools = append(coipPools, page.CoipPools...) + if len(input.Filters) == 0 { + input.Filters = nil + } - return !lastPage - }) + output, err := FindCOIPPools(conn, input) if err != nil { - return fmt.Errorf("error describing EC2 COIP Pools: %w", err) - } - - if len(coipPools) == 0 { - return fmt.Errorf("no matching EC2 COIP Pools found") + return fmt.Errorf("error reading EC2 COIP Pools: %w", err) } var poolIDs []string - for _, coipPool := range coipPools { - if coipPool == nil { - continue - } - - poolIDs = append(poolIDs, aws.StringValue(coipPool.PoolId)) + for _, v := range output { + poolIDs = append(poolIDs, aws.StringValue(v.PoolId)) } d.SetId(meta.(*conns.AWSClient).Region) - - if err := d.Set("pool_ids", poolIDs); err != nil { - return fmt.Errorf("error setting pool_ids: %w", err) - } + d.Set("pool_ids", poolIDs) return nil } diff --git a/internal/service/ec2/errors.go b/internal/service/ec2/errors.go index d30d6e33e22..f64e5b1d822 100644 --- a/internal/service/ec2/errors.go +++ b/internal/service/ec2/errors.go @@ -43,6 +43,7 @@ const ( ErrCodeInvalidPermissionMalformed = "InvalidPermission.Malformed" ErrCodeInvalidPermissionNotFound = "InvalidPermission.NotFound" ErrCodeInvalidPlacementGroupUnknown = "InvalidPlacementGroup.Unknown" + ErrCodeInvalidPoolIDNotFound = "InvalidPoolID.NotFound" ErrCodeInvalidPrefixListIDNotFound = "InvalidPrefixListID.NotFound" ErrCodeInvalidRouteNotFound = "InvalidRoute.NotFound" ErrCodeInvalidRouteTableIDNotFound = "InvalidRouteTableID.NotFound" diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index 9a4a9f19d2d..e3a1779c2c7 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -172,12 +172,24 @@ func FindClientVPNRouteByID(conn *ec2.EC2, routeID string) (*ec2.DescribeClientV return FindClientVPNRoute(conn, endpointID, targetSubnetID, destinationCidr) } -func FindEIPs(conn *ec2.EC2, input *ec2.DescribeAddressesInput) ([]*ec2.Address, error) { - var addresses []*ec2.Address +func FindCOIPPools(conn *ec2.EC2, input *ec2.DescribeCoipPoolsInput) ([]*ec2.CoipPool, error) { + var output []*ec2.CoipPool - output, err := conn.DescribeAddresses(input) + err := conn.DescribeCoipPoolsPages(input, func(page *ec2.DescribeCoipPoolsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.CoipPools { + if v != nil { + output = append(output, v) + } + } + + return !lastPage + }) - if tfawserr.ErrCodeEquals(err, ErrCodeInvalidAddressNotFound, ErrCodeInvalidAllocationIDNotFound) { + if tfawserr.ErrCodeEquals(err, ErrCodeInvalidPoolIDNotFound) { return nil, &resource.NotFoundError{ LastError: err, LastRequest: input, @@ -188,13 +200,25 @@ func FindEIPs(conn *ec2.EC2, input *ec2.DescribeAddressesInput) ([]*ec2.Address, return nil, err } - for _, v := range output.Addresses { - if v != nil { - addresses = append(addresses, v) - } + return output, nil +} + +func FindCOIPPool(conn *ec2.EC2, input *ec2.DescribeCoipPoolsInput) (*ec2.CoipPool, error) { + output, err := FindCOIPPools(conn, input) + + if err != nil { + return nil, err } - return addresses, nil + if len(output) == 0 || output[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } + + return output[0], nil } func FindHostByID(conn *ec2.EC2, id string) (*ec2.Host, error) { From 6c25f8d4e4d2e98039d5a58e1d88b84d8e50b7cd Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 25 Jan 2022 16:57:50 -0500 Subject: [PATCH 072/116] d/aws_ec2_local_gateway_route_tables: Add and use 'FindLocalGatewayRouteTables'. Acceptance test output: % make testacc TESTS=TestAccEC2LocalGatewayRouteTablesDataSource_ PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2LocalGatewayRouteTablesDataSource_' -timeout 180m === RUN TestAccEC2LocalGatewayRouteTablesDataSource_basic === PAUSE TestAccEC2LocalGatewayRouteTablesDataSource_basic === RUN TestAccEC2LocalGatewayRouteTablesDataSource_filter === PAUSE TestAccEC2LocalGatewayRouteTablesDataSource_filter === CONT TestAccEC2LocalGatewayRouteTablesDataSource_basic === CONT TestAccEC2LocalGatewayRouteTablesDataSource_filter === CONT TestAccEC2LocalGatewayRouteTablesDataSource_basic acctest.go:1255: skipping since no Outposts found --- SKIP: TestAccEC2LocalGatewayRouteTablesDataSource_basic (2.31s) === CONT TestAccEC2LocalGatewayRouteTablesDataSource_filter acctest.go:1255: skipping since no Outposts found --- SKIP: TestAccEC2LocalGatewayRouteTablesDataSource_filter (8.82s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 12.555s --- .changelog/21219.txt | 4 ++ internal/service/ec2/find.go | 42 +++++++++++++++ .../local_gateway_route_tables_data_source.go | 53 ++++++------------- 3 files changed, 61 insertions(+), 38 deletions(-) diff --git a/.changelog/21219.txt b/.changelog/21219.txt index 25df856ea6d..06537a702d6 100644 --- a/.changelog/21219.txt +++ b/.changelog/21219.txt @@ -20,4 +20,8 @@ data-source/aws_ec2_transit_gateway_route_tables: The type of the `ids` attribut ```release-note:note data-source/aws_ec2_coip_pools: The type of the `pool_ids` attributes has changed from Set to List. If no COIP pools match the specified criteria an empty list is returned (previously an error was raised) +``` + +```release-note:note +data-source/aws_ec2_local_gateway_route_tables: The type of the `ids` attributes has changed from Set to List. If no local gateway route tables match the specified criteria an empty list is returned (previously an error was raised) ``` \ No newline at end of file diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index e3a1779c2c7..3d72b4995ab 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -358,6 +358,48 @@ func FindInstanceByID(conn *ec2.EC2, id string) (*ec2.Instance, error) { return output, nil } +func FindLocalGatewayRouteTables(conn *ec2.EC2, input *ec2.DescribeLocalGatewayRouteTablesInput) ([]*ec2.LocalGatewayRouteTable, error) { + var output []*ec2.LocalGatewayRouteTable + + err := conn.DescribeLocalGatewayRouteTablesPages(input, func(page *ec2.DescribeLocalGatewayRouteTablesOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.LocalGatewayRouteTables { + if v != nil { + output = append(output, v) + } + } + + return !lastPage + }) + + if err != nil { + return nil, err + } + + return output, nil +} + +func FindLocalGatewayRouteTable(conn *ec2.EC2, input *ec2.DescribeLocalGatewayRouteTablesInput) (*ec2.LocalGatewayRouteTable, error) { + output, err := FindLocalGatewayRouteTables(conn, input) + + if err != nil { + return nil, err + } + + if len(output) == 0 || output[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } + + return output[0], nil +} + func FindNetworkACL(conn *ec2.EC2, input *ec2.DescribeNetworkAclsInput) (*ec2.NetworkAcl, error) { output, err := FindNetworkACLs(conn, input) diff --git a/internal/service/ec2/local_gateway_route_tables_data_source.go b/internal/service/ec2/local_gateway_route_tables_data_source.go index d16d24e4ec4..d559e69942d 100644 --- a/internal/service/ec2/local_gateway_route_tables_data_source.go +++ b/internal/service/ec2/local_gateway_route_tables_data_source.go @@ -13,17 +13,15 @@ import ( func DataSourceLocalGatewayRouteTables() *schema.Resource { return &schema.Resource{ Read: dataSourceLocalGatewayRouteTablesRead, + Schema: map[string]*schema.Schema{ "filter": CustomFiltersSchema(), - - "tags": tftags.TagsSchemaComputed(), - "ids": { - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, }, + "tags": tftags.TagsSchemaComputed(), }, } } @@ -31,55 +29,34 @@ func DataSourceLocalGatewayRouteTables() *schema.Resource { func dataSourceLocalGatewayRouteTablesRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - req := &ec2.DescribeLocalGatewayRouteTablesInput{} + input := &ec2.DescribeLocalGatewayRouteTablesInput{} - req.Filters = append(req.Filters, BuildTagFilterList( + input.Filters = append(input.Filters, BuildTagFilterList( Tags(tftags.New(d.Get("tags").(map[string]interface{}))), )...) - req.Filters = append(req.Filters, BuildCustomFilterList( + input.Filters = append(input.Filters, BuildFiltersDataSource( d.Get("filter").(*schema.Set), )...) - if len(req.Filters) == 0 { - // Don't send an empty filters list; the EC2 API won't accept it. - req.Filters = nil - } - - var localGatewayRouteTables []*ec2.LocalGatewayRouteTable - err := conn.DescribeLocalGatewayRouteTablesPages(req, func(page *ec2.DescribeLocalGatewayRouteTablesOutput, lastPage bool) bool { - if page == nil { - return !lastPage - } - - localGatewayRouteTables = append(localGatewayRouteTables, page.LocalGatewayRouteTables...) + if len(input.Filters) == 0 { + input.Filters = nil + } - return !lastPage - }) + output, err := FindLocalGatewayRouteTables(conn, input) if err != nil { - return fmt.Errorf("error describing EC2 Local Gateway Route Tables: %w", err) - } - - if len(localGatewayRouteTables) == 0 { - return fmt.Errorf("no matching EC2 Local Gateway Route Tables found") + return fmt.Errorf("error reading EC2 Local Gateway Route Tables: %w", err) } - var ids []string + var routeTableIDs []string - for _, localGatewayRouteTable := range localGatewayRouteTables { - if localGatewayRouteTable == nil { - continue - } - - ids = append(ids, aws.StringValue(localGatewayRouteTable.LocalGatewayRouteTableId)) + for _, v := range output { + routeTableIDs = append(routeTableIDs, aws.StringValue(v.LocalGatewayRouteTableId)) } d.SetId(meta.(*conns.AWSClient).Region) - - if err := d.Set("ids", ids); err != nil { - return fmt.Errorf("error setting ids: %w", err) - } + d.Set("ids", routeTableIDs) return nil } From 284ae31b369503d41117b6891fd072a8f8ec9498 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jan 2022 08:42:56 -0500 Subject: [PATCH 073/116] d/aws_ec2_local_gateway_virtual_interface_groups: Add and use 'FindLocalGatewayVirtualInterfaceGroups'. Acceptance test output: % make testacc TESTS=TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_ PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_' -timeout 180m === RUN TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_basic === PAUSE TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_basic === RUN TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_filter === PAUSE TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_filter === RUN TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_tags === PAUSE TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_tags === CONT TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_basic === CONT TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_tags === CONT TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_filter acctest.go:1255: skipping since no Outposts found --- SKIP: TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_filter (1.40s) === CONT TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_basic acctest.go:1255: skipping since no Outposts found --- SKIP: TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_basic (8.10s) === CONT TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_tags acctest.go:1255: skipping since no Outposts found --- SKIP: TestAccEC2LocalGatewayVirtualInterfaceGroupsDataSource_tags (8.12s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 14.867s --- .changelog/21219.txt | 16 ++++--- internal/service/ec2/find.go | 42 ++++++++++++++++ ...ay_virtual_interface_groups_data_source.go | 48 +++++-------------- 3 files changed, 64 insertions(+), 42 deletions(-) diff --git a/.changelog/21219.txt b/.changelog/21219.txt index 06537a702d6..f05107e2ca4 100644 --- a/.changelog/21219.txt +++ b/.changelog/21219.txt @@ -3,25 +3,29 @@ data-source/aws_security_groups: If no security groups match the specified crite ``` ```release-note:note -data-source/aws_route_tables: The type of the `ids` attributes has changed from Set to List. If no route tables match the specified criteria an empty list is returned (previously an error was raised) +data-source/aws_route_tables: The type of the `ids` attribute has changed from Set to List. If no route tables match the specified criteria an empty list is returned (previously an error was raised) ``` ```release-note:note -data-source/aws_network_interfaces: The type of the `ids` attributes has changed from Set to List. If no network interfaces match the specified criteria an empty list is returned (previously an error was raised) +data-source/aws_network_interfaces: The type of the `ids` attribute has changed from Set to List. If no network interfaces match the specified criteria an empty list is returned (previously an error was raised) ``` ```release-note:note -data-source/aws_network_acls: The type of the `ids` attributes has changed from Set to List. If no NACLs match the specified criteria an empty list is returned (previously an error was raised) +data-source/aws_network_acls: The type of the `ids` attribute has changed from Set to List. If no NACLs match the specified criteria an empty list is returned (previously an error was raised) ``` ```release-note:note -data-source/aws_ec2_transit_gateway_route_tables: The type of the `ids` attributes has changed from Set to List. If no transit gateway route tables match the specified criteria an empty list is returned (previously an error was raised) +data-source/aws_ec2_transit_gateway_route_tables: The type of the `ids` attribute has changed from Set to List. If no transit gateway route tables match the specified criteria an empty list is returned (previously an error was raised) ``` ```release-note:note -data-source/aws_ec2_coip_pools: The type of the `pool_ids` attributes has changed from Set to List. If no COIP pools match the specified criteria an empty list is returned (previously an error was raised) +data-source/aws_ec2_coip_pools: The type of the `pool_ids` attribute has changed from Set to List. If no COIP pools match the specified criteria an empty list is returned (previously an error was raised) ``` ```release-note:note -data-source/aws_ec2_local_gateway_route_tables: The type of the `ids` attributes has changed from Set to List. If no local gateway route tables match the specified criteria an empty list is returned (previously an error was raised) +data-source/aws_ec2_local_gateway_route_tables: The type of the `ids` attribute has changed from Set to List. If no local gateway route tables match the specified criteria an empty list is returned (previously an error was raised) +``` + +```release-note:note +data-source/aws_ec2_local_gateway_virtual_interface_groups: The type of the `ids` and `local_gateway_virtual_interface_ids` attributes has changed from Set to List. If no local gateway virtual interface groups match the specified criteria an empty list is returned (previously an error was raised) ``` \ No newline at end of file diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index 3d72b4995ab..03e0b3d281a 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -400,6 +400,48 @@ func FindLocalGatewayRouteTable(conn *ec2.EC2, input *ec2.DescribeLocalGatewayRo return output[0], nil } +func FindLocalGatewayVirtualInterfaceGroups(conn *ec2.EC2, input *ec2.DescribeLocalGatewayVirtualInterfaceGroupsInput) ([]*ec2.LocalGatewayVirtualInterfaceGroup, error) { + var output []*ec2.LocalGatewayVirtualInterfaceGroup + + err := conn.DescribeLocalGatewayVirtualInterfaceGroupsPages(input, func(page *ec2.DescribeLocalGatewayVirtualInterfaceGroupsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.LocalGatewayVirtualInterfaceGroups { + if v != nil { + output = append(output, v) + } + } + + return !lastPage + }) + + if err != nil { + return nil, err + } + + return output, nil +} + +func FindLocalGatewayVirtualInterfaceGroup(conn *ec2.EC2, input *ec2.DescribeLocalGatewayVirtualInterfaceGroupsInput) (*ec2.LocalGatewayVirtualInterfaceGroup, error) { + output, err := FindLocalGatewayVirtualInterfaceGroups(conn, input) + + if err != nil { + return nil, err + } + + if len(output) == 0 || output[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } + + return output[0], nil +} + func FindNetworkACL(conn *ec2.EC2, input *ec2.DescribeNetworkAclsInput) (*ec2.NetworkAcl, error) { output, err := FindNetworkACLs(conn, input) diff --git a/internal/service/ec2/local_gateway_virtual_interface_groups_data_source.go b/internal/service/ec2/local_gateway_virtual_interface_groups_data_source.go index 7a61ecbe88d..54ef39655ba 100644 --- a/internal/service/ec2/local_gateway_virtual_interface_groups_data_source.go +++ b/internal/service/ec2/local_gateway_virtual_interface_groups_data_source.go @@ -3,6 +3,7 @@ package ec2 import ( "fmt" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" @@ -16,12 +17,12 @@ func DataSourceLocalGatewayVirtualInterfaceGroups() *schema.Resource { Schema: map[string]*schema.Schema{ "filter": CustomFiltersSchema(), "ids": { - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "local_gateway_virtual_interface_ids": { - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, @@ -39,55 +40,30 @@ func dataSourceLocalGatewayVirtualInterfaceGroupsRead(d *schema.ResourceData, me Tags(tftags.New(d.Get("tags").(map[string]interface{}))), )...) - input.Filters = append(input.Filters, BuildCustomFilterList( + input.Filters = append(input.Filters, BuildFiltersDataSource( d.Get("filter").(*schema.Set), )...) if len(input.Filters) == 0 { - // Don't send an empty filters list; the EC2 API won't accept it. input.Filters = nil } - var localGatewayVirtualInterfaceGroups []*ec2.LocalGatewayVirtualInterfaceGroup - - err := conn.DescribeLocalGatewayVirtualInterfaceGroupsPages(input, func(page *ec2.DescribeLocalGatewayVirtualInterfaceGroupsOutput, lastPage bool) bool { - if page == nil { - return !lastPage - } - - localGatewayVirtualInterfaceGroups = append(localGatewayVirtualInterfaceGroups, page.LocalGatewayVirtualInterfaceGroups...) - - return !lastPage - }) + output, err := FindLocalGatewayVirtualInterfaceGroups(conn, input) if err != nil { - return fmt.Errorf("error describing EC2 Local Gateway Virtual Interface Groups: %w", err) - } - - if len(localGatewayVirtualInterfaceGroups) == 0 { - return fmt.Errorf("no matching EC2 Local Gateway Virtual Interface Groups found") + return fmt.Errorf("error reading EC2 Local Gateway Virtual Interface Groups: %w", err) } - var ids, localGatewayVirtualInterfaceIds []*string + var groupIDs, interfaceIDs []string - for _, group := range localGatewayVirtualInterfaceGroups { - if group == nil { - continue - } - - ids = append(ids, group.LocalGatewayVirtualInterfaceGroupId) - localGatewayVirtualInterfaceIds = append(localGatewayVirtualInterfaceIds, group.LocalGatewayVirtualInterfaceIds...) + for _, v := range output { + groupIDs = append(groupIDs, aws.StringValue(v.LocalGatewayVirtualInterfaceGroupId)) + interfaceIDs = append(interfaceIDs, aws.StringValueSlice(v.LocalGatewayVirtualInterfaceIds)...) } d.SetId(meta.(*conns.AWSClient).Region) - - if err := d.Set("ids", ids); err != nil { - return fmt.Errorf("error setting ids: %w", err) - } - - if err := d.Set("local_gateway_virtual_interface_ids", localGatewayVirtualInterfaceIds); err != nil { - return fmt.Errorf("error setting local_gateway_virtual_interface_ids: %w", err) - } + d.Set("ids", groupIDs) + d.Set("local_gateway_virtual_interface_ids", interfaceIDs) return nil } From 419665a7f6417538e34b69d665e9cf8a8b9a6b5a Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jan 2022 08:58:09 -0500 Subject: [PATCH 074/116] d/aws_ec2_local_gateways: Add and use 'FindLocalGateways'. Acceptance test output: % make testacc TESTS=TestAccEC2LocalGatewaysDataSource_ PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2LocalGatewaysDataSource_' -timeout 180m === RUN TestAccEC2LocalGatewaysDataSource_basic === PAUSE TestAccEC2LocalGatewaysDataSource_basic === CONT TestAccEC2LocalGatewaysDataSource_basic acctest.go:1255: skipping since no Outposts found --- SKIP: TestAccEC2LocalGatewaysDataSource_basic (3.35s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 9.011s --- .changelog/21219.txt | 4 ++ internal/service/ec2/find.go | 42 ++++++++++++ .../service/ec2/local_gateways_data_source.go | 64 ++++++------------- 3 files changed, 64 insertions(+), 46 deletions(-) diff --git a/.changelog/21219.txt b/.changelog/21219.txt index f05107e2ca4..ceb6e7096e3 100644 --- a/.changelog/21219.txt +++ b/.changelog/21219.txt @@ -28,4 +28,8 @@ data-source/aws_ec2_local_gateway_route_tables: The type of the `ids` attribute ```release-note:note data-source/aws_ec2_local_gateway_virtual_interface_groups: The type of the `ids` and `local_gateway_virtual_interface_ids` attributes has changed from Set to List. If no local gateway virtual interface groups match the specified criteria an empty list is returned (previously an error was raised) +``` + +```release-note:note +data-source/aws_ec2_local_gateways: The type of the `ids` attribute has changed from Set to List. If no local gateways match the specified criteria an empty list is returned (previously an error was raised) ``` \ No newline at end of file diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index 03e0b3d281a..ccb2bb76150 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -442,6 +442,48 @@ func FindLocalGatewayVirtualInterfaceGroup(conn *ec2.EC2, input *ec2.DescribeLoc return output[0], nil } +func FindLocalGateways(conn *ec2.EC2, input *ec2.DescribeLocalGatewaysInput) ([]*ec2.LocalGateway, error) { + var output []*ec2.LocalGateway + + err := conn.DescribeLocalGatewaysPages(input, func(page *ec2.DescribeLocalGatewaysOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.LocalGateways { + if v != nil { + output = append(output, v) + } + } + + return !lastPage + }) + + if err != nil { + return nil, err + } + + return output, nil +} + +func FindLocalGateway(conn *ec2.EC2, input *ec2.DescribeLocalGatewaysInput) (*ec2.LocalGateway, error) { + output, err := FindLocalGateways(conn, input) + + if err != nil { + return nil, err + } + + if len(output) == 0 || output[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } + + return output[0], nil +} + func FindNetworkACL(conn *ec2.EC2, input *ec2.DescribeNetworkAclsInput) (*ec2.NetworkAcl, error) { output, err := FindNetworkACLs(conn, input) diff --git a/internal/service/ec2/local_gateways_data_source.go b/internal/service/ec2/local_gateways_data_source.go index cf46eae5255..a3934d0d1b1 100644 --- a/internal/service/ec2/local_gateways_data_source.go +++ b/internal/service/ec2/local_gateways_data_source.go @@ -15,15 +15,12 @@ func DataSourceLocalGateways() *schema.Resource { Read: dataSourceLocalGatewaysRead, Schema: map[string]*schema.Schema{ "filter": CustomFiltersSchema(), - - "tags": tftags.TagsSchemaComputed(), - "ids": { - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, }, + "tags": tftags.TagsSchemaComputed(), }, } } @@ -31,59 +28,34 @@ func DataSourceLocalGateways() *schema.Resource { func dataSourceLocalGatewaysRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - req := &ec2.DescribeLocalGatewaysInput{} + input := &ec2.DescribeLocalGatewaysInput{} - if tags, tagsOk := d.GetOk("tags"); tagsOk { - req.Filters = append(req.Filters, BuildTagFilterList( - Tags(tftags.New(tags.(map[string]interface{}))), - )...) - } - - if filters, filtersOk := d.GetOk("filter"); filtersOk { - req.Filters = append(req.Filters, BuildCustomFilterList( - filters.(*schema.Set), - )...) - } - if len(req.Filters) == 0 { - // Don't send an empty filters list; the EC2 API won't accept it. - req.Filters = nil - } + input.Filters = append(input.Filters, BuildTagFilterList( + Tags(tftags.New(d.Get("tags").(map[string]interface{}))), + )...) - var localGateways []*ec2.LocalGateway + input.Filters = append(input.Filters, BuildFiltersDataSource( + d.Get("filter").(*schema.Set), + )...) - err := conn.DescribeLocalGatewaysPages(req, func(page *ec2.DescribeLocalGatewaysOutput, lastPage bool) bool { - if page == nil { - return !lastPage - } - - localGateways = append(localGateways, page.LocalGateways...) + if len(input.Filters) == 0 { + input.Filters = nil + } - return !lastPage - }) + output, err := FindLocalGateways(conn, input) if err != nil { - return fmt.Errorf("error describing EC2 Local Gateways: %w", err) - } - - if len(localGateways) == 0 { - return fmt.Errorf("no matching EC2 Local Gateways found") + return fmt.Errorf("error reading EC2 Local Gateways: %w", err) } - var ids []string + var gatewayIDs []string - for _, localGateway := range localGateways { - if localGateway == nil { - continue - } - - ids = append(ids, aws.StringValue(localGateway.LocalGatewayId)) + for _, v := range output { + gatewayIDs = append(gatewayIDs, aws.StringValue(v.LocalGatewayId)) } d.SetId(meta.(*conns.AWSClient).Region) - - if err := d.Set("ids", ids); err != nil { - return fmt.Errorf("error setting ids: %w", err) - } + d.Set("ids", gatewayIDs) return nil } From 923ae04bdad479d921bbc6153d6cdf9322a67644 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jan 2022 09:27:26 -0500 Subject: [PATCH 075/116] d/aws_ebs_volumes: Add and use 'FindEBSVolumes'. Acceptance test output: % make testacc TESTS=TestAccEC2EBSVolumesDataSource_ PKG=ec2 ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ec2/... -v -count 1 -parallel 20 -run='TestAccEC2EBSVolumesDataSource_' -timeout 180m === RUN TestAccEC2EBSVolumesDataSource_basic === PAUSE TestAccEC2EBSVolumesDataSource_basic === CONT TestAccEC2EBSVolumesDataSource_basic --- PASS: TestAccEC2EBSVolumesDataSource_basic (31.42s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ec2 36.659s --- .changelog/21219.txt | 4 ++ .../service/ec2/ebs_volumes_data_source.go | 55 ++++++---------- .../ec2/ebs_volumes_data_source_test.go | 64 +++++++++++-------- internal/service/ec2/errors.go | 1 + internal/service/ec2/find.go | 49 ++++++++++++++ 5 files changed, 111 insertions(+), 62 deletions(-) diff --git a/.changelog/21219.txt b/.changelog/21219.txt index ceb6e7096e3..2e00a59f67a 100644 --- a/.changelog/21219.txt +++ b/.changelog/21219.txt @@ -32,4 +32,8 @@ data-source/aws_ec2_local_gateway_virtual_interface_groups: The type of the `ids ```release-note:note data-source/aws_ec2_local_gateways: The type of the `ids` attribute has changed from Set to List. If no local gateways match the specified criteria an empty list is returned (previously an error was raised) +``` + +```release-note:note +data-source/aws_ebs_volumes: The type of the `ids` attribute has changed from Set to List. If no volumes match the specified criteria an empty list is returned (previously an error was raised) ``` \ No newline at end of file diff --git a/internal/service/ec2/ebs_volumes_data_source.go b/internal/service/ec2/ebs_volumes_data_source.go index bc9f90cb121..fd5f38b41ab 100644 --- a/internal/service/ec2/ebs_volumes_data_source.go +++ b/internal/service/ec2/ebs_volumes_data_source.go @@ -1,10 +1,9 @@ package ec2 import ( - "errors" "fmt" - "log" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" @@ -15,16 +14,13 @@ func DataSourceEBSVolumes() *schema.Resource { return &schema.Resource{ Read: dataSourceEBSVolumesRead, Schema: map[string]*schema.Schema{ - "filter": CustomFiltersSchema(), - - "tags": tftags.TagsSchema(), - + "filter": DataSourceFiltersSchema(), "ids": { - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, }, + "tags": tftags.TagsSchema(), }, } } @@ -32,45 +28,34 @@ func DataSourceEBSVolumes() *schema.Resource { func dataSourceEBSVolumesRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EC2Conn - req := &ec2.DescribeVolumesInput{} + input := &ec2.DescribeVolumesInput{} - if tags, tagsOk := d.GetOk("tags"); tagsOk { - req.Filters = append(req.Filters, BuildTagFilterList( - Tags(tftags.New(tags.(map[string]interface{}))), - )...) - } + input.Filters = append(input.Filters, BuildTagFilterList( + Tags(tftags.New(d.Get("tags").(map[string]interface{}))), + )...) - if filters, filtersOk := d.GetOk("filter"); filtersOk { - req.Filters = append(req.Filters, BuildCustomFilterList( - filters.(*schema.Set), - )...) - } + input.Filters = append(input.Filters, BuildFiltersDataSource( + d.Get("filter").(*schema.Set), + )...) - if len(req.Filters) == 0 { - req.Filters = nil + if len(input.Filters) == 0 { + input.Filters = nil } - log.Printf("[DEBUG] DescribeVolumes %s\n", req) - resp, err := conn.DescribeVolumes(req) - if err != nil { - return fmt.Errorf("error describing EC2 Volumes: %w", err) - } + output, err := FindEBSVolumes(conn, input) - if resp == nil || len(resp.Volumes) == 0 { - return errors.New("no matching volumes found") + if err != nil { + return fmt.Errorf("error reading EC2 Volumes: %w", err) } - volumes := make([]string, 0) + var volumeIDs []string - for _, volume := range resp.Volumes { - volumes = append(volumes, *volume.VolumeId) + for _, v := range output { + volumeIDs = append(volumeIDs, aws.StringValue(v.VolumeId)) } d.SetId(meta.(*conns.AWSClient).Region) - - if err := d.Set("ids", volumes); err != nil { - return fmt.Errorf("error setting ids: %w", err) - } + d.Set("ids", volumeIDs) return nil } diff --git a/internal/service/ec2/ebs_volumes_data_source_test.go b/internal/service/ec2/ebs_volumes_data_source_test.go index 26d60fa7e0c..e71ffcce07d 100644 --- a/internal/service/ec2/ebs_volumes_data_source_test.go +++ b/internal/service/ec2/ebs_volumes_data_source_test.go @@ -11,7 +11,8 @@ import ( ) func TestAccEC2EBSVolumesDataSource_basic(t *testing.T) { - rInt := sdkacctest.RandIntRange(0, 256) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, ec2.EndpointsID), @@ -19,47 +20,56 @@ func TestAccEC2EBSVolumesDataSource_basic(t *testing.T) { CheckDestroy: testAccCheckVolumeDestroy, Steps: []resource.TestStep{ { - Config: testAccEBSVolumeIDsDataSourceConfig(rInt), - }, - { - Config: testAccEBSVolumeIDsWithDataSourceDataSourceConfig(rInt), + Config: testAccEBSVolumeIDsDataSourceConfig(rName), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("data.aws_ebs_volumes.subject_under_test", "ids.#", "2"), + resource.TestCheckResourceAttr("data.aws_ebs_volumes.by_tags", "ids.#", "2"), + resource.TestCheckResourceAttr("data.aws_ebs_volumes.by_filter", "ids.#", "1"), + resource.TestCheckResourceAttr("data.aws_ebs_volumes.empty", "ids.#", "0"), ), }, - { - // Force the destroy to not refresh the data source (leading to an error) - Config: testAccEBSVolumeIDsDataSourceConfig(rInt), - }, }, }) } -func testAccEBSVolumeIDsWithDataSourceDataSourceConfig(rInt int) string { - return fmt.Sprintf(` -%s - -data "aws_ebs_volumes" "subject_under_test" { - tags = { - TestIdentifierSet = "testAccDataSourceAwsEbsVolumes-%d" - } -} -`, testAccEBSVolumeIDsDataSourceConfig(rInt), rInt) -} - -func testAccEBSVolumeIDsDataSourceConfig(rInt int) string { - return acctest.ConfigAvailableAZsNoOptIn() + fmt.Sprintf(` +func testAccEBSVolumeIDsDataSourceConfig(rName string) string { + return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(` data "aws_region" "current" {} -resource "aws_ebs_volume" "volume" { +resource "aws_ebs_volume" "test" { count = 2 availability_zone = data.aws_availability_zones.available.names[0] size = 1 tags = { - TestIdentifierSet = "testAccDataSourceAwsEbsVolumes-%d" + Name = %[1]q + } +} + +data "aws_ebs_volumes" "by_tags" { + tags = { + Name = %[1]q + } + + depends_on = [aws_ebs_volume.test[0], aws_ebs_volume.test[1]] +} + +data "aws_ebs_volumes" "by_filter" { + filter { + name = "volume-id" + values = [aws_ebs_volume.test[0].id] + } + + depends_on = [aws_ebs_volume.test[0], aws_ebs_volume.test[1]] +} + +data "aws_ebs_volumes" "empty" { + filter { + name = "create-time" + values = ["2000-01-01T00:00:00.000Z"] } + + depends_on = [aws_ebs_volume.test[0], aws_ebs_volume.test[1]] } -`, rInt) +`, rName)) } diff --git a/internal/service/ec2/errors.go b/internal/service/ec2/errors.go index f64e5b1d822..6c4bf62c7da 100644 --- a/internal/service/ec2/errors.go +++ b/internal/service/ec2/errors.go @@ -57,6 +57,7 @@ const ( ErrCodeInvalidSubnetIdNotFound = "InvalidSubnetId.NotFound" ErrCodeInvalidTransitGatewayAttachmentIDNotFound = "InvalidTransitGatewayAttachmentID.NotFound" ErrCodeInvalidTransitGatewayIDNotFound = "InvalidTransitGatewayID.NotFound" + ErrCodeInvalidVolumeNotFound = "InvalidVolume.NotFound" ErrCodeInvalidVpcCidrBlockAssociationIDNotFound = "InvalidVpcCidrBlockAssociationID.NotFound" ErrCodeInvalidVpcEndpointIdNotFound = "InvalidVpcEndpointId.NotFound" ErrCodeInvalidVpcEndpointNotFound = "InvalidVpcEndpoint.NotFound" diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index ccb2bb76150..16caa202866 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -221,6 +221,55 @@ func FindCOIPPool(conn *ec2.EC2, input *ec2.DescribeCoipPoolsInput) (*ec2.CoipPo return output[0], nil } +func FindEBSVolumes(conn *ec2.EC2, input *ec2.DescribeVolumesInput) ([]*ec2.Volume, error) { + var output []*ec2.Volume + + err := conn.DescribeVolumesPages(input, func(page *ec2.DescribeVolumesOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.Volumes { + if v != nil { + output = append(output, v) + } + } + + return !lastPage + }) + + if tfawserr.ErrCodeEquals(err, ErrCodeInvalidVolumeNotFound) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + return output, nil +} + +func FindEBSVolume(conn *ec2.EC2, input *ec2.DescribeVolumesInput) (*ec2.Volume, error) { + output, err := FindEBSVolumes(conn, input) + + if err != nil { + return nil, err + } + + if len(output) == 0 || output[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } + + return output[0], nil +} + func FindHostByID(conn *ec2.EC2, id string) (*ec2.Host, error) { input := &ec2.DescribeHostsInput{ HostIds: aws.StringSlice([]string{id}), From 7dc7ca9d20aea3c6cc8876d028b5510667067f8c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jan 2022 09:30:54 -0500 Subject: [PATCH 076/116] 'CustomFiltersSchema' -> 'DataSourceFiltersSchema'. --- internal/service/ec2/local_gateway_route_tables_data_source.go | 2 +- .../ec2/local_gateway_virtual_interface_groups_data_source.go | 2 +- internal/service/ec2/local_gateways_data_source.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/service/ec2/local_gateway_route_tables_data_source.go b/internal/service/ec2/local_gateway_route_tables_data_source.go index d559e69942d..4db12ee2680 100644 --- a/internal/service/ec2/local_gateway_route_tables_data_source.go +++ b/internal/service/ec2/local_gateway_route_tables_data_source.go @@ -15,7 +15,7 @@ func DataSourceLocalGatewayRouteTables() *schema.Resource { Read: dataSourceLocalGatewayRouteTablesRead, Schema: map[string]*schema.Schema{ - "filter": CustomFiltersSchema(), + "filter": DataSourceFiltersSchema(), "ids": { Type: schema.TypeList, Computed: true, diff --git a/internal/service/ec2/local_gateway_virtual_interface_groups_data_source.go b/internal/service/ec2/local_gateway_virtual_interface_groups_data_source.go index 54ef39655ba..b4481123d48 100644 --- a/internal/service/ec2/local_gateway_virtual_interface_groups_data_source.go +++ b/internal/service/ec2/local_gateway_virtual_interface_groups_data_source.go @@ -15,7 +15,7 @@ func DataSourceLocalGatewayVirtualInterfaceGroups() *schema.Resource { Read: dataSourceLocalGatewayVirtualInterfaceGroupsRead, Schema: map[string]*schema.Schema{ - "filter": CustomFiltersSchema(), + "filter": DataSourceFiltersSchema(), "ids": { Type: schema.TypeList, Computed: true, diff --git a/internal/service/ec2/local_gateways_data_source.go b/internal/service/ec2/local_gateways_data_source.go index a3934d0d1b1..9a4ae075086 100644 --- a/internal/service/ec2/local_gateways_data_source.go +++ b/internal/service/ec2/local_gateways_data_source.go @@ -14,7 +14,7 @@ func DataSourceLocalGateways() *schema.Resource { return &schema.Resource{ Read: dataSourceLocalGatewaysRead, Schema: map[string]*schema.Schema{ - "filter": CustomFiltersSchema(), + "filter": DataSourceFiltersSchema(), "ids": { Type: schema.TypeList, Computed: true, From a0c42d7e77082232a6efd6c063fcf1b9bd86a014 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jan 2022 09:55:20 -0500 Subject: [PATCH 077/116] d/aws_cognito_user_pools: Allow no pools to be selected. Acceptance test output: % make testacc TESTS=TestAccCognitoIDPUserPoolsDataSource_ PKG=cognitoidp ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/cognitoidp/... -v -count 1 -parallel 20 -run='TestAccCognitoIDPUserPoolsDataSource_' -timeout 180m === RUN TestAccCognitoIDPUserPoolsDataSource_basic === PAUSE TestAccCognitoIDPUserPoolsDataSource_basic === CONT TestAccCognitoIDPUserPoolsDataSource_basic --- PASS: TestAccCognitoIDPUserPoolsDataSource_basic (18.78s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/cognitoidp 24.721s --- .changelog/21219.txt | 4 + .../cognitoidp/user_pools_data_source.go | 99 ++++++++++--------- .../cognitoidp/user_pools_data_source_test.go | 38 ++++--- 3 files changed, 72 insertions(+), 69 deletions(-) diff --git a/.changelog/21219.txt b/.changelog/21219.txt index 2e00a59f67a..da14c5b792d 100644 --- a/.changelog/21219.txt +++ b/.changelog/21219.txt @@ -36,4 +36,8 @@ data-source/aws_ec2_local_gateways: The type of the `ids` attribute has changed ```release-note:note data-source/aws_ebs_volumes: The type of the `ids` attribute has changed from Set to List. If no volumes match the specified criteria an empty list is returned (previously an error was raised) +``` + +```release-note:note +data-source/aws_cognito_user_pools: The type of the `ids` and `arns` attributes has changed from Set to List. If no volumes match the specified criteria an empty list is returned (previously an error was raised) ``` \ No newline at end of file diff --git a/internal/service/cognitoidp/user_pools_data_source.go b/internal/service/cognitoidp/user_pools_data_source.go index 0c29cc0e82a..30ed24abdd4 100644 --- a/internal/service/cognitoidp/user_pools_data_source.go +++ b/internal/service/cognitoidp/user_pools_data_source.go @@ -13,85 +13,86 @@ import ( func DataSourceUserPools() *schema.Resource { return &schema.Resource{ Read: dataSourceUserPoolsRead, + Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - }, - "ids": { - Type: schema.TypeSet, + "arns": { + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, - "arns": { - Type: schema.TypeSet, + "ids": { + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, + "name": { + Type: schema.TypeString, + Required: true, + }, }, } } func dataSourceUserPoolsRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).CognitoIDPConn - name := d.Get("name").(string) - var ids []string - var arns []string - pools, err := getAllCognitoUserPools(conn) + output, err := findUserPoolDescriptionTypes(conn) + if err != nil { - return fmt.Errorf("Error listing cognito user pools: %w", err) + return fmt.Errorf("error reading Cognito User Pools: %w", err) } - for _, pool := range pools { - if name == aws.StringValue(pool.Name) { - id := aws.StringValue(pool.Id) - arn := arn.ARN{ - Partition: meta.(*conns.AWSClient).Partition, - Service: "cognito-idp", - Region: meta.(*conns.AWSClient).Region, - AccountID: meta.(*conns.AWSClient).AccountID, - Resource: fmt.Sprintf("userpool/%s", id), - }.String() - - ids = append(ids, id) - arns = append(arns, arn) + + name := d.Get("name").(string) + var arns, userPoolIDs []string + + for _, v := range output { + if name != aws.StringValue(v.Name) { + continue } - } - if len(ids) == 0 { - return fmt.Errorf("No cognito user pool found with name: %s", name) + userPoolID := aws.StringValue(v.Id) + arn := arn.ARN{ + Partition: meta.(*conns.AWSClient).Partition, + Service: cognitoidentityprovider.ServiceName, + Region: meta.(*conns.AWSClient).Region, + AccountID: meta.(*conns.AWSClient).AccountID, + Resource: fmt.Sprintf("userpool/%s", userPoolID), + }.String() + + userPoolIDs = append(userPoolIDs, userPoolID) + arns = append(arns, arn) } d.SetId(name) - d.Set("ids", ids) + d.Set("ids", userPoolIDs) d.Set("arns", arns) return nil } -func getAllCognitoUserPools(conn *cognitoidentityprovider.CognitoIdentityProvider) ([]*cognitoidentityprovider.UserPoolDescriptionType, error) { - var pools []*cognitoidentityprovider.UserPoolDescriptionType - var nextToken string +func findUserPoolDescriptionTypes(conn *cognitoidentityprovider.CognitoIdentityProvider) ([]*cognitoidentityprovider.UserPoolDescriptionType, error) { + input := &cognitoidentityprovider.ListUserPoolsInput{ + MaxResults: aws.Int64(60), + } + var output []*cognitoidentityprovider.UserPoolDescriptionType - for { - input := &cognitoidentityprovider.ListUserPoolsInput{ - // MaxResults Valid Range: Minimum value of 1. Maximum value of 60 - MaxResults: aws.Int64(60), - } - if nextToken != "" { - input.NextToken = aws.String(nextToken) - } - out, err := conn.ListUserPools(input) - if err != nil { - return pools, err + err := conn.ListUserPoolsPages(input, func(page *cognitoidentityprovider.ListUserPoolsOutput, lastPage bool) bool { + if page == nil { + return !lastPage } - pools = append(pools, out.UserPools...) - if out.NextToken == nil { - break + for _, v := range page.UserPools { + if v != nil { + output = append(output, v) + } } - nextToken = aws.StringValue(out.NextToken) + + return !lastPage + }) + + if err != nil { + return nil, err } - return pools, nil + return output, nil } diff --git a/internal/service/cognitoidp/user_pools_data_source_test.go b/internal/service/cognitoidp/user_pools_data_source_test.go index ecce4ddc6bd..1a5eb7cbd4a 100644 --- a/internal/service/cognitoidp/user_pools_data_source_test.go +++ b/internal/service/cognitoidp/user_pools_data_source_test.go @@ -2,7 +2,6 @@ package cognitoidp_test import ( "fmt" - "regexp" "testing" "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" @@ -12,44 +11,43 @@ import ( ) func TestAccCognitoIDPUserPoolsDataSource_basic(t *testing.T) { - rName := fmt.Sprintf("tf_acc_ds_cognito_user_pools_%s", sdkacctest.RandString(7)) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIdentityProvider(t) }, ErrorCheck: acctest.ErrorCheck(t, cognitoidentityprovider.EndpointsID), Providers: acctest.Providers, Steps: []resource.TestStep{ { - Config: testAccUserPoolsDataSourceConfig_basic(rName), + Config: testAccUserPoolsDataSourceConfig(rName), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("data.aws_cognito_user_pools.selected", "ids.#", "2"), - resource.TestCheckResourceAttr("data.aws_cognito_user_pools.selected", "arns.#", "2"), + resource.TestCheckResourceAttr("data.aws_cognito_user_pools.test", "arns.#", "2"), + resource.TestCheckResourceAttr("data.aws_cognito_user_pools.test", "ids.#", "2"), + resource.TestCheckResourceAttr("data.aws_cognito_user_pools.empty", "arns.#", "0"), + resource.TestCheckResourceAttr("data.aws_cognito_user_pools.empty", "ids.#", "0"), ), }, - { - Config: testAccUserPoolsDataSourceConfig_notFound(rName), - ExpectError: regexp.MustCompile(`No cognito user pool found with name:`), - }, }, }) } -func testAccUserPoolsDataSourceConfig_basic(rName string) string { +func testAccUserPoolsDataSourceConfig(rName string) string { return fmt.Sprintf(` -resource "aws_cognito_user_pool" "main" { +resource "aws_cognito_user_pool" "test" { count = 2 - name = "%s" + name = %[1]q } -data "aws_cognito_user_pools" "selected" { - name = aws_cognito_user_pool.main.*.name[0] -} -`, rName) +data "aws_cognito_user_pools" "test" { + name = %[1]q + + depends_on = [aws_cognito_user_pool.test[0], aws_cognito_user_pool.test[1]] } -func testAccUserPoolsDataSourceConfig_notFound(rName string) string { - return fmt.Sprintf(` -data "aws_cognito_user_pools" "selected" { - name = "%s-not-found" +data "aws_cognito_user_pools" "empty" { + name = "not.%[1]s" + + depends_on = [aws_cognito_user_pool.test[0], aws_cognito_user_pool.test[1]] } `, rName) } From f145d79405f2eb8084617cc541e4cc08487d7f9b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jan 2022 10:05:49 -0500 Subject: [PATCH 078/116] d/aws_ip_ranges: Allow empty results. Acceptance test output: % make testacc TESTS=TestAccMetaIPRangesDataSource_ PKG=meta ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/meta/... -v -count 1 -parallel 20 -run='TestAccMetaIPRangesDataSource_' -timeout 180m === RUN TestAccMetaIPRangesDataSource_basic === PAUSE TestAccMetaIPRangesDataSource_basic === RUN TestAccMetaIPRangesDataSource_url === PAUSE TestAccMetaIPRangesDataSource_url === CONT TestAccMetaIPRangesDataSource_basic === CONT TestAccMetaIPRangesDataSource_url --- PASS: TestAccMetaIPRangesDataSource_url (16.39s) --- PASS: TestAccMetaIPRangesDataSource_basic (17.24s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/meta 22.673s --- .changelog/21219.txt | 4 ++++ internal/service/meta/ip_ranges_data_source.go | 4 ---- internal/service/meta/ip_ranges_data_source_test.go | 7 +++++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.changelog/21219.txt b/.changelog/21219.txt index da14c5b792d..6d3992fe0c8 100644 --- a/.changelog/21219.txt +++ b/.changelog/21219.txt @@ -40,4 +40,8 @@ data-source/aws_ebs_volumes: The type of the `ids` attribute has changed from Se ```release-note:note data-source/aws_cognito_user_pools: The type of the `ids` and `arns` attributes has changed from Set to List. If no volumes match the specified criteria an empty list is returned (previously an error was raised) +``` + +```release-note:note +data-source/aws_ip_ranges: If no ranges match the specified criteria an empty list is returned (previously an error was raised) ``` \ No newline at end of file diff --git a/internal/service/meta/ip_ranges_data_source.go b/internal/service/meta/ip_ranges_data_source.go index ba208bb09f4..2ad149767f3 100644 --- a/internal/service/meta/ip_ranges_data_source.go +++ b/internal/service/meta/ip_ranges_data_source.go @@ -160,10 +160,6 @@ func dataSourceIPRangesRead(d *schema.ResourceData, meta interface{}) error { } } - if len(ipPrefixes) == 0 && len(ipv6Prefixes) == 0 { - return fmt.Errorf("No IP ranges result from filters from (%s)", url) - } - sort.Strings(ipPrefixes) if err := d.Set("cidr_blocks", ipPrefixes); err != nil { diff --git a/internal/service/meta/ip_ranges_data_source_test.go b/internal/service/meta/ip_ranges_data_source_test.go index e3dbe2fdf6a..547afd791d6 100644 --- a/internal/service/meta/ip_ranges_data_source_test.go +++ b/internal/service/meta/ip_ranges_data_source_test.go @@ -27,6 +27,8 @@ func TestAccMetaIPRangesDataSource_basic(t *testing.T) { testAccIPRangesCheckAttributes("data.aws_ip_ranges.some"), testAccIPRangesCheckCIDRBlocksAttribute("data.aws_ip_ranges.some", "cidr_blocks"), testAccIPRangesCheckCIDRBlocksAttribute("data.aws_ip_ranges.some", "ipv6_cidr_blocks"), + resource.TestCheckResourceAttr("data.aws_ip_ranges.none", "cidr_blocks.#", "0"), + resource.TestCheckResourceAttr("data.aws_ip_ranges.none", "ipv6_cidr_blocks.#", "0"), ), }, }, @@ -163,6 +165,11 @@ data "aws_ip_ranges" "some" { regions = ["eu-west-1", "eu-central-1"] services = ["ec2"] } + +data "aws_ip_ranges" "none" { + regions = ["mars-1"] + services = ["blueorigin"] +} ` // lintignore:AWSAT003 From 51375d7b3fb7a87ea1080d00b07fa901a3fc5510 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jan 2022 12:23:55 -0500 Subject: [PATCH 079/116] d/aws_efs_access_points: Allow empty results. Acceptance test output: % make testacc TESTS=TestAccEFSAccessPointsDataSource_ PKG=efs ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/efs/... -v -count 1 -parallel 20 -run='TestAccEFSAccessPointsDataSource_' -timeout 180m === RUN TestAccEFSAccessPointsDataSource_basic === PAUSE TestAccEFSAccessPointsDataSource_basic === RUN TestAccEFSAccessPointsDataSource_empty === PAUSE TestAccEFSAccessPointsDataSource_empty === CONT TestAccEFSAccessPointsDataSource_basic === CONT TestAccEFSAccessPointsDataSource_empty --- PASS: TestAccEFSAccessPointsDataSource_empty (29.39s) --- PASS: TestAccEFSAccessPointsDataSource_basic (39.36s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/efs 45.604s --- .changelog/21219.txt | 4 ++ .../service/efs/access_points_data_source.go | 62 ++++++++++--------- .../efs/access_points_data_source_test.go | 30 +++++++++ 3 files changed, 67 insertions(+), 29 deletions(-) diff --git a/.changelog/21219.txt b/.changelog/21219.txt index 6d3992fe0c8..cfa8e491a8d 100644 --- a/.changelog/21219.txt +++ b/.changelog/21219.txt @@ -44,4 +44,8 @@ data-source/aws_cognito_user_pools: The type of the `ids` and `arns` attributes ```release-note:note data-source/aws_ip_ranges: If no ranges match the specified criteria an empty list is returned (previously an error was raised) +``` + +```release-note:note +data-source/aws_efs_access_points: The type of the `ids` and `arns` attributes has changed from Set to List. If no access points match the specified criteria an empty list is returned (previously an error was raised) ``` \ No newline at end of file diff --git a/internal/service/efs/access_points_data_source.go b/internal/service/efs/access_points_data_source.go index 3fc36a150d1..44b4abf0516 100644 --- a/internal/service/efs/access_points_data_source.go +++ b/internal/service/efs/access_points_data_source.go @@ -16,7 +16,7 @@ func DataSourceAccessPoints() *schema.Resource { Schema: map[string]*schema.Schema{ "arns": { - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, @@ -26,7 +26,7 @@ func DataSourceAccessPoints() *schema.Resource { ValidateFunc: validation.StringIsNotEmpty, }, "ids": { - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, @@ -37,47 +37,51 @@ func DataSourceAccessPoints() *schema.Resource { func dataSourceAccessPointsRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).EFSConn - fileSystemId := d.Get("file_system_id").(string) + fileSystemID := d.Get("file_system_id").(string) input := &efs.DescribeAccessPointsInput{ - FileSystemId: aws.String(fileSystemId), + FileSystemId: aws.String(fileSystemID), } - var accessPoints []*efs.AccessPointDescription + output, err := findAccessPointDescriptions(conn, input) + + if err != nil { + return fmt.Errorf("error reading EFS Access Points: %w", err) + } + + var accessPointIDs, arns []string + + for _, v := range output { + accessPointIDs = append(accessPointIDs, aws.StringValue(v.AccessPointId)) + arns = append(arns, aws.StringValue(v.AccessPointArn)) + } + + d.SetId(fileSystemID) + d.Set("arns", arns) + d.Set("ids", accessPointIDs) + + return nil +} + +func findAccessPointDescriptions(conn *efs.EFS, input *efs.DescribeAccessPointsInput) ([]*efs.AccessPointDescription, error) { + var output []*efs.AccessPointDescription err := conn.DescribeAccessPointsPages(input, func(page *efs.DescribeAccessPointsOutput, lastPage bool) bool { if page == nil { return !lastPage } - accessPoints = append(accessPoints, page.AccessPoints...) + for _, v := range page.AccessPoints { + if v != nil { + output = append(output, v) + } + } return !lastPage }) if err != nil { - return fmt.Errorf("error reading EFS Access Points for File System (%s): %w", fileSystemId, err) + return nil, err } - if len(accessPoints) == 0 { - return fmt.Errorf("no matching EFS Access Points for File System (%s) found", fileSystemId) - } - - d.SetId(fileSystemId) - - var arns, ids []string - - for _, accessPoint := range accessPoints { - arns = append(arns, aws.StringValue(accessPoint.AccessPointArn)) - ids = append(ids, aws.StringValue(accessPoint.AccessPointId)) - } - - if err := d.Set("arns", arns); err != nil { - return fmt.Errorf("error setting arns: %w", err) - } - - if err := d.Set("ids", ids); err != nil { - return fmt.Errorf("error setting ids: %w", err) - } - - return nil + return output, nil } diff --git a/internal/service/efs/access_points_data_source_test.go b/internal/service/efs/access_points_data_source_test.go index 9e87e146a34..9ae9a1b3f4d 100644 --- a/internal/service/efs/access_points_data_source_test.go +++ b/internal/service/efs/access_points_data_source_test.go @@ -28,6 +28,26 @@ func TestAccEFSAccessPointsDataSource_basic(t *testing.T) { }) } +func TestAccEFSAccessPointsDataSource_empty(t *testing.T) { + dataSourceName := "data.aws_efs_access_points.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, efs.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckEfsAccessPointDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAccessPointsEmptyDataSourceConfig(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "arns.#", "0"), + resource.TestCheckResourceAttr(dataSourceName, "ids.#", "0"), + ), + }, + }, + }) +} + func testAccAccessPointsDataSourceConfig() string { return ` resource "aws_efs_file_system" "test" {} @@ -41,3 +61,13 @@ data "aws_efs_access_points" "test" { } ` } + +func testAccAccessPointsEmptyDataSourceConfig() string { + return ` +resource "aws_efs_file_system" "test" {} + +data "aws_efs_access_points" "test" { + file_system_id = aws_efs_file_system.test.id +} +` +} From b466351f6ab3fe49d1b31a17c67f6e8bd3aa4e96 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jan 2022 13:49:23 -0500 Subject: [PATCH 080/116] d/aws_emr_release_labels: Allow empty result. Acceptance test output: % make testacc TESTS=TestAccEMRReleaseLabels_ PKG=emr ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/emr/... -v -count 1 -parallel 20 -run='TestAccEMRReleaseLabels_' -timeout 180m === RUN TestAccEMRReleaseLabels_basic === PAUSE TestAccEMRReleaseLabels_basic === RUN TestAccEMRReleaseLabels_prefix === PAUSE TestAccEMRReleaseLabels_prefix === RUN TestAccEMRReleaseLabels_application === PAUSE TestAccEMRReleaseLabels_application === RUN TestAccEMRReleaseLabels_full === PAUSE TestAccEMRReleaseLabels_full === RUN TestAccEMRReleaseLabels_empty === PAUSE TestAccEMRReleaseLabels_empty === CONT TestAccEMRReleaseLabels_basic === CONT TestAccEMRReleaseLabels_full === CONT TestAccEMRReleaseLabels_empty === CONT TestAccEMRReleaseLabels_prefix === CONT TestAccEMRReleaseLabels_application --- PASS: TestAccEMRReleaseLabels_application (18.21s) --- PASS: TestAccEMRReleaseLabels_prefix (18.57s) --- PASS: TestAccEMRReleaseLabels_empty (18.75s) --- PASS: TestAccEMRReleaseLabels_full (18.79s) --- PASS: TestAccEMRReleaseLabels_basic (19.38s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/emr 24.816s --- .changelog/21219.txt | 6 ++- .../service/emr/release_labels_data_source.go | 44 +++++++++++++++---- .../emr/release_labels_data_source_test.go | 29 ++++++++++++ 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/.changelog/21219.txt b/.changelog/21219.txt index cfa8e491a8d..7bfb3ce009d 100644 --- a/.changelog/21219.txt +++ b/.changelog/21219.txt @@ -48,4 +48,8 @@ data-source/aws_ip_ranges: If no ranges match the specified criteria an empty li ```release-note:note data-source/aws_efs_access_points: The type of the `ids` and `arns` attributes has changed from Set to List. If no access points match the specified criteria an empty list is returned (previously an error was raised) -``` \ No newline at end of file +``` + +```release-note:note +data-source/aws_emr_release_labels: The type of the `ids` attribute has changed from Set to List. If no release labels match the specified criteria an empty list is returned (previously an error was raised) +``` diff --git a/internal/service/emr/release_labels_data_source.go b/internal/service/emr/release_labels_data_source.go index b863bac5584..b8b92b9f8b5 100644 --- a/internal/service/emr/release_labels_data_source.go +++ b/internal/service/emr/release_labels_data_source.go @@ -10,12 +10,12 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" - "github.com/hashicorp/terraform-provider-aws/internal/flex" ) func DataSourceReleaseLabels() *schema.Resource { return &schema.Resource{ ReadWithoutTimeout: dataSourceReleaseLabelsRead, + Schema: map[string]*schema.Schema{ "filters": { Type: schema.TypeList, @@ -35,7 +35,7 @@ func DataSourceReleaseLabels() *schema.Resource { }, }, "release_labels": { - Type: schema.TypeSet, + Type: schema.TypeList, Elem: &schema.Schema{Type: schema.TypeString}, Computed: true, }, @@ -52,17 +52,20 @@ func dataSourceReleaseLabelsRead(ctx context.Context, d *schema.ResourceData, me input.Filters = expandReleaseLabelsFilters(v.([]interface{})) } - out, err := conn.ListReleaseLabels(input) + output, err := findReleaseLabels(conn, input) + if err != nil { - return diag.FromErr(fmt.Errorf("error reading EMR Release Label: %w", err)) + return diag.FromErr(fmt.Errorf("error reading EMR Release Labels: %w", err)) } - if len(out.ReleaseLabels) == 0 { - return diag.Errorf("no EMR release labels found") - } + releaseLabels := aws.StringValueSlice(output) - d.SetId(strings.Join(aws.StringValueSlice(out.ReleaseLabels), ",")) - d.Set("release_labels", flex.FlattenStringSet(out.ReleaseLabels)) + if len(releaseLabels) == 0 { + d.SetId(",") + } else { + d.SetId(strings.Join(releaseLabels, ",")) + } + d.Set("release_labels", releaseLabels) return nil } @@ -85,3 +88,26 @@ func expandReleaseLabelsFilters(filters []interface{}) *emr.ReleaseLabelFilter { return app } + +func findReleaseLabels(conn *emr.EMR, input *emr.ListReleaseLabelsInput) ([]*string, error) { + var output []*string + + err := conn.ListReleaseLabelsPages(input, func(page *emr.ListReleaseLabelsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + for _, v := range page.ReleaseLabels { + if v != nil { + output = append(output, v) + } + } + + return !lastPage + }) + + if err != nil { + return nil, err + } + + return output, nil +} diff --git a/internal/service/emr/release_labels_data_source_test.go b/internal/service/emr/release_labels_data_source_test.go index ca2836f04a0..646adf090a6 100644 --- a/internal/service/emr/release_labels_data_source_test.go +++ b/internal/service/emr/release_labels_data_source_test.go @@ -84,6 +84,25 @@ func TestAccEMRReleaseLabels_full(t *testing.T) { }) } +func TestAccEMRReleaseLabels_empty(t *testing.T) { + dataSourceResourceName := "data.aws_emr_release_labels.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, emr.EndpointsID), + ProviderFactories: acctest.ProviderFactories, + CheckDestroy: nil, + Steps: []resource.TestStep{ + { + Config: testAccReleaseLabelsDataSourceConfigEmpty(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceResourceName, "release_labels.#", "0"), + ), + }, + }, + }) +} + func testAccReleaseLabelsDataSourceConfigBasic() string { return ` data "aws_emr_release_labels" "test" {} @@ -120,3 +139,13 @@ data "aws_emr_release_labels" "test" { } ` } + +func testAccReleaseLabelsDataSourceConfigEmpty() string { + return ` +data "aws_emr_release_labels" "test" { + filters { + prefix = "emr-0" + } +} +` +} From 6d5fbae4ed68a40d2ce15b5113511f5db86fe0e5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jan 2022 14:40:46 -0500 Subject: [PATCH 081/116] d/aws_ssoadmin_instances: Allow empty results. Acceptance test output: % make testacc TESTS=TestAccSSOAdminInstancesDataSource_ PKG=ssoadmin ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./internal/service/ssoadmin/... -v -count 1 -parallel 20 -run='TestAccSSOAdminInstancesDataSource_' -timeout 180m === RUN TestAccSSOAdminInstancesDataSource_basic === PAUSE TestAccSSOAdminInstancesDataSource_basic === CONT TestAccSSOAdminInstancesDataSource_basic --- PASS: TestAccSSOAdminInstancesDataSource_basic (12.10s) PASS ok github.com/hashicorp/terraform-provider-aws/internal/service/ssoadmin 17.085s --- .changelog/21219.txt | 12 ++++ .../inspector/rules_packages_data_source.go | 45 ++++++++------ .../rds/event_categories_data_source.go | 60 +++++++++++-------- .../service/ssoadmin/instances_data_source.go | 59 ++++++++++-------- 4 files changed, 108 insertions(+), 68 deletions(-) diff --git a/.changelog/21219.txt b/.changelog/21219.txt index 7bfb3ce009d..4870302226c 100644 --- a/.changelog/21219.txt +++ b/.changelog/21219.txt @@ -53,3 +53,15 @@ data-source/aws_efs_access_points: The type of the `ids` and `arns` attributes h ```release-note:note data-source/aws_emr_release_labels: The type of the `ids` attribute has changed from Set to List. If no release labels match the specified criteria an empty list is returned (previously an error was raised) ``` + +```release-note:note +data-source/aws_inspector_rules_packages: If no rules packages match the specified criteria an empty list is returned (previously an error was raised) +``` + +```release-note:note +data-source/aws_db_event_categories: The type of the `ids` attribute has changed from Set to List. If no event categories match the specified criteria an empty list is returned (previously an error was raised) +``` + +```release-note:note +data-source/aws_ssoadmin_instances: The type of the `identity_store_ids` and `arns` attributes has changed from Set to List. If no instances match the specified criteria an empty list is returned (previously an error was raised) +``` \ No newline at end of file diff --git a/internal/service/inspector/rules_packages_data_source.go b/internal/service/inspector/rules_packages_data_source.go index 5e92d5dc240..6ab5d66e0e6 100644 --- a/internal/service/inspector/rules_packages_data_source.go +++ b/internal/service/inspector/rules_packages_data_source.go @@ -1,11 +1,10 @@ package inspector import ( - "errors" "fmt" - "log" "sort" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/inspector" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" @@ -28,30 +27,42 @@ func DataSourceRulesPackages() *schema.Resource { func dataSourceRulesPackagesRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).InspectorConn - log.Printf("[DEBUG] Reading Rules Packages.") + output, err := findRulesPackageArns(conn) - var arns []string + if err != nil { + return fmt.Errorf("error reading Inspector Rules Packages: %w", err) + } + + arns := aws.StringValueSlice(output) + sort.Strings(arns) + d.SetId(meta.(*conns.AWSClient).Region) + d.Set("arns", arns) + + return nil +} + +func findRulesPackageArns(conn *inspector.Inspector) ([]*string, error) { input := &inspector.ListRulesPackagesInput{} + var output []*string err := conn.ListRulesPackagesPages(input, func(page *inspector.ListRulesPackagesOutput, lastPage bool) bool { - for _, arn := range page.RulesPackageArns { - arns = append(arns, *arn) + if page == nil { + return !lastPage + } + + for _, v := range page.RulesPackageArns { + if v != nil { + output = append(output, v) + } } + return !lastPage }) - if err != nil { - return fmt.Errorf("Error fetching Rules Packages: %w", err) - } - if len(arns) == 0 { - return errors.New("No rules packages found.") + if err != nil { + return nil, err } - d.SetId(meta.(*conns.AWSClient).Region) - - sort.Strings(arns) - d.Set("arns", arns) - - return nil + return output, nil } diff --git a/internal/service/rds/event_categories_data_source.go b/internal/service/rds/event_categories_data_source.go index 433f5106478..7fbce681efb 100644 --- a/internal/service/rds/event_categories_data_source.go +++ b/internal/service/rds/event_categories_data_source.go @@ -2,11 +2,11 @@ package rds import ( "fmt" - "log" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/rds" "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" ) @@ -15,15 +15,15 @@ func DataSourceEventCategories() *schema.Resource { Read: dataSourceEventCategoriesRead, Schema: map[string]*schema.Schema{ - "source_type": { - Type: schema.TypeString, - Optional: true, - }, "event_categories": { - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, + }, + "source_type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice(rds.SourceType_Values(), false), }, }, } @@ -32,35 +32,45 @@ func DataSourceEventCategories() *schema.Resource { func dataSourceEventCategoriesRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).RDSConn - req := &rds.DescribeEventCategoriesInput{} + input := &rds.DescribeEventCategoriesInput{} - if sourceType := d.Get("source_type").(string); sourceType != "" { - req.SourceType = aws.String(sourceType) + if v, ok := d.GetOk("source_type"); ok { + input.SourceType = aws.String(v.(string)) } - log.Printf("[DEBUG] Describe Event Categories %s\n", req) - resp, err := conn.DescribeEventCategories(req) - if err != nil { - return err - } + output, err := findEventCategoriesMaps(conn, input) - if resp == nil || len(resp.EventCategoriesMapList) == 0 { - return fmt.Errorf("Event Categories not found") + if err != nil { + return fmt.Errorf("error reading RDS Event Categories: %w", err) } - eventCategories := make([]string, 0) + var eventCategories []string - for _, eventMap := range resp.EventCategoriesMapList { - for _, v := range eventMap.EventCategories { - eventCategories = append(eventCategories, aws.StringValue(v)) - } + for _, v := range output { + eventCategories = append(eventCategories, aws.StringValueSlice(v.EventCategories)...) } d.SetId(meta.(*conns.AWSClient).Region) - if err := d.Set("event_categories", eventCategories); err != nil { - return fmt.Errorf("Error setting Event Categories: %w", err) - } + d.Set("event_categories", eventCategories) return nil } + +func findEventCategoriesMaps(conn *rds.RDS, input *rds.DescribeEventCategoriesInput) ([]*rds.EventCategoriesMap, error) { + var output []*rds.EventCategoriesMap + + page, err := conn.DescribeEventCategories(input) + + if err != nil { + return nil, err + } + + for _, v := range page.EventCategoriesMapList { + if v != nil { + output = append(output, v) + } + } + + return output, nil +} diff --git a/internal/service/ssoadmin/instances_data_source.go b/internal/service/ssoadmin/instances_data_source.go index a97e418c82d..5bafb16dfc3 100644 --- a/internal/service/ssoadmin/instances_data_source.go +++ b/internal/service/ssoadmin/instances_data_source.go @@ -15,13 +15,12 @@ func DataSourceInstances() *schema.Resource { Schema: map[string]*schema.Schema{ "arns": { - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, - "identity_store_ids": { - Type: schema.TypeSet, + Type: schema.TypeList, Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, @@ -32,39 +31,47 @@ func DataSourceInstances() *schema.Resource { func dataSourceInstancesRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).SSOAdminConn - var instances []*ssoadmin.InstanceMetadata - var arns, ids []string + output, err := findInstanceMetadatas(conn) + + if err != nil { + return fmt.Errorf("error reading SSO Instances: %w", err) + } + + var identityStoreIDs, arns []string + + for _, v := range output { + identityStoreIDs = append(identityStoreIDs, aws.StringValue(v.IdentityStoreId)) + arns = append(arns, aws.StringValue(v.InstanceArn)) + } + + d.SetId(meta.(*conns.AWSClient).Region) + d.Set("arns", arns) + d.Set("identity_store_ids", identityStoreIDs) + + return nil +} - err := conn.ListInstancesPages(&ssoadmin.ListInstancesInput{}, func(page *ssoadmin.ListInstancesOutput, lastPage bool) bool { +func findInstanceMetadatas(conn *ssoadmin.SSOAdmin) ([]*ssoadmin.InstanceMetadata, error) { + input := &ssoadmin.ListInstancesInput{} + var output []*ssoadmin.InstanceMetadata + + err := conn.ListInstancesPages(input, func(page *ssoadmin.ListInstancesOutput, lastPage bool) bool { if page == nil { return !lastPage } - instances = append(instances, page.Instances...) + for _, v := range page.Instances { + if v != nil { + output = append(output, v) + } + } return !lastPage }) if err != nil { - return fmt.Errorf("error reading SSO Instances: %w", err) - } - - if len(instances) == 0 { - return fmt.Errorf("error reading SSO Instance: no instances found") - } - - for _, instance := range instances { - arns = append(arns, aws.StringValue(instance.InstanceArn)) - ids = append(ids, aws.StringValue(instance.IdentityStoreId)) - } - - d.SetId(meta.(*conns.AWSClient).Region) - if err := d.Set("arns", arns); err != nil { - return fmt.Errorf("error setting arns: %w", err) - } - if err := d.Set("identity_store_ids", ids); err != nil { - return fmt.Errorf("error setting identity_store_ids: %w", err) + return nil, err } - return nil + return output, nil } From a710572d5b5f7aa34b96e8e87d2e9820c59fb21d Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 26 Jan 2022 16:32:00 -0500 Subject: [PATCH 082/116] d/aws_instances: Correct argument name. --- internal/service/ec2/instances_data_source.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/ec2/instances_data_source.go b/internal/service/ec2/instances_data_source.go index 13dd3204753..4f9d9b2e1e0 100644 --- a/internal/service/ec2/instances_data_source.go +++ b/internal/service/ec2/instances_data_source.go @@ -64,7 +64,7 @@ func dataSourceInstancesRead(d *schema.ResourceData, meta interface{}) error { } input.Filters = append(input.Filters, BuildTagFilterList( - Tags(tftags.New(d.Get("tags").(map[string]interface{}))), + Tags(tftags.New(d.Get("instance_tags").(map[string]interface{}))), )...) input.Filters = append(input.Filters, BuildFiltersDataSource( From 4b185511c1f81252772066861144d9c2ae96049b Mon Sep 17 00:00:00 2001 From: andrew quartey Date: Thu, 27 Jan 2022 13:52:21 -0500 Subject: [PATCH 083/116] Add aws_s3_bucket_cors_configuration resource (#12141) * docs: document S3 CORS configuration resource * r/s3_bucket_cors_configuration: CR updates * r/s3_bucket_cors_configuration: update ID methods to generic ones; docs formatting * correct error message Co-authored-by: Angie Pinilla --- .changelog/12141.txt | 3 + internal/provider/provider.go | 1 + .../service/s3/bucket_cors_configuration.go | 301 ++++++++++++++ .../s3/bucket_cors_configuration_test.go | 377 ++++++++++++++++++ internal/service/s3/errors.go | 1 + ...s3_bucket_cors_configuration.html.markdown | 75 ++++ 6 files changed, 758 insertions(+) create mode 100644 .changelog/12141.txt create mode 100644 internal/service/s3/bucket_cors_configuration.go create mode 100644 internal/service/s3/bucket_cors_configuration_test.go create mode 100644 website/docs/r/s3_bucket_cors_configuration.html.markdown diff --git a/.changelog/12141.txt b/.changelog/12141.txt new file mode 100644 index 00000000000..260bcc2c1f4 --- /dev/null +++ b/.changelog/12141.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_s3_bucket_cors_configuration +``` \ No newline at end of file diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 95781614b62..7e495efc9c0 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1588,6 +1588,7 @@ func Provider() *schema.Provider { "aws_s3_bucket": s3.ResourceBucket(), "aws_s3_bucket_analytics_configuration": s3.ResourceBucketAnalyticsConfiguration(), + "aws_s3_bucket_cors_configuration": s3.ResourceBucketCorsConfiguration(), "aws_s3_bucket_intelligent_tiering_configuration": s3.ResourceBucketIntelligentTieringConfiguration(), "aws_s3_bucket_inventory": s3.ResourceBucketInventory(), "aws_s3_bucket_metric": s3.ResourceBucketMetric(), diff --git a/internal/service/s3/bucket_cors_configuration.go b/internal/service/s3/bucket_cors_configuration.go new file mode 100644 index 00000000000..e22b637662f --- /dev/null +++ b/internal/service/s3/bucket_cors_configuration.go @@ -0,0 +1,301 @@ +package s3 + +import ( + "context" + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/s3" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "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" + "github.com/hashicorp/terraform-provider-aws/internal/flex" + "github.com/hashicorp/terraform-provider-aws/internal/verify" +) + +func ResourceBucketCorsConfiguration() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceBucketCorsConfigurationCreate, + ReadContext: resourceBucketCorsConfigurationRead, + UpdateContext: resourceBucketCorsConfigurationUpdate, + DeleteContext: resourceBucketCorsConfigurationDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Schema: map[string]*schema.Schema{ + "bucket": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(1, 63), + }, + "expected_bucket_owner": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: verify.ValidAccountID, + }, + "cors_rule": { + Type: schema.TypeSet, + Required: true, + MaxItems: 100, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "allowed_headers": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "allowed_methods": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "allowed_origins": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "expose_headers": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "id": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 255), + }, + "max_age_seconds": { + Type: schema.TypeInt, + Optional: true, + }, + }, + }, + }, + }, + } +} + +func resourceBucketCorsConfigurationCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).S3Conn + + bucket := d.Get("bucket").(string) + expectedBucketOwner := d.Get("expected_bucket_owner").(string) + + input := &s3.PutBucketCorsInput{ + Bucket: aws.String(bucket), + CORSConfiguration: &s3.CORSConfiguration{ + CORSRules: expandBucketCorsConfigurationCorsRules(d.Get("cors_rule").(*schema.Set).List()), + }, + } + + if expectedBucketOwner != "" { + input.ExpectedBucketOwner = aws.String(expectedBucketOwner) + } + + _, err := verify.RetryOnAWSCode(s3.ErrCodeNoSuchBucket, func() (interface{}, error) { + return conn.PutBucketCorsWithContext(ctx, input) + }) + + if err != nil { + return diag.FromErr(fmt.Errorf("error creating S3 bucket (%s) CORS configuration: %w", bucket, err)) + } + + d.SetId(CreateResourceID(bucket, expectedBucketOwner)) + + return resourceBucketCorsConfigurationRead(ctx, d, meta) +} + +func resourceBucketCorsConfigurationRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).S3Conn + + bucket, expectedBucketOwner, err := ParseResourceID(d.Id()) + if err != nil { + return diag.FromErr(err) + } + + input := &s3.GetBucketCorsInput{ + Bucket: aws.String(bucket), + } + + if expectedBucketOwner != "" { + input.ExpectedBucketOwner = aws.String(expectedBucketOwner) + } + + output, err := conn.GetBucketCorsWithContext(ctx, input) + + if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, s3.ErrCodeNoSuchBucket, ErrCodeNoSuchCORSConfiguration) { + log.Printf("[WARN] S3 Bucket CORS Configuration (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return diag.FromErr(fmt.Errorf("error reading S3 bucket CORS configuration (%s): %w", d.Id(), err)) + } + + if output == nil { + if d.IsNewResource() { + return diag.FromErr(fmt.Errorf("error reading S3 bucket CORS configuration (%s): empty output", d.Id())) + } + log.Printf("[WARN] S3 Bucket CORS Configuration (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + d.Set("bucket", bucket) + d.Set("expected_bucket_owner", expectedBucketOwner) + + if err := d.Set("cors_rule", flattenBucketCorsConfigurationCorsRules(output.CORSRules)); err != nil { + return diag.FromErr(fmt.Errorf("error setting cors_rule: %w", err)) + } + + return nil +} + +func resourceBucketCorsConfigurationUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).S3Conn + + bucket, expectedBucketOwner, err := ParseResourceID(d.Id()) + if err != nil { + return diag.FromErr(err) + } + + input := &s3.PutBucketCorsInput{ + Bucket: aws.String(bucket), + CORSConfiguration: &s3.CORSConfiguration{ + CORSRules: expandBucketCorsConfigurationCorsRules(d.Get("cors_rule").(*schema.Set).List()), + }, + } + + if expectedBucketOwner != "" { + input.ExpectedBucketOwner = aws.String(expectedBucketOwner) + } + + _, err = conn.PutBucketCorsWithContext(ctx, input) + + if err != nil { + return diag.FromErr(fmt.Errorf("error updating S3 bucket CORS configuration (%s): %w", d.Id(), err)) + } + + return resourceBucketCorsConfigurationRead(ctx, d, meta) +} + +func resourceBucketCorsConfigurationDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*conns.AWSClient).S3Conn + + bucket, expectedBucketOwner, err := ParseResourceID(d.Id()) + if err != nil { + return diag.FromErr(err) + } + + input := &s3.DeleteBucketCorsInput{ + Bucket: aws.String(bucket), + } + + if expectedBucketOwner != "" { + input.ExpectedBucketOwner = aws.String(expectedBucketOwner) + } + + _, err = conn.DeleteBucketCorsWithContext(ctx, input) + + if tfawserr.ErrCodeEquals(err, s3.ErrCodeNoSuchBucket) { + return nil + } + + if err != nil { + return diag.FromErr(fmt.Errorf("error deleting S3 bucket CORS configuration (%s): %w", d.Id(), err)) + } + + return nil +} + +func expandBucketCorsConfigurationCorsRules(l []interface{}) []*s3.CORSRule { + if len(l) == 0 { + return nil + } + + var rules []*s3.CORSRule + + for _, tfMapRaw := range l { + tfMap, ok := tfMapRaw.(map[string]interface{}) + if !ok { + continue + } + + rule := &s3.CORSRule{} + + if v, ok := tfMap["allowed_headers"].(*schema.Set); ok && v.Len() > 0 { + rule.AllowedHeaders = flex.ExpandStringSet(v) + } + + if v, ok := tfMap["allowed_methods"].(*schema.Set); ok && v.Len() > 0 { + rule.AllowedMethods = flex.ExpandStringSet(v) + } + + if v, ok := tfMap["allowed_origins"].(*schema.Set); ok && v.Len() > 0 { + rule.AllowedOrigins = flex.ExpandStringSet(v) + } + + if v, ok := tfMap["expose_headers"].(*schema.Set); ok && v.Len() > 0 { + rule.ExposeHeaders = flex.ExpandStringSet(v) + } + + if v, ok := tfMap["id"].(string); ok && v != "" { + rule.ID = aws.String(v) + } + + if v, ok := tfMap["max_age_seconds"].(int); ok { + rule.MaxAgeSeconds = aws.Int64(int64(v)) + } + + rules = append(rules, rule) + } + + return rules +} + +func flattenBucketCorsConfigurationCorsRules(rules []*s3.CORSRule) []interface{} { + var results []interface{} + + for _, rule := range rules { + if rule == nil { + continue + } + + m := make(map[string]interface{}) + + if len(rule.AllowedHeaders) > 0 { + m["allowed_headers"] = flex.FlattenStringSet(rule.AllowedHeaders) + } + + if len(rule.AllowedMethods) > 0 { + m["allowed_methods"] = flex.FlattenStringSet(rule.AllowedMethods) + } + + if len(rule.AllowedOrigins) > 0 { + m["allowed_origins"] = flex.FlattenStringSet(rule.AllowedOrigins) + } + + if len(rule.ExposeHeaders) > 0 { + m["expose_headers"] = flex.FlattenStringSet(rule.ExposeHeaders) + } + + if rule.ID != nil { + m["id"] = aws.StringValue(rule.ID) + } + + if rule.MaxAgeSeconds != nil { + m["max_age_seconds"] = aws.Int64Value(rule.MaxAgeSeconds) + } + + results = append(results, m) + } + + return results +} diff --git a/internal/service/s3/bucket_cors_configuration_test.go b/internal/service/s3/bucket_cors_configuration_test.go new file mode 100644 index 00000000000..0f0e30adee3 --- /dev/null +++ b/internal/service/s3/bucket_cors_configuration_test.go @@ -0,0 +1,377 @@ +package s3_test + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/s3" + "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" + tfs3 "github.com/hashicorp/terraform-provider-aws/internal/service/s3" +) + +func TestAccS3BucketCorsConfiguration_basic(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_s3_bucket_cors_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckBucketCorsConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccBucketCorsConfigurationBasicConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckBucketCorsConfigurationExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "bucket", "aws_s3_bucket.test", "id"), + resource.TestCheckResourceAttr(resourceName, "cors_rule.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "cors_rule.*", map[string]string{ + "allowed_methods.#": "1", + "allowed_origins.#": "1", + }), + resource.TestCheckTypeSetElemAttr(resourceName, "cors_rule.*.allowed_methods.*", "PUT"), + resource.TestCheckTypeSetElemAttr(resourceName, "cors_rule.*.allowed_origins.*", "https://www.example.com"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccS3BucketCorsConfiguration_disappears(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_s3_bucket_cors_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckBucketCorsConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccBucketCorsConfigurationBasicConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckBucketCorsConfigurationExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfs3.ResourceBucketCorsConfiguration(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccS3BucketCorsConfiguration_update(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_s3_bucket_cors_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckBucketCorsConfigurationDestroy, + Steps: []resource.TestStep{ + + { + Config: testAccBucketCorsConfigurationCompleteConfig_SingleRule(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckBucketCorsConfigurationExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "bucket", "aws_s3_bucket.test", "id"), + resource.TestCheckResourceAttr(resourceName, "cors_rule.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "cors_rule.*", map[string]string{ + "allowed_headers.#": "1", + "allowed_methods.#": "3", + "allowed_origins.#": "1", + "expose_headers.#": "1", + "id": rName, + "max_age_seconds": "3000", + }), + ), + }, + { + Config: testAccBucketCorsConfigurationConfig_MultipleRules(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckBucketCorsConfigurationExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "bucket", "aws_s3_bucket.test", "id"), + resource.TestCheckResourceAttr(resourceName, "cors_rule.#", "2"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "cors_rule.*", map[string]string{ + "allowed_headers.#": "1", + "allowed_methods.#": "3", + "allowed_origins.#": "1", + }), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "cors_rule.*", map[string]string{ + "allowed_methods.#": "1", + "allowed_origins.#": "1", + }), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccBucketCorsConfigurationBasicConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckBucketCorsConfigurationExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "cors_rule.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "cors_rule.*", map[string]string{ + "allowed_methods.#": "1", + "allowed_origins.#": "1", + }), + ), + }, + }, + }) +} + +func TestAccS3BucketCorsConfiguration_SingleRule(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_s3_bucket_cors_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckBucketCorsConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccBucketCorsConfigurationCompleteConfig_SingleRule(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckBucketCorsConfigurationExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "bucket", "aws_s3_bucket.test", "id"), + resource.TestCheckResourceAttr(resourceName, "cors_rule.#", "1"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "cors_rule.*", map[string]string{ + "allowed_headers.#": "1", + "allowed_methods.#": "3", + "allowed_origins.#": "1", + "expose_headers.#": "1", + "id": rName, + "max_age_seconds": "3000", + }), + resource.TestCheckTypeSetElemAttr(resourceName, "cors_rule.*.allowed_headers.*", "*"), + resource.TestCheckTypeSetElemAttr(resourceName, "cors_rule.*.allowed_methods.*", "DELETE"), + resource.TestCheckTypeSetElemAttr(resourceName, "cors_rule.*.allowed_methods.*", "POST"), + resource.TestCheckTypeSetElemAttr(resourceName, "cors_rule.*.allowed_methods.*", "PUT"), + resource.TestCheckTypeSetElemAttr(resourceName, "cors_rule.*.allowed_origins.*", "https://www.example.com"), + resource.TestCheckTypeSetElemAttr(resourceName, "cors_rule.*.expose_headers.*", "ETag"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccS3BucketCorsConfiguration_MultipleRules(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_s3_bucket_cors_configuration.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckBucketCorsConfigurationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccBucketCorsConfigurationConfig_MultipleRules(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckBucketCorsConfigurationExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "bucket", "aws_s3_bucket.test", "id"), + resource.TestCheckResourceAttr(resourceName, "cors_rule.#", "2"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "cors_rule.*", map[string]string{ + "allowed_headers.#": "1", + "allowed_methods.#": "3", + "allowed_origins.#": "1", + }), + resource.TestCheckTypeSetElemAttr(resourceName, "cors_rule.*.allowed_headers.*", "*"), + resource.TestCheckTypeSetElemAttr(resourceName, "cors_rule.*.allowed_methods.*", "DELETE"), + resource.TestCheckTypeSetElemAttr(resourceName, "cors_rule.*.allowed_methods.*", "POST"), + resource.TestCheckTypeSetElemAttr(resourceName, "cors_rule.*.allowed_methods.*", "PUT"), + resource.TestCheckTypeSetElemAttr(resourceName, "cors_rule.*.allowed_origins.*", "https://www.example.com"), + resource.TestCheckTypeSetElemNestedAttrs(resourceName, "cors_rule.*", map[string]string{ + "allowed_methods.#": "1", + "allowed_origins.#": "1", + }), + resource.TestCheckTypeSetElemAttr(resourceName, "cors_rule.*.allowed_methods.*", "GET"), + resource.TestCheckTypeSetElemAttr(resourceName, "cors_rule.*.allowed_origins.*", "*"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccCheckBucketCorsConfigurationDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).S3Conn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_s3_bucket_cors_configuration" { + continue + } + + bucket, expectedBucketOwner, err := tfs3.ParseResourceID(rs.Primary.ID) + if err != nil { + return err + } + + input := &s3.GetBucketCorsInput{ + Bucket: aws.String(bucket), + } + + if expectedBucketOwner != "" { + input.ExpectedBucketOwner = aws.String(expectedBucketOwner) + } + + output, err := conn.GetBucketCors(input) + + if tfawserr.ErrCodeEquals(err, s3.ErrCodeNoSuchBucket, tfs3.ErrCodeNoSuchCORSConfiguration) { + continue + } + + if err != nil { + return fmt.Errorf("error getting S3 Bucket CORS configuration (%s): %w", rs.Primary.ID, err) + } + + if output != nil { + return fmt.Errorf("S3 Bucket CORS configuration (%s) still exists", rs.Primary.ID) + } + } + + return nil +} + +func testAccCheckBucketCorsConfigurationExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("Resource (%s) ID not set", resourceName) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).S3Conn + + bucket, expectedBucketOwner, err := tfs3.ParseResourceID(rs.Primary.ID) + if err != nil { + return err + } + + input := &s3.GetBucketCorsInput{ + Bucket: aws.String(bucket), + } + + if expectedBucketOwner != "" { + input.ExpectedBucketOwner = aws.String(expectedBucketOwner) + } + + output, err := conn.GetBucketCors(input) + + if err != nil { + return fmt.Errorf("error getting S3 Bucket CORS configuration (%s): %w", rs.Primary.ID, err) + } + + if output == nil || len(output.CORSRules) == 0 { + return fmt.Errorf("S3 Bucket CORS configuration (%s) not found", rs.Primary.ID) + } + + return nil + } +} + +func testAccBucketCorsConfigurationBasicConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_s3_bucket" "test" { + bucket = %[1]q + + lifecycle { + ignore_changes = [ + cors_rule + ] + } +} + +resource "aws_s3_bucket_cors_configuration" "test" { + bucket = aws_s3_bucket.test.id + + cors_rule { + allowed_methods = ["PUT"] + allowed_origins = ["https://www.example.com"] + } +} +`, rName) +} + +func testAccBucketCorsConfigurationCompleteConfig_SingleRule(rName string) string { + return fmt.Sprintf(` +resource "aws_s3_bucket" "test" { + bucket = %[1]q + + lifecycle { + ignore_changes = [ + cors_rule + ] + } +} + +resource "aws_s3_bucket_cors_configuration" "test" { + bucket = aws_s3_bucket.test.id + + cors_rule { + allowed_headers = ["*"] + allowed_methods = ["PUT", "POST", "DELETE"] + allowed_origins = ["https://www.example.com"] + expose_headers = ["ETag"] + id = %[1]q + max_age_seconds = 3000 + } +} +`, rName) +} + +func testAccBucketCorsConfigurationConfig_MultipleRules(rName string) string { + return fmt.Sprintf(` +resource "aws_s3_bucket" "test" { + bucket = %[1]q + + lifecycle { + ignore_changes = [ + cors_rule + ] + } +} + +resource "aws_s3_bucket_cors_configuration" "test" { + bucket = aws_s3_bucket.test.id + + cors_rule { + allowed_headers = ["*"] + allowed_methods = ["PUT", "POST", "DELETE"] + allowed_origins = ["https://www.example.com"] + } + + cors_rule { + allowed_methods = ["GET"] + allowed_origins = ["*"] + } +} +`, rName) +} diff --git a/internal/service/s3/errors.go b/internal/service/s3/errors.go index bfbbb273ba7..425080a8817 100644 --- a/internal/service/s3/errors.go +++ b/internal/service/s3/errors.go @@ -5,6 +5,7 @@ package s3 const ( ErrCodeNoSuchConfiguration = "NoSuchConfiguration" + ErrCodeNoSuchCORSConfiguration = "NoSuchCORSConfiguration" ErrCodeNoSuchPublicAccessBlockConfiguration = "NoSuchPublicAccessBlockConfiguration" ErrCodeOperationAborted = "OperationAborted" ) diff --git a/website/docs/r/s3_bucket_cors_configuration.html.markdown b/website/docs/r/s3_bucket_cors_configuration.html.markdown new file mode 100644 index 00000000000..f747598b623 --- /dev/null +++ b/website/docs/r/s3_bucket_cors_configuration.html.markdown @@ -0,0 +1,75 @@ +--- +subcategory: "S3" +layout: "aws" +page_title: "AWS: aws_s3_bucket_cors_configuration" +description: |- + Provides an S3 bucket CORS configuration resource. +--- + +# Resource: aws_s3_bucket_cors_configuration + +Provides an S3 bucket CORS configuration resource. For more information about CORS, go to [Enabling Cross-Origin Resource Sharing](https://docs.aws.amazon.com/AmazonS3/latest/userguide/cors.html) in the Amazon S3 User Guide. + +## Example Usage + +```terraform +resource "aws_s3_bucket" "example" { + bucket = "mybucket" +} + +resource "aws_s3_bucket_cors_configuration" "example" { + bucket = aws_s3_bucket.example.bucket + + cors_rule { + allowed_headers = ["*"] + allowed_methods = ["PUT", "POST"] + allowed_origins = ["https://s3-website-test.hashicorp.com"] + expose_headers = ["ETag"] + max_age_seconds = 3000 + } + + cors_rule { + allowed_methods = ["GET"] + allowed_origins = ["*"] + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `bucket` - (Required, Forces new resource) The name of the bucket. +* `expected_bucket_owner` - (Optional, Forces new resource) The account ID of the expected bucket owner. +* `cors_rule` - (Required) Set of origins and methods (cross-origin access that you want to allow) [documented below](#cors_rule). You can configure up to 100 rules. + +### cors_rule + +The `cors_rule` configuration block supports the following arguments: + +* `allowed_headers` - (Optional) Set of Headers that are specified in the `Access-Control-Request-Headers` header. +* `allowed_methods` - (Required) Set of HTTP methods that you allow the origin to execute. Valid values are `GET`, `PUT`, `HEAD`, `POST`, and `DELETE`. +* `allowed_origins` - (Required) Set of origins you want customers to be able to access the bucket from. +* `expose_headers` - (Optional) Set of headers in the response that you want customers to be able to access from their applications (for example, from a JavaScript `XMLHttpRequest` object). +* `id` - (Optional) Unique identifier for the rule. The value cannot be longer than 255 characters. +* `max_age_seconds` - (Optional) The time in seconds that your browser is to cache the preflight response for the specified resource. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The `bucket` or `bucket` and `expected_bucket_owner` separated by a comma (`,`) if the latter is provided. + +## Import + +S3 bucket CORS configuration can be imported using the `bucket` e.g., + +``` +$ terraform import aws_s3_bucket_cors_configuration.example bucket-name +``` + +In addition, S3 bucket CORS configuration can be imported using the `bucket` and `expected_bucket_owner` separated by a comma (`,`) e.g., + +``` +$ terraform import aws_s3_bucket_cors_configuration.example bucket-name,123456789012 +``` From 0e32c103ff157c518fbe935668c6818bca0bd90c Mon Sep 17 00:00:00 2001 From: Roberth Kulbin <6707630+roberth-k@users.noreply.github.com> Date: Wed, 26 Jan 2022 23:43:39 +0000 Subject: [PATCH 084/116] r/aws_ecs_cluster: deprecate the capacity_providers & default_capacity_provider_strategy attributes --- internal/service/ecs/cluster.go | 14 +++++----- website/docs/r/ecs_cluster.html.markdown | 34 +++++++++++++++++++++--- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/internal/service/ecs/cluster.go b/internal/service/ecs/cluster.go index aa27d680d47..af87c05084d 100644 --- a/internal/service/ecs/cluster.go +++ b/internal/service/ecs/cluster.go @@ -50,9 +50,10 @@ func ResourceCluster() *schema.Resource { Computed: true, }, "capacity_providers": { - Type: schema.TypeSet, - Optional: true, - Computed: true, + Type: schema.TypeSet, + Optional: true, + Computed: true, + Deprecated: "Use the aws_ecs_cluster_capacity_providers resource instead", Elem: &schema.Schema{ Type: schema.TypeString, }, @@ -114,9 +115,10 @@ func ResourceCluster() *schema.Resource { }, }, "default_capacity_provider_strategy": { - Type: schema.TypeSet, - Optional: true, - Computed: true, + Type: schema.TypeSet, + Optional: true, + Computed: true, + Deprecated: "Use the aws_ecs_cluster_capacity_providers resource instead", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "base": { diff --git a/website/docs/r/ecs_cluster.html.markdown b/website/docs/r/ecs_cluster.html.markdown index 82830183fca..651cb3508b7 100644 --- a/website/docs/r/ecs_cluster.html.markdown +++ b/website/docs/r/ecs_cluster.html.markdown @@ -25,7 +25,7 @@ resource "aws_ecs_cluster" "foo" { } ``` -## Example W/Log Configuration +### Example with Log Configuration ```terraform resource "aws_kms_key" "example" { @@ -54,13 +54,41 @@ resource "aws_ecs_cluster" "test" { } ``` +### Example with Capacity Providers + +```terraform +resource "aws_ecs_cluster" "example" { + name = "example" +} + +resource "aws_ecs_cluster_capacity_providers" "example" { + cluster_name = aws_ecs_cluster.example.name + + capacity_providers = [aws_ecs_capacity_provider.example.name] + + default_capacity_provider_strategy { + base = 1 + weight = 100 + capacity_provider = aws_ecs_capacity_provider.example.name + } +} + +resource "aws_ecs_capacity_provider" "example" { + name = "example" + + auto_scaling_group_provider { + auto_scaling_group_arn = aws_autoscaling_group.example.arn + } +} +``` + ## Argument Reference The following arguments are supported: -* `capacity_providers` - (Optional) List of short names of one or more capacity providers to associate with the cluster. Valid values also include `FARGATE` and `FARGATE_SPOT`. +* `capacity_providers` - (Optional, **Deprecated** use the `aws_ecs_cluster_capacity_providers` resource instead) List of short names of one or more capacity providers to associate with the cluster. Valid values also include `FARGATE` and `FARGATE_SPOT`. * `configuration` - (Optional) The execute command configuration for the cluster. Detailed below. -* `default_capacity_provider_strategy` - (Optional) Configuration block for capacity provider strategy to use by default for the cluster. Can be one or more. Detailed below. +* `default_capacity_provider_strategy` - (Optional, **Deprecated** use the `aws_ecs_cluster_capacity_providers` resource instead) Configuration block for capacity provider strategy to use by default for the cluster. Can be one or more. Detailed below. * `name` - (Required) Name of the cluster (up to 255 letters, numbers, hyphens, and underscores) * `setting` - (Optional) Configuration block(s) with cluster settings. For example, this can be used to enable CloudWatch Container Insights for a cluster. Detailed below. * `tags` - (Optional) Key-value map of resource tags. If configured with a provider [`default_tags` configuration block](https://www.terraform.io/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. From eb47150acd0417ba22bd5e50a9ce238c6ecf952d Mon Sep 17 00:00:00 2001 From: Roberth Kulbin <6707630+roberth-k@users.noreply.github.com> Date: Wed, 26 Jan 2022 23:50:06 +0000 Subject: [PATCH 085/116] add changelog entry for #22783 --- .changelog/22783.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/22783.txt diff --git a/.changelog/22783.txt b/.changelog/22783.txt new file mode 100644 index 00000000000..708224b486f --- /dev/null +++ b/.changelog/22783.txt @@ -0,0 +1,3 @@ +```release-note:note +resource/aws_ecs_cluster: The `capacity_providers` and `default_capacity_provider_strategy` arguments have been deprecated. Use the `aws_ecs_cluster_capacity_providers` resource instead. + ``` From e1997c6f1c7c209df8e4efd560c59d390f83d106 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 28 Jan 2022 14:56:30 -0500 Subject: [PATCH 086/116] rebase error: remove pre SP file --- aws/data_source_aws_instances_test.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 aws/data_source_aws_instances_test.go diff --git a/aws/data_source_aws_instances_test.go b/aws/data_source_aws_instances_test.go deleted file mode 100644 index e69de29bb2d..00000000000 From 7430e73c55872fabae759075ccb41cfa62943f58 Mon Sep 17 00:00:00 2001 From: nikhil Date: Thu, 22 Apr 2021 22:15:51 +0530 Subject: [PATCH 087/116] f/aws_securityhub_member: email is optional variable --- internal/service/securityhub/member.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/securityhub/member.go b/internal/service/securityhub/member.go index c8224e1da15..61fb9338956 100644 --- a/internal/service/securityhub/member.go +++ b/internal/service/securityhub/member.go @@ -41,7 +41,7 @@ func ResourceMember() *schema.Resource { }, "email": { Type: schema.TypeString, - Required: true, + Optional: true, ForceNew: true, }, "invite": { From 1a050ac6e3ee84faf83817c865ac6739f5a52d8c Mon Sep 17 00:00:00 2001 From: nikhil Date: Sun, 25 Apr 2021 12:36:05 +0530 Subject: [PATCH 088/116] f/aws_securityhub_member: email is optional variable --- internal/service/securityhub/member.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/securityhub/member.go b/internal/service/securityhub/member.go index 61fb9338956..c8224e1da15 100644 --- a/internal/service/securityhub/member.go +++ b/internal/service/securityhub/member.go @@ -41,7 +41,7 @@ func ResourceMember() *schema.Resource { }, "email": { Type: schema.TypeString, - Optional: true, + Required: true, ForceNew: true, }, "invite": { From f2efcdb3e970fb1b8fd6d43092ac9d2505a7035e Mon Sep 17 00:00:00 2001 From: nikhil Date: Thu, 22 Apr 2021 22:15:51 +0530 Subject: [PATCH 089/116] f/aws_securityhub_member: email is optional variable --- internal/service/securityhub/member.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/securityhub/member.go b/internal/service/securityhub/member.go index c8224e1da15..61fb9338956 100644 --- a/internal/service/securityhub/member.go +++ b/internal/service/securityhub/member.go @@ -41,7 +41,7 @@ func ResourceMember() *schema.Resource { }, "email": { Type: schema.TypeString, - Required: true, + Optional: true, ForceNew: true, }, "invite": { From 3ec20b3245786eb89d19000c286a1d01906c843a Mon Sep 17 00:00:00 2001 From: nikhil Date: Sun, 25 Apr 2021 12:36:05 +0530 Subject: [PATCH 090/116] f/aws_securityhub_member: email is optional variable --- internal/service/securityhub/member.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/securityhub/member.go b/internal/service/securityhub/member.go index 61fb9338956..c8224e1da15 100644 --- a/internal/service/securityhub/member.go +++ b/internal/service/securityhub/member.go @@ -41,7 +41,7 @@ func ResourceMember() *schema.Resource { }, "email": { Type: schema.TypeString, - Optional: true, + Required: true, ForceNew: true, }, "invite": { From fc6d374a388f06f5a0912bbdc090325475a2c760 Mon Sep 17 00:00:00 2001 From: nikhil Date: Thu, 22 Apr 2021 22:15:51 +0530 Subject: [PATCH 091/116] f/aws_securityhub_member: email is optional variable --- internal/service/securityhub/member.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/securityhub/member.go b/internal/service/securityhub/member.go index c8224e1da15..61fb9338956 100644 --- a/internal/service/securityhub/member.go +++ b/internal/service/securityhub/member.go @@ -41,7 +41,7 @@ func ResourceMember() *schema.Resource { }, "email": { Type: schema.TypeString, - Required: true, + Optional: true, ForceNew: true, }, "invite": { From 7b72b585a8c54b18727718b5bc039906e94f666e Mon Sep 17 00:00:00 2001 From: nikhil Date: Sun, 25 Apr 2021 12:36:05 +0530 Subject: [PATCH 092/116] f/aws_securityhub_member: email is optional variable --- internal/service/securityhub/member.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/securityhub/member.go b/internal/service/securityhub/member.go index 61fb9338956..c8224e1da15 100644 --- a/internal/service/securityhub/member.go +++ b/internal/service/securityhub/member.go @@ -41,7 +41,7 @@ func ResourceMember() *schema.Resource { }, "email": { Type: schema.TypeString, - Optional: true, + Required: true, ForceNew: true, }, "invite": { From 41104eb0d39af19db549291b06cfe7d852dc939a Mon Sep 17 00:00:00 2001 From: nikhil Date: Sun, 2 May 2021 15:41:28 +0530 Subject: [PATCH 093/116] resource/aws_elasticache_global_replication_group: Remove deprecated parameter actual_engine_version --- internal/service/elasticache/global_replication_group.go | 6 ------ .../service/elasticache/global_replication_group_test.go | 1 - .../r/elasticache_global_replication_group.html.markdown | 1 - 3 files changed, 8 deletions(-) diff --git a/internal/service/elasticache/global_replication_group.go b/internal/service/elasticache/global_replication_group.go index 49fd9306052..6ec61b556c2 100644 --- a/internal/service/elasticache/global_replication_group.go +++ b/internal/service/elasticache/global_replication_group.go @@ -77,11 +77,6 @@ func ResourceGlobalReplicationGroup() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "actual_engine_version": { - Type: schema.TypeString, - Computed: true, - Deprecated: "Use engine_version_actual instead", - }, "global_replication_group_id": { Type: schema.TypeString, Computed: true, @@ -200,7 +195,6 @@ func resourceGlobalReplicationGroupRead(d *schema.ResourceData, meta interface{} d.Set("cluster_enabled", globalReplicationGroup.ClusterEnabled) d.Set("engine", globalReplicationGroup.Engine) d.Set("engine_version_actual", globalReplicationGroup.EngineVersion) - d.Set("actual_engine_version", globalReplicationGroup.EngineVersion) d.Set("global_replication_group_description", globalReplicationGroup.GlobalReplicationGroupDescription) d.Set("global_replication_group_id", globalReplicationGroup.GlobalReplicationGroupId) d.Set("transit_encryption_enabled", globalReplicationGroup.TransitEncryptionEnabled) diff --git a/internal/service/elasticache/global_replication_group_test.go b/internal/service/elasticache/global_replication_group_test.go index 8af6895e985..14334fa3fe5 100644 --- a/internal/service/elasticache/global_replication_group_test.go +++ b/internal/service/elasticache/global_replication_group_test.go @@ -46,7 +46,6 @@ func TestAccElastiCacheGlobalReplicationGroup_basic(t *testing.T) { resource.TestCheckResourceAttrPair(resourceName, "cluster_enabled", primaryReplicationGroupResourceName, "cluster_enabled"), resource.TestCheckResourceAttrPair(resourceName, "engine", primaryReplicationGroupResourceName, "engine"), resource.TestCheckResourceAttrPair(resourceName, "engine_version_actual", primaryReplicationGroupResourceName, "engine_version"), - resource.TestCheckResourceAttrPair(resourceName, "actual_engine_version", primaryReplicationGroupResourceName, "engine_version"), resource.TestCheckResourceAttr(resourceName, "global_replication_group_id_suffix", rName), resource.TestMatchResourceAttr(resourceName, "global_replication_group_id", regexp.MustCompile(tfelasticache.GlobalReplicationGroupRegionPrefixFormat+rName)), resource.TestCheckResourceAttr(resourceName, "global_replication_group_description", tfelasticache.EmptyDescription), diff --git a/website/docs/r/elasticache_global_replication_group.html.markdown b/website/docs/r/elasticache_global_replication_group.html.markdown index edc0580a583..659ae612279 100644 --- a/website/docs/r/elasticache_global_replication_group.html.markdown +++ b/website/docs/r/elasticache_global_replication_group.html.markdown @@ -58,7 +58,6 @@ In addition to all arguments above, the following attributes are exported: * `id` - The ID of the ElastiCache Global Replication Group. * `arn` - The ARN of the ElastiCache Global Replication Group. -* `actual_engine_version` - (**DEPRECATED** use `engine_version_actual` instead) The full version number of the cache engine running on the members of this global replication group. * `engine_version_actual` - The full version number of the cache engine running on the members of this global replication group. * `at_rest_encryption_enabled` - A flag that indicate whether the encryption at rest is enabled. * `auth_token_enabled` - A flag that indicate whether AuthToken (password) is enabled. From a6ff35bcd22e5e4ddc80df863bf8f18bf64e186e Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 28 Jan 2022 17:37:21 -0500 Subject: [PATCH 094/116] fix rebase errors --- internal/service/ec2/find.go | 25 +++++++++++++++++++ .../ec2/network_acls_data_source_test.go | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/internal/service/ec2/find.go b/internal/service/ec2/find.go index 16caa202866..2a8d78d2887 100644 --- a/internal/service/ec2/find.go +++ b/internal/service/ec2/find.go @@ -270,6 +270,31 @@ func FindEBSVolume(conn *ec2.EC2, input *ec2.DescribeVolumesInput) (*ec2.Volume, return output[0], nil } +func FindEIPs(conn *ec2.EC2, input *ec2.DescribeAddressesInput) ([]*ec2.Address, error) { + var addresses []*ec2.Address + + output, err := conn.DescribeAddresses(input) + + if tfawserr.ErrCodeEquals(err, ErrCodeInvalidAddressNotFound, ErrCodeInvalidAllocationIDNotFound) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + for _, v := range output.Addresses { + if v != nil { + addresses = append(addresses, v) + } + } + + return addresses, nil +} + func FindHostByID(conn *ec2.EC2, id string) (*ec2.Host, error) { input := &ec2.DescribeHostsInput{ HostIds: aws.StringSlice([]string{id}), diff --git a/internal/service/ec2/network_acls_data_source_test.go b/internal/service/ec2/network_acls_data_source_test.go index bb72cfbbc3b..692413f3ca4 100644 --- a/internal/service/ec2/network_acls_data_source_test.go +++ b/internal/service/ec2/network_acls_data_source_test.go @@ -23,7 +23,7 @@ func TestAccEC2NetworkACLsDataSource_basic(t *testing.T) { { Config: testAccNetworkACLsDataSourceConfig_basic(rName), Check: resource.ComposeTestCheckFunc( - testCheckResourceAttrGreaterThanValue(dataSourceName, "ids.#", "1"), + acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "ids.#", "1"), ), }, }, From 4a386239a9a9e817845c4345140cf083e4cee585 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 31 Jan 2022 12:09:59 -0500 Subject: [PATCH 095/116] Rename s3_bucket_object to s3_object --- internal/provider/provider.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 7e495efc9c0..871357a9d74 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -685,8 +685,8 @@ func Provider() *schema.Provider { "aws_canonical_user_id": s3.DataSourceCanonicalUserID(), "aws_s3_bucket": s3.DataSourceBucket(), - "aws_s3_bucket_object": s3.DataSourceBucketObject(), - "aws_s3_bucket_objects": s3.DataSourceBucketObjects(), + "aws_s3_object": s3.DataSourceBucketObject(), + "aws_s3_objects": s3.DataSourceBucketObjects(), "aws_sagemaker_prebuilt_ecr_image": sagemaker.DataSourcePrebuiltECRImage(), @@ -1593,7 +1593,7 @@ func Provider() *schema.Provider { "aws_s3_bucket_inventory": s3.ResourceBucketInventory(), "aws_s3_bucket_metric": s3.ResourceBucketMetric(), "aws_s3_bucket_notification": s3.ResourceBucketNotification(), - "aws_s3_bucket_object": s3.ResourceBucketObject(), + "aws_s3_object": s3.ResourceBucketObject(), "aws_s3_bucket_ownership_controls": s3.ResourceBucketOwnershipControls(), "aws_s3_bucket_policy": s3.ResourceBucketPolicy(), "aws_s3_bucket_public_access_block": s3.ResourceBucketPublicAccessBlock(), From 7e28324c1706ea3ca168f5c7d2e6d0face924b3b Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 31 Jan 2022 12:10:32 -0500 Subject: [PATCH 096/116] Update examples --- examples/s3-cross-account-access/main.tf | 4 ++-- examples/sagemaker/main.tf | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/s3-cross-account-access/main.tf b/examples/s3-cross-account-access/main.tf index 178f9131b00..ddae63032fa 100644 --- a/examples/s3-cross-account-access/main.tf +++ b/examples/s3-cross-account-access/main.tf @@ -34,7 +34,7 @@ resource "aws_s3_bucket" "prod" { POLICY } -resource "aws_s3_bucket_object" "prod" { +resource "aws_s3_object" "prod" { provider = aws.prod bucket = aws_s3_bucket.prod.id @@ -50,7 +50,7 @@ provider "aws" { secret_key = var.test_secret_key } -resource "aws_s3_bucket_object" "test" { +resource "aws_s3_object" "test" { provider = aws.test bucket = aws_s3_bucket.prod.id diff --git a/examples/sagemaker/main.tf b/examples/sagemaker/main.tf index ded75b3b90e..2babe537ee2 100644 --- a/examples/sagemaker/main.tf +++ b/examples/sagemaker/main.tf @@ -86,7 +86,7 @@ resource "aws_s3_bucket" "foo" { force_destroy = true } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.foo.bucket key = "model.tar.gz" source = "model.tar.gz" From 885c687e3e106b4747b51ba333f8fcf339132c6d Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 31 Jan 2022 12:12:00 -0500 Subject: [PATCH 097/116] Update s3 package --- internal/service/s3/bucket.go | 2 +- .../s3/bucket_object_data_source_test.go | 122 +++++++++--------- internal/service/s3/bucket_object_test.go | 112 ++++++++-------- .../s3/bucket_objects_data_source_test.go | 110 ++++++++-------- internal/service/s3/bucket_test.go | 2 +- internal/service/s3/object_copy_test.go | 14 +- internal/service/s3/sweep.go | 6 +- 7 files changed, 184 insertions(+), 184 deletions(-) diff --git a/internal/service/s3/bucket.go b/internal/service/s3/bucket.go index cda17ff1bbd..1d538674c2d 100644 --- a/internal/service/s3/bucket.go +++ b/internal/service/s3/bucket.go @@ -1426,7 +1426,7 @@ func resourceBucketDelete(d *schema.ResourceData, meta interface{}) error { if tfawserr.ErrMessageContains(err, "BucketNotEmpty", "") { if d.Get("force_destroy").(bool) { // Use a S3 service client that can handle multiple slashes in URIs. - // While aws_s3_bucket_object resources cannot create these object + // While aws_s3_object resources cannot create these object // keys, other AWS services and applications using the S3 Bucket can. conn = meta.(*conns.AWSClient).S3ConnURICleaningDisabled diff --git a/internal/service/s3/bucket_object_data_source_test.go b/internal/service/s3/bucket_object_data_source_test.go index 733e97b054f..85e596a7e19 100644 --- a/internal/service/s3/bucket_object_data_source_test.go +++ b/internal/service/s3/bucket_object_data_source_test.go @@ -23,8 +23,8 @@ func TestAccS3BucketObjectDataSource_basic(t *testing.T) { var rObj s3.GetObjectOutput var dsObj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" - dataSourceName := "data.aws_s3_bucket_object.obj" + resourceName := "aws_s3_object.object" + dataSourceName := "data.aws_s3_object.obj" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -55,8 +55,8 @@ func TestAccS3BucketObjectDataSource_basicViaAccessPoint(t *testing.T) { var dsObj, rObj s3.GetObjectOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - dataSourceName := "data.aws_s3_bucket_object.test" - resourceName := "aws_s3_bucket_object.test" + dataSourceName := "data.aws_s3_object.test" + resourceName := "aws_s3_object.test" accessPointResourceName := "aws_s3_access_point.test" resource.ParallelTest(t, resource.TestCase{ @@ -84,8 +84,8 @@ func TestAccS3BucketObjectDataSource_readableBody(t *testing.T) { var rObj s3.GetObjectOutput var dsObj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" - dataSourceName := "data.aws_s3_bucket_object.obj" + resourceName := "aws_s3_object.object" + dataSourceName := "data.aws_s3_object.obj" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -118,8 +118,8 @@ func TestAccS3BucketObjectDataSource_kmsEncrypted(t *testing.T) { var rObj s3.GetObjectOutput var dsObj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" - dataSourceName := "data.aws_s3_bucket_object.obj" + resourceName := "aws_s3_object.object" + dataSourceName := "data.aws_s3_object.obj" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -154,8 +154,8 @@ func TestAccS3BucketObjectDataSource_bucketKeyEnabled(t *testing.T) { var rObj s3.GetObjectOutput var dsObj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" - dataSourceName := "data.aws_s3_bucket_object.obj" + resourceName := "aws_s3_object.object" + dataSourceName := "data.aws_s3_object.obj" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -191,8 +191,8 @@ func TestAccS3BucketObjectDataSource_allParams(t *testing.T) { var rObj s3.GetObjectOutput var dsObj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" - dataSourceName := "data.aws_s3_bucket_object.obj" + resourceName := "aws_s3_object.object" + dataSourceName := "data.aws_s3_object.obj" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -222,7 +222,7 @@ func TestAccS3BucketObjectDataSource_allParams(t *testing.T) { // Supported, but difficult to reproduce in short testing time resource.TestCheckResourceAttrPair(dataSourceName, "storage_class", resourceName, "storage_class"), resource.TestCheckResourceAttr(dataSourceName, "expiration", ""), - // Currently unsupported in aws_s3_bucket_object resource + // Currently unsupported in aws_s3_object resource resource.TestCheckResourceAttr(dataSourceName, "expires", ""), resource.TestCheckResourceAttrPair(dataSourceName, "website_redirect_location", resourceName, "website_redirect"), resource.TestCheckResourceAttr(dataSourceName, "metadata.%", "0"), @@ -242,8 +242,8 @@ func TestAccS3BucketObjectDataSource_objectLockLegalHoldOff(t *testing.T) { var rObj s3.GetObjectOutput var dsObj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" - dataSourceName := "data.aws_s3_bucket_object.obj" + resourceName := "aws_s3_object.object" + dataSourceName := "data.aws_s3_object.obj" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -277,8 +277,8 @@ func TestAccS3BucketObjectDataSource_objectLockLegalHoldOn(t *testing.T) { var rObj s3.GetObjectOutput var dsObj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" - dataSourceName := "data.aws_s3_bucket_object.obj" + resourceName := "aws_s3_object.object" + dataSourceName := "data.aws_s3_object.obj" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -309,10 +309,10 @@ func TestAccS3BucketObjectDataSource_leadingSlash(t *testing.T) { var rObj s3.GetObjectOutput var dsObj1, dsObj2, dsObj3 s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" - dataSourceName1 := "data.aws_s3_bucket_object.obj1" - dataSourceName2 := "data.aws_s3_bucket_object.obj2" - dataSourceName3 := "data.aws_s3_bucket_object.obj3" + resourceName := "aws_s3_object.object" + dataSourceName1 := "data.aws_s3_object.obj1" + dataSourceName2 := "data.aws_s3_object.obj2" + dataSourceName3 := "data.aws_s3_object.obj3" rInt := sdkacctest.RandInt() resourceOnlyConf, conf := testAccObjectDataSourceConfig_leadingSlash(rInt) @@ -362,11 +362,11 @@ func TestAccS3BucketObjectDataSource_multipleSlashes(t *testing.T) { var rObj1, rObj2 s3.GetObjectOutput var dsObj1, dsObj2, dsObj3 s3.GetObjectOutput - resourceName1 := "aws_s3_bucket_object.object1" - resourceName2 := "aws_s3_bucket_object.object2" - dataSourceName1 := "data.aws_s3_bucket_object.obj1" - dataSourceName2 := "data.aws_s3_bucket_object.obj2" - dataSourceName3 := "data.aws_s3_bucket_object.obj3" + resourceName1 := "aws_s3_object.object1" + resourceName2 := "aws_s3_object.object2" + dataSourceName1 := "data.aws_s3_object.obj1" + dataSourceName2 := "data.aws_s3_object.obj2" + dataSourceName3 := "data.aws_s3_object.obj3" rInt := sdkacctest.RandInt() resourceOnlyConf, conf := testAccObjectDataSourceConfig_multipleSlashes(rInt) @@ -410,7 +410,7 @@ func TestAccS3BucketObjectDataSource_multipleSlashes(t *testing.T) { func TestAccS3BucketObjectDataSource_singleSlashAsKey(t *testing.T) { var dsObj s3.GetObjectOutput - dataSourceName := "data.aws_s3_bucket_object.test" + dataSourceName := "data.aws_s3_object.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -463,15 +463,15 @@ resource "aws_s3_bucket" "object_bucket" { bucket = "tf-object-test-bucket-%[1]d" } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.object_bucket.bucket key = "tf-testing-obj-%[1]d" content = "Hello World" } -data "aws_s3_bucket_object" "obj" { +data "aws_s3_object" "obj" { bucket = aws_s3_bucket.object_bucket.bucket - key = aws_s3_bucket_object.object.key + key = aws_s3_object.object.key } `, randInt) } @@ -487,15 +487,15 @@ resource "aws_s3_access_point" "test" { name = %[1]q } -resource "aws_s3_bucket_object" "test" { +resource "aws_s3_object" "test" { bucket = aws_s3_bucket.test.bucket key = %[1]q content = "Hello World" } -data "aws_s3_bucket_object" "test" { +data "aws_s3_object" "test" { bucket = aws_s3_access_point.test.arn - key = aws_s3_bucket_object.test.key + key = aws_s3_object.test.key } `, rName) } @@ -506,16 +506,16 @@ resource "aws_s3_bucket" "object_bucket" { bucket = "tf-object-test-bucket-%[1]d" } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.object_bucket.bucket key = "tf-testing-obj-%[1]d-readable" content = "yes" content_type = "text/plain" } -data "aws_s3_bucket_object" "obj" { +data "aws_s3_object" "obj" { bucket = aws_s3_bucket.object_bucket.bucket - key = aws_s3_bucket_object.object.key + key = aws_s3_object.object.key } `, randInt) } @@ -531,7 +531,7 @@ resource "aws_kms_key" "example" { deletion_window_in_days = 7 } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.object_bucket.bucket key = "tf-testing-obj-%[1]d-encrypted" content = "Keep Calm and Carry On" @@ -539,9 +539,9 @@ resource "aws_s3_bucket_object" "object" { kms_key_id = aws_kms_key.example.arn } -data "aws_s3_bucket_object" "obj" { +data "aws_s3_object" "obj" { bucket = aws_s3_bucket.object_bucket.bucket - key = aws_s3_bucket_object.object.key + key = aws_s3_object.object.key } `, randInt) } @@ -557,7 +557,7 @@ resource "aws_kms_key" "example" { deletion_window_in_days = 7 } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.object_bucket.bucket key = "tf-testing-obj-%[1]d-encrypted" content = "Keep Calm and Carry On" @@ -566,9 +566,9 @@ resource "aws_s3_bucket_object" "object" { bucket_key_enabled = true } -data "aws_s3_bucket_object" "obj" { +data "aws_s3_object" "obj" { bucket = aws_s3_bucket.object_bucket.bucket - key = aws_s3_bucket_object.object.key + key = aws_s3_object.object.key } `, randInt) } @@ -583,7 +583,7 @@ resource "aws_s3_bucket" "object_bucket" { } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.object_bucket.bucket key = "tf-testing-obj-%[1]d-all-params" @@ -603,9 +603,9 @@ CONTENT } } -data "aws_s3_bucket_object" "obj" { +data "aws_s3_object" "obj" { bucket = aws_s3_bucket.object_bucket.bucket - key = aws_s3_bucket_object.object.key + key = aws_s3_object.object.key } `, randInt) } @@ -624,16 +624,16 @@ resource "aws_s3_bucket" "object_bucket" { } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.object_bucket.bucket key = "tf-testing-obj-%[1]d" content = "Hello World" object_lock_legal_hold_status = "OFF" } -data "aws_s3_bucket_object" "obj" { +data "aws_s3_object" "obj" { bucket = aws_s3_bucket.object_bucket.bucket - key = aws_s3_bucket_object.object.key + key = aws_s3_object.object.key } `, randInt) } @@ -652,7 +652,7 @@ resource "aws_s3_bucket" "object_bucket" { } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.object_bucket.bucket key = "tf-testing-obj-%[1]d" content = "Hello World" @@ -662,9 +662,9 @@ resource "aws_s3_bucket_object" "object" { object_lock_retain_until_date = "%[2]s" } -data "aws_s3_bucket_object" "obj" { +data "aws_s3_object" "obj" { bucket = aws_s3_bucket.object_bucket.bucket - key = aws_s3_bucket_object.object.key + key = aws_s3_object.object.key } `, randInt, retainUntilDate) } @@ -675,7 +675,7 @@ resource "aws_s3_bucket" "object_bucket" { bucket = "tf-object-test-bucket-%[1]d" } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.object_bucket.bucket key = "//tf-testing-obj-%[1]d-readable" content = "yes" @@ -686,17 +686,17 @@ resource "aws_s3_bucket_object" "object" { both := fmt.Sprintf(` %[1]s -data "aws_s3_bucket_object" "obj1" { +data "aws_s3_object" "obj1" { bucket = aws_s3_bucket.object_bucket.bucket key = "tf-testing-obj-%[2]d-readable" } -data "aws_s3_bucket_object" "obj2" { +data "aws_s3_object" "obj2" { bucket = aws_s3_bucket.object_bucket.bucket key = "/tf-testing-obj-%[2]d-readable" } -data "aws_s3_bucket_object" "obj3" { +data "aws_s3_object" "obj3" { bucket = aws_s3_bucket.object_bucket.bucket key = "//tf-testing-obj-%[2]d-readable" } @@ -711,7 +711,7 @@ resource "aws_s3_bucket" "object_bucket" { bucket = "tf-object-test-bucket-%[1]d" } -resource "aws_s3_bucket_object" "object1" { +resource "aws_s3_object" "object1" { bucket = aws_s3_bucket.object_bucket.bucket key = "first//second///third//" content = "yes" @@ -719,7 +719,7 @@ resource "aws_s3_bucket_object" "object1" { } # Without a trailing slash. -resource "aws_s3_bucket_object" "object2" { +resource "aws_s3_object" "object2" { bucket = aws_s3_bucket.object_bucket.bucket key = "/first////second/third" content = "no" @@ -730,17 +730,17 @@ resource "aws_s3_bucket_object" "object2" { both := fmt.Sprintf(` %s -data "aws_s3_bucket_object" "obj1" { +data "aws_s3_object" "obj1" { bucket = aws_s3_bucket.object_bucket.bucket key = "first/second/third/" } -data "aws_s3_bucket_object" "obj2" { +data "aws_s3_object" "obj2" { bucket = aws_s3_bucket.object_bucket.bucket key = "first//second///third//" } -data "aws_s3_bucket_object" "obj3" { +data "aws_s3_object" "obj3" { bucket = aws_s3_bucket.object_bucket.bucket key = "first/second/third" } @@ -755,7 +755,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -data "aws_s3_bucket_object" "test" { +data "aws_s3_object" "test" { bucket = aws_s3_bucket.test.bucket key = "/" } diff --git a/internal/service/s3/bucket_object_test.go b/internal/service/s3/bucket_object_test.go index e46d9314eb0..86ac712fdbe 100644 --- a/internal/service/s3/bucket_object_test.go +++ b/internal/service/s3/bucket_object_test.go @@ -51,7 +51,7 @@ func TestAccS3BucketObject_noNameNoKey(t *testing.T) { func TestAccS3BucketObject_empty(t *testing.T) { var obj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -81,7 +81,7 @@ func TestAccS3BucketObject_empty(t *testing.T) { func TestAccS3BucketObject_source(t *testing.T) { var obj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) source := testAccBucketObjectCreateTempFile(t, "{anything will do }") @@ -113,7 +113,7 @@ func TestAccS3BucketObject_source(t *testing.T) { func TestAccS3BucketObject_content(t *testing.T) { var obj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -143,7 +143,7 @@ func TestAccS3BucketObject_content(t *testing.T) { func TestAccS3BucketObject_etagEncryption(t *testing.T) { var obj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) source := testAccBucketObjectCreateTempFile(t, "{anything will do }") defer os.Remove(source) @@ -176,7 +176,7 @@ func TestAccS3BucketObject_etagEncryption(t *testing.T) { func TestAccS3BucketObject_contentBase64(t *testing.T) { var obj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -199,7 +199,7 @@ func TestAccS3BucketObject_contentBase64(t *testing.T) { func TestAccS3BucketObject_sourceHashTrigger(t *testing.T) { var obj, updated_obj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) startingData := "Ebben!" @@ -255,7 +255,7 @@ func TestAccS3BucketObject_sourceHashTrigger(t *testing.T) { func TestAccS3BucketObject_withContentCharacteristics(t *testing.T) { var obj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) source := testAccBucketObjectCreateTempFile(t, "{anything will do }") @@ -285,7 +285,7 @@ func TestAccS3BucketObject_nonVersioned(t *testing.T) { defer os.Remove(sourceInitial) rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) var originalObj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t); acctest.PreCheckAssumeRoleARN(t) }, @@ -314,7 +314,7 @@ func TestAccS3BucketObject_nonVersioned(t *testing.T) { func TestAccS3BucketObject_updates(t *testing.T) { var originalObj, modifiedObj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) sourceInitial := testAccBucketObjectCreateTempFile(t, "initial object state") @@ -363,7 +363,7 @@ func TestAccS3BucketObject_updates(t *testing.T) { func TestAccS3BucketObject_updateSameFile(t *testing.T) { var originalObj, modifiedObj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) startingData := "lane 8" @@ -410,7 +410,7 @@ func TestAccS3BucketObject_updateSameFile(t *testing.T) { func TestAccS3BucketObject_updatesWithVersioning(t *testing.T) { var originalObj, modifiedObj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) sourceInitial := testAccBucketObjectCreateTempFile(t, "initial versioned object state") @@ -455,7 +455,7 @@ func TestAccS3BucketObject_updatesWithVersioning(t *testing.T) { func TestAccS3BucketObject_updatesWithVersioningViaAccessPoint(t *testing.T) { var originalObj, modifiedObj s3.GetObjectOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resourceName := "aws_s3_bucket_object.test" + resourceName := "aws_s3_object.test" accessPointResourceName := "aws_s3_access_point.test" sourceInitial := testAccBucketObjectCreateTempFile(t, "initial versioned object state") @@ -493,7 +493,7 @@ func TestAccS3BucketObject_updatesWithVersioningViaAccessPoint(t *testing.T) { func TestAccS3BucketObject_kms(t *testing.T) { var obj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) source := testAccBucketObjectCreateTempFile(t, "{anything will do }") @@ -527,7 +527,7 @@ func TestAccS3BucketObject_kms(t *testing.T) { func TestAccS3BucketObject_sse(t *testing.T) { var obj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) source := testAccBucketObjectCreateTempFile(t, "{anything will do }") @@ -561,7 +561,7 @@ func TestAccS3BucketObject_sse(t *testing.T) { func TestAccS3BucketObject_acl(t *testing.T) { var obj1, obj2, obj3 s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -613,7 +613,7 @@ func TestAccS3BucketObject_acl(t *testing.T) { func TestAccS3BucketObject_metadata(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) var obj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -659,7 +659,7 @@ func TestAccS3BucketObject_metadata(t *testing.T) { func TestAccS3BucketObject_storageClass(t *testing.T) { var obj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -723,7 +723,7 @@ func TestAccS3BucketObject_storageClass(t *testing.T) { func TestAccS3BucketObject_tags(t *testing.T) { var obj1, obj2, obj3, obj4 s3.GetObjectOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" key := "test-key" resource.ParallelTest(t, resource.TestCase{ @@ -795,7 +795,7 @@ func TestAccS3BucketObject_tags(t *testing.T) { func TestAccS3BucketObject_tagsLeadingSingleSlash(t *testing.T) { var obj1, obj2, obj3, obj4 s3.GetObjectOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" key := "/test-key" resource.ParallelTest(t, resource.TestCase{ @@ -867,7 +867,7 @@ func TestAccS3BucketObject_tagsLeadingSingleSlash(t *testing.T) { func TestAccS3BucketObject_tagsLeadingMultipleSlashes(t *testing.T) { var obj1, obj2, obj3, obj4 s3.GetObjectOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" key := "/////test-key" resource.ParallelTest(t, resource.TestCase{ @@ -932,7 +932,7 @@ func TestAccS3BucketObject_tagsLeadingMultipleSlashes(t *testing.T) { func TestAccS3BucketObject_tagsMultipleSlashes(t *testing.T) { var obj1, obj2, obj3, obj4 s3.GetObjectOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" key := "first//second///third//" resource.ParallelTest(t, resource.TestCase{ @@ -996,7 +996,7 @@ func TestAccS3BucketObject_tagsMultipleSlashes(t *testing.T) { func TestAccS3BucketObject_objectLockLegalHoldStartWithNone(t *testing.T) { var obj1, obj2, obj3 s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -1044,7 +1044,7 @@ func TestAccS3BucketObject_objectLockLegalHoldStartWithNone(t *testing.T) { func TestAccS3BucketObject_objectLockLegalHoldStartWithOn(t *testing.T) { var obj1, obj2 s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -1080,7 +1080,7 @@ func TestAccS3BucketObject_objectLockLegalHoldStartWithOn(t *testing.T) { func TestAccS3BucketObject_objectLockRetentionStartWithNone(t *testing.T) { var obj1, obj2, obj3 s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) retainUntilDate := time.Now().UTC().AddDate(0, 0, 10).Format(time.RFC3339) @@ -1129,7 +1129,7 @@ func TestAccS3BucketObject_objectLockRetentionStartWithNone(t *testing.T) { func TestAccS3BucketObject_objectLockRetentionStartWithSet(t *testing.T) { var obj1, obj2, obj3, obj4 s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) retainUntilDate1 := time.Now().UTC().AddDate(0, 0, 20).Format(time.RFC3339) retainUntilDate2 := time.Now().UTC().AddDate(0, 0, 30).Format(time.RFC3339) @@ -1190,7 +1190,7 @@ func TestAccS3BucketObject_objectLockRetentionStartWithSet(t *testing.T) { func TestAccS3BucketObject_objectBucketKeyEnabled(t *testing.T) { var obj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -1213,7 +1213,7 @@ func TestAccS3BucketObject_objectBucketKeyEnabled(t *testing.T) { func TestAccS3BucketObject_bucketBucketKeyEnabled(t *testing.T) { var obj s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -1236,7 +1236,7 @@ func TestAccS3BucketObject_bucketBucketKeyEnabled(t *testing.T) { func TestAccS3BucketObject_defaultBucketSSE(t *testing.T) { var obj1 s3.GetObjectOutput - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -1259,7 +1259,7 @@ func TestAccS3BucketObject_defaultBucketSSE(t *testing.T) { func TestAccS3BucketObject_ignoreTags(t *testing.T) { var obj s3.GetObjectOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - resourceName := "aws_s3_bucket_object.object" + resourceName := "aws_s3_object.object" key := "test-key" var providers []*schema.Provider @@ -1346,7 +1346,7 @@ func testAccCheckBucketObjectDestroy(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).S3Conn for _, rs := range s.RootModule().Resources { - if rs.Type != "aws_s3_bucket_object" { + if rs.Type != "aws_s3_object" { continue } @@ -1562,7 +1562,7 @@ func testAccCheckBucketObjectCheckTags(n string, expectedTags map[string]string) func testAccBucketObjectBasicConfig(bucket, key string) string { return fmt.Sprintf(` -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = %[1]q key = %[2]q } @@ -1575,7 +1575,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" } @@ -1588,7 +1588,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" source = %[2]q @@ -1603,7 +1603,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" source = %[2]q @@ -1620,7 +1620,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" content = %[2]q @@ -1634,7 +1634,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" server_side_encryption = "AES256" @@ -1650,7 +1650,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" content_base64 = %[2]q @@ -1664,7 +1664,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" source = %[2]q @@ -1683,7 +1683,7 @@ resource "aws_s3_bucket" "object_bucket_3" { } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.object_bucket_3.bucket key = "updateable-key" source = %[3]q @@ -1707,7 +1707,7 @@ resource "aws_s3_access_point" "test" { name = %[1]q } -resource "aws_s3_bucket_object" "test" { +resource "aws_s3_object" "test" { bucket = aws_s3_access_point.test.arn key = "updateable-key" source = %[3]q @@ -1724,7 +1724,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" source = %[2]q @@ -1739,7 +1739,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" source = %[2]q @@ -1758,7 +1758,7 @@ resource "aws_s3_bucket" "test" { } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" content = %[2]q @@ -1773,7 +1773,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" content = "some_bucket_content" @@ -1792,7 +1792,7 @@ resource "aws_s3_bucket" "test" { } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = %[2]q content = %[3]q @@ -1816,7 +1816,7 @@ resource "aws_s3_bucket" "test" { } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = %[2]q content = %[3]q @@ -1841,7 +1841,7 @@ resource "aws_s3_bucket" "test" { } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = %[2]q content = %[3]q @@ -1855,7 +1855,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" @@ -1881,7 +1881,7 @@ resource "aws_s3_bucket" "test" { } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" content = %[2]q @@ -1904,7 +1904,7 @@ resource "aws_s3_bucket" "test" { } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" content = %[2]q @@ -1928,7 +1928,7 @@ resource "aws_s3_bucket" "test" { } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" content = %[2]q @@ -1951,7 +1951,7 @@ resource "aws_s3_bucket" "test" { } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" content = %[2]q @@ -1989,7 +1989,7 @@ resource "aws_s3_bucket" "object_bucket_3" { bucket = %[1]q } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.object_bucket_3.bucket key = "updateable-key" source = %[2]q @@ -2009,7 +2009,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" content = %q @@ -2040,7 +2040,7 @@ resource "aws_s3_bucket" "test" { } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" content = %q @@ -2067,7 +2067,7 @@ resource "aws_s3_bucket" "test" { } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.test.bucket key = "test-key" content = %[2]q diff --git a/internal/service/s3/bucket_objects_data_source_test.go b/internal/service/s3/bucket_objects_data_source_test.go index 54b2beb3c27..8c13beaa912 100644 --- a/internal/service/s3/bucket_objects_data_source_test.go +++ b/internal/service/s3/bucket_objects_data_source_test.go @@ -27,10 +27,10 @@ func TestAccS3BucketObjectsDataSource_basic(t *testing.T) { { Config: testAccObjectsBasicDataSourceConfig(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckObjectsExistsDataSource("data.aws_s3_bucket_objects.yesh"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.#", "2"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.0", "arch/navajo/north_window"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.1", "arch/navajo/sand_dune"), + testAccCheckObjectsExistsDataSource("data.aws_s3_objects.yesh"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.#", "2"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.0", "arch/navajo/north_window"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.1", "arch/navajo/sand_dune"), ), }, }, @@ -53,10 +53,10 @@ func TestAccS3BucketObjectsDataSource_basicViaAccessPoint(t *testing.T) { { Config: testAccObjectsBasicViaAccessPointDataSourceConfig(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckObjectsExistsDataSource("data.aws_s3_bucket_objects.yesh"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.#", "2"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.0", "arch/navajo/north_window"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.1", "arch/navajo/sand_dune"), + testAccCheckObjectsExistsDataSource("data.aws_s3_objects.yesh"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.#", "2"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.0", "arch/navajo/north_window"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.1", "arch/navajo/sand_dune"), ), }, }, @@ -79,15 +79,15 @@ func TestAccS3BucketObjectsDataSource_all(t *testing.T) { { Config: testAccObjectsAllDataSourceConfig(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckObjectsExistsDataSource("data.aws_s3_bucket_objects.yesh"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.#", "7"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.0", "arch/courthouse_towers/landscape"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.1", "arch/navajo/north_window"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.2", "arch/navajo/sand_dune"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.3", "arch/partition/park_avenue"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.4", "arch/rubicon"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.5", "arch/three_gossips/broken"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.6", "arch/three_gossips/turret"), + testAccCheckObjectsExistsDataSource("data.aws_s3_objects.yesh"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.#", "7"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.0", "arch/courthouse_towers/landscape"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.1", "arch/navajo/north_window"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.2", "arch/navajo/sand_dune"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.3", "arch/partition/park_avenue"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.4", "arch/rubicon"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.5", "arch/three_gossips/broken"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.6", "arch/three_gossips/turret"), ), }, }, @@ -110,14 +110,14 @@ func TestAccS3BucketObjectsDataSource_prefixes(t *testing.T) { { Config: testAccObjectsPrefixesDataSourceConfig(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckObjectsExistsDataSource("data.aws_s3_bucket_objects.yesh"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.#", "1"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.0", "arch/rubicon"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "common_prefixes.#", "4"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "common_prefixes.0", "arch/courthouse_towers/"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "common_prefixes.1", "arch/navajo/"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "common_prefixes.2", "arch/partition/"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "common_prefixes.3", "arch/three_gossips/"), + testAccCheckObjectsExistsDataSource("data.aws_s3_objects.yesh"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.#", "1"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.0", "arch/rubicon"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "common_prefixes.#", "4"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "common_prefixes.0", "arch/courthouse_towers/"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "common_prefixes.1", "arch/navajo/"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "common_prefixes.2", "arch/partition/"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "common_prefixes.3", "arch/three_gossips/"), ), }, }, @@ -140,10 +140,10 @@ func TestAccS3BucketObjectsDataSource_encoded(t *testing.T) { { Config: testAccObjectsEncodedDataSourceConfig(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckObjectsExistsDataSource("data.aws_s3_bucket_objects.yesh"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.#", "2"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.0", "arch/ru+b+ic+on"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.1", "arch/rubicon"), + testAccCheckObjectsExistsDataSource("data.aws_s3_objects.yesh"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.#", "2"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.0", "arch/ru+b+ic+on"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.1", "arch/rubicon"), ), }, }, @@ -166,10 +166,10 @@ func TestAccS3BucketObjectsDataSource_maxKeys(t *testing.T) { { Config: testAccObjectsMaxKeysDataSourceConfig(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckObjectsExistsDataSource("data.aws_s3_bucket_objects.yesh"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.#", "2"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.0", "arch/courthouse_towers/landscape"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.1", "arch/navajo/north_window"), + testAccCheckObjectsExistsDataSource("data.aws_s3_objects.yesh"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.#", "2"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.0", "arch/courthouse_towers/landscape"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.1", "arch/navajo/north_window"), ), }, }, @@ -192,9 +192,9 @@ func TestAccS3BucketObjectsDataSource_startAfter(t *testing.T) { { Config: testAccObjectsStartAfterDataSourceConfig(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckObjectsExistsDataSource("data.aws_s3_bucket_objects.yesh"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.#", "1"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.0", "arch/three_gossips/turret"), + testAccCheckObjectsExistsDataSource("data.aws_s3_objects.yesh"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.#", "1"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.0", "arch/three_gossips/turret"), ), }, }, @@ -217,9 +217,9 @@ func TestAccS3BucketObjectsDataSource_fetchOwner(t *testing.T) { { Config: testAccObjectsOwnersDataSourceConfig(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckObjectsExistsDataSource("data.aws_s3_bucket_objects.yesh"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "keys.#", "2"), - resource.TestCheckResourceAttr("data.aws_s3_bucket_objects.yesh", "owners.#", "2"), + testAccCheckObjectsExistsDataSource("data.aws_s3_objects.yesh"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "keys.#", "2"), + resource.TestCheckResourceAttr("data.aws_s3_objects.yesh", "owners.#", "2"), ), }, }, @@ -247,43 +247,43 @@ resource "aws_s3_bucket" "objects_bucket" { bucket = "tf-acc-objects-test-bucket-%d" } -resource "aws_s3_bucket_object" "object1" { +resource "aws_s3_object" "object1" { bucket = aws_s3_bucket.objects_bucket.id key = "arch/three_gossips/turret" content = "Delicate" } -resource "aws_s3_bucket_object" "object2" { +resource "aws_s3_object" "object2" { bucket = aws_s3_bucket.objects_bucket.id key = "arch/three_gossips/broken" content = "Dark Angel" } -resource "aws_s3_bucket_object" "object3" { +resource "aws_s3_object" "object3" { bucket = aws_s3_bucket.objects_bucket.id key = "arch/navajo/north_window" content = "Balanced Rock" } -resource "aws_s3_bucket_object" "object4" { +resource "aws_s3_object" "object4" { bucket = aws_s3_bucket.objects_bucket.id key = "arch/navajo/sand_dune" content = "Queen Victoria Rock" } -resource "aws_s3_bucket_object" "object5" { +resource "aws_s3_object" "object5" { bucket = aws_s3_bucket.objects_bucket.id key = "arch/partition/park_avenue" content = "Double-O" } -resource "aws_s3_bucket_object" "object6" { +resource "aws_s3_object" "object6" { bucket = aws_s3_bucket.objects_bucket.id key = "arch/courthouse_towers/landscape" content = "Fiery Furnace" } -resource "aws_s3_bucket_object" "object7" { +resource "aws_s3_object" "object7" { bucket = aws_s3_bucket.objects_bucket.id key = "arch/rubicon" content = "Devils Garden" @@ -304,7 +304,7 @@ func testAccObjectsBasicDataSourceConfig(randInt int) string { return fmt.Sprintf(` %s -data "aws_s3_bucket_objects" "yesh" { +data "aws_s3_objects" "yesh" { bucket = aws_s3_bucket.objects_bucket.id prefix = "arch/navajo/" delimiter = "/" @@ -314,7 +314,7 @@ data "aws_s3_bucket_objects" "yesh" { func testAccObjectsBasicViaAccessPointDataSourceConfig(randInt int) string { return testAccObjectsResourcesPlusAccessPointDataSourceConfig(randInt) + ` -data "aws_s3_bucket_objects" "yesh" { +data "aws_s3_objects" "yesh" { bucket = aws_s3_access_point.test.arn prefix = "arch/navajo/" delimiter = "/" @@ -326,7 +326,7 @@ func testAccObjectsAllDataSourceConfig(randInt int) string { return fmt.Sprintf(` %s -data "aws_s3_bucket_objects" "yesh" { +data "aws_s3_objects" "yesh" { bucket = aws_s3_bucket.objects_bucket.id } `, testAccObjectsResourcesDataSourceConfig(randInt)) @@ -336,7 +336,7 @@ func testAccObjectsPrefixesDataSourceConfig(randInt int) string { return fmt.Sprintf(` %s -data "aws_s3_bucket_objects" "yesh" { +data "aws_s3_objects" "yesh" { bucket = aws_s3_bucket.objects_bucket.id prefix = "arch/" delimiter = "/" @@ -348,7 +348,7 @@ func testAccObjectsExtraResourceDataSourceConfig(randInt int) string { return fmt.Sprintf(` %s -resource "aws_s3_bucket_object" "object8" { +resource "aws_s3_object" "object8" { bucket = aws_s3_bucket.objects_bucket.id key = "arch/ru b ic on" content = "Goose Island" @@ -360,7 +360,7 @@ func testAccObjectsEncodedDataSourceConfig(randInt int) string { return fmt.Sprintf(` %s -data "aws_s3_bucket_objects" "yesh" { +data "aws_s3_objects" "yesh" { bucket = aws_s3_bucket.objects_bucket.id encoding_type = "url" prefix = "arch/ru" @@ -372,7 +372,7 @@ func testAccObjectsMaxKeysDataSourceConfig(randInt int) string { return fmt.Sprintf(` %s -data "aws_s3_bucket_objects" "yesh" { +data "aws_s3_objects" "yesh" { bucket = aws_s3_bucket.objects_bucket.id max_keys = 2 } @@ -383,7 +383,7 @@ func testAccObjectsStartAfterDataSourceConfig(randInt int) string { return fmt.Sprintf(` %s -data "aws_s3_bucket_objects" "yesh" { +data "aws_s3_objects" "yesh" { bucket = aws_s3_bucket.objects_bucket.id start_after = "arch/three_gossips/broken" } @@ -394,7 +394,7 @@ func testAccObjectsOwnersDataSourceConfig(randInt int) string { return fmt.Sprintf(` %s -data "aws_s3_bucket_objects" "yesh" { +data "aws_s3_objects" "yesh" { bucket = aws_s3_bucket.objects_bucket.id prefix = "arch/three_gossips/" fetch_owner = true diff --git a/internal/service/s3/bucket_test.go b/internal/service/s3/bucket_test.go index 491029b2bd0..0ca48e2f65e 100644 --- a/internal/service/s3/bucket_test.go +++ b/internal/service/s3/bucket_test.go @@ -2580,7 +2580,7 @@ func TestAccS3Bucket_Basic_forceDestroy(t *testing.T) { // By default, the AWS Go SDK cleans up URIs by removing extra slashes // when the service API requests use the URI as part of making a request. -// While the aws_s3_bucket_object resource automatically cleans the key +// While the aws_s3_object resource automatically cleans the key // to not contain these extra slashes, out-of-band handling and other AWS // services may create keys with extra slashes (empty "directory" prefixes). func TestAccS3Bucket_Basic_forceDestroyWithEmptyPrefixes(t *testing.T) { diff --git a/internal/service/s3/object_copy_test.go b/internal/service/s3/object_copy_test.go index 97a18348325..ecfb04d0e59 100644 --- a/internal/service/s3/object_copy_test.go +++ b/internal/service/s3/object_copy_test.go @@ -17,7 +17,7 @@ func TestAccS3ObjectCopy_basic(t *testing.T) { rName1 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) rName2 := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_s3_object_copy.test" - sourceName := "aws_s3_bucket_object.source" + sourceName := "aws_s3_object.source" key := "HundBegraven" sourceKey := "WshngtnNtnls" @@ -136,7 +136,7 @@ resource "aws_s3_bucket" "source" { bucket = %[1]q } -resource "aws_s3_bucket_object" "source" { +resource "aws_s3_object" "source" { bucket = aws_s3_bucket.source.bucket key = %[2]q content = "Ingen ko på isen" @@ -149,7 +149,7 @@ resource "aws_s3_bucket" "target" { resource "aws_s3_object_copy" "test" { bucket = aws_s3_bucket.target.bucket key = %[4]q - source = "${aws_s3_bucket.source.bucket}/${aws_s3_bucket_object.source.key}" + source = "${aws_s3_bucket.source.bucket}/${aws_s3_object.source.key}" grant { uri = "http://acs.amazonaws.com/groups/global/AllUsers" @@ -171,7 +171,7 @@ resource "aws_s3_bucket" "source" { bucket = "%[1]s-source" } -resource "aws_s3_bucket_object" "source" { +resource "aws_s3_object" "source" { bucket = aws_s3_bucket.source.bucket content = "Ingen ko på isen" key = "test" @@ -194,7 +194,7 @@ resource "aws_s3_bucket" "target" { resource "aws_s3_object_copy" "test" { bucket = aws_s3_bucket.target.bucket key = "test" - source = "${aws_s3_bucket.source.bucket}/${aws_s3_bucket_object.source.key}" + source = "${aws_s3_bucket.source.bucket}/${aws_s3_object.source.key}" } `, rName) } @@ -210,7 +210,7 @@ resource "aws_s3_bucket" "source" { bucket = "%[1]s-source" } -resource "aws_s3_bucket_object" "source" { +resource "aws_s3_object" "source" { bucket = aws_s3_bucket.source.bucket content = "Ingen ko på isen" key = "test" @@ -225,7 +225,7 @@ resource "aws_s3_object_copy" "test" { bucket_key_enabled = true key = "test" kms_key_id = aws_kms_key.test.arn - source = "${aws_s3_bucket.source.bucket}/${aws_s3_bucket_object.source.key}" + source = "${aws_s3_bucket.source.bucket}/${aws_s3_object.source.key}" } `, rName) } diff --git a/internal/service/s3/sweep.go b/internal/service/s3/sweep.go index 849816cf0e0..7ba3b87f31b 100644 --- a/internal/service/s3/sweep.go +++ b/internal/service/s3/sweep.go @@ -22,8 +22,8 @@ import ( ) func init() { - resource.AddTestSweepers("aws_s3_bucket_object", &resource.Sweeper{ - Name: "aws_s3_bucket_object", + resource.AddTestSweepers("aws_s3_object", &resource.Sweeper{ + Name: "aws_s3_object", F: sweepBucketObjects, }) @@ -32,7 +32,7 @@ func init() { F: sweepBuckets, Dependencies: []string{ "aws_s3_access_point", - "aws_s3_bucket_object", + "aws_s3_object", "aws_s3control_multi_region_access_point", }, }) From 973034145c30d65d788d7af1e8ce3cb8a89a23b5 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 31 Jan 2022 12:15:49 -0500 Subject: [PATCH 098/116] tests: Update tests --- .../service/apigateway/domain_name_test.go | 8 +-- .../service/apigatewayv2/domain_name_test.go | 12 ++-- .../service/cloudformation/stack_set_test.go | 8 +-- internal/service/cloudformation/stack_test.go | 8 +-- .../cloudformation/type_data_source_test.go | 4 +- internal/service/cloudformation/type_test.go | 8 +-- internal/service/codebuild/project_test.go | 8 +-- .../configservice/conformance_pack_test.go | 8 +-- .../organization_conformance_pack_test.go | 4 +- .../service/ec2/ebs_snapshot_import_test.go | 12 ++-- .../application_version_test.go | 18 ++--- .../elasticbeanstalk/environment_test.go | 8 +-- internal/service/emr/cluster_test.go | 8 +-- internal/service/guardduty/ipset_test.go | 12 ++-- .../service/guardduty/threatintelset_test.go | 12 ++-- .../service/imagebuilder/component_test.go | 4 +- .../custom_plugin_data_source_test.go | 2 +- .../kafkaconnect/custom_plugin_test.go | 20 +++--- .../kinesisanalyticsv2/application_test.go | 66 +++++++++---------- internal/service/lambda/function_test.go | 18 ++--- internal/service/lambda/layer_version_test.go | 4 +- internal/service/mwaa/environment_test.go | 28 ++++---- .../service/quicksight/data_source_test.go | 12 ++-- internal/service/rds/cluster_test.go | 2 +- internal/service/rds/instance_test.go | 2 +- internal/service/sagemaker/endpoint_test.go | 4 +- internal/service/sagemaker/model_test.go | 4 +- internal/service/sagemaker/project_test.go | 4 +- .../service/servicecatalog/constraint_test.go | 4 +- .../service/servicecatalog/product_test.go | 6 +- .../provisioned_product_test.go | 4 +- .../provisioning_artifact_test.go | 8 +-- .../signer/signing_job_data_source_test.go | 8 +-- internal/service/signer/signing_job_test.go | 8 +-- internal/service/ssm/document_test.go | 6 +- internal/service/synthetics/canary_test.go | 8 +-- 36 files changed, 180 insertions(+), 180 deletions(-) diff --git a/internal/service/apigateway/domain_name_test.go b/internal/service/apigateway/domain_name_test.go index ac8db5fac72..56178ef56da 100644 --- a/internal/service/apigateway/domain_name_test.go +++ b/internal/service/apigateway/domain_name_test.go @@ -305,7 +305,7 @@ func TestAccAPIGatewayDomainName_mutualTLSAuthentication(t *testing.T) { var v apigateway.DomainName resourceName := "aws_api_gateway_domain_name.test" acmCertificateResourceName := "aws_acm_certificate.test" - s3BucketObjectResourceName := "aws_s3_bucket_object.test" + s3BucketObjectResourceName := "aws_s3_object.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -647,7 +647,7 @@ resource "aws_s3_bucket" "test" { } } -resource "aws_s3_bucket_object" "test" { +resource "aws_s3_object" "test" { bucket = aws_s3_bucket.test.id key = %[1]q source = "test-fixtures/apigateway-domain-name-truststore-1.pem" @@ -663,8 +663,8 @@ resource "aws_api_gateway_domain_name" "test" { } mutual_tls_authentication { - truststore_uri = "s3://${aws_s3_bucket_object.test.bucket}/${aws_s3_bucket_object.test.key}" - truststore_version = aws_s3_bucket_object.test.version_id + truststore_uri = "s3://${aws_s3_object.test.bucket}/${aws_s3_object.test.key}" + truststore_version = aws_s3_object.test.version_id } } `, rName)) diff --git a/internal/service/apigatewayv2/domain_name_test.go b/internal/service/apigatewayv2/domain_name_test.go index 1cd042d3902..0e8024d2073 100644 --- a/internal/service/apigatewayv2/domain_name_test.go +++ b/internal/service/apigatewayv2/domain_name_test.go @@ -221,7 +221,7 @@ func TestAccAPIGatewayV2DomainName_mutualTLSAuthentication(t *testing.T) { var v apigatewayv2.GetDomainNameOutput resourceName := "aws_apigatewayv2_domain_name.test" acmCertificateResourceName := "aws_acm_certificate.test" - s3BucketObjectResourceName := "aws_s3_bucket_object.test" + s3BucketObjectResourceName := "aws_s3_object.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -469,7 +469,7 @@ resource "aws_s3_bucket" "test" { force_destroy = true } -resource "aws_s3_bucket_object" "test" { +resource "aws_s3_object" "test" { bucket = aws_s3_bucket.test.id key = %[1]q source = "test-fixtures/%[2]s" @@ -485,7 +485,7 @@ resource "aws_apigatewayv2_domain_name" "test" { } mutual_tls_authentication { - truststore_uri = "s3://${aws_s3_bucket_object.test.bucket}/${aws_s3_bucket_object.test.key}" + truststore_uri = "s3://${aws_s3_object.test.bucket}/${aws_s3_object.test.key}" } } `, rName, pemFileName)) @@ -505,7 +505,7 @@ resource "aws_s3_bucket" "test" { } } -resource "aws_s3_bucket_object" "test" { +resource "aws_s3_object" "test" { bucket = aws_s3_bucket.test.id key = %[1]q source = "test-fixtures/%[2]s" @@ -521,8 +521,8 @@ resource "aws_apigatewayv2_domain_name" "test" { } mutual_tls_authentication { - truststore_uri = "s3://${aws_s3_bucket_object.test.bucket}/${aws_s3_bucket_object.test.key}" - truststore_version = aws_s3_bucket_object.test.version_id + truststore_uri = "s3://${aws_s3_object.test.bucket}/${aws_s3_object.test.key}" + truststore_version = aws_s3_object.test.version_id } } `, rName, pemFileName)) diff --git a/internal/service/cloudformation/stack_set_test.go b/internal/service/cloudformation/stack_set_test.go index 1cafd48cc2d..10fb87fd5c0 100644 --- a/internal/service/cloudformation/stack_set_test.go +++ b/internal/service/cloudformation/stack_set_test.go @@ -1348,7 +1348,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -resource "aws_s3_bucket_object" "test" { +resource "aws_s3_object" "test" { acl = "public-read" bucket = aws_s3_bucket.test.bucket @@ -1362,7 +1362,7 @@ CONTENT resource "aws_cloudformation_stack_set" "test" { administration_role_arn = aws_iam_role.test.arn name = %[1]q - template_url = "https://${aws_s3_bucket.test.bucket_regional_domain_name}/${aws_s3_bucket_object.test.key}" + template_url = "https://${aws_s3_bucket.test.bucket_regional_domain_name}/${aws_s3_object.test.key}" } `, rName, testAccStackSetTemplateBodyVPC(rName+"1")) } @@ -1397,7 +1397,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -resource "aws_s3_bucket_object" "test" { +resource "aws_s3_object" "test" { acl = "public-read" bucket = aws_s3_bucket.test.bucket @@ -1411,7 +1411,7 @@ CONTENT resource "aws_cloudformation_stack_set" "test" { administration_role_arn = aws_iam_role.test.arn name = %[1]q - template_url = "https://${aws_s3_bucket.test.bucket_regional_domain_name}/${aws_s3_bucket_object.test.key}" + template_url = "https://${aws_s3_bucket.test.bucket_regional_domain_name}/${aws_s3_object.test.key}" } `, rName, testAccStackSetTemplateBodyVPC(rName+"2")) } diff --git a/internal/service/cloudformation/stack_test.go b/internal/service/cloudformation/stack_test.go index 48af97c0bb8..fab244b7513 100644 --- a/internal/service/cloudformation/stack_test.go +++ b/internal/service/cloudformation/stack_test.go @@ -859,7 +859,7 @@ POLICY } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.b.id key = %[2]q source = "test-fixtures/cloudformation-template.json" @@ -872,7 +872,7 @@ resource "aws_cloudformation_stack" "test" { VpcCIDR = %[3]q } - template_url = "https://${aws_s3_bucket.b.id}.s3-${data.aws_region.current.name}.${data.aws_partition.current.dns_suffix}/${aws_s3_bucket_object.object.key}" + template_url = "https://${aws_s3_bucket.b.id}.s3-${data.aws_region.current.name}.${data.aws_partition.current.dns_suffix}/${aws_s3_object.object.key}" on_failure = "DELETE" timeout_in_minutes = 1 } @@ -913,7 +913,7 @@ POLICY } } -resource "aws_s3_bucket_object" "object" { +resource "aws_s3_object" "object" { bucket = aws_s3_bucket.b.id key = %[2]q source = "test-fixtures/cloudformation-template.yaml" @@ -926,7 +926,7 @@ resource "aws_cloudformation_stack" "test" { VpcCIDR = %[3]q } - template_url = "https://${aws_s3_bucket.b.id}.s3-${data.aws_region.current.name}.${data.aws_partition.current.dns_suffix}/${aws_s3_bucket_object.object.key}" + template_url = "https://${aws_s3_bucket.b.id}.s3-${data.aws_region.current.name}.${data.aws_partition.current.dns_suffix}/${aws_s3_object.object.key}" on_failure = "DELETE" timeout_in_minutes = 1 } diff --git a/internal/service/cloudformation/type_data_source_test.go b/internal/service/cloudformation/type_data_source_test.go index f646af0da16..94d3dc8483c 100644 --- a/internal/service/cloudformation/type_data_source_test.go +++ b/internal/service/cloudformation/type_data_source_test.go @@ -150,14 +150,14 @@ resource "aws_s3_bucket" "test" { force_destroy = true } -resource "aws_s3_bucket_object" "test" { +resource "aws_s3_object" "test" { bucket = aws_s3_bucket.test.bucket key = "test" source = %[2]q } resource "aws_cloudformation_type" "test" { - schema_handler_package = "s3://${aws_s3_bucket_object.test.bucket}/${aws_s3_bucket_object.test.key}" + schema_handler_package = "s3://${aws_s3_object.test.bucket}/${aws_s3_object.test.key}" type = "RESOURCE" type_name = %[3]q } diff --git a/internal/service/cloudformation/type_test.go b/internal/service/cloudformation/type_test.go index 4f6b555f8a3..89ea941f2da 100644 --- a/internal/service/cloudformation/type_test.go +++ b/internal/service/cloudformation/type_test.go @@ -377,7 +377,7 @@ resource "aws_s3_bucket" "test" { force_destroy = true } -resource "aws_s3_bucket_object" "test" { +resource "aws_s3_object" "test" { bucket = aws_s3_bucket.test.bucket key = "test" source = %[2]q @@ -406,7 +406,7 @@ resource "aws_iam_role" "test" { resource "aws_cloudformation_type" "test" { execution_role_arn = aws_iam_role.test.arn - schema_handler_package = "s3://${aws_s3_bucket_object.test.bucket}/${aws_s3_bucket_object.test.key}" + schema_handler_package = "s3://${aws_s3_object.test.bucket}/${aws_s3_object.test.key}" type = "RESOURCE" type_name = %[2]q } @@ -437,7 +437,7 @@ resource "aws_iam_role" "test" { } resource "aws_cloudformation_type" "test" { - schema_handler_package = "s3://${aws_s3_bucket_object.test.bucket}/${aws_s3_bucket_object.test.key}" + schema_handler_package = "s3://${aws_s3_object.test.bucket}/${aws_s3_object.test.key}" type = "RESOURCE" type_name = %[2]q @@ -454,7 +454,7 @@ func testAccCloudformationTypeConfigTypeName(rName string, zipPath string, typeN testAccCloudformationTypeConfigBase(rName, zipPath), fmt.Sprintf(` resource "aws_cloudformation_type" "test" { - schema_handler_package = "s3://${aws_s3_bucket_object.test.bucket}/${aws_s3_bucket_object.test.key}" + schema_handler_package = "s3://${aws_s3_object.test.bucket}/${aws_s3_object.test.key}" type = "RESOURCE" type_name = %[1]q } diff --git a/internal/service/codebuild/project_test.go b/internal/service/codebuild/project_test.go index 9917c2399a4..2cfa74ad4a1 100644 --- a/internal/service/codebuild/project_test.go +++ b/internal/service/codebuild/project_test.go @@ -3171,7 +3171,7 @@ resource "aws_s3_bucket" "test" { force_destroy = true } -resource "aws_s3_bucket_object" "test" { +resource "aws_s3_object" "test" { bucket = aws_s3_bucket.test.bucket key = %[1]q content = "test" @@ -3189,7 +3189,7 @@ resource "aws_codebuild_project" "test" { compute_type = "BUILD_GENERAL1_SMALL" image = "2" type = "LINUX_CONTAINER" - certificate = "${aws_s3_bucket.test.bucket}/${aws_s3_bucket_object.test.key}" + certificate = "${aws_s3_bucket.test.bucket}/${aws_s3_object.test.key}" } source { @@ -3956,7 +3956,7 @@ resource "aws_s3_bucket" "test" { bucket = %[1]q } -resource "aws_s3_bucket_object" "test" { +resource "aws_s3_object" "test" { bucket = aws_s3_bucket.test.bucket content = "test" key = "test.txt" @@ -3977,7 +3977,7 @@ resource "aws_codebuild_project" "test" { } source { - location = "${aws_s3_bucket.test.bucket}/${aws_s3_bucket_object.test.key}" + location = "${aws_s3_bucket.test.bucket}/${aws_s3_object.test.key}" type = "S3" } } diff --git a/internal/service/configservice/conformance_pack_test.go b/internal/service/configservice/conformance_pack_test.go index 28141d408bd..ba32d579170 100644 --- a/internal/service/configservice/conformance_pack_test.go +++ b/internal/service/configservice/conformance_pack_test.go @@ -657,7 +657,7 @@ resource "aws_s3_bucket" "test" { force_destroy = true } -resource "aws_s3_bucket_object" "test" { +resource "aws_s3_object" "test" { bucket = aws_s3_bucket.test.id key = %[1]q content = < Date: Mon, 31 Jan 2022 12:18:32 -0500 Subject: [PATCH 099/116] s3/docs: Update docs --- website/docs/d/s3_bucket_object.html.markdown | 16 ++++++++-------- website/docs/d/s3_bucket_objects.html.markdown | 14 +++++++------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/website/docs/d/s3_bucket_object.html.markdown b/website/docs/d/s3_bucket_object.html.markdown index 590ffb876c2..88bf8a0894a 100644 --- a/website/docs/d/s3_bucket_object.html.markdown +++ b/website/docs/d/s3_bucket_object.html.markdown @@ -1,12 +1,12 @@ --- subcategory: "S3" layout: "aws" -page_title: "AWS: aws_s3_bucket_object" +page_title: "AWS: aws_s3_object" description: |- Provides metadata and optionally content of an S3 object --- -# Data Source: aws_s3_bucket_object +# Data Source: aws_s3_object The S3 object data source allows access to the metadata and _optionally_ (see below) content of an object stored inside S3 bucket. @@ -19,7 +19,7 @@ The following example retrieves a text object (which must have a `Content-Type` value starting with `text/`) and uses it as the `user_data` for an EC2 instance: ```terraform -data "aws_s3_bucket_object" "bootstrap_script" { +data "aws_s3_object" "bootstrap_script" { bucket = "ourcorp-deploy-config" key = "ec2-bootstrap-script.sh" } @@ -27,7 +27,7 @@ data "aws_s3_bucket_object" "bootstrap_script" { resource "aws_instance" "example" { instance_type = "t2.micro" ami = "ami-2757f631" - user_data = data.aws_s3_bucket_object.bootstrap_script.body + user_data = data.aws_s3_object.bootstrap_script.body } ``` @@ -38,15 +38,15 @@ Lambda functions is available in the documentation for [`aws_lambda_function`](/docs/providers/aws/r/lambda_function.html). ```terraform -data "aws_s3_bucket_object" "lambda" { +data "aws_s3_object" "lambda" { bucket = "ourcorp-lambda-functions" key = "hello-world.zip" } resource "aws_lambda_function" "test_lambda" { - s3_bucket = data.aws_s3_bucket_object.lambda.bucket - s3_key = data.aws_s3_bucket_object.lambda.key - s3_object_version = data.aws_s3_bucket_object.lambda.version_id + s3_bucket = data.aws_s3_object.lambda.bucket + s3_key = data.aws_s3_object.lambda.key + s3_object_version = data.aws_s3_object.lambda.version_id function_name = "lambda_function_name" role = aws_iam_role.iam_for_lambda.arn # (not shown) handler = "exports.test" diff --git a/website/docs/d/s3_bucket_objects.html.markdown b/website/docs/d/s3_bucket_objects.html.markdown index 8e246023c1f..1b488786070 100644 --- a/website/docs/d/s3_bucket_objects.html.markdown +++ b/website/docs/d/s3_bucket_objects.html.markdown @@ -1,12 +1,12 @@ --- subcategory: "S3" layout: "aws" -page_title: "AWS: aws_s3_bucket_objects" +page_title: "AWS: aws_s3_objects" description: |- Returns keys and metadata of S3 objects --- -# Data Source: aws_s3_bucket_objects +# Data Source: aws_s3_objects ~> **NOTE on `max_keys`:** Retrieving very large numbers of keys can adversely affect Terraform's performance. @@ -17,14 +17,14 @@ The bucket-objects data source returns keys (i.e., file names) and other metadat The following example retrieves a list of all object keys in an S3 bucket and creates corresponding Terraform object data sources: ```terraform -data "aws_s3_bucket_objects" "my_objects" { +data "aws_s3_objects" "my_objects" { bucket = "ourcorp" } -data "aws_s3_bucket_object" "object_info" { - count = length(data.aws_s3_bucket_objects.my_objects.keys) - key = element(data.aws_s3_bucket_objects.my_objects.keys, count.index) - bucket = data.aws_s3_bucket_objects.my_objects.bucket +data "aws_s3_object" "object_info" { + count = length(data.aws_s3_objects.my_objects.keys) + key = element(data.aws_s3_objects.my_objects.keys, count.index) + bucket = data.aws_s3_objects.my_objects.bucket } ``` From be1981818e8a50e115906c70e68f3b4f694af7f8 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 31 Jan 2022 12:19:13 -0500 Subject: [PATCH 100/116] docs: Update docs --- .../docs/r/cloudformation_type.html.markdown | 2 +- .../r/config_conformance_pack.html.markdown | 4 ++-- ...organization_conformance_pack.html.markdown | 4 ++-- ...beanstalk_application_version.html.markdown | 4 ++-- website/docs/r/gamelift_build.html.markdown | 2 +- website/docs/r/guardduty_ipset.html.markdown | 4 ++-- .../r/guardduty_threatintelset.html.markdown | 4 ++-- .../r/imagebuilder_component.html.markdown | 2 +- ...inesisanalyticsv2_application.html.markdown | 8 ++++---- website/docs/r/lambda_function.html.markdown | 2 +- .../docs/r/lambda_layer_version.html.markdown | 2 +- .../r/mskconnect_custom_plugin.html.markdown | 4 ++-- website/docs/r/s3_bucket_object.html.markdown | 18 +++++++++--------- ...catalog_provisioning_artifact.html.markdown | 2 +- 14 files changed, 31 insertions(+), 31 deletions(-) diff --git a/website/docs/r/cloudformation_type.html.markdown b/website/docs/r/cloudformation_type.html.markdown index b3819d49c16..c4dd058d23a 100644 --- a/website/docs/r/cloudformation_type.html.markdown +++ b/website/docs/r/cloudformation_type.html.markdown @@ -16,7 +16,7 @@ Manages a version of a CloudFormation Type. ```terraform resource "aws_cloudformation_type" "example" { - schema_handler_package = "s3://${aws_s3_bucket_object.example.bucket}/${aws_s3_bucket_object.example.key}" + schema_handler_package = "s3://${aws_s3_object.example.bucket}/${aws_s3_object.example.key}" type = "RESOURCE" type_name = "ExampleCompany::ExampleService::ExampleResource" diff --git a/website/docs/r/config_conformance_pack.html.markdown b/website/docs/r/config_conformance_pack.html.markdown index 3f135afec28..ac10f34fd48 100644 --- a/website/docs/r/config_conformance_pack.html.markdown +++ b/website/docs/r/config_conformance_pack.html.markdown @@ -53,7 +53,7 @@ EOT ```terraform resource "aws_config_conformance_pack" "example" { name = "example" - template_s3_uri = "s3://${aws_s3_bucket.example.bucket}/${aws_s3_bucket_object.example.key}" + template_s3_uri = "s3://${aws_s3_bucket.example.bucket}/${aws_s3_object.example.key}" depends_on = [aws_config_configuration_recorder.example] } @@ -62,7 +62,7 @@ resource "aws_s3_bucket" "example" { bucket = "example" } -resource "aws_s3_bucket_object" "example" { +resource "aws_s3_object" "example" { bucket = aws_s3_bucket.example.id key = "example-key" content = < Date: Mon, 31 Jan 2022 12:20:38 -0500 Subject: [PATCH 101/116] docs: Rename files --- .../d/{s3_bucket_object.html.markdown => s3_object.html.markdown} | 0 .../{s3_bucket_objects.html.markdown => s3_objects.html.markdown} | 0 .../r/{s3_bucket_object.html.markdown => s3_object.html.markdown} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename website/docs/d/{s3_bucket_object.html.markdown => s3_object.html.markdown} (100%) rename website/docs/d/{s3_bucket_objects.html.markdown => s3_objects.html.markdown} (100%) rename website/docs/r/{s3_bucket_object.html.markdown => s3_object.html.markdown} (100%) diff --git a/website/docs/d/s3_bucket_object.html.markdown b/website/docs/d/s3_object.html.markdown similarity index 100% rename from website/docs/d/s3_bucket_object.html.markdown rename to website/docs/d/s3_object.html.markdown diff --git a/website/docs/d/s3_bucket_objects.html.markdown b/website/docs/d/s3_objects.html.markdown similarity index 100% rename from website/docs/d/s3_bucket_objects.html.markdown rename to website/docs/d/s3_objects.html.markdown diff --git a/website/docs/r/s3_bucket_object.html.markdown b/website/docs/r/s3_object.html.markdown similarity index 100% rename from website/docs/r/s3_bucket_object.html.markdown rename to website/docs/r/s3_object.html.markdown From c7f2a8eede4f2e8ccb477621611af2b68de8b9e9 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 31 Jan 2022 12:23:49 -0500 Subject: [PATCH 102/116] Rename files --- internal/service/s3/{bucket_object.go => object.go} | 0 .../s3/{bucket_object_data_source.go => object_data_source.go} | 0 ...cket_object_data_source_test.go => object_data_source_test.go} | 0 internal/service/s3/{bucket_object_test.go => object_test.go} | 0 .../s3/{bucket_objects_data_source.go => objects_data_source.go} | 0 ...et_objects_data_source_test.go => objects_data_source_test.go} | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename internal/service/s3/{bucket_object.go => object.go} (100%) rename internal/service/s3/{bucket_object_data_source.go => object_data_source.go} (100%) rename internal/service/s3/{bucket_object_data_source_test.go => object_data_source_test.go} (100%) rename internal/service/s3/{bucket_object_test.go => object_test.go} (100%) rename internal/service/s3/{bucket_objects_data_source.go => objects_data_source.go} (100%) rename internal/service/s3/{bucket_objects_data_source_test.go => objects_data_source_test.go} (100%) diff --git a/internal/service/s3/bucket_object.go b/internal/service/s3/object.go similarity index 100% rename from internal/service/s3/bucket_object.go rename to internal/service/s3/object.go diff --git a/internal/service/s3/bucket_object_data_source.go b/internal/service/s3/object_data_source.go similarity index 100% rename from internal/service/s3/bucket_object_data_source.go rename to internal/service/s3/object_data_source.go diff --git a/internal/service/s3/bucket_object_data_source_test.go b/internal/service/s3/object_data_source_test.go similarity index 100% rename from internal/service/s3/bucket_object_data_source_test.go rename to internal/service/s3/object_data_source_test.go diff --git a/internal/service/s3/bucket_object_test.go b/internal/service/s3/object_test.go similarity index 100% rename from internal/service/s3/bucket_object_test.go rename to internal/service/s3/object_test.go diff --git a/internal/service/s3/bucket_objects_data_source.go b/internal/service/s3/objects_data_source.go similarity index 100% rename from internal/service/s3/bucket_objects_data_source.go rename to internal/service/s3/objects_data_source.go diff --git a/internal/service/s3/bucket_objects_data_source_test.go b/internal/service/s3/objects_data_source_test.go similarity index 100% rename from internal/service/s3/bucket_objects_data_source_test.go rename to internal/service/s3/objects_data_source_test.go From d6d5afd69e878f9db8cf0b3b492da68a6dd0c29e Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 31 Jan 2022 12:26:54 -0500 Subject: [PATCH 103/116] Update messages --- internal/service/s3/object.go | 4 ++-- website/docs/r/cloudtrail.html.markdown | 2 +- .../docs/r/s3_bucket_analytics_configuration.html.markdown | 2 +- .../s3_bucket_intelligent_tiering_configuration.html.markdown | 2 +- website/docs/r/s3_bucket_inventory.html.markdown | 2 +- website/docs/r/s3_bucket_metric.html.markdown | 2 +- website/docs/r/s3_object.html.markdown | 4 ++-- website/docs/r/storagegateway_nfs_file_share.html.markdown | 2 +- website/docs/r/storagegateway_smb_file_share.html.markdown | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/internal/service/s3/object.go b/internal/service/s3/object.go index 8dca8fc1625..47ed737d709 100644 --- a/internal/service/s3/object.go +++ b/internal/service/s3/object.go @@ -434,14 +434,14 @@ func resourceBucketObjectUpload(d *schema.ResourceData, meta interface{}) error } file, err := os.Open(path) if err != nil { - return fmt.Errorf("Error opening S3 bucket object source (%s): %s", path, err) + return fmt.Errorf("Error opening S3 object source (%s): %s", path, err) } body = file defer func() { err := file.Close() if err != nil { - log.Printf("[WARN] Error closing S3 bucket object source (%s): %s", path, err) + log.Printf("[WARN] Error closing S3 object source (%s): %s", path, err) } }() } else if v, ok := d.GetOk("content"); ok { diff --git a/website/docs/r/cloudtrail.html.markdown b/website/docs/r/cloudtrail.html.markdown index b9f861a5083..ef5b5a5ddd6 100644 --- a/website/docs/r/cloudtrail.html.markdown +++ b/website/docs/r/cloudtrail.html.markdown @@ -70,7 +70,7 @@ POLICY ### Data Event Logging -CloudTrail can log [Data Events](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-data-events-with-cloudtrail.html) for certain services such as S3 bucket objects and Lambda function invocations. Additional information about data event configuration can be found in the following links: +CloudTrail can log [Data Events](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-data-events-with-cloudtrail.html) for certain services such as S3 objects and Lambda function invocations. Additional information about data event configuration can be found in the following links: * [CloudTrail API DataResource documentation](https://docs.aws.amazon.com/awscloudtrail/latest/APIReference/API_DataResource.html) (for basic event selector). * [CloudTrail API AdvancedFieldSelector documentation](https://docs.aws.amazon.com/awscloudtrail/latest/APIReference/API_AdvancedFieldSelector.html) (for advanced event selector). diff --git a/website/docs/r/s3_bucket_analytics_configuration.html.markdown b/website/docs/r/s3_bucket_analytics_configuration.html.markdown index f847db50611..af45c545027 100644 --- a/website/docs/r/s3_bucket_analytics_configuration.html.markdown +++ b/website/docs/r/s3_bucket_analytics_configuration.html.markdown @@ -39,7 +39,7 @@ resource "aws_s3_bucket" "analytics" { } ``` -### Add analytics configuration with S3 bucket object filter +### Add analytics configuration with S3 object filter ```terraform resource "aws_s3_bucket_analytics_configuration" "example-filtered" { diff --git a/website/docs/r/s3_bucket_intelligent_tiering_configuration.html.markdown b/website/docs/r/s3_bucket_intelligent_tiering_configuration.html.markdown index 7d16efd69c9..844dee3876f 100644 --- a/website/docs/r/s3_bucket_intelligent_tiering_configuration.html.markdown +++ b/website/docs/r/s3_bucket_intelligent_tiering_configuration.html.markdown @@ -34,7 +34,7 @@ resource "aws_s3_bucket" "example" { } ``` -### Add intelligent tiering configuration with S3 bucket object filter +### Add intelligent tiering configuration with S3 object filter ```terraform resource "aws_s3_bucket_intelligent_tiering_configuration" "example-filtered" { diff --git a/website/docs/r/s3_bucket_inventory.html.markdown b/website/docs/r/s3_bucket_inventory.html.markdown index 3f79ce72aed..1a5f806ab66 100644 --- a/website/docs/r/s3_bucket_inventory.html.markdown +++ b/website/docs/r/s3_bucket_inventory.html.markdown @@ -42,7 +42,7 @@ resource "aws_s3_bucket_inventory" "test" { } ``` -### Add inventory configuration with S3 bucket object prefix +### Add inventory configuration with S3 object prefix ```terraform resource "aws_s3_bucket" "test" { diff --git a/website/docs/r/s3_bucket_metric.html.markdown b/website/docs/r/s3_bucket_metric.html.markdown index 65aee084f0a..64d363c80e2 100644 --- a/website/docs/r/s3_bucket_metric.html.markdown +++ b/website/docs/r/s3_bucket_metric.html.markdown @@ -25,7 +25,7 @@ resource "aws_s3_bucket_metric" "example-entire-bucket" { } ``` -### Add metrics configuration with S3 bucket object filter +### Add metrics configuration with S3 object filter ```terraform resource "aws_s3_bucket" "example" { diff --git a/website/docs/r/s3_object.html.markdown b/website/docs/r/s3_object.html.markdown index 2e4762fc8ee..d690538279d 100644 --- a/website/docs/r/s3_object.html.markdown +++ b/website/docs/r/s3_object.html.markdown @@ -3,12 +3,12 @@ subcategory: "S3" layout: "aws" page_title: "AWS: aws_s3_object" description: |- - Provides a S3 bucket object resource. + Provides an S3 object resource. --- # Resource: aws_s3_object -Provides a S3 bucket object resource. +Provides an S3 object resource. ## Example Usage diff --git a/website/docs/r/storagegateway_nfs_file_share.html.markdown b/website/docs/r/storagegateway_nfs_file_share.html.markdown index ef3083836db..5e9cb2d474f 100644 --- a/website/docs/r/storagegateway_nfs_file_share.html.markdown +++ b/website/docs/r/storagegateway_nfs_file_share.html.markdown @@ -36,7 +36,7 @@ The following arguments are supported: * `kms_key_arn` - (Optional) Amazon Resource Name (ARN) for KMS key used for Amazon S3 server side encryption. This value can only be set when `kms_encrypted` is true. * `nfs_file_share_defaults` - (Optional) Nested argument with file share default values. More information below. see [NFS File Share Defaults](#nfs_file_share_defaults) for more details. * `cache_attributes` - (Optional) Refresh cache information. see [Cache Attributes](#cache_attributes) for more details. -* `object_acl` - (Optional) Access Control List permission for S3 bucket objects. Defaults to `private`. +* `object_acl` - (Optional) Access Control List permission for S3 objects. Defaults to `private`. * `read_only` - (Optional) Boolean to indicate write status of file share. File share does not accept writes if `true`. Defaults to `false`. * `requester_pays` - (Optional) Boolean who pays the cost of the request and the data download from the Amazon S3 bucket. Set this value to `true` if you want the requester to pay instead of the bucket owner. Defaults to `false`. * `squash` - (Optional) Maps a user to anonymous user. Defaults to `RootSquash`. Valid values: `RootSquash` (only root is mapped to anonymous user), `NoSquash` (no one is mapped to anonymous user), `AllSquash` (everyone is mapped to anonymous user) diff --git a/website/docs/r/storagegateway_smb_file_share.html.markdown b/website/docs/r/storagegateway_smb_file_share.html.markdown index e235f442230..223f9c1812e 100644 --- a/website/docs/r/storagegateway_smb_file_share.html.markdown +++ b/website/docs/r/storagegateway_smb_file_share.html.markdown @@ -56,7 +56,7 @@ The following arguments are supported: * `invalid_user_list` - (Optional) A list of users in the Active Directory that are not allowed to access the file share. Only valid if `authentication` is set to `ActiveDirectory`. * `kms_encrypted` - (Optional) Boolean value if `true` to use Amazon S3 server side encryption with your own AWS KMS key, or `false` to use a key managed by Amazon S3. Defaults to `false`. * `kms_key_arn` - (Optional) Amazon Resource Name (ARN) for KMS key used for Amazon S3 server side encryption. This value can only be set when `kms_encrypted` is true. -* `object_acl` - (Optional) Access Control List permission for S3 bucket objects. Defaults to `private`. +* `object_acl` - (Optional) Access Control List permission for S3 objects. Defaults to `private`. * `oplocks_enabled` - (Optional) Boolean to indicate Opportunistic lock (oplock) status. Defaults to `true`. * `cache_attributes` - (Optional) Refresh cache information. see [Cache Attributes](#cache_attributes) for more details. * `read_only` - (Optional) Boolean to indicate write status of file share. File share does not accept writes if `true`. Defaults to `false`. From 266219b5a8959461b411451b8c6b5fc39d9c59cc Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 31 Jan 2022 12:29:15 -0500 Subject: [PATCH 104/116] Update messages --- internal/service/s3/bucket.go | 2 +- internal/service/s3/object.go | 2 +- internal/service/s3/object_copy.go | 2 +- internal/service/s3/object_copy_test.go | 2 +- internal/service/s3/object_data_source.go | 2 +- internal/service/s3/object_test.go | 2 +- internal/service/s3/sweep.go | 6 +++--- website/docs/r/cloudtrail.html.markdown | 4 ++-- website/docs/r/dms_endpoint.html.markdown | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/internal/service/s3/bucket.go b/internal/service/s3/bucket.go index 1d538674c2d..22fe3f8119c 100644 --- a/internal/service/s3/bucket.go +++ b/internal/service/s3/bucket.go @@ -1308,7 +1308,7 @@ func resourceBucketRead(d *schema.ResourceData, meta interface{}) error { // Object lock not supported in all partitions (extra guard, also guards in read func) if err != nil && (meta.(*conns.AWSClient).Partition == endpoints.AwsPartitionID || meta.(*conns.AWSClient).Partition == endpoints.AwsUsGovPartitionID) { - return fmt.Errorf("error getting S3 Bucket Object Lock configuration: %s", err) + return fmt.Errorf("error getting S3 Object Lock configuration: %s", err) } if err != nil { diff --git a/internal/service/s3/object.go b/internal/service/s3/object.go index 47ed737d709..dfb0666d945 100644 --- a/internal/service/s3/object.go +++ b/internal/service/s3/object.go @@ -235,7 +235,7 @@ func resourceBucketObjectRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("error reading S3 Object (%s): %w", d.Id(), err) } - log.Printf("[DEBUG] Reading S3 Bucket Object meta: %s", resp) + log.Printf("[DEBUG] Reading S3 Object meta: %s", resp) d.Set("bucket_key_enabled", resp.BucketKeyEnabled) d.Set("cache_control", resp.CacheControl) diff --git a/internal/service/s3/object_copy.go b/internal/service/s3/object_copy.go index 5db14b97e91..829c1d14ee9 100644 --- a/internal/service/s3/object_copy.go +++ b/internal/service/s3/object_copy.go @@ -323,7 +323,7 @@ func resourceObjectCopyRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("error reading S3 Object (%s): empty response", d.Id()) } - log.Printf("[DEBUG] Reading S3 Bucket Object meta: %s", resp) + log.Printf("[DEBUG] Reading S3 Object meta: %s", resp) d.Set("bucket_key_enabled", resp.BucketKeyEnabled) d.Set("cache_control", resp.CacheControl) diff --git a/internal/service/s3/object_copy_test.go b/internal/service/s3/object_copy_test.go index ecfb04d0e59..5b70b17f5cb 100644 --- a/internal/service/s3/object_copy_test.go +++ b/internal/service/s3/object_copy_test.go @@ -112,7 +112,7 @@ func testAccCheckObjectCopyExists(n string) resource.TestCheckFunc { } if rs.Primary.ID == "" { - return fmt.Errorf("No S3 Bucket Object ID is set") + return fmt.Errorf("No S3 Object ID is set") } conn := acctest.Provider.Meta().(*conns.AWSClient).S3Conn diff --git a/internal/service/s3/object_data_source.go b/internal/service/s3/object_data_source.go index 0f548d308ca..68d424b2c98 100644 --- a/internal/service/s3/object_data_source.go +++ b/internal/service/s3/object_data_source.go @@ -150,7 +150,7 @@ func dataSourceBucketObjectRead(d *schema.ResourceData, meta interface{}) error uniqueId += "@" + v.(string) } - log.Printf("[DEBUG] Reading S3 Bucket Object: %s", input) + log.Printf("[DEBUG] Reading S3 Object: %s", input) out, err := conn.HeadObject(&input) if err != nil { return fmt.Errorf("failed getting S3 Bucket (%s) Object (%s): %w", bucket, key, err) diff --git a/internal/service/s3/object_test.go b/internal/service/s3/object_test.go index 86ac712fdbe..b53a61b18a2 100644 --- a/internal/service/s3/object_test.go +++ b/internal/service/s3/object_test.go @@ -1371,7 +1371,7 @@ func testAccCheckBucketObjectExists(n string, obj *s3.GetObjectOutput) resource. } if rs.Primary.ID == "" { - return fmt.Errorf("No S3 Bucket Object ID is set") + return fmt.Errorf("No S3 Object ID is set") } conn := acctest.Provider.Meta().(*conns.AWSClient).S3Conn diff --git a/internal/service/s3/sweep.go b/internal/service/s3/sweep.go index 7ba3b87f31b..a0d255169c2 100644 --- a/internal/service/s3/sweep.go +++ b/internal/service/s3/sweep.go @@ -50,16 +50,16 @@ func sweepBucketObjects(region string) error { output, err := conn.ListBuckets(input) if sweep.SkipSweepError(err) { - log.Printf("[WARN] Skipping S3 Bucket Objects sweep for %s: %s", region, err) + log.Printf("[WARN] Skipping S3 Objects sweep for %s: %s", region, err) return nil } if err != nil { - return fmt.Errorf("error listing S3 Bucket Objects: %s", err) + return fmt.Errorf("error listing S3 Objects: %s", err) } if len(output.Buckets) == 0 { - log.Print("[DEBUG] No S3 Bucket Objects to sweep") + log.Print("[DEBUG] No S3 Objects to sweep") return nil } diff --git a/website/docs/r/cloudtrail.html.markdown b/website/docs/r/cloudtrail.html.markdown index ef5b5a5ddd6..279b5155578 100644 --- a/website/docs/r/cloudtrail.html.markdown +++ b/website/docs/r/cloudtrail.html.markdown @@ -93,7 +93,7 @@ resource "aws_cloudtrail" "example" { } ``` -#### Logging All S3 Bucket Object Events By Using Basic Event Selectors +#### Logging All S3 Object Events By Using Basic Event Selectors ```terraform resource "aws_cloudtrail" "example" { @@ -136,7 +136,7 @@ resource "aws_cloudtrail" "example" { } ``` -#### Logging All S3 Bucket Object Events Except For Two S3 Buckets By Using Advanced Event Selectors +#### Logging All S3 Object Events Except For Two S3 Buckets By Using Advanced Event Selectors ```terraform data "aws_s3_bucket" "not-important-bucket-1" { diff --git a/website/docs/r/dms_endpoint.html.markdown b/website/docs/r/dms_endpoint.html.markdown index 5309b4eb969..dd0b04e9c78 100644 --- a/website/docs/r/dms_endpoint.html.markdown +++ b/website/docs/r/dms_endpoint.html.markdown @@ -142,7 +142,7 @@ The `mongodb_settings` configuration block supports the following arguments: The `s3_settings` configuration block supports the following arguments: -* `bucket_folder` - (Optional) S3 Bucket Object prefix. +* `bucket_folder` - (Optional) S3 Object prefix. * `bucket_name` - (Optional) S3 Bucket name. * `compression_type` - (Optional) Set to compress target files. Defaults to `NONE`. Valid values are `GZIP` and `NONE`. * `csv_delimiter` - (Optional) Delimiter used to separate columns in the source files. Defaults to `,`. From 8c627ef7dd93ac2423a4a51699d8de728a26794c Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 31 Jan 2022 12:32:02 -0500 Subject: [PATCH 105/116] Change names --- internal/service/s3/object.go | 6 +- internal/service/s3/object_copy_test.go | 2 +- .../service/s3/object_data_source_test.go | 22 +++---- internal/service/s3/object_test.go | 62 +++++++++---------- .../service/s3/objects_data_source_test.go | 16 ++--- 5 files changed, 54 insertions(+), 54 deletions(-) diff --git a/internal/service/s3/object.go b/internal/service/s3/object.go index dfb0666d945..741c6acbcdb 100644 --- a/internal/service/s3/object.go +++ b/internal/service/s3/object.go @@ -305,7 +305,7 @@ func resourceBucketObjectRead(d *schema.ResourceData, meta interface{}) error { } func resourceBucketObjectUpdate(d *schema.ResourceData, meta interface{}) error { - if hasS3BucketObjectContentChanges(d) { + if hasS3ObjectContentChanges(d) { return resourceBucketObjectUpload(d, meta) } @@ -573,7 +573,7 @@ func validateMetadataIsLowerCase(v interface{}, k string) (ws []string, errors [ } func resourceBucketObjectCustomizeDiff(_ context.Context, d *schema.ResourceDiff, meta interface{}) error { - if hasS3BucketObjectContentChanges(d) { + if hasS3ObjectContentChanges(d) { return d.SetNewComputed("version_id") } @@ -585,7 +585,7 @@ func resourceBucketObjectCustomizeDiff(_ context.Context, d *schema.ResourceDiff return nil } -func hasS3BucketObjectContentChanges(d verify.ResourceDiffer) bool { +func hasS3ObjectContentChanges(d verify.ResourceDiffer) bool { for _, key := range []string{ "bucket_key_enabled", "cache_control", diff --git a/internal/service/s3/object_copy_test.go b/internal/service/s3/object_copy_test.go index 5b70b17f5cb..5b17a595870 100644 --- a/internal/service/s3/object_copy_test.go +++ b/internal/service/s3/object_copy_test.go @@ -123,7 +123,7 @@ func testAccCheckObjectCopyExists(n string) resource.TestCheckFunc { IfMatch: aws.String(rs.Primary.Attributes["etag"]), }) if err != nil { - return fmt.Errorf("S3Bucket Object error: %s", err) + return fmt.Errorf("S3 Object error: %s", err) } return nil diff --git a/internal/service/s3/object_data_source_test.go b/internal/service/s3/object_data_source_test.go index 85e596a7e19..3570a81a72e 100644 --- a/internal/service/s3/object_data_source_test.go +++ b/internal/service/s3/object_data_source_test.go @@ -17,7 +17,7 @@ import ( const rfc1123RegexPattern = `^[a-zA-Z]{3}, [0-9]+ [a-zA-Z]+ [0-9]{4} [0-9:]+ [A-Z]+$` -func TestAccS3BucketObjectDataSource_basic(t *testing.T) { +func TestAccS3ObjectDataSource_basic(t *testing.T) { rInt := sdkacctest.RandInt() var rObj s3.GetObjectOutput @@ -51,7 +51,7 @@ func TestAccS3BucketObjectDataSource_basic(t *testing.T) { }) } -func TestAccS3BucketObjectDataSource_basicViaAccessPoint(t *testing.T) { +func TestAccS3ObjectDataSource_basicViaAccessPoint(t *testing.T) { var dsObj, rObj s3.GetObjectOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -78,7 +78,7 @@ func TestAccS3BucketObjectDataSource_basicViaAccessPoint(t *testing.T) { }) } -func TestAccS3BucketObjectDataSource_readableBody(t *testing.T) { +func TestAccS3ObjectDataSource_readableBody(t *testing.T) { rInt := sdkacctest.RandInt() var rObj s3.GetObjectOutput @@ -112,7 +112,7 @@ func TestAccS3BucketObjectDataSource_readableBody(t *testing.T) { }) } -func TestAccS3BucketObjectDataSource_kmsEncrypted(t *testing.T) { +func TestAccS3ObjectDataSource_kmsEncrypted(t *testing.T) { rInt := sdkacctest.RandInt() var rObj s3.GetObjectOutput @@ -148,7 +148,7 @@ func TestAccS3BucketObjectDataSource_kmsEncrypted(t *testing.T) { }) } -func TestAccS3BucketObjectDataSource_bucketKeyEnabled(t *testing.T) { +func TestAccS3ObjectDataSource_bucketKeyEnabled(t *testing.T) { rInt := sdkacctest.RandInt() var rObj s3.GetObjectOutput @@ -185,7 +185,7 @@ func TestAccS3BucketObjectDataSource_bucketKeyEnabled(t *testing.T) { }) } -func TestAccS3BucketObjectDataSource_allParams(t *testing.T) { +func TestAccS3ObjectDataSource_allParams(t *testing.T) { rInt := sdkacctest.RandInt() var rObj s3.GetObjectOutput @@ -236,7 +236,7 @@ func TestAccS3BucketObjectDataSource_allParams(t *testing.T) { }) } -func TestAccS3BucketObjectDataSource_objectLockLegalHoldOff(t *testing.T) { +func TestAccS3ObjectDataSource_objectLockLegalHoldOff(t *testing.T) { rInt := sdkacctest.RandInt() var rObj s3.GetObjectOutput @@ -270,7 +270,7 @@ func TestAccS3BucketObjectDataSource_objectLockLegalHoldOff(t *testing.T) { }) } -func TestAccS3BucketObjectDataSource_objectLockLegalHoldOn(t *testing.T) { +func TestAccS3ObjectDataSource_objectLockLegalHoldOn(t *testing.T) { rInt := sdkacctest.RandInt() retainUntilDate := time.Now().UTC().AddDate(0, 0, 10).Format(time.RFC3339) @@ -305,7 +305,7 @@ func TestAccS3BucketObjectDataSource_objectLockLegalHoldOn(t *testing.T) { }) } -func TestAccS3BucketObjectDataSource_leadingSlash(t *testing.T) { +func TestAccS3ObjectDataSource_leadingSlash(t *testing.T) { var rObj s3.GetObjectOutput var dsObj1, dsObj2, dsObj3 s3.GetObjectOutput @@ -358,7 +358,7 @@ func TestAccS3BucketObjectDataSource_leadingSlash(t *testing.T) { }) } -func TestAccS3BucketObjectDataSource_multipleSlashes(t *testing.T) { +func TestAccS3ObjectDataSource_multipleSlashes(t *testing.T) { var rObj1, rObj2 s3.GetObjectOutput var dsObj1, dsObj2, dsObj3 s3.GetObjectOutput @@ -408,7 +408,7 @@ func TestAccS3BucketObjectDataSource_multipleSlashes(t *testing.T) { }) } -func TestAccS3BucketObjectDataSource_singleSlashAsKey(t *testing.T) { +func TestAccS3ObjectDataSource_singleSlashAsKey(t *testing.T) { var dsObj s3.GetObjectOutput dataSourceName := "data.aws_s3_object.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) diff --git a/internal/service/s3/object_test.go b/internal/service/s3/object_test.go index b53a61b18a2..69f53a90354 100644 --- a/internal/service/s3/object_test.go +++ b/internal/service/s3/object_test.go @@ -25,7 +25,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -func TestAccS3BucketObject_noNameNoKey(t *testing.T) { +func TestAccS3Object_noNameNoKey(t *testing.T) { bucketError := regexp.MustCompile(`bucket must not be empty`) keyError := regexp.MustCompile(`key must not be empty`) @@ -49,7 +49,7 @@ func TestAccS3BucketObject_noNameNoKey(t *testing.T) { }) } -func TestAccS3BucketObject_empty(t *testing.T) { +func TestAccS3Object_empty(t *testing.T) { var obj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -79,7 +79,7 @@ func TestAccS3BucketObject_empty(t *testing.T) { }) } -func TestAccS3BucketObject_source(t *testing.T) { +func TestAccS3Object_source(t *testing.T) { var obj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -111,7 +111,7 @@ func TestAccS3BucketObject_source(t *testing.T) { }) } -func TestAccS3BucketObject_content(t *testing.T) { +func TestAccS3Object_content(t *testing.T) { var obj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -141,7 +141,7 @@ func TestAccS3BucketObject_content(t *testing.T) { }) } -func TestAccS3BucketObject_etagEncryption(t *testing.T) { +func TestAccS3Object_etagEncryption(t *testing.T) { var obj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -174,7 +174,7 @@ func TestAccS3BucketObject_etagEncryption(t *testing.T) { }) } -func TestAccS3BucketObject_contentBase64(t *testing.T) { +func TestAccS3Object_contentBase64(t *testing.T) { var obj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -197,7 +197,7 @@ func TestAccS3BucketObject_contentBase64(t *testing.T) { }) } -func TestAccS3BucketObject_sourceHashTrigger(t *testing.T) { +func TestAccS3Object_sourceHashTrigger(t *testing.T) { var obj, updated_obj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -253,7 +253,7 @@ func TestAccS3BucketObject_sourceHashTrigger(t *testing.T) { }) } -func TestAccS3BucketObject_withContentCharacteristics(t *testing.T) { +func TestAccS3Object_withContentCharacteristics(t *testing.T) { var obj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -280,7 +280,7 @@ func TestAccS3BucketObject_withContentCharacteristics(t *testing.T) { }) } -func TestAccS3BucketObject_nonVersioned(t *testing.T) { +func TestAccS3Object_nonVersioned(t *testing.T) { sourceInitial := testAccBucketObjectCreateTempFile(t, "initial object state") defer os.Remove(sourceInitial) rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -312,7 +312,7 @@ func TestAccS3BucketObject_nonVersioned(t *testing.T) { }) } -func TestAccS3BucketObject_updates(t *testing.T) { +func TestAccS3Object_updates(t *testing.T) { var originalObj, modifiedObj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -361,7 +361,7 @@ func TestAccS3BucketObject_updates(t *testing.T) { }) } -func TestAccS3BucketObject_updateSameFile(t *testing.T) { +func TestAccS3Object_updateSameFile(t *testing.T) { var originalObj, modifiedObj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -408,7 +408,7 @@ func TestAccS3BucketObject_updateSameFile(t *testing.T) { }) } -func TestAccS3BucketObject_updatesWithVersioning(t *testing.T) { +func TestAccS3Object_updatesWithVersioning(t *testing.T) { var originalObj, modifiedObj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -452,7 +452,7 @@ func TestAccS3BucketObject_updatesWithVersioning(t *testing.T) { }) } -func TestAccS3BucketObject_updatesWithVersioningViaAccessPoint(t *testing.T) { +func TestAccS3Object_updatesWithVersioningViaAccessPoint(t *testing.T) { var originalObj, modifiedObj s3.GetObjectOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_s3_object.test" @@ -491,7 +491,7 @@ func TestAccS3BucketObject_updatesWithVersioningViaAccessPoint(t *testing.T) { }) } -func TestAccS3BucketObject_kms(t *testing.T) { +func TestAccS3Object_kms(t *testing.T) { var obj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -525,7 +525,7 @@ func TestAccS3BucketObject_kms(t *testing.T) { }) } -func TestAccS3BucketObject_sse(t *testing.T) { +func TestAccS3Object_sse(t *testing.T) { var obj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -559,7 +559,7 @@ func TestAccS3BucketObject_sse(t *testing.T) { }) } -func TestAccS3BucketObject_acl(t *testing.T) { +func TestAccS3Object_acl(t *testing.T) { var obj1, obj2, obj3 s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -610,7 +610,7 @@ func TestAccS3BucketObject_acl(t *testing.T) { }) } -func TestAccS3BucketObject_metadata(t *testing.T) { +func TestAccS3Object_metadata(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) var obj s3.GetObjectOutput resourceName := "aws_s3_object.object" @@ -657,7 +657,7 @@ func TestAccS3BucketObject_metadata(t *testing.T) { }) } -func TestAccS3BucketObject_storageClass(t *testing.T) { +func TestAccS3Object_storageClass(t *testing.T) { var obj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -720,7 +720,7 @@ func TestAccS3BucketObject_storageClass(t *testing.T) { }) } -func TestAccS3BucketObject_tags(t *testing.T) { +func TestAccS3Object_tags(t *testing.T) { var obj1, obj2, obj3, obj4 s3.GetObjectOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_s3_object.object" @@ -792,7 +792,7 @@ func TestAccS3BucketObject_tags(t *testing.T) { }) } -func TestAccS3BucketObject_tagsLeadingSingleSlash(t *testing.T) { +func TestAccS3Object_tagsLeadingSingleSlash(t *testing.T) { var obj1, obj2, obj3, obj4 s3.GetObjectOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_s3_object.object" @@ -864,7 +864,7 @@ func TestAccS3BucketObject_tagsLeadingSingleSlash(t *testing.T) { }) } -func TestAccS3BucketObject_tagsLeadingMultipleSlashes(t *testing.T) { +func TestAccS3Object_tagsLeadingMultipleSlashes(t *testing.T) { var obj1, obj2, obj3, obj4 s3.GetObjectOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_s3_object.object" @@ -929,7 +929,7 @@ func TestAccS3BucketObject_tagsLeadingMultipleSlashes(t *testing.T) { }) } -func TestAccS3BucketObject_tagsMultipleSlashes(t *testing.T) { +func TestAccS3Object_tagsMultipleSlashes(t *testing.T) { var obj1, obj2, obj3, obj4 s3.GetObjectOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_s3_object.object" @@ -994,7 +994,7 @@ func TestAccS3BucketObject_tagsMultipleSlashes(t *testing.T) { }) } -func TestAccS3BucketObject_objectLockLegalHoldStartWithNone(t *testing.T) { +func TestAccS3Object_objectLockLegalHoldStartWithNone(t *testing.T) { var obj1, obj2, obj3 s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1042,7 +1042,7 @@ func TestAccS3BucketObject_objectLockLegalHoldStartWithNone(t *testing.T) { }) } -func TestAccS3BucketObject_objectLockLegalHoldStartWithOn(t *testing.T) { +func TestAccS3Object_objectLockLegalHoldStartWithOn(t *testing.T) { var obj1, obj2 s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1078,7 +1078,7 @@ func TestAccS3BucketObject_objectLockLegalHoldStartWithOn(t *testing.T) { }) } -func TestAccS3BucketObject_objectLockRetentionStartWithNone(t *testing.T) { +func TestAccS3Object_objectLockRetentionStartWithNone(t *testing.T) { var obj1, obj2, obj3 s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1127,7 +1127,7 @@ func TestAccS3BucketObject_objectLockRetentionStartWithNone(t *testing.T) { }) } -func TestAccS3BucketObject_objectLockRetentionStartWithSet(t *testing.T) { +func TestAccS3Object_objectLockRetentionStartWithSet(t *testing.T) { var obj1, obj2, obj3, obj4 s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1188,7 +1188,7 @@ func TestAccS3BucketObject_objectLockRetentionStartWithSet(t *testing.T) { }) } -func TestAccS3BucketObject_objectBucketKeyEnabled(t *testing.T) { +func TestAccS3Object_objectBucketKeyEnabled(t *testing.T) { var obj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1211,7 +1211,7 @@ func TestAccS3BucketObject_objectBucketKeyEnabled(t *testing.T) { }) } -func TestAccS3BucketObject_bucketBucketKeyEnabled(t *testing.T) { +func TestAccS3Object_bucketBucketKeyEnabled(t *testing.T) { var obj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1234,7 +1234,7 @@ func TestAccS3BucketObject_bucketBucketKeyEnabled(t *testing.T) { }) } -func TestAccS3BucketObject_defaultBucketSSE(t *testing.T) { +func TestAccS3Object_defaultBucketSSE(t *testing.T) { var obj1 s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1256,7 +1256,7 @@ func TestAccS3BucketObject_defaultBucketSSE(t *testing.T) { }) } -func TestAccS3BucketObject_ignoreTags(t *testing.T) { +func TestAccS3Object_ignoreTags(t *testing.T) { var obj s3.GetObjectOutput rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_s3_object.object" @@ -1405,7 +1405,7 @@ func testAccCheckBucketObjectExists(n string, obj *s3.GetObjectOutput) resource. } if err != nil { - return fmt.Errorf("S3Bucket Object error: %s", err) + return fmt.Errorf("S3 Object error: %s", err) } *obj = *out diff --git a/internal/service/s3/objects_data_source_test.go b/internal/service/s3/objects_data_source_test.go index 8c13beaa912..9d90aca9bd9 100644 --- a/internal/service/s3/objects_data_source_test.go +++ b/internal/service/s3/objects_data_source_test.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/acctest" ) -func TestAccS3BucketObjectsDataSource_basic(t *testing.T) { +func TestAccS3ObjectsDataSource_basic(t *testing.T) { rInt := sdkacctest.RandInt() resource.ParallelTest(t, resource.TestCase{ @@ -37,7 +37,7 @@ func TestAccS3BucketObjectsDataSource_basic(t *testing.T) { }) } -func TestAccS3BucketObjectsDataSource_basicViaAccessPoint(t *testing.T) { +func TestAccS3ObjectsDataSource_basicViaAccessPoint(t *testing.T) { rInt := sdkacctest.RandInt() resource.ParallelTest(t, resource.TestCase{ @@ -63,7 +63,7 @@ func TestAccS3BucketObjectsDataSource_basicViaAccessPoint(t *testing.T) { }) } -func TestAccS3BucketObjectsDataSource_all(t *testing.T) { +func TestAccS3ObjectsDataSource_all(t *testing.T) { rInt := sdkacctest.RandInt() resource.ParallelTest(t, resource.TestCase{ @@ -94,7 +94,7 @@ func TestAccS3BucketObjectsDataSource_all(t *testing.T) { }) } -func TestAccS3BucketObjectsDataSource_prefixes(t *testing.T) { +func TestAccS3ObjectsDataSource_prefixes(t *testing.T) { rInt := sdkacctest.RandInt() resource.ParallelTest(t, resource.TestCase{ @@ -124,7 +124,7 @@ func TestAccS3BucketObjectsDataSource_prefixes(t *testing.T) { }) } -func TestAccS3BucketObjectsDataSource_encoded(t *testing.T) { +func TestAccS3ObjectsDataSource_encoded(t *testing.T) { rInt := sdkacctest.RandInt() resource.ParallelTest(t, resource.TestCase{ @@ -150,7 +150,7 @@ func TestAccS3BucketObjectsDataSource_encoded(t *testing.T) { }) } -func TestAccS3BucketObjectsDataSource_maxKeys(t *testing.T) { +func TestAccS3ObjectsDataSource_maxKeys(t *testing.T) { rInt := sdkacctest.RandInt() resource.ParallelTest(t, resource.TestCase{ @@ -176,7 +176,7 @@ func TestAccS3BucketObjectsDataSource_maxKeys(t *testing.T) { }) } -func TestAccS3BucketObjectsDataSource_startAfter(t *testing.T) { +func TestAccS3ObjectsDataSource_startAfter(t *testing.T) { rInt := sdkacctest.RandInt() resource.ParallelTest(t, resource.TestCase{ @@ -201,7 +201,7 @@ func TestAccS3BucketObjectsDataSource_startAfter(t *testing.T) { }) } -func TestAccS3BucketObjectsDataSource_fetchOwner(t *testing.T) { +func TestAccS3ObjectsDataSource_fetchOwner(t *testing.T) { rInt := sdkacctest.RandInt() resource.ParallelTest(t, resource.TestCase{ From 1706bbb5829866a35631165e1d2372761a4d76e7 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 31 Jan 2022 12:36:58 -0500 Subject: [PATCH 106/116] Update functions, consts, etc --- internal/provider/provider.go | 2 +- .../service/apigateway/domain_name_test.go | 4 +- .../service/apigatewayv2/domain_name_test.go | 6 +- .../service/ec2/ebs_snapshot_import_test.go | 4 +- .../kinesisanalyticsv2/application_test.go | 98 +++++++++---------- internal/service/mwaa/environment_test.go | 6 +- internal/service/s3/bucket.go | 4 +- internal/service/s3/object.go | 44 ++++----- internal/service/s3/object_copy.go | 4 +- 9 files changed, 86 insertions(+), 86 deletions(-) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 871357a9d74..cfbbb7236d8 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -1593,12 +1593,12 @@ func Provider() *schema.Provider { "aws_s3_bucket_inventory": s3.ResourceBucketInventory(), "aws_s3_bucket_metric": s3.ResourceBucketMetric(), "aws_s3_bucket_notification": s3.ResourceBucketNotification(), - "aws_s3_object": s3.ResourceBucketObject(), "aws_s3_bucket_ownership_controls": s3.ResourceBucketOwnershipControls(), "aws_s3_bucket_policy": s3.ResourceBucketPolicy(), "aws_s3_bucket_public_access_block": s3.ResourceBucketPublicAccessBlock(), "aws_s3_bucket_replication_configuration": s3.ResourceBucketReplicationConfiguration(), "aws_s3_bucket_versioning": s3.ResourceBucketVersioning(), + "aws_s3_object": s3.ResourceObject(), "aws_s3_object_copy": s3.ResourceObjectCopy(), "aws_s3_access_point": s3control.ResourceAccessPoint(), diff --git a/internal/service/apigateway/domain_name_test.go b/internal/service/apigateway/domain_name_test.go index 56178ef56da..8534ded436e 100644 --- a/internal/service/apigateway/domain_name_test.go +++ b/internal/service/apigateway/domain_name_test.go @@ -305,7 +305,7 @@ func TestAccAPIGatewayDomainName_mutualTLSAuthentication(t *testing.T) { var v apigateway.DomainName resourceName := "aws_api_gateway_domain_name.test" acmCertificateResourceName := "aws_acm_certificate.test" - s3BucketObjectResourceName := "aws_s3_object.test" + s3ObjectResourceName := "aws_s3_object.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -322,7 +322,7 @@ func TestAccAPIGatewayDomainName_mutualTLSAuthentication(t *testing.T) { resource.TestCheckResourceAttrPair(resourceName, "domain_name", acmCertificateResourceName, "domain_name"), resource.TestCheckResourceAttr(resourceName, "mutual_tls_authentication.#", "1"), resource.TestCheckResourceAttr(resourceName, "mutual_tls_authentication.0.truststore_uri", fmt.Sprintf("s3://%s/%s", rName, rName)), - resource.TestCheckResourceAttrPair(resourceName, "mutual_tls_authentication.0.truststore_version", s3BucketObjectResourceName, "version_id"), + resource.TestCheckResourceAttrPair(resourceName, "mutual_tls_authentication.0.truststore_version", s3ObjectResourceName, "version_id"), ), }, { diff --git a/internal/service/apigatewayv2/domain_name_test.go b/internal/service/apigatewayv2/domain_name_test.go index 0e8024d2073..933bd93dcb1 100644 --- a/internal/service/apigatewayv2/domain_name_test.go +++ b/internal/service/apigatewayv2/domain_name_test.go @@ -221,7 +221,7 @@ func TestAccAPIGatewayV2DomainName_mutualTLSAuthentication(t *testing.T) { var v apigatewayv2.GetDomainNameOutput resourceName := "aws_apigatewayv2_domain_name.test" acmCertificateResourceName := "aws_acm_certificate.test" - s3BucketObjectResourceName := "aws_s3_object.test" + s3ObjectResourceName := "aws_s3_object.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -262,7 +262,7 @@ func TestAccAPIGatewayV2DomainName_mutualTLSAuthentication(t *testing.T) { resource.TestCheckResourceAttrSet(resourceName, "domain_name_configuration.0.target_domain_name"), resource.TestCheckResourceAttr(resourceName, "mutual_tls_authentication.#", "1"), resource.TestCheckResourceAttr(resourceName, "mutual_tls_authentication.0.truststore_uri", fmt.Sprintf("s3://%s/%s", rName, rName)), - resource.TestCheckResourceAttrPair(resourceName, "mutual_tls_authentication.0.truststore_version", s3BucketObjectResourceName, "version_id"), + resource.TestCheckResourceAttrPair(resourceName, "mutual_tls_authentication.0.truststore_version", s3ObjectResourceName, "version_id"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, @@ -280,7 +280,7 @@ func TestAccAPIGatewayV2DomainName_mutualTLSAuthentication(t *testing.T) { resource.TestCheckResourceAttrSet(resourceName, "domain_name_configuration.0.target_domain_name"), resource.TestCheckResourceAttr(resourceName, "mutual_tls_authentication.#", "1"), resource.TestCheckResourceAttr(resourceName, "mutual_tls_authentication.0.truststore_uri", fmt.Sprintf("s3://%s/%s", rName, rName)), - resource.TestCheckResourceAttrPair(resourceName, "mutual_tls_authentication.0.truststore_version", s3BucketObjectResourceName, "version_id"), + resource.TestCheckResourceAttrPair(resourceName, "mutual_tls_authentication.0.truststore_version", s3ObjectResourceName, "version_id"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, diff --git a/internal/service/ec2/ebs_snapshot_import_test.go b/internal/service/ec2/ebs_snapshot_import_test.go index cf35e234ae6..0ed1025e113 100644 --- a/internal/service/ec2/ebs_snapshot_import_test.go +++ b/internal/service/ec2/ebs_snapshot_import_test.go @@ -136,7 +136,7 @@ func TestAccEC2EBSSnapshotImport_disappears(t *testing.T) { }) } -func TestAccEC2EBSSnapshotImport_Disappears_s3BucketObject(t *testing.T) { +func TestAccEC2EBSSnapshotImport_Disappears_s3Object(t *testing.T) { var v ec2.Snapshot rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) parentResourceName := "aws_s3_object.image" @@ -155,7 +155,7 @@ func TestAccEC2EBSSnapshotImport_Disappears_s3BucketObject(t *testing.T) { acctest.MatchResourceAttrRegionalARNNoAccount(resourceName, "arn", "ec2", regexp.MustCompile(`snapshot/snap-.+`)), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), acctest.CheckResourceAttrAccountID(resourceName, "owner_id"), - acctest.CheckResourceDisappears(acctest.Provider, tfs3.ResourceBucketObject(), parentResourceName), + acctest.CheckResourceDisappears(acctest.Provider, tfs3.ResourceObject(), parentResourceName), ), ExpectNonEmptyPlan: true, }, diff --git a/internal/service/kinesisanalyticsv2/application_test.go b/internal/service/kinesisanalyticsv2/application_test.go index 4ba72b4f553..3dcbeae9eda 100644 --- a/internal/service/kinesisanalyticsv2/application_test.go +++ b/internal/service/kinesisanalyticsv2/application_test.go @@ -595,7 +595,7 @@ func TestAccKinesisAnalyticsV2Application_EnvironmentProperties_update(t *testin resourceName := "aws_kinesisanalyticsv2_application.test" iamRoleResourceName := "aws_iam_role.test.0" s3BucketResourceName := "aws_s3_bucket.test" - s3BucketObjectResourceName := "aws_s3_object.test.0" + s3ObjectResourceName := "aws_s3_object.test.0" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -613,7 +613,7 @@ func TestAccKinesisAnalyticsV2Application_EnvironmentProperties_update(t *testin resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), @@ -674,7 +674,7 @@ func TestAccKinesisAnalyticsV2Application_EnvironmentProperties_update(t *testin resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), @@ -743,7 +743,7 @@ func TestAccKinesisAnalyticsV2Application_EnvironmentProperties_update(t *testin resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), @@ -791,8 +791,8 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplication_update(t *testing.T) resourceName := "aws_kinesisanalyticsv2_application.test" iamRoleResourceName := "aws_iam_role.test.0" s3BucketResourceName := "aws_s3_bucket.test" - s3BucketObject1ResourceName := "aws_s3_object.test.0" - s3BucketObject2ResourceName := "aws_s3_object.test.1" + s3Object1ResourceName := "aws_s3_object.test.0" + s3Object2ResourceName := "aws_s3_object.test.1" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -810,8 +810,8 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplication_update(t *testing.T) resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObject1ResourceName, "key"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3BucketObject1ResourceName, "version_id"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3Object1ResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3Object1ResourceName, "version_id"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.0.snapshots_enabled", "false"), @@ -858,8 +858,8 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplication_update(t *testing.T) resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObject2ResourceName, "key"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3BucketObject2ResourceName, "version_id"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3Object2ResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3Object2ResourceName, "version_id"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.0.snapshots_enabled", "false"), @@ -912,8 +912,8 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplicationEnvironmentProperties_ iamRole1ResourceName := "aws_iam_role.test.0" iamRole2ResourceName := "aws_iam_role.test.1" s3BucketResourceName := "aws_s3_bucket.test" - s3BucketObject1ResourceName := "aws_s3_object.test.0" - s3BucketObject2ResourceName := "aws_s3_object.test.1" + s3Object1ResourceName := "aws_s3_object.test.0" + s3Object2ResourceName := "aws_s3_object.test.1" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -931,8 +931,8 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplicationEnvironmentProperties_ resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObject1ResourceName, "key"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3BucketObject1ResourceName, "version_id"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3Object1ResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3Object1ResourceName, "version_id"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.0.snapshots_enabled", "false"), @@ -993,8 +993,8 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplicationEnvironmentProperties_ resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObject2ResourceName, "key"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3BucketObject2ResourceName, "version_id"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3Object2ResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3Object2ResourceName, "version_id"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.0.snapshots_enabled", "true"), @@ -1064,7 +1064,7 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplication_restoreFromSnapshot(t resourceName := "aws_kinesisanalyticsv2_application.test" iamRoleResourceName := "aws_iam_role.test.0" s3BucketResourceName := "aws_s3_bucket.test" - s3BucketObjectResourceName := "aws_s3_object.test" + s3ObjectResourceName := "aws_s3_object.test" snapshotResourceName := "aws_kinesisanalyticsv2_application_snapshot.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -1083,7 +1083,7 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplication_restoreFromSnapshot(t resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.text_content", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), @@ -1147,7 +1147,7 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplication_restoreFromSnapshot(t resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.text_content", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), @@ -1212,7 +1212,7 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplication_restoreFromSnapshot(t resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.text_content", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), @@ -1276,7 +1276,7 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplication_restoreFromSnapshot(t resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.text_content", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), @@ -1335,7 +1335,7 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplicationStartApplication_onCre resourceName := "aws_kinesisanalyticsv2_application.test" iamRoleResourceName := "aws_iam_role.test.0" s3BucketResourceName := "aws_s3_bucket.test" - s3BucketObjectResourceName := "aws_s3_object.test.0" + s3ObjectResourceName := "aws_s3_object.test.0" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -1353,8 +1353,8 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplicationStartApplication_onCre resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3BucketObjectResourceName, "version_id"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3ObjectResourceName, "version_id"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.0.snapshots_enabled", "false"), @@ -1411,7 +1411,7 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplicationStartApplication_onUpd resourceName := "aws_kinesisanalyticsv2_application.test" iamRoleResourceName := "aws_iam_role.test.0" s3BucketResourceName := "aws_s3_bucket.test" - s3BucketObjectResourceName := "aws_s3_object.test.0" + s3ObjectResourceName := "aws_s3_object.test.0" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -1429,8 +1429,8 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplicationStartApplication_onUpd resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3BucketObjectResourceName, "version_id"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3ObjectResourceName, "version_id"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.0.snapshots_enabled", "false"), @@ -1483,8 +1483,8 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplicationStartApplication_onUpd resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3BucketObjectResourceName, "version_id"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3ObjectResourceName, "version_id"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.0.snapshots_enabled", "false"), @@ -1535,8 +1535,8 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplicationStartApplication_onUpd resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3BucketObjectResourceName, "version_id"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3ObjectResourceName, "version_id"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.0.snapshots_enabled", "false"), @@ -1583,8 +1583,8 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplication_updateRunning(t *test resourceName := "aws_kinesisanalyticsv2_application.test" iamRoleResourceName := "aws_iam_role.test.0" s3BucketResourceName := "aws_s3_bucket.test" - s3BucketObject1ResourceName := "aws_s3_object.test.0" - s3BucketObject2ResourceName := "aws_s3_object.test.1" + s3Object1ResourceName := "aws_s3_object.test.0" + s3Object2ResourceName := "aws_s3_object.test.1" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resource.ParallelTest(t, resource.TestCase{ @@ -1602,8 +1602,8 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplication_updateRunning(t *test resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObject1ResourceName, "key"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3BucketObject1ResourceName, "version_id"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3Object1ResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3Object1ResourceName, "version_id"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.0.snapshots_enabled", "false"), @@ -1660,8 +1660,8 @@ func TestAccKinesisAnalyticsV2Application_FlinkApplication_updateRunning(t *test resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObject2ResourceName, "key"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3BucketObject2ResourceName, "version_id"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3Object2ResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", s3Object2ResourceName, "version_id"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.0.snapshots_enabled", "false"), @@ -3592,7 +3592,7 @@ func TestAccKinesisAnalyticsV2Application_SQLApplicationVPC_add(t *testing.T) { resourceName := "aws_kinesisanalyticsv2_application.test" iamRoleResourceName := "aws_iam_role.test.0" s3BucketResourceName := "aws_s3_bucket.test" - s3BucketObjectResourceName := "aws_s3_object.test.0" + s3ObjectResourceName := "aws_s3_object.test.0" vpcResourceName := "aws_vpc.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -3611,7 +3611,7 @@ func TestAccKinesisAnalyticsV2Application_SQLApplicationVPC_add(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), @@ -3659,7 +3659,7 @@ func TestAccKinesisAnalyticsV2Application_SQLApplicationVPC_add(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), @@ -3716,7 +3716,7 @@ func TestAccKinesisAnalyticsV2Application_SQLApplicationVPC_delete(t *testing.T) resourceName := "aws_kinesisanalyticsv2_application.test" iamRoleResourceName := "aws_iam_role.test.0" s3BucketResourceName := "aws_s3_bucket.test" - s3BucketObjectResourceName := "aws_s3_object.test.0" + s3ObjectResourceName := "aws_s3_object.test.0" vpcResourceName := "aws_vpc.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -3735,7 +3735,7 @@ func TestAccKinesisAnalyticsV2Application_SQLApplicationVPC_delete(t *testing.T) resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), @@ -3787,7 +3787,7 @@ func TestAccKinesisAnalyticsV2Application_SQLApplicationVPC_delete(t *testing.T) resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), @@ -3840,7 +3840,7 @@ func TestAccKinesisAnalyticsV2Application_SQLApplicationVPC_update(t *testing.T) resourceName := "aws_kinesisanalyticsv2_application.test" iamRoleResourceName := "aws_iam_role.test.0" s3BucketResourceName := "aws_s3_bucket.test" - s3BucketObjectResourceName := "aws_s3_object.test.0" + s3ObjectResourceName := "aws_s3_object.test.0" vpcResourceName := "aws_vpc.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -3859,7 +3859,7 @@ func TestAccKinesisAnalyticsV2Application_SQLApplicationVPC_update(t *testing.T) resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), @@ -3911,7 +3911,7 @@ func TestAccKinesisAnalyticsV2Application_SQLApplicationVPC_update(t *testing.T) resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_snapshot_configuration.#", "1"), @@ -3968,7 +3968,7 @@ func TestAccKinesisAnalyticsV2Application_RunConfiguration_Update(t *testing.T) resourceName := "aws_kinesisanalyticsv2_application.test" iamRoleResourceName := "aws_iam_role.test.0" s3BucketResourceName := "aws_s3_bucket.test" - s3BucketObjectResourceName := "aws_s3_object.test" + s3ObjectResourceName := "aws_s3_object.test" snapshotResourceName := "aws_kinesisanalyticsv2_application_snapshot.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -3987,7 +3987,7 @@ func TestAccKinesisAnalyticsV2Application_RunConfiguration_Update(t *testing.T) resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.text_content", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), @@ -4050,7 +4050,7 @@ func TestAccKinesisAnalyticsV2Application_RunConfiguration_Update(t *testing.T) resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.#", "1"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.#", "1"), resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.bucket_arn", s3BucketResourceName, "arn"), - resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3BucketObjectResourceName, "key"), + resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.file_key", s3ObjectResourceName, "key"), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.s3_content_location.0.object_version", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content.0.text_content", ""), resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_code_configuration.0.code_content_type", "ZIPFILE"), diff --git a/internal/service/mwaa/environment_test.go b/internal/service/mwaa/environment_test.go index 798533f600c..84f6bdcea2a 100644 --- a/internal/service/mwaa/environment_test.go +++ b/internal/service/mwaa/environment_test.go @@ -311,7 +311,7 @@ func TestAccMWAAEnvironment_pluginsS3ObjectVersion(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mwaa_environment.test" - s3BucketObjectResourceName := "aws_s3_object.plugins" + s3ObjectResourceName := "aws_s3_object.plugins" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, @@ -323,7 +323,7 @@ func TestAccMWAAEnvironment_pluginsS3ObjectVersion(t *testing.T) { Config: testAccEnvironmentPluginsS3ObjectVersionConfig(rName, "test"), Check: resource.ComposeTestCheckFunc( testAccCheckEnvironmentExists(resourceName, &environment), - resource.TestCheckResourceAttrPair(resourceName, "plugins_s3_object_version", s3BucketObjectResourceName, "version_id"), + resource.TestCheckResourceAttrPair(resourceName, "plugins_s3_object_version", s3ObjectResourceName, "version_id"), ), }, { @@ -335,7 +335,7 @@ func TestAccMWAAEnvironment_pluginsS3ObjectVersion(t *testing.T) { Config: testAccEnvironmentPluginsS3ObjectVersionConfig(rName, "test-updated"), Check: resource.ComposeTestCheckFunc( testAccCheckEnvironmentExists(resourceName, &environment), - resource.TestCheckResourceAttrPair(resourceName, "plugins_s3_object_version", s3BucketObjectResourceName, "version_id"), + resource.TestCheckResourceAttrPair(resourceName, "plugins_s3_object_version", s3ObjectResourceName, "version_id"), ), }, { diff --git a/internal/service/s3/bucket.go b/internal/service/s3/bucket.go index 22fe3f8119c..d67168104f9 100644 --- a/internal/service/s3/bucket.go +++ b/internal/service/s3/bucket.go @@ -842,7 +842,7 @@ func resourceBucketUpdate(d *schema.ResourceData, meta interface{}) error { } if d.HasChange("object_lock_configuration") { - if err := resourceBucketObjectLockConfigurationUpdate(conn, d); err != nil { + if err := resourceObjectLockConfigurationUpdate(conn, d); err != nil { return err } } @@ -2014,7 +2014,7 @@ func resourceBucketServerSideEncryptionConfigurationUpdate(conn *s3.S3, d *schem return nil } -func resourceBucketObjectLockConfigurationUpdate(conn *s3.S3, d *schema.ResourceData) error { +func resourceObjectLockConfigurationUpdate(conn *s3.S3, d *schema.ResourceData) error { // S3 Object Lock configuration cannot be deleted, only updated. req := &s3.PutObjectLockConfigurationInput{ Bucket: aws.String(d.Get("bucket").(string)), diff --git a/internal/service/s3/object.go b/internal/service/s3/object.go index 741c6acbcdb..65c9ba7df2d 100644 --- a/internal/service/s3/object.go +++ b/internal/service/s3/object.go @@ -30,21 +30,21 @@ import ( "github.com/mitchellh/go-homedir" ) -const s3BucketObjectCreationTimeout = 2 * time.Minute +const s3ObjectCreationTimeout = 2 * time.Minute -func ResourceBucketObject() *schema.Resource { +func ResourceObject() *schema.Resource { return &schema.Resource{ - Create: resourceBucketObjectCreate, - Read: resourceBucketObjectRead, - Update: resourceBucketObjectUpdate, - Delete: resourceBucketObjectDelete, + Create: resourceObjectCreate, + Read: resourceObjectRead, + Update: resourceObjectUpdate, + Delete: resourceObjectDelete, Importer: &schema.ResourceImporter{ - State: resourceBucketObjectImport, + State: resourceObjectImport, }, CustomizeDiff: customdiff.Sequence( - resourceBucketObjectCustomizeDiff, + resourceObjectCustomizeDiff, verify.SetTagsDiff, ), @@ -186,11 +186,11 @@ func ResourceBucketObject() *schema.Resource { } } -func resourceBucketObjectCreate(d *schema.ResourceData, meta interface{}) error { - return resourceBucketObjectUpload(d, meta) +func resourceObjectCreate(d *schema.ResourceData, meta interface{}) error { + return resourceObjectUpload(d, meta) } -func resourceBucketObjectRead(d *schema.ResourceData, meta interface{}) error { +func resourceObjectRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).S3Conn defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig @@ -205,7 +205,7 @@ func resourceBucketObjectRead(d *schema.ResourceData, meta interface{}) error { var resp *s3.HeadObjectOutput - err := resource.Retry(s3BucketObjectCreationTimeout, func() *resource.RetryError { + err := resource.Retry(s3ObjectCreationTimeout, func() *resource.RetryError { var err error resp, err = conn.HeadObject(input) @@ -261,7 +261,7 @@ func resourceBucketObjectRead(d *schema.ResourceData, meta interface{}) error { d.Set("object_lock_mode", resp.ObjectLockMode) d.Set("object_lock_retain_until_date", flattenS3ObjectDate(resp.ObjectLockRetainUntilDate)) - if err := resourceBucketObjectSetKMS(d, meta, resp.SSEKMSKeyId); err != nil { + if err := resourceObjectSetKMS(d, meta, resp.SSEKMSKeyId); err != nil { return fmt.Errorf("bucket object KMS: %w", err) } @@ -304,9 +304,9 @@ func resourceBucketObjectRead(d *schema.ResourceData, meta interface{}) error { return nil } -func resourceBucketObjectUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceObjectUpdate(d *schema.ResourceData, meta interface{}) error { if hasS3ObjectContentChanges(d) { - return resourceBucketObjectUpload(d, meta) + return resourceObjectUpload(d, meta) } conn := meta.(*conns.AWSClient).S3Conn @@ -372,10 +372,10 @@ func resourceBucketObjectUpdate(d *schema.ResourceData, meta interface{}) error } } - return resourceBucketObjectRead(d, meta) + return resourceObjectRead(d, meta) } -func resourceBucketObjectDelete(d *schema.ResourceData, meta interface{}) error { +func resourceObjectDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).S3Conn bucket := d.Get("bucket").(string) @@ -399,7 +399,7 @@ func resourceBucketObjectDelete(d *schema.ResourceData, meta interface{}) error return nil } -func resourceBucketObjectImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { +func resourceObjectImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { id := d.Id() id = strings.TrimPrefix(id, "s3://") parts := strings.Split(id, "/") @@ -418,7 +418,7 @@ func resourceBucketObjectImport(d *schema.ResourceData, meta interface{}) ([]*sc return []*schema.ResourceData{d}, nil } -func resourceBucketObjectUpload(d *schema.ResourceData, meta interface{}) error { +func resourceObjectUpload(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).S3Conn uploader := s3manager.NewUploaderWithClient(conn) defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig @@ -538,10 +538,10 @@ func resourceBucketObjectUpload(d *schema.ResourceData, meta interface{}) error d.SetId(key) - return resourceBucketObjectRead(d, meta) + return resourceObjectRead(d, meta) } -func resourceBucketObjectSetKMS(d *schema.ResourceData, meta interface{}, sseKMSKeyId *string) error { +func resourceObjectSetKMS(d *schema.ResourceData, meta interface{}, sseKMSKeyId *string) error { // Only set non-default KMS key ID (one that doesn't match default) if sseKMSKeyId != nil { // retrieve S3 KMS Default Master Key @@ -572,7 +572,7 @@ func validateMetadataIsLowerCase(v interface{}, k string) (ws []string, errors [ return } -func resourceBucketObjectCustomizeDiff(_ context.Context, d *schema.ResourceDiff, meta interface{}) error { +func resourceObjectCustomizeDiff(_ context.Context, d *schema.ResourceDiff, meta interface{}) error { if hasS3ObjectContentChanges(d) { return d.SetNewComputed("version_id") } diff --git a/internal/service/s3/object_copy.go b/internal/service/s3/object_copy.go index 829c1d14ee9..df3a256345a 100644 --- a/internal/service/s3/object_copy.go +++ b/internal/service/s3/object_copy.go @@ -349,7 +349,7 @@ func resourceObjectCopyRead(d *schema.ResourceData, meta interface{}) error { d.Set("object_lock_mode", resp.ObjectLockMode) d.Set("object_lock_retain_until_date", flattenS3ObjectDate(resp.ObjectLockRetainUntilDate)) - if err := resourceBucketObjectSetKMS(d, meta, resp.SSEKMSKeyId); err != nil { + if err := resourceObjectSetKMS(d, meta, resp.SSEKMSKeyId); err != nil { return fmt.Errorf("bucket object KMS: %w", err) } @@ -647,7 +647,7 @@ func resourceObjectCopyDoCopy(d *schema.ResourceData, meta interface{}) error { d.Set("version_id", output.VersionId) d.SetId(d.Get("key").(string)) - return resourceBucketObjectRead(d, meta) + return resourceObjectRead(d, meta) } type s3Grants struct { From a41b9240c33364633f020645c198d188f8cecb49 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 31 Jan 2022 12:38:10 -0500 Subject: [PATCH 107/116] Update data sources --- internal/provider/provider.go | 4 ++-- internal/service/s3/object_data_source.go | 6 +++--- internal/service/s3/objects_data_source.go | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index cfbbb7236d8..90d0a9c1d82 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -685,8 +685,8 @@ func Provider() *schema.Provider { "aws_canonical_user_id": s3.DataSourceCanonicalUserID(), "aws_s3_bucket": s3.DataSourceBucket(), - "aws_s3_object": s3.DataSourceBucketObject(), - "aws_s3_objects": s3.DataSourceBucketObjects(), + "aws_s3_object": s3.DataSourceObject(), + "aws_s3_objects": s3.DataSourceObjects(), "aws_sagemaker_prebuilt_ecr_image": sagemaker.DataSourcePrebuiltECRImage(), diff --git a/internal/service/s3/object_data_source.go b/internal/service/s3/object_data_source.go index 68d424b2c98..767aca9a499 100644 --- a/internal/service/s3/object_data_source.go +++ b/internal/service/s3/object_data_source.go @@ -16,9 +16,9 @@ import ( tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" ) -func DataSourceBucketObject() *schema.Resource { +func DataSourceObject() *schema.Resource { return &schema.Resource{ - Read: dataSourceBucketObjectRead, + Read: dataSourceObjectRead, Schema: map[string]*schema.Schema{ "body": { @@ -125,7 +125,7 @@ func DataSourceBucketObject() *schema.Resource { } } -func dataSourceBucketObjectRead(d *schema.ResourceData, meta interface{}) error { +func dataSourceObjectRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).S3Conn ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig diff --git a/internal/service/s3/objects_data_source.go b/internal/service/s3/objects_data_source.go index 9c9fc2d856d..5c6503829c2 100644 --- a/internal/service/s3/objects_data_source.go +++ b/internal/service/s3/objects_data_source.go @@ -11,9 +11,9 @@ import ( const keyRequestPageSize = 1000 -func DataSourceBucketObjects() *schema.Resource { +func DataSourceObjects() *schema.Resource { return &schema.Resource{ - Read: dataSourceBucketObjectsRead, + Read: dataSourceObjectsRead, Schema: map[string]*schema.Schema{ "bucket": { @@ -64,7 +64,7 @@ func DataSourceBucketObjects() *schema.Resource { } } -func dataSourceBucketObjectsRead(d *schema.ResourceData, meta interface{}) error { +func dataSourceObjectsRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*conns.AWSClient).S3Conn bucket := d.Get("bucket").(string) From 5e95780fbab871edbbff294dcef60a047c2bb98c Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 31 Jan 2022 12:39:48 -0500 Subject: [PATCH 108/116] Update function names --- internal/service/s3/bucket_test.go | 8 +- .../service/s3/object_data_source_test.go | 24 +- internal/service/s3/object_test.go | 598 +++++++++--------- internal/service/s3/sweep.go | 4 +- 4 files changed, 317 insertions(+), 317 deletions(-) diff --git a/internal/service/s3/bucket_test.go b/internal/service/s3/bucket_test.go index 0ca48e2f65e..a80e3f076e1 100644 --- a/internal/service/s3/bucket_test.go +++ b/internal/service/s3/bucket_test.go @@ -2528,7 +2528,7 @@ func TestAccS3Bucket_Manage_objectLock(t *testing.T) { CheckDestroy: testAccCheckBucketDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectLockEnabledNoDefaultRetention(bucketName), + Config: testAccObjectLockEnabledNoDefaultRetention(bucketName), Check: resource.ComposeTestCheckFunc( testAccCheckBucketExists(resourceName), resource.TestCheckResourceAttr(resourceName, "object_lock_configuration.#", "1"), @@ -2543,7 +2543,7 @@ func TestAccS3Bucket_Manage_objectLock(t *testing.T) { ImportStateVerifyIgnore: []string{"force_destroy", "acl"}, }, { - Config: testAccBucketObjectLockEnabledWithDefaultRetention(bucketName), + Config: testAccObjectLockEnabledWithDefaultRetention(bucketName), Check: resource.ComposeTestCheckFunc( testAccCheckBucketExists(resourceName), resource.TestCheckResourceAttr(resourceName, "object_lock_configuration.#", "1"), @@ -5042,7 +5042,7 @@ resource "aws_s3_bucket" "bucket" { `, randInt) } -func testAccBucketObjectLockEnabledNoDefaultRetention(bucketName string) string { +func testAccObjectLockEnabledNoDefaultRetention(bucketName string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "arbitrary" { bucket = %[1]q @@ -5054,7 +5054,7 @@ resource "aws_s3_bucket" "arbitrary" { `, bucketName) } -func testAccBucketObjectLockEnabledWithDefaultRetention(bucketName string) string { +func testAccObjectLockEnabledWithDefaultRetention(bucketName string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "arbitrary" { bucket = %[1]q diff --git a/internal/service/s3/object_data_source_test.go b/internal/service/s3/object_data_source_test.go index 3570a81a72e..821a21d273a 100644 --- a/internal/service/s3/object_data_source_test.go +++ b/internal/service/s3/object_data_source_test.go @@ -35,7 +35,7 @@ func TestAccS3ObjectDataSource_basic(t *testing.T) { { Config: testAccObjectDataSourceConfig_basic(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &rObj), + testAccCheckObjectExists(resourceName, &rObj), testAccCheckObjectExistsDataSource(dataSourceName, &dsObj), resource.TestCheckResourceAttr(dataSourceName, "content_length", "11"), resource.TestCheckResourceAttrPair(dataSourceName, "content_type", resourceName, "content_type"), @@ -67,9 +67,9 @@ func TestAccS3ObjectDataSource_basicViaAccessPoint(t *testing.T) { { Config: testAccObjectDataSourceConfig_basicViaAccessPoint(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &rObj), + testAccCheckObjectExists(resourceName, &rObj), testAccCheckObjectExistsDataSource(dataSourceName, &dsObj), - testAccCheckBucketObjectExists(resourceName, &rObj), + testAccCheckObjectExists(resourceName, &rObj), resource.TestCheckResourceAttrPair(dataSourceName, "bucket", accessPointResourceName, "arn"), resource.TestCheckResourceAttrPair(dataSourceName, "key", resourceName, "key"), ), @@ -96,7 +96,7 @@ func TestAccS3ObjectDataSource_readableBody(t *testing.T) { { Config: testAccObjectDataSourceConfig_readableBody(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &rObj), + testAccCheckObjectExists(resourceName, &rObj), testAccCheckObjectExistsDataSource(dataSourceName, &dsObj), resource.TestCheckResourceAttr(dataSourceName, "content_length", "3"), resource.TestCheckResourceAttrPair(dataSourceName, "content_type", resourceName, "content_type"), @@ -130,7 +130,7 @@ func TestAccS3ObjectDataSource_kmsEncrypted(t *testing.T) { { Config: testAccObjectDataSourceConfig_kmsEncrypted(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &rObj), + testAccCheckObjectExists(resourceName, &rObj), testAccCheckObjectExistsDataSource(dataSourceName, &dsObj), resource.TestCheckResourceAttr(dataSourceName, "content_length", "22"), resource.TestCheckResourceAttrPair(dataSourceName, "content_type", resourceName, "content_type"), @@ -166,7 +166,7 @@ func TestAccS3ObjectDataSource_bucketKeyEnabled(t *testing.T) { { Config: testAccObjectDataSourceConfig_bucketKeyEnabled(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &rObj), + testAccCheckObjectExists(resourceName, &rObj), testAccCheckObjectExistsDataSource(dataSourceName, &dsObj), resource.TestCheckResourceAttr(dataSourceName, "content_length", "22"), resource.TestCheckResourceAttrPair(dataSourceName, "content_type", resourceName, "content_type"), @@ -203,7 +203,7 @@ func TestAccS3ObjectDataSource_allParams(t *testing.T) { { Config: testAccObjectDataSourceConfig_allParams(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &rObj), + testAccCheckObjectExists(resourceName, &rObj), testAccCheckObjectExistsDataSource(dataSourceName, &dsObj), resource.TestCheckResourceAttr(dataSourceName, "content_length", "25"), resource.TestCheckResourceAttrPair(dataSourceName, "content_type", resourceName, "content_type"), @@ -254,7 +254,7 @@ func TestAccS3ObjectDataSource_objectLockLegalHoldOff(t *testing.T) { { Config: testAccObjectDataSourceConfig_objectLockLegalHoldOff(rInt), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &rObj), + testAccCheckObjectExists(resourceName, &rObj), testAccCheckObjectExistsDataSource(dataSourceName, &dsObj), resource.TestCheckResourceAttr(dataSourceName, "content_length", "11"), resource.TestCheckResourceAttrPair(dataSourceName, "content_type", resourceName, "content_type"), @@ -289,7 +289,7 @@ func TestAccS3ObjectDataSource_objectLockLegalHoldOn(t *testing.T) { { Config: testAccObjectDataSourceConfig_objectLockLegalHoldOn(rInt, retainUntilDate), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &rObj), + testAccCheckObjectExists(resourceName, &rObj), testAccCheckObjectExistsDataSource(dataSourceName, &dsObj), resource.TestCheckResourceAttr(dataSourceName, "content_length", "11"), resource.TestCheckResourceAttrPair(dataSourceName, "content_type", resourceName, "content_type"), @@ -326,7 +326,7 @@ func TestAccS3ObjectDataSource_leadingSlash(t *testing.T) { { Config: resourceOnlyConf, Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &rObj), + testAccCheckObjectExists(resourceName, &rObj), ), }, { @@ -380,8 +380,8 @@ func TestAccS3ObjectDataSource_multipleSlashes(t *testing.T) { { Config: resourceOnlyConf, Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName1, &rObj1), - testAccCheckBucketObjectExists(resourceName2, &rObj2), + testAccCheckObjectExists(resourceName1, &rObj1), + testAccCheckObjectExists(resourceName2, &rObj2), ), }, { diff --git a/internal/service/s3/object_test.go b/internal/service/s3/object_test.go index 69f53a90354..b00ba882372 100644 --- a/internal/service/s3/object_test.go +++ b/internal/service/s3/object_test.go @@ -33,16 +33,16 @@ func TestAccS3Object_noNameNoKey(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { PreConfig: func() {}, - Config: testAccBucketObjectBasicConfig("", "a key"), + Config: testAccObjectBasicConfig("", "a key"), ExpectError: bucketError, }, { PreConfig: func() {}, - Config: testAccBucketObjectBasicConfig("a name", ""), + Config: testAccObjectBasicConfig("a name", ""), ExpectError: keyError, }, }, @@ -58,14 +58,14 @@ func TestAccS3Object_empty(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { PreConfig: func() {}, - Config: testAccBucketObjectEmptyConfig(rName), + Config: testAccObjectEmptyConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), - testAccCheckBucketObjectBody(&obj, ""), + testAccCheckObjectExists(resourceName, &obj), + testAccCheckObjectBody(&obj, ""), ), }, { @@ -84,20 +84,20 @@ func TestAccS3Object_source(t *testing.T) { resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - source := testAccBucketObjectCreateTempFile(t, "{anything will do }") + source := testAccObjectCreateTempFile(t, "{anything will do }") defer os.Remove(source) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectSourceConfig(rName, source), + Config: testAccObjectSourceConfig(rName, source), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), - testAccCheckBucketObjectBody(&obj, "{anything will do }"), + testAccCheckObjectExists(resourceName, &obj), + testAccCheckObjectBody(&obj, "{anything will do }"), ), }, { @@ -120,14 +120,14 @@ func TestAccS3Object_content(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { PreConfig: func() {}, - Config: testAccBucketObjectContentConfig(rName, "some_bucket_content"), + Config: testAccObjectContentConfig(rName, "some_bucket_content"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), - testAccCheckBucketObjectBody(&obj, "some_bucket_content"), + testAccCheckObjectExists(resourceName, &obj), + testAccCheckObjectBody(&obj, "some_bucket_content"), ), }, { @@ -145,21 +145,21 @@ func TestAccS3Object_etagEncryption(t *testing.T) { var obj s3.GetObjectOutput resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - source := testAccBucketObjectCreateTempFile(t, "{anything will do }") + source := testAccObjectCreateTempFile(t, "{anything will do }") defer os.Remove(source) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { PreConfig: func() {}, - Config: testAccBucketObjectEtagEncryption(rName, source), + Config: testAccObjectEtagEncryption(rName, source), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), - testAccCheckBucketObjectBody(&obj, "{anything will do }"), + testAccCheckObjectExists(resourceName, &obj), + testAccCheckObjectBody(&obj, "{anything will do }"), resource.TestCheckResourceAttr(resourceName, "etag", "7b006ff4d70f68cc65061acf2f802e6f"), ), }, @@ -183,14 +183,14 @@ func TestAccS3Object_contentBase64(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { PreConfig: func() {}, - Config: testAccBucketObjectContentBase64Config(rName, base64.StdEncoding.EncodeToString([]byte("some_bucket_content"))), + Config: testAccObjectContentBase64Config(rName, base64.StdEncoding.EncodeToString([]byte("some_bucket_content"))), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), - testAccCheckBucketObjectBody(&obj, "some_bucket_content"), + testAccCheckObjectExists(resourceName, &obj), + testAccCheckObjectBody(&obj, "some_bucket_content"), ), }, }, @@ -205,7 +205,7 @@ func TestAccS3Object_sourceHashTrigger(t *testing.T) { startingData := "Ebben!" changingData := "Ne andrò lontana" - filename := testAccBucketObjectCreateTempFile(t, startingData) + filename := testAccObjectCreateTempFile(t, startingData) defer os.Remove(filename) rewriteFile := func(*terraform.State) error { @@ -220,14 +220,14 @@ func TestAccS3Object_sourceHashTrigger(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { PreConfig: func() {}, - Config: testAccBucketObjectConfig_sourceHashTrigger(rName, filename), + Config: testAccObjectConfig_sourceHashTrigger(rName, filename), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), - testAccCheckBucketObjectBody(&obj, "Ebben!"), + testAccCheckObjectExists(resourceName, &obj), + testAccCheckObjectBody(&obj, "Ebben!"), resource.TestCheckResourceAttr(resourceName, "source_hash", "7c7e02a79f28968882bb1426c8f8bfc6"), rewriteFile, ), @@ -235,10 +235,10 @@ func TestAccS3Object_sourceHashTrigger(t *testing.T) { }, { PreConfig: func() {}, - Config: testAccBucketObjectConfig_sourceHashTrigger(rName, filename), + Config: testAccObjectConfig_sourceHashTrigger(rName, filename), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &updated_obj), - testAccCheckBucketObjectBody(&updated_obj, "Ne andrò lontana"), + testAccCheckObjectExists(resourceName, &updated_obj), + testAccCheckObjectBody(&updated_obj, "Ne andrò lontana"), resource.TestCheckResourceAttr(resourceName, "source_hash", "cffc5e20de2d21764145b1124c9b337b"), ), }, @@ -258,20 +258,20 @@ func TestAccS3Object_withContentCharacteristics(t *testing.T) { resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - source := testAccBucketObjectCreateTempFile(t, "{anything will do }") + source := testAccObjectCreateTempFile(t, "{anything will do }") defer os.Remove(source) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectConfig_withContentCharacteristics(rName, source), + Config: testAccObjectConfig_withContentCharacteristics(rName, source), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), - testAccCheckBucketObjectBody(&obj, "{anything will do }"), + testAccCheckObjectExists(resourceName, &obj), + testAccCheckObjectBody(&obj, "{anything will do }"), resource.TestCheckResourceAttr(resourceName, "content_type", "binary/octet-stream"), resource.TestCheckResourceAttr(resourceName, "website_redirect", "http://google.com"), ), @@ -281,7 +281,7 @@ func TestAccS3Object_withContentCharacteristics(t *testing.T) { } func TestAccS3Object_nonVersioned(t *testing.T) { - sourceInitial := testAccBucketObjectCreateTempFile(t, "initial object state") + sourceInitial := testAccObjectCreateTempFile(t, "initial object state") defer os.Remove(sourceInitial) rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) var originalObj s3.GetObjectOutput @@ -291,13 +291,13 @@ func TestAccS3Object_nonVersioned(t *testing.T) { PreCheck: func() { acctest.PreCheck(t); acctest.PreCheckAssumeRoleARN(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectConfig_nonVersioned(rName, sourceInitial), + Config: testAccObjectConfig_nonVersioned(rName, sourceInitial), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &originalObj), - testAccCheckBucketObjectBody(&originalObj, "initial object state"), + testAccCheckObjectExists(resourceName, &originalObj), + testAccCheckObjectBody(&originalObj, "initial object state"), resource.TestCheckResourceAttr(resourceName, "version_id", ""), ), }, @@ -317,22 +317,22 @@ func TestAccS3Object_updates(t *testing.T) { resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - sourceInitial := testAccBucketObjectCreateTempFile(t, "initial object state") + sourceInitial := testAccObjectCreateTempFile(t, "initial object state") defer os.Remove(sourceInitial) - sourceModified := testAccBucketObjectCreateTempFile(t, "modified object") + sourceModified := testAccObjectCreateTempFile(t, "modified object") defer os.Remove(sourceInitial) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectConfig_updateable(rName, false, sourceInitial), + Config: testAccObjectConfig_updateable(rName, false, sourceInitial), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &originalObj), - testAccCheckBucketObjectBody(&originalObj, "initial object state"), + testAccCheckObjectExists(resourceName, &originalObj), + testAccCheckObjectBody(&originalObj, "initial object state"), resource.TestCheckResourceAttr(resourceName, "etag", "647d1d58e1011c743ec67d5e8af87b53"), resource.TestCheckResourceAttr(resourceName, "object_lock_legal_hold_status", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_mode", ""), @@ -340,10 +340,10 @@ func TestAccS3Object_updates(t *testing.T) { ), }, { - Config: testAccBucketObjectConfig_updateable(rName, false, sourceModified), + Config: testAccObjectConfig_updateable(rName, false, sourceModified), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &modifiedObj), - testAccCheckBucketObjectBody(&modifiedObj, "modified object"), + testAccCheckObjectExists(resourceName, &modifiedObj), + testAccCheckObjectBody(&modifiedObj, "modified object"), resource.TestCheckResourceAttr(resourceName, "etag", "1c7fd13df1515c2a13ad9eb068931f09"), resource.TestCheckResourceAttr(resourceName, "object_lock_legal_hold_status", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_mode", ""), @@ -369,7 +369,7 @@ func TestAccS3Object_updateSameFile(t *testing.T) { startingData := "lane 8" changingData := "chicane" - filename := testAccBucketObjectCreateTempFile(t, startingData) + filename := testAccObjectCreateTempFile(t, startingData) defer os.Remove(filename) rewriteFile := func(*terraform.State) error { @@ -384,23 +384,23 @@ func TestAccS3Object_updateSameFile(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectConfig_updateable(rName, false, filename), + Config: testAccObjectConfig_updateable(rName, false, filename), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &originalObj), - testAccCheckBucketObjectBody(&originalObj, startingData), + testAccCheckObjectExists(resourceName, &originalObj), + testAccCheckObjectBody(&originalObj, startingData), resource.TestCheckResourceAttr(resourceName, "etag", "aa48b42f36a2652cbee40c30a5df7d25"), rewriteFile, ), ExpectNonEmptyPlan: true, }, { - Config: testAccBucketObjectConfig_updateable(rName, false, filename), + Config: testAccObjectConfig_updateable(rName, false, filename), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &modifiedObj), - testAccCheckBucketObjectBody(&modifiedObj, changingData), + testAccCheckObjectExists(resourceName, &modifiedObj), + testAccCheckObjectBody(&modifiedObj, changingData), resource.TestCheckResourceAttr(resourceName, "etag", "fafc05f8c4da0266a99154681ab86e8c"), ), }, @@ -413,32 +413,32 @@ func TestAccS3Object_updatesWithVersioning(t *testing.T) { resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - sourceInitial := testAccBucketObjectCreateTempFile(t, "initial versioned object state") + sourceInitial := testAccObjectCreateTempFile(t, "initial versioned object state") defer os.Remove(sourceInitial) - sourceModified := testAccBucketObjectCreateTempFile(t, "modified versioned object") + sourceModified := testAccObjectCreateTempFile(t, "modified versioned object") defer os.Remove(sourceInitial) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectConfig_updateable(rName, true, sourceInitial), + Config: testAccObjectConfig_updateable(rName, true, sourceInitial), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &originalObj), - testAccCheckBucketObjectBody(&originalObj, "initial versioned object state"), + testAccCheckObjectExists(resourceName, &originalObj), + testAccCheckObjectBody(&originalObj, "initial versioned object state"), resource.TestCheckResourceAttr(resourceName, "etag", "cee4407fa91906284e2a5e5e03e86b1b"), ), }, { - Config: testAccBucketObjectConfig_updateable(rName, true, sourceModified), + Config: testAccObjectConfig_updateable(rName, true, sourceModified), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &modifiedObj), - testAccCheckBucketObjectBody(&modifiedObj, "modified versioned object"), + testAccCheckObjectExists(resourceName, &modifiedObj), + testAccCheckObjectBody(&modifiedObj, "modified versioned object"), resource.TestCheckResourceAttr(resourceName, "etag", "00b8c73b1b50e7cc932362c7225b8e29"), - testAccCheckBucketObjectVersionIdDiffers(&modifiedObj, &originalObj), + testAccCheckObjectVersionIdDiffers(&modifiedObj, &originalObj), ), }, { @@ -458,33 +458,33 @@ func TestAccS3Object_updatesWithVersioningViaAccessPoint(t *testing.T) { resourceName := "aws_s3_object.test" accessPointResourceName := "aws_s3_access_point.test" - sourceInitial := testAccBucketObjectCreateTempFile(t, "initial versioned object state") + sourceInitial := testAccObjectCreateTempFile(t, "initial versioned object state") defer os.Remove(sourceInitial) - sourceModified := testAccBucketObjectCreateTempFile(t, "modified versioned object") + sourceModified := testAccObjectCreateTempFile(t, "modified versioned object") defer os.Remove(sourceInitial) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectConfig_updateableViaAccessPoint(rName, true, sourceInitial), + Config: testAccObjectConfig_updateableViaAccessPoint(rName, true, sourceInitial), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &originalObj), - testAccCheckBucketObjectBody(&originalObj, "initial versioned object state"), + testAccCheckObjectExists(resourceName, &originalObj), + testAccCheckObjectBody(&originalObj, "initial versioned object state"), resource.TestCheckResourceAttrPair(resourceName, "bucket", accessPointResourceName, "arn"), resource.TestCheckResourceAttr(resourceName, "etag", "cee4407fa91906284e2a5e5e03e86b1b"), ), }, { - Config: testAccBucketObjectConfig_updateableViaAccessPoint(rName, true, sourceModified), + Config: testAccObjectConfig_updateableViaAccessPoint(rName, true, sourceModified), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &modifiedObj), - testAccCheckBucketObjectBody(&modifiedObj, "modified versioned object"), + testAccCheckObjectExists(resourceName, &modifiedObj), + testAccCheckObjectBody(&modifiedObj, "modified versioned object"), resource.TestCheckResourceAttr(resourceName, "etag", "00b8c73b1b50e7cc932362c7225b8e29"), - testAccCheckBucketObjectVersionIdDiffers(&modifiedObj, &originalObj), + testAccCheckObjectVersionIdDiffers(&modifiedObj, &originalObj), ), }, }, @@ -496,22 +496,22 @@ func TestAccS3Object_kms(t *testing.T) { resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - source := testAccBucketObjectCreateTempFile(t, "{anything will do }") + source := testAccObjectCreateTempFile(t, "{anything will do }") defer os.Remove(source) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withKMSID(rName, source), + Config: testAccObjectConfig_withKMSID(rName, source), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), - testAccCheckBucketObjectSSE(resourceName, "aws:kms"), - testAccCheckBucketObjectBody(&obj, "{anything will do }"), + testAccCheckObjectExists(resourceName, &obj), + testAccCheckObjectSSE(resourceName, "aws:kms"), + testAccCheckObjectBody(&obj, "{anything will do }"), ), }, { @@ -530,22 +530,22 @@ func TestAccS3Object_sse(t *testing.T) { resourceName := "aws_s3_object.object" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - source := testAccBucketObjectCreateTempFile(t, "{anything will do }") + source := testAccObjectCreateTempFile(t, "{anything will do }") defer os.Remove(source) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withSSE(rName, source), + Config: testAccObjectConfig_withSSE(rName, source), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), - testAccCheckBucketObjectSSE(resourceName, "AES256"), - testAccCheckBucketObjectBody(&obj, "{anything will do }"), + testAccCheckObjectExists(resourceName, &obj), + testAccCheckObjectSSE(resourceName, "AES256"), + testAccCheckObjectBody(&obj, "{anything will do }"), ), }, { @@ -568,35 +568,35 @@ func TestAccS3Object_acl(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectConfig_acl(rName, "some_bucket_content", "private"), + Config: testAccObjectConfig_acl(rName, "some_bucket_content", "private"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj1), - testAccCheckBucketObjectBody(&obj1, "some_bucket_content"), + testAccCheckObjectExists(resourceName, &obj1), + testAccCheckObjectBody(&obj1, "some_bucket_content"), resource.TestCheckResourceAttr(resourceName, "acl", "private"), - testAccCheckBucketObjectACL(resourceName, []string{"FULL_CONTROL"}), + testAccCheckObjectACL(resourceName, []string{"FULL_CONTROL"}), ), }, { - Config: testAccBucketObjectConfig_acl(rName, "some_bucket_content", "public-read"), + Config: testAccObjectConfig_acl(rName, "some_bucket_content", "public-read"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj2), - testAccCheckBucketObjectVersionIdEquals(&obj2, &obj1), - testAccCheckBucketObjectBody(&obj2, "some_bucket_content"), + testAccCheckObjectExists(resourceName, &obj2), + testAccCheckObjectVersionIdEquals(&obj2, &obj1), + testAccCheckObjectBody(&obj2, "some_bucket_content"), resource.TestCheckResourceAttr(resourceName, "acl", "public-read"), - testAccCheckBucketObjectACL(resourceName, []string{"FULL_CONTROL", "READ"}), + testAccCheckObjectACL(resourceName, []string{"FULL_CONTROL", "READ"}), ), }, { - Config: testAccBucketObjectConfig_acl(rName, "changed_some_bucket_content", "private"), + Config: testAccObjectConfig_acl(rName, "changed_some_bucket_content", "private"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj3), - testAccCheckBucketObjectVersionIdDiffers(&obj3, &obj2), - testAccCheckBucketObjectBody(&obj3, "changed_some_bucket_content"), + testAccCheckObjectExists(resourceName, &obj3), + testAccCheckObjectVersionIdDiffers(&obj3, &obj2), + testAccCheckObjectBody(&obj3, "changed_some_bucket_content"), resource.TestCheckResourceAttr(resourceName, "acl", "private"), - testAccCheckBucketObjectACL(resourceName, []string{"FULL_CONTROL"}), + testAccCheckObjectACL(resourceName, []string{"FULL_CONTROL"}), ), }, { @@ -619,30 +619,30 @@ func TestAccS3Object_metadata(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectConfig_withMetadata(rName, "key1", "value1", "key2", "value2"), + Config: testAccObjectConfig_withMetadata(rName, "key1", "value1", "key2", "value2"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), + testAccCheckObjectExists(resourceName, &obj), resource.TestCheckResourceAttr(resourceName, "metadata.%", "2"), resource.TestCheckResourceAttr(resourceName, "metadata.key1", "value1"), resource.TestCheckResourceAttr(resourceName, "metadata.key2", "value2"), ), }, { - Config: testAccBucketObjectConfig_withMetadata(rName, "key1", "value1updated", "key3", "value3"), + Config: testAccObjectConfig_withMetadata(rName, "key1", "value1updated", "key3", "value3"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), + testAccCheckObjectExists(resourceName, &obj), resource.TestCheckResourceAttr(resourceName, "metadata.%", "2"), resource.TestCheckResourceAttr(resourceName, "metadata.key1", "value1updated"), resource.TestCheckResourceAttr(resourceName, "metadata.key3", "value3"), ), }, { - Config: testAccBucketObjectEmptyConfig(rName), + Config: testAccObjectEmptyConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), + testAccCheckObjectExists(resourceName, &obj), resource.TestCheckResourceAttr(resourceName, "metadata.%", "0"), ), }, @@ -666,47 +666,47 @@ func TestAccS3Object_storageClass(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { PreConfig: func() {}, - Config: testAccBucketObjectContentConfig(rName, "some_bucket_content"), + Config: testAccObjectContentConfig(rName, "some_bucket_content"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), + testAccCheckObjectExists(resourceName, &obj), resource.TestCheckResourceAttr(resourceName, "storage_class", "STANDARD"), - testAccCheckBucketObjectStorageClass(resourceName, "STANDARD"), + testAccCheckObjectStorageClass(resourceName, "STANDARD"), ), }, { - Config: testAccBucketObjectConfig_storageClass(rName, "REDUCED_REDUNDANCY"), + Config: testAccObjectConfig_storageClass(rName, "REDUCED_REDUNDANCY"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), + testAccCheckObjectExists(resourceName, &obj), resource.TestCheckResourceAttr(resourceName, "storage_class", "REDUCED_REDUNDANCY"), - testAccCheckBucketObjectStorageClass(resourceName, "REDUCED_REDUNDANCY"), + testAccCheckObjectStorageClass(resourceName, "REDUCED_REDUNDANCY"), ), }, { - Config: testAccBucketObjectConfig_storageClass(rName, "GLACIER"), + Config: testAccObjectConfig_storageClass(rName, "GLACIER"), Check: resource.ComposeTestCheckFunc( // Can't GetObject on an object in Glacier without restoring it. resource.TestCheckResourceAttr(resourceName, "storage_class", "GLACIER"), - testAccCheckBucketObjectStorageClass(resourceName, "GLACIER"), + testAccCheckObjectStorageClass(resourceName, "GLACIER"), ), }, { - Config: testAccBucketObjectConfig_storageClass(rName, "INTELLIGENT_TIERING"), + Config: testAccObjectConfig_storageClass(rName, "INTELLIGENT_TIERING"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), + testAccCheckObjectExists(resourceName, &obj), resource.TestCheckResourceAttr(resourceName, "storage_class", "INTELLIGENT_TIERING"), - testAccCheckBucketObjectStorageClass(resourceName, "INTELLIGENT_TIERING"), + testAccCheckObjectStorageClass(resourceName, "INTELLIGENT_TIERING"), ), }, { - Config: testAccBucketObjectConfig_storageClass(rName, "DEEP_ARCHIVE"), + Config: testAccObjectConfig_storageClass(rName, "DEEP_ARCHIVE"), Check: resource.ComposeTestCheckFunc( // Can't GetObject on an object in DEEP_ARCHIVE without restoring it. resource.TestCheckResourceAttr(resourceName, "storage_class", "DEEP_ARCHIVE"), - testAccCheckBucketObjectStorageClass(resourceName, "DEEP_ARCHIVE"), + testAccCheckObjectStorageClass(resourceName, "DEEP_ARCHIVE"), ), }, { @@ -730,14 +730,14 @@ func TestAccS3Object_tags(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withTags(rName, key, "stuff"), + Config: testAccObjectConfig_withTags(rName, key, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj1), - testAccCheckBucketObjectBody(&obj1, "stuff"), + testAccCheckObjectExists(resourceName, &obj1), + testAccCheckObjectBody(&obj1, "stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "3"), resource.TestCheckResourceAttr(resourceName, "tags.Key1", "A@AA"), resource.TestCheckResourceAttr(resourceName, "tags.Key2", "BBB"), @@ -746,11 +746,11 @@ func TestAccS3Object_tags(t *testing.T) { }, { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withUpdatedTags(rName, key, "stuff"), + Config: testAccObjectConfig_withUpdatedTags(rName, key, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj2), - testAccCheckBucketObjectVersionIdEquals(&obj2, &obj1), - testAccCheckBucketObjectBody(&obj2, "stuff"), + testAccCheckObjectExists(resourceName, &obj2), + testAccCheckObjectVersionIdEquals(&obj2, &obj1), + testAccCheckObjectBody(&obj2, "stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "4"), resource.TestCheckResourceAttr(resourceName, "tags.Key2", "B@BB"), resource.TestCheckResourceAttr(resourceName, "tags.Key3", "X X"), @@ -760,21 +760,21 @@ func TestAccS3Object_tags(t *testing.T) { }, { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withNoTags(rName, key, "stuff"), + Config: testAccObjectConfig_withNoTags(rName, key, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj3), - testAccCheckBucketObjectVersionIdEquals(&obj3, &obj2), - testAccCheckBucketObjectBody(&obj3, "stuff"), + testAccCheckObjectExists(resourceName, &obj3), + testAccCheckObjectVersionIdEquals(&obj3, &obj2), + testAccCheckObjectBody(&obj3, "stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withTags(rName, key, "changed stuff"), + Config: testAccObjectConfig_withTags(rName, key, "changed stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj4), - testAccCheckBucketObjectVersionIdDiffers(&obj4, &obj3), - testAccCheckBucketObjectBody(&obj4, "changed stuff"), + testAccCheckObjectExists(resourceName, &obj4), + testAccCheckObjectVersionIdDiffers(&obj4, &obj3), + testAccCheckObjectBody(&obj4, "changed stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "3"), resource.TestCheckResourceAttr(resourceName, "tags.Key1", "A@AA"), resource.TestCheckResourceAttr(resourceName, "tags.Key2", "BBB"), @@ -802,14 +802,14 @@ func TestAccS3Object_tagsLeadingSingleSlash(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withTags(rName, key, "stuff"), + Config: testAccObjectConfig_withTags(rName, key, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj1), - testAccCheckBucketObjectBody(&obj1, "stuff"), + testAccCheckObjectExists(resourceName, &obj1), + testAccCheckObjectBody(&obj1, "stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "3"), resource.TestCheckResourceAttr(resourceName, "tags.Key1", "A@AA"), resource.TestCheckResourceAttr(resourceName, "tags.Key2", "BBB"), @@ -818,11 +818,11 @@ func TestAccS3Object_tagsLeadingSingleSlash(t *testing.T) { }, { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withUpdatedTags(rName, key, "stuff"), + Config: testAccObjectConfig_withUpdatedTags(rName, key, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj2), - testAccCheckBucketObjectVersionIdEquals(&obj2, &obj1), - testAccCheckBucketObjectBody(&obj2, "stuff"), + testAccCheckObjectExists(resourceName, &obj2), + testAccCheckObjectVersionIdEquals(&obj2, &obj1), + testAccCheckObjectBody(&obj2, "stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "4"), resource.TestCheckResourceAttr(resourceName, "tags.Key2", "B@BB"), resource.TestCheckResourceAttr(resourceName, "tags.Key3", "X X"), @@ -832,21 +832,21 @@ func TestAccS3Object_tagsLeadingSingleSlash(t *testing.T) { }, { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withNoTags(rName, key, "stuff"), + Config: testAccObjectConfig_withNoTags(rName, key, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj3), - testAccCheckBucketObjectVersionIdEquals(&obj3, &obj2), - testAccCheckBucketObjectBody(&obj3, "stuff"), + testAccCheckObjectExists(resourceName, &obj3), + testAccCheckObjectVersionIdEquals(&obj3, &obj2), + testAccCheckObjectBody(&obj3, "stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withTags(rName, key, "changed stuff"), + Config: testAccObjectConfig_withTags(rName, key, "changed stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj4), - testAccCheckBucketObjectVersionIdDiffers(&obj4, &obj3), - testAccCheckBucketObjectBody(&obj4, "changed stuff"), + testAccCheckObjectExists(resourceName, &obj4), + testAccCheckObjectVersionIdDiffers(&obj4, &obj3), + testAccCheckObjectBody(&obj4, "changed stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "3"), resource.TestCheckResourceAttr(resourceName, "tags.Key1", "A@AA"), resource.TestCheckResourceAttr(resourceName, "tags.Key2", "BBB"), @@ -874,14 +874,14 @@ func TestAccS3Object_tagsLeadingMultipleSlashes(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withTags(rName, key, "stuff"), + Config: testAccObjectConfig_withTags(rName, key, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj1), - testAccCheckBucketObjectBody(&obj1, "stuff"), + testAccCheckObjectExists(resourceName, &obj1), + testAccCheckObjectBody(&obj1, "stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "3"), resource.TestCheckResourceAttr(resourceName, "tags.Key1", "A@AA"), resource.TestCheckResourceAttr(resourceName, "tags.Key2", "BBB"), @@ -890,11 +890,11 @@ func TestAccS3Object_tagsLeadingMultipleSlashes(t *testing.T) { }, { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withUpdatedTags(rName, key, "stuff"), + Config: testAccObjectConfig_withUpdatedTags(rName, key, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj2), - testAccCheckBucketObjectVersionIdEquals(&obj2, &obj1), - testAccCheckBucketObjectBody(&obj2, "stuff"), + testAccCheckObjectExists(resourceName, &obj2), + testAccCheckObjectVersionIdEquals(&obj2, &obj1), + testAccCheckObjectBody(&obj2, "stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "4"), resource.TestCheckResourceAttr(resourceName, "tags.Key2", "B@BB"), resource.TestCheckResourceAttr(resourceName, "tags.Key3", "X X"), @@ -904,21 +904,21 @@ func TestAccS3Object_tagsLeadingMultipleSlashes(t *testing.T) { }, { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withNoTags(rName, key, "stuff"), + Config: testAccObjectConfig_withNoTags(rName, key, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj3), - testAccCheckBucketObjectVersionIdEquals(&obj3, &obj2), - testAccCheckBucketObjectBody(&obj3, "stuff"), + testAccCheckObjectExists(resourceName, &obj3), + testAccCheckObjectVersionIdEquals(&obj3, &obj2), + testAccCheckObjectBody(&obj3, "stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withTags(rName, key, "changed stuff"), + Config: testAccObjectConfig_withTags(rName, key, "changed stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj4), - testAccCheckBucketObjectVersionIdDiffers(&obj4, &obj3), - testAccCheckBucketObjectBody(&obj4, "changed stuff"), + testAccCheckObjectExists(resourceName, &obj4), + testAccCheckObjectVersionIdDiffers(&obj4, &obj3), + testAccCheckObjectBody(&obj4, "changed stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "3"), resource.TestCheckResourceAttr(resourceName, "tags.Key1", "A@AA"), resource.TestCheckResourceAttr(resourceName, "tags.Key2", "BBB"), @@ -939,14 +939,14 @@ func TestAccS3Object_tagsMultipleSlashes(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withTags(rName, key, "stuff"), + Config: testAccObjectConfig_withTags(rName, key, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj1), - testAccCheckBucketObjectBody(&obj1, "stuff"), + testAccCheckObjectExists(resourceName, &obj1), + testAccCheckObjectBody(&obj1, "stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "3"), resource.TestCheckResourceAttr(resourceName, "tags.Key1", "A@AA"), resource.TestCheckResourceAttr(resourceName, "tags.Key2", "BBB"), @@ -955,11 +955,11 @@ func TestAccS3Object_tagsMultipleSlashes(t *testing.T) { }, { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withUpdatedTags(rName, key, "stuff"), + Config: testAccObjectConfig_withUpdatedTags(rName, key, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj2), - testAccCheckBucketObjectVersionIdEquals(&obj2, &obj1), - testAccCheckBucketObjectBody(&obj2, "stuff"), + testAccCheckObjectExists(resourceName, &obj2), + testAccCheckObjectVersionIdEquals(&obj2, &obj1), + testAccCheckObjectBody(&obj2, "stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "4"), resource.TestCheckResourceAttr(resourceName, "tags.Key2", "B@BB"), resource.TestCheckResourceAttr(resourceName, "tags.Key3", "X X"), @@ -969,21 +969,21 @@ func TestAccS3Object_tagsMultipleSlashes(t *testing.T) { }, { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withNoTags(rName, key, "stuff"), + Config: testAccObjectConfig_withNoTags(rName, key, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj3), - testAccCheckBucketObjectVersionIdEquals(&obj3, &obj2), - testAccCheckBucketObjectBody(&obj3, "stuff"), + testAccCheckObjectExists(resourceName, &obj3), + testAccCheckObjectVersionIdEquals(&obj3, &obj2), + testAccCheckObjectBody(&obj3, "stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), ), }, { PreConfig: func() {}, - Config: testAccBucketObjectConfig_withTags(rName, key, "changed stuff"), + Config: testAccObjectConfig_withTags(rName, key, "changed stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj4), - testAccCheckBucketObjectVersionIdDiffers(&obj4, &obj3), - testAccCheckBucketObjectBody(&obj4, "changed stuff"), + testAccCheckObjectExists(resourceName, &obj4), + testAccCheckObjectVersionIdDiffers(&obj4, &obj3), + testAccCheckObjectBody(&obj4, "changed stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "3"), resource.TestCheckResourceAttr(resourceName, "tags.Key1", "A@AA"), resource.TestCheckResourceAttr(resourceName, "tags.Key2", "BBB"), @@ -1003,24 +1003,24 @@ func TestAccS3Object_objectLockLegalHoldStartWithNone(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectConfig_noObjectLockLegalHold(rName, "stuff"), + Config: testAccObjectConfig_noObjectLockLegalHold(rName, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj1), - testAccCheckBucketObjectBody(&obj1, "stuff"), + testAccCheckObjectExists(resourceName, &obj1), + testAccCheckObjectBody(&obj1, "stuff"), resource.TestCheckResourceAttr(resourceName, "object_lock_legal_hold_status", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_mode", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_retain_until_date", ""), ), }, { - Config: testAccBucketObjectConfig_withObjectLockLegalHold(rName, "stuff", "ON"), + Config: testAccObjectConfig_withObjectLockLegalHold(rName, "stuff", "ON"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj2), - testAccCheckBucketObjectVersionIdEquals(&obj2, &obj1), - testAccCheckBucketObjectBody(&obj2, "stuff"), + testAccCheckObjectExists(resourceName, &obj2), + testAccCheckObjectVersionIdEquals(&obj2, &obj1), + testAccCheckObjectBody(&obj2, "stuff"), resource.TestCheckResourceAttr(resourceName, "object_lock_legal_hold_status", "ON"), resource.TestCheckResourceAttr(resourceName, "object_lock_mode", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_retain_until_date", ""), @@ -1028,11 +1028,11 @@ func TestAccS3Object_objectLockLegalHoldStartWithNone(t *testing.T) { }, // Remove legal hold but create a new object version to test force_destroy { - Config: testAccBucketObjectConfig_withObjectLockLegalHold(rName, "changed stuff", "OFF"), + Config: testAccObjectConfig_withObjectLockLegalHold(rName, "changed stuff", "OFF"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj3), - testAccCheckBucketObjectVersionIdDiffers(&obj3, &obj2), - testAccCheckBucketObjectBody(&obj3, "changed stuff"), + testAccCheckObjectExists(resourceName, &obj3), + testAccCheckObjectVersionIdDiffers(&obj3, &obj2), + testAccCheckObjectBody(&obj3, "changed stuff"), resource.TestCheckResourceAttr(resourceName, "object_lock_legal_hold_status", "OFF"), resource.TestCheckResourceAttr(resourceName, "object_lock_mode", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_retain_until_date", ""), @@ -1051,24 +1051,24 @@ func TestAccS3Object_objectLockLegalHoldStartWithOn(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectConfig_withObjectLockLegalHold(rName, "stuff", "ON"), + Config: testAccObjectConfig_withObjectLockLegalHold(rName, "stuff", "ON"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj1), - testAccCheckBucketObjectBody(&obj1, "stuff"), + testAccCheckObjectExists(resourceName, &obj1), + testAccCheckObjectBody(&obj1, "stuff"), resource.TestCheckResourceAttr(resourceName, "object_lock_legal_hold_status", "ON"), resource.TestCheckResourceAttr(resourceName, "object_lock_mode", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_retain_until_date", ""), ), }, { - Config: testAccBucketObjectConfig_withObjectLockLegalHold(rName, "stuff", "OFF"), + Config: testAccObjectConfig_withObjectLockLegalHold(rName, "stuff", "OFF"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj2), - testAccCheckBucketObjectVersionIdEquals(&obj2, &obj1), - testAccCheckBucketObjectBody(&obj2, "stuff"), + testAccCheckObjectExists(resourceName, &obj2), + testAccCheckObjectVersionIdEquals(&obj2, &obj1), + testAccCheckObjectBody(&obj2, "stuff"), resource.TestCheckResourceAttr(resourceName, "object_lock_legal_hold_status", "OFF"), resource.TestCheckResourceAttr(resourceName, "object_lock_mode", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_retain_until_date", ""), @@ -1088,24 +1088,24 @@ func TestAccS3Object_objectLockRetentionStartWithNone(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectConfig_noObjectLockRetention(rName, "stuff"), + Config: testAccObjectConfig_noObjectLockRetention(rName, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj1), - testAccCheckBucketObjectBody(&obj1, "stuff"), + testAccCheckObjectExists(resourceName, &obj1), + testAccCheckObjectBody(&obj1, "stuff"), resource.TestCheckResourceAttr(resourceName, "object_lock_legal_hold_status", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_mode", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_retain_until_date", ""), ), }, { - Config: testAccBucketObjectConfig_withObjectLockRetention(rName, "stuff", retainUntilDate), + Config: testAccObjectConfig_withObjectLockRetention(rName, "stuff", retainUntilDate), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj2), - testAccCheckBucketObjectVersionIdEquals(&obj2, &obj1), - testAccCheckBucketObjectBody(&obj2, "stuff"), + testAccCheckObjectExists(resourceName, &obj2), + testAccCheckObjectVersionIdEquals(&obj2, &obj1), + testAccCheckObjectBody(&obj2, "stuff"), resource.TestCheckResourceAttr(resourceName, "object_lock_legal_hold_status", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_mode", "GOVERNANCE"), resource.TestCheckResourceAttr(resourceName, "object_lock_retain_until_date", retainUntilDate), @@ -1113,11 +1113,11 @@ func TestAccS3Object_objectLockRetentionStartWithNone(t *testing.T) { }, // Remove retention period but create a new object version to test force_destroy { - Config: testAccBucketObjectConfig_noObjectLockRetention(rName, "changed stuff"), + Config: testAccObjectConfig_noObjectLockRetention(rName, "changed stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj3), - testAccCheckBucketObjectVersionIdDiffers(&obj3, &obj2), - testAccCheckBucketObjectBody(&obj3, "changed stuff"), + testAccCheckObjectExists(resourceName, &obj3), + testAccCheckObjectVersionIdDiffers(&obj3, &obj2), + testAccCheckObjectBody(&obj3, "changed stuff"), resource.TestCheckResourceAttr(resourceName, "object_lock_legal_hold_status", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_mode", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_retain_until_date", ""), @@ -1139,46 +1139,46 @@ func TestAccS3Object_objectLockRetentionStartWithSet(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectConfig_withObjectLockRetention(rName, "stuff", retainUntilDate1), + Config: testAccObjectConfig_withObjectLockRetention(rName, "stuff", retainUntilDate1), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj1), - testAccCheckBucketObjectBody(&obj1, "stuff"), + testAccCheckObjectExists(resourceName, &obj1), + testAccCheckObjectBody(&obj1, "stuff"), resource.TestCheckResourceAttr(resourceName, "object_lock_legal_hold_status", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_mode", "GOVERNANCE"), resource.TestCheckResourceAttr(resourceName, "object_lock_retain_until_date", retainUntilDate1), ), }, { - Config: testAccBucketObjectConfig_withObjectLockRetention(rName, "stuff", retainUntilDate2), + Config: testAccObjectConfig_withObjectLockRetention(rName, "stuff", retainUntilDate2), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj2), - testAccCheckBucketObjectVersionIdEquals(&obj2, &obj1), - testAccCheckBucketObjectBody(&obj2, "stuff"), + testAccCheckObjectExists(resourceName, &obj2), + testAccCheckObjectVersionIdEquals(&obj2, &obj1), + testAccCheckObjectBody(&obj2, "stuff"), resource.TestCheckResourceAttr(resourceName, "object_lock_legal_hold_status", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_mode", "GOVERNANCE"), resource.TestCheckResourceAttr(resourceName, "object_lock_retain_until_date", retainUntilDate2), ), }, { - Config: testAccBucketObjectConfig_withObjectLockRetention(rName, "stuff", retainUntilDate3), + Config: testAccObjectConfig_withObjectLockRetention(rName, "stuff", retainUntilDate3), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj3), - testAccCheckBucketObjectVersionIdEquals(&obj3, &obj2), - testAccCheckBucketObjectBody(&obj3, "stuff"), + testAccCheckObjectExists(resourceName, &obj3), + testAccCheckObjectVersionIdEquals(&obj3, &obj2), + testAccCheckObjectBody(&obj3, "stuff"), resource.TestCheckResourceAttr(resourceName, "object_lock_legal_hold_status", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_mode", "GOVERNANCE"), resource.TestCheckResourceAttr(resourceName, "object_lock_retain_until_date", retainUntilDate3), ), }, { - Config: testAccBucketObjectConfig_noObjectLockRetention(rName, "stuff"), + Config: testAccObjectConfig_noObjectLockRetention(rName, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj4), - testAccCheckBucketObjectVersionIdEquals(&obj4, &obj3), - testAccCheckBucketObjectBody(&obj4, "stuff"), + testAccCheckObjectExists(resourceName, &obj4), + testAccCheckObjectVersionIdEquals(&obj4, &obj3), + testAccCheckObjectBody(&obj4, "stuff"), resource.TestCheckResourceAttr(resourceName, "object_lock_legal_hold_status", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_mode", ""), resource.TestCheckResourceAttr(resourceName, "object_lock_retain_until_date", ""), @@ -1197,13 +1197,13 @@ func TestAccS3Object_objectBucketKeyEnabled(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectConfig_objectBucketKeyEnabled(rName, "stuff"), + Config: testAccObjectConfig_objectBucketKeyEnabled(rName, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), - testAccCheckBucketObjectBody(&obj, "stuff"), + testAccCheckObjectExists(resourceName, &obj), + testAccCheckObjectBody(&obj, "stuff"), resource.TestCheckResourceAttr(resourceName, "bucket_key_enabled", "true"), ), }, @@ -1220,13 +1220,13 @@ func TestAccS3Object_bucketBucketKeyEnabled(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectConfig_bucketBucketKeyEnabled(rName, "stuff"), + Config: testAccObjectConfig_bucketBucketKeyEnabled(rName, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), - testAccCheckBucketObjectBody(&obj, "stuff"), + testAccCheckObjectExists(resourceName, &obj), + testAccCheckObjectBody(&obj, "stuff"), resource.TestCheckResourceAttr(resourceName, "bucket_key_enabled", "true"), ), }, @@ -1243,13 +1243,13 @@ func TestAccS3Object_defaultBucketSSE(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), Providers: acctest.Providers, - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { - Config: testAccBucketObjectConfig_defaultBucketSSE(rName, "stuff"), + Config: testAccObjectConfig_defaultBucketSSE(rName, "stuff"), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj1), - testAccCheckBucketObjectBody(&obj1, "stuff"), + testAccCheckObjectExists(resourceName, &obj1), + testAccCheckObjectBody(&obj1, "stuff"), ), }, }, @@ -1267,19 +1267,19 @@ func TestAccS3Object_ignoreTags(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) }, ErrorCheck: acctest.ErrorCheck(t, s3.EndpointsID), ProviderFactories: acctest.FactoriesInternal(&providers), - CheckDestroy: testAccCheckBucketObjectDestroy, + CheckDestroy: testAccCheckObjectDestroy, Steps: []resource.TestStep{ { PreConfig: func() {}, Config: acctest.ConfigCompose( acctest.ConfigIgnoreTagsKeyPrefixes1("ignorekey"), - testAccBucketObjectConfig_withNoTags(rName, key, "stuff")), + testAccObjectConfig_withNoTags(rName, key, "stuff")), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), - testAccCheckBucketObjectBody(&obj, "stuff"), - testAccCheckBucketObjectUpdateTags(resourceName, nil, map[string]string{"ignorekey1": "ignorevalue1"}), + testAccCheckObjectExists(resourceName, &obj), + testAccCheckObjectBody(&obj, "stuff"), + testAccCheckObjectUpdateTags(resourceName, nil, map[string]string{"ignorekey1": "ignorevalue1"}), resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), - testAccCheckBucketObjectCheckTags(resourceName, map[string]string{ + testAccCheckObjectCheckTags(resourceName, map[string]string{ "ignorekey1": "ignorevalue1", }), ), @@ -1288,15 +1288,15 @@ func TestAccS3Object_ignoreTags(t *testing.T) { PreConfig: func() {}, Config: acctest.ConfigCompose( acctest.ConfigIgnoreTagsKeyPrefixes1("ignorekey"), - testAccBucketObjectConfig_withTags(rName, key, "stuff")), + testAccObjectConfig_withTags(rName, key, "stuff")), Check: resource.ComposeTestCheckFunc( - testAccCheckBucketObjectExists(resourceName, &obj), - testAccCheckBucketObjectBody(&obj, "stuff"), + testAccCheckObjectExists(resourceName, &obj), + testAccCheckObjectBody(&obj, "stuff"), resource.TestCheckResourceAttr(resourceName, "tags.%", "3"), resource.TestCheckResourceAttr(resourceName, "tags.Key1", "A@AA"), resource.TestCheckResourceAttr(resourceName, "tags.Key2", "BBB"), resource.TestCheckResourceAttr(resourceName, "tags.Key3", "CCC"), - testAccCheckBucketObjectCheckTags(resourceName, map[string]string{ + testAccCheckObjectCheckTags(resourceName, map[string]string{ "ignorekey1": "ignorevalue1", "Key1": "A@AA", "Key2": "BBB", @@ -1308,7 +1308,7 @@ func TestAccS3Object_ignoreTags(t *testing.T) { }) } -func testAccCheckBucketObjectVersionIdDiffers(first, second *s3.GetObjectOutput) resource.TestCheckFunc { +func testAccCheckObjectVersionIdDiffers(first, second *s3.GetObjectOutput) resource.TestCheckFunc { return func(s *terraform.State) error { if first.VersionId == nil { return fmt.Errorf("Expected first object to have VersionId: %s", first) @@ -1325,7 +1325,7 @@ func testAccCheckBucketObjectVersionIdDiffers(first, second *s3.GetObjectOutput) } } -func testAccCheckBucketObjectVersionIdEquals(first, second *s3.GetObjectOutput) resource.TestCheckFunc { +func testAccCheckObjectVersionIdEquals(first, second *s3.GetObjectOutput) resource.TestCheckFunc { return func(s *terraform.State) error { if first.VersionId == nil { return fmt.Errorf("Expected first object to have VersionId: %s", first) @@ -1342,7 +1342,7 @@ func testAccCheckBucketObjectVersionIdEquals(first, second *s3.GetObjectOutput) } } -func testAccCheckBucketObjectDestroy(s *terraform.State) error { +func testAccCheckObjectDestroy(s *terraform.State) error { conn := acctest.Provider.Meta().(*conns.AWSClient).S3Conn for _, rs := range s.RootModule().Resources { @@ -1363,7 +1363,7 @@ func testAccCheckBucketObjectDestroy(s *terraform.State) error { return nil } -func testAccCheckBucketObjectExists(n string, obj *s3.GetObjectOutput) resource.TestCheckFunc { +func testAccCheckObjectExists(n string, obj *s3.GetObjectOutput) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { @@ -1414,7 +1414,7 @@ func testAccCheckBucketObjectExists(n string, obj *s3.GetObjectOutput) resource. } } -func testAccCheckBucketObjectBody(obj *s3.GetObjectOutput, want string) resource.TestCheckFunc { +func testAccCheckObjectBody(obj *s3.GetObjectOutput, want string) resource.TestCheckFunc { return func(s *terraform.State) error { body, err := io.ReadAll(obj.Body) if err != nil { @@ -1430,7 +1430,7 @@ func testAccCheckBucketObjectBody(obj *s3.GetObjectOutput, want string) resource } } -func testAccCheckBucketObjectACL(n string, expectedPerms []string) resource.TestCheckFunc { +func testAccCheckObjectACL(n string, expectedPerms []string) resource.TestCheckFunc { return func(s *terraform.State) error { rs := s.RootModule().Resources[n] conn := acctest.Provider.Meta().(*conns.AWSClient).S3Conn @@ -1458,7 +1458,7 @@ func testAccCheckBucketObjectACL(n string, expectedPerms []string) resource.Test } } -func testAccCheckBucketObjectStorageClass(n, expectedClass string) resource.TestCheckFunc { +func testAccCheckObjectStorageClass(n, expectedClass string) resource.TestCheckFunc { return func(s *terraform.State) error { rs := s.RootModule().Resources[n] conn := acctest.Provider.Meta().(*conns.AWSClient).S3Conn @@ -1488,7 +1488,7 @@ func testAccCheckBucketObjectStorageClass(n, expectedClass string) resource.Test } } -func testAccCheckBucketObjectSSE(n, expectedSSE string) resource.TestCheckFunc { +func testAccCheckObjectSSE(n, expectedSSE string) resource.TestCheckFunc { return func(s *terraform.State) error { rs := s.RootModule().Resources[n] conn := acctest.Provider.Meta().(*conns.AWSClient).S3Conn @@ -1516,7 +1516,7 @@ func testAccCheckBucketObjectSSE(n, expectedSSE string) resource.TestCheckFunc { } } -func testAccBucketObjectCreateTempFile(t *testing.T, data string) string { +func testAccObjectCreateTempFile(t *testing.T, data string) string { tmpFile, err := os.CreateTemp("", "tf-acc-s3-obj") if err != nil { t.Fatal(err) @@ -1532,7 +1532,7 @@ func testAccBucketObjectCreateTempFile(t *testing.T, data string) string { return filename } -func testAccCheckBucketObjectUpdateTags(n string, oldTags, newTags map[string]string) resource.TestCheckFunc { +func testAccCheckObjectUpdateTags(n string, oldTags, newTags map[string]string) resource.TestCheckFunc { return func(s *terraform.State) error { rs := s.RootModule().Resources[n] conn := acctest.Provider.Meta().(*conns.AWSClient).S3Conn @@ -1541,7 +1541,7 @@ func testAccCheckBucketObjectUpdateTags(n string, oldTags, newTags map[string]st } } -func testAccCheckBucketObjectCheckTags(n string, expectedTags map[string]string) resource.TestCheckFunc { +func testAccCheckObjectCheckTags(n string, expectedTags map[string]string) resource.TestCheckFunc { return func(s *terraform.State) error { rs := s.RootModule().Resources[n] conn := acctest.Provider.Meta().(*conns.AWSClient).S3Conn @@ -1560,7 +1560,7 @@ func testAccCheckBucketObjectCheckTags(n string, expectedTags map[string]string) } } -func testAccBucketObjectBasicConfig(bucket, key string) string { +func testAccObjectBasicConfig(bucket, key string) string { return fmt.Sprintf(` resource "aws_s3_object" "object" { bucket = %[1]q @@ -1569,7 +1569,7 @@ resource "aws_s3_object" "object" { `, bucket, key) } -func testAccBucketObjectEmptyConfig(rName string) string { +func testAccObjectEmptyConfig(rName string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1582,7 +1582,7 @@ resource "aws_s3_object" "object" { `, rName) } -func testAccBucketObjectSourceConfig(rName string, source string) string { +func testAccObjectSourceConfig(rName string, source string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1597,7 +1597,7 @@ resource "aws_s3_object" "object" { `, rName, source) } -func testAccBucketObjectConfig_withContentCharacteristics(rName string, source string) string { +func testAccObjectConfig_withContentCharacteristics(rName string, source string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1614,7 +1614,7 @@ resource "aws_s3_object" "object" { `, rName, source) } -func testAccBucketObjectContentConfig(rName string, content string) string { +func testAccObjectContentConfig(rName string, content string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1628,7 +1628,7 @@ resource "aws_s3_object" "object" { `, rName, content) } -func testAccBucketObjectEtagEncryption(rName string, source string) string { +func testAccObjectEtagEncryption(rName string, source string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1644,7 +1644,7 @@ resource "aws_s3_object" "object" { `, rName, source) } -func testAccBucketObjectContentBase64Config(rName string, contentBase64 string) string { +func testAccObjectContentBase64Config(rName string, contentBase64 string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1658,7 +1658,7 @@ resource "aws_s3_object" "object" { `, rName, contentBase64) } -func testAccBucketObjectConfig_sourceHashTrigger(rName string, source string) string { +func testAccObjectConfig_sourceHashTrigger(rName string, source string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1673,7 +1673,7 @@ resource "aws_s3_object" "object" { `, rName, source) } -func testAccBucketObjectConfig_updateable(rName string, bucketVersioning bool, source string) string { +func testAccObjectConfig_updateable(rName string, bucketVersioning bool, source string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "object_bucket_3" { bucket = %[1]q @@ -1692,7 +1692,7 @@ resource "aws_s3_object" "object" { `, rName, bucketVersioning, source) } -func testAccBucketObjectConfig_updateableViaAccessPoint(rName string, bucketVersioning bool, source string) string { +func testAccObjectConfig_updateableViaAccessPoint(rName string, bucketVersioning bool, source string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1716,7 +1716,7 @@ resource "aws_s3_object" "test" { `, rName, bucketVersioning, source) } -func testAccBucketObjectConfig_withKMSID(rName string, source string) string { +func testAccObjectConfig_withKMSID(rName string, source string) string { return fmt.Sprintf(` resource "aws_kms_key" "kms_key_1" {} @@ -1733,7 +1733,7 @@ resource "aws_s3_object" "object" { `, rName, source) } -func testAccBucketObjectConfig_withSSE(rName string, source string) string { +func testAccObjectConfig_withSSE(rName string, source string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1748,7 +1748,7 @@ resource "aws_s3_object" "object" { `, rName, source) } -func testAccBucketObjectConfig_acl(rName string, content, acl string) string { +func testAccObjectConfig_acl(rName string, content, acl string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1767,7 +1767,7 @@ resource "aws_s3_object" "object" { `, rName, content, acl) } -func testAccBucketObjectConfig_storageClass(rName string, storage_class string) string { +func testAccObjectConfig_storageClass(rName string, storage_class string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1782,7 +1782,7 @@ resource "aws_s3_object" "object" { `, rName, storage_class) } -func testAccBucketObjectConfig_withTags(rName, key, content string) string { +func testAccObjectConfig_withTags(rName, key, content string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1806,7 +1806,7 @@ resource "aws_s3_object" "object" { `, rName, key, content) } -func testAccBucketObjectConfig_withUpdatedTags(rName, key, content string) string { +func testAccObjectConfig_withUpdatedTags(rName, key, content string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1831,7 +1831,7 @@ resource "aws_s3_object" "object" { `, rName, key, content) } -func testAccBucketObjectConfig_withNoTags(rName, key, content string) string { +func testAccObjectConfig_withNoTags(rName, key, content string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1849,7 +1849,7 @@ resource "aws_s3_object" "object" { `, rName, key, content) } -func testAccBucketObjectConfig_withMetadata(rName string, metadataKey1, metadataValue1, metadataKey2, metadataValue2 string) string { +func testAccObjectConfig_withMetadata(rName string, metadataKey1, metadataValue1, metadataKey2, metadataValue2 string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1867,7 +1867,7 @@ resource "aws_s3_object" "object" { `, rName, metadataKey1, metadataValue1, metadataKey2, metadataValue2) } -func testAccBucketObjectConfig_noObjectLockLegalHold(rName string, content string) string { +func testAccObjectConfig_noObjectLockLegalHold(rName string, content string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1890,7 +1890,7 @@ resource "aws_s3_object" "object" { `, rName, content) } -func testAccBucketObjectConfig_withObjectLockLegalHold(rName string, content, legalHoldStatus string) string { +func testAccObjectConfig_withObjectLockLegalHold(rName string, content, legalHoldStatus string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1914,7 +1914,7 @@ resource "aws_s3_object" "object" { `, rName, content, legalHoldStatus) } -func testAccBucketObjectConfig_noObjectLockRetention(rName string, content string) string { +func testAccObjectConfig_noObjectLockRetention(rName string, content string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1937,7 +1937,7 @@ resource "aws_s3_object" "object" { `, rName, content) } -func testAccBucketObjectConfig_withObjectLockRetention(rName string, content, retainUntilDate string) string { +func testAccObjectConfig_withObjectLockRetention(rName string, content, retainUntilDate string) string { return fmt.Sprintf(` resource "aws_s3_bucket" "test" { bucket = %[1]q @@ -1962,7 +1962,7 @@ resource "aws_s3_object" "object" { `, rName, content, retainUntilDate) } -func testAccBucketObjectConfig_nonVersioned(rName string, source string) string { +func testAccObjectConfig_nonVersioned(rName string, source string) string { policy := `{ "Version": "2012-10-17", "Statement": [ @@ -1998,7 +1998,7 @@ resource "aws_s3_object" "object" { `, rName, source) } -func testAccBucketObjectConfig_objectBucketKeyEnabled(rName string, content string) string { +func testAccObjectConfig_objectBucketKeyEnabled(rName string, content string) string { return fmt.Sprintf(` resource "aws_kms_key" "test" { description = "Encrypts test bucket objects" @@ -2019,7 +2019,7 @@ resource "aws_s3_object" "object" { `, rName, content) } -func testAccBucketObjectConfig_bucketBucketKeyEnabled(rName string, content string) string { +func testAccObjectConfig_bucketBucketKeyEnabled(rName string, content string) string { return fmt.Sprintf(` resource "aws_kms_key" "test" { description = "Encrypts test bucket objects" @@ -2048,7 +2048,7 @@ resource "aws_s3_object" "object" { `, rName, content) } -func testAccBucketObjectConfig_defaultBucketSSE(rName string, content string) string { +func testAccObjectConfig_defaultBucketSSE(rName string, content string) string { return fmt.Sprintf(` resource "aws_kms_key" "test" { description = "Encrypts test bucket objects" diff --git a/internal/service/s3/sweep.go b/internal/service/s3/sweep.go index a0d255169c2..18e0e8043a8 100644 --- a/internal/service/s3/sweep.go +++ b/internal/service/s3/sweep.go @@ -24,7 +24,7 @@ import ( func init() { resource.AddTestSweepers("aws_s3_object", &resource.Sweeper{ Name: "aws_s3_object", - F: sweepBucketObjects, + F: sweepObjects, }) resource.AddTestSweepers("aws_s3_bucket", &resource.Sweeper{ @@ -38,7 +38,7 @@ func init() { }) } -func sweepBucketObjects(region string) error { +func sweepObjects(region string) error { client, err := sweep.SharedRegionalSweepClient(region) if err != nil { return fmt.Errorf("error getting client: %s", err) From 2033587364efb0f4fec1291250ce904175458987 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 31 Jan 2022 12:40:39 -0500 Subject: [PATCH 109/116] Update sweeper --- internal/service/s3/sweep.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/s3/sweep.go b/internal/service/s3/sweep.go index 18e0e8043a8..7d4289bc336 100644 --- a/internal/service/s3/sweep.go +++ b/internal/service/s3/sweep.go @@ -93,7 +93,7 @@ func sweepObjects(region string) error { continue } - objectLockEnabled, err := bucketObjectLockEnabled(conn, bucketName) + objectLockEnabled, err := objectLockEnabled(conn, bucketName) if err != nil { log.Printf("[ERROR] Error getting S3 Bucket (%s) Object Lock: %s", bucketName, err) @@ -217,7 +217,7 @@ func bucketRegion(conn *s3.S3, bucket string) (string, error) { return region, nil } -func bucketObjectLockEnabled(conn *s3.S3, bucket string) (bool, error) { +func objectLockEnabled(conn *s3.S3, bucket string) (bool, error) { input := &s3.GetObjectLockConfigurationInput{ Bucket: aws.String(bucket), } From 2dad84e87d3324362a46a98865f8114649e906ae Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 31 Jan 2022 12:43:47 -0500 Subject: [PATCH 110/116] Update miscellaneous --- .semgrep.yml | 2 +- internal/service/s3/object.go | 4 ++-- internal/service/s3/object_copy.go | 2 +- internal/service/s3/object_copy_test.go | 4 ++-- internal/service/s3/object_test.go | 6 +++--- website/docs/r/s3_bucket.html.markdown | 2 +- website/docs/r/signer_signing_job.html.markdown | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.semgrep.yml b/.semgrep.yml index b9b3814753c..076d19b86e9 100644 --- a/.semgrep.yml +++ b/.semgrep.yml @@ -568,7 +568,7 @@ rules: - internal/service/mq/forge_test.go - internal/service/route53/sweep.go - internal/service/s3/bucket_test.go - - internal/service/s3/bucket_object_test.go + - internal/service/s3/object_test.go - internal/service/storagegateway/cached_iscsi_volume.go - internal/service/storagegateway/cached_iscsi_volume_test.go - internal/service/storagegateway/stored_iscsi_volume_test.go diff --git a/internal/service/s3/object.go b/internal/service/s3/object.go index 65c9ba7df2d..c9ea297dd73 100644 --- a/internal/service/s3/object.go +++ b/internal/service/s3/object.go @@ -262,7 +262,7 @@ func resourceObjectRead(d *schema.ResourceData, meta interface{}) error { d.Set("object_lock_retain_until_date", flattenS3ObjectDate(resp.ObjectLockRetainUntilDate)) if err := resourceObjectSetKMS(d, meta, resp.SSEKMSKeyId); err != nil { - return fmt.Errorf("bucket object KMS: %w", err) + return fmt.Errorf("object KMS: %w", err) } // See https://forums.aws.amazon.com/thread.jspa?threadID=44003 @@ -749,7 +749,7 @@ func DeleteAllObjectVersions(conn *s3.S3, bucketName, key string, force, ignoreO return nil } -// deleteS3ObjectVersion deletes a specific bucket object version. +// deleteS3ObjectVersion deletes a specific object version. // Set force to true to override any S3 object lock protections. func deleteS3ObjectVersion(conn *s3.S3, b, k, v string, force bool) error { input := &s3.DeleteObjectInput{ diff --git a/internal/service/s3/object_copy.go b/internal/service/s3/object_copy.go index df3a256345a..e010d45731a 100644 --- a/internal/service/s3/object_copy.go +++ b/internal/service/s3/object_copy.go @@ -350,7 +350,7 @@ func resourceObjectCopyRead(d *schema.ResourceData, meta interface{}) error { d.Set("object_lock_retain_until_date", flattenS3ObjectDate(resp.ObjectLockRetainUntilDate)) if err := resourceObjectSetKMS(d, meta, resp.SSEKMSKeyId); err != nil { - return fmt.Errorf("bucket object KMS: %w", err) + return fmt.Errorf("object KMS: %w", err) } // See https://forums.aws.amazon.com/thread.jspa?threadID=44003 diff --git a/internal/service/s3/object_copy_test.go b/internal/service/s3/object_copy_test.go index 5b17a595870..73f4efb790d 100644 --- a/internal/service/s3/object_copy_test.go +++ b/internal/service/s3/object_copy_test.go @@ -163,7 +163,7 @@ resource "aws_s3_object_copy" "test" { func testAccObjectCopyConfig_BucketKeyEnabled_Bucket(rName string) string { return fmt.Sprintf(` resource "aws_kms_key" "test" { - description = "Encrypts test bucket objects" + description = "Encrypts test objects" deletion_window_in_days = 7 } @@ -202,7 +202,7 @@ resource "aws_s3_object_copy" "test" { func testAccObjectCopyConfig_BucketKeyEnabled_Object(rName string) string { return fmt.Sprintf(` resource "aws_kms_key" "test" { - description = "Encrypts test bucket objects" + description = "Encrypts test objects" deletion_window_in_days = 7 } diff --git a/internal/service/s3/object_test.go b/internal/service/s3/object_test.go index b00ba882372..12e95f71c99 100644 --- a/internal/service/s3/object_test.go +++ b/internal/service/s3/object_test.go @@ -2001,7 +2001,7 @@ resource "aws_s3_object" "object" { func testAccObjectConfig_objectBucketKeyEnabled(rName string, content string) string { return fmt.Sprintf(` resource "aws_kms_key" "test" { - description = "Encrypts test bucket objects" + description = "Encrypts test objects" deletion_window_in_days = 7 } @@ -2022,7 +2022,7 @@ resource "aws_s3_object" "object" { func testAccObjectConfig_bucketBucketKeyEnabled(rName string, content string) string { return fmt.Sprintf(` resource "aws_kms_key" "test" { - description = "Encrypts test bucket objects" + description = "Encrypts test objects" deletion_window_in_days = 7 } @@ -2051,7 +2051,7 @@ resource "aws_s3_object" "object" { func testAccObjectConfig_defaultBucketSSE(rName string, content string) string { return fmt.Sprintf(` resource "aws_kms_key" "test" { - description = "Encrypts test bucket objects" + description = "Encrypts test objects" deletion_window_in_days = 7 } diff --git a/website/docs/r/s3_bucket.html.markdown b/website/docs/r/s3_bucket.html.markdown index 6e269c5c9b9..1aa05a81856 100644 --- a/website/docs/r/s3_bucket.html.markdown +++ b/website/docs/r/s3_bucket.html.markdown @@ -307,7 +307,7 @@ resource "aws_s3_bucket" "source" { ```terraform resource "aws_kms_key" "mykey" { - description = "This key is used to encrypt bucket objects" + description = "This key is used to encrypt objects" deletion_window_in_days = 10 } diff --git a/website/docs/r/signer_signing_job.html.markdown b/website/docs/r/signer_signing_job.html.markdown index 3022b433121..63eecd9afa4 100644 --- a/website/docs/r/signer_signing_job.html.markdown +++ b/website/docs/r/signer_signing_job.html.markdown @@ -57,7 +57,7 @@ The source configuration block supports the following arguments: The configuration block supports the following arguments: * `bucket` - (Required) Name of the S3 bucket. -* `key` - (Required) Key name of the bucket object that contains your unsigned code. +* `key` - (Required) Key name of the object that contains your unsigned code. * `version` - (Required) Version of your source image in your version enabled S3 bucket. ### Destination From 811c0c82fbb7fdad5c270136071fa5b4782c50ea Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 31 Jan 2022 12:47:32 -0500 Subject: [PATCH 111/116] Misc updates --- website/docs/d/s3_objects.html.markdown | 2 +- website/docs/r/cloudtrail.html.markdown | 2 +- website/docs/r/s3_object.html.markdown | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/website/docs/d/s3_objects.html.markdown b/website/docs/d/s3_objects.html.markdown index 1b488786070..7ae4c32cbf8 100644 --- a/website/docs/d/s3_objects.html.markdown +++ b/website/docs/d/s3_objects.html.markdown @@ -10,7 +10,7 @@ description: |- ~> **NOTE on `max_keys`:** Retrieving very large numbers of keys can adversely affect Terraform's performance. -The bucket-objects data source returns keys (i.e., file names) and other metadata about objects in an S3 bucket. +The objects data source returns keys (i.e., file names) and other metadata about objects in an S3 bucket. ## Example Usage diff --git a/website/docs/r/cloudtrail.html.markdown b/website/docs/r/cloudtrail.html.markdown index 279b5155578..363aadab7d9 100644 --- a/website/docs/r/cloudtrail.html.markdown +++ b/website/docs/r/cloudtrail.html.markdown @@ -151,7 +151,7 @@ resource "aws_cloudtrail" "example" { # ... other configuration ... advanced_event_selector { - name = "Log all S3 buckets objects events except for two S3 buckets" + name = "Log all S3 objects events except for two S3 buckets" field_selector { field = "eventCategory" diff --git a/website/docs/r/s3_object.html.markdown b/website/docs/r/s3_object.html.markdown index d690538279d..fad048f3b29 100644 --- a/website/docs/r/s3_object.html.markdown +++ b/website/docs/r/s3_object.html.markdown @@ -40,7 +40,7 @@ resource "aws_s3_bucket" "examplebucket" { acl = "private" } -resource "aws_s3_object" "examplebucket_object" { +resource "aws_s3_object" "example" { key = "someobject" bucket = aws_s3_bucket.examplebucket.id source = "index.html" @@ -56,7 +56,7 @@ resource "aws_s3_bucket" "examplebucket" { acl = "private" } -resource "aws_s3_object" "examplebucket_object" { +resource "aws_s3_object" "example" { key = "someobject" bucket = aws_s3_bucket.examplebucket.id source = "index.html" @@ -72,7 +72,7 @@ resource "aws_s3_bucket" "examplebucket" { acl = "private" } -resource "aws_s3_object" "examplebucket_object" { +resource "aws_s3_object" "example" { key = "someobject" bucket = aws_s3_bucket.examplebucket.id source = "index.html" @@ -96,7 +96,7 @@ resource "aws_s3_bucket" "examplebucket" { } } -resource "aws_s3_object" "examplebucket_object" { +resource "aws_s3_object" "example" { key = "someobject" bucket = aws_s3_bucket.examplebucket.id source = "important.txt" From 585486ee8956d633d0786e88dfecddcfdd5550c5 Mon Sep 17 00:00:00 2001 From: changelogbot Date: Mon, 31 Jan 2022 18:31:59 +0000 Subject: [PATCH 112/116] Update CHANGELOG.md for #22850 --- CHANGELOG.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3288f90022c..d3bf4ed3292 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,48 @@ NOTES: +* data-source/aws_cognito_user_pools: The type of the `ids` and `arns` attributes has changed from Set to List. If no volumes match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_db_event_categories: The type of the `ids` attribute has changed from Set to List. If no event categories match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_ebs_volumes: The type of the `ids` attribute has changed from Set to List. If no volumes match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_ec2_coip_pools: The type of the `pool_ids` attribute has changed from Set to List. If no COIP pools match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_ec2_local_gateway_route_tables: The type of the `ids` attribute has changed from Set to List. If no local gateway route tables match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_ec2_local_gateway_virtual_interface_groups: The type of the `ids` and `local_gateway_virtual_interface_ids` attributes has changed from Set to List. If no local gateway virtual interface groups match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_ec2_local_gateways: The type of the `ids` attribute has changed from Set to List. If no local gateways match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_ec2_transit_gateway_route_tables: The type of the `ids` attribute has changed from Set to List. If no transit gateway route tables match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_efs_access_points: The type of the `ids` and `arns` attributes has changed from Set to List. If no access points match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_emr_release_labels: The type of the `ids` attribute has changed from Set to List. If no release labels match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_inspector_rules_packages: If no rules packages match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_instances: If no instances match the specified criteria an empty list is returned (previously an error was raised) ([#5055](https://github.com/hashicorp/terraform-provider-aws/issues/5055)) +* data-source/aws_ip_ranges: If no ranges match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_network_acls: The type of the `ids` attribute has changed from Set to List. If no NACLs match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_network_interfaces: The type of the `ids` attribute has changed from Set to List. If no network interfaces match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_route_tables: The type of the `ids` attribute has changed from Set to List. If no route tables match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_security_groups: If no security groups match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_ssoadmin_instances: The type of the `identity_store_ids` and `arns` attributes has changed from Set to List. If no instances match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_vpcs: The type of the `ids` attributes has changed from Set to List. If no VPCs match the specified criteria an empty list is returned (previously an error was raised) ([#22253](https://github.com/hashicorp/terraform-provider-aws/issues/22253)) +* resource/aws_default_subnet: If no default subnet exists in the specified Availability Zone one is now created. The `force_destroy` destroy argument has been added (defaults to `false`). Setting this argument to `true` deletes the default subnet on `terraform destroy` ([#22253](https://github.com/hashicorp/terraform-provider-aws/issues/22253)) +* resource/aws_default_vpc: If no default VPC exists in the current AWS Region one is now created. The `force_destroy` destroy argument has been added (defaults to `false`). Setting this argument to `true` deletes the default VPC on `terraform destroy` ([#22253](https://github.com/hashicorp/terraform-provider-aws/issues/22253)) +* resource/aws_ecs_cluster: The `capacity_providers` and `default_capacity_provider_strategy` arguments have been deprecated. Use the `aws_ecs_cluster_capacity_providers` resource instead. ([#22783](https://github.com/hashicorp/terraform-provider-aws/issues/22783)) * resource/aws_route: The `instance_id` argument has been deprecated. All configurations using `instance_id` should be updated to use the `network_interface_id` argument instead ([#22664](https://github.com/hashicorp/terraform-provider-aws/issues/22664)) * resource/aws_route_table: The `instance_id` argument of the `route` configuration block has been deprecated. All configurations using `route` `instance_id` should be updated to use the `route` `network_interface_id` argument instead ([#22664](https://github.com/hashicorp/terraform-provider-aws/issues/22664)) +FEATURES: + +* **New Data Source:** `aws_eips` ([#7537](https://github.com/hashicorp/terraform-provider-aws/issues/7537)) +* **New Resource:** `aws_s3_bucket_cors_configuration` ([#12141](https://github.com/hashicorp/terraform-provider-aws/issues/12141)) +* **New Resource:** `aws_s3_bucket_versioning` ([#5132](https://github.com/hashicorp/terraform-provider-aws/issues/5132)) + +ENHANCEMENTS: + +* data-source/aws_cloudwatch_log_group: Automatically trim `:*` suffix from `arn` attribute ([#22043](https://github.com/hashicorp/terraform-provider-aws/issues/22043)) +* resource/aws_vpn_connection: Add the ability to revert changes to unconfigured tunnel options made outside of Terraform to their (documented default values)[(https://docs.aws.amazon.com/vpn/latest/s2svpn/VPNTunnels.html)] ([#17031](https://github.com/hashicorp/terraform-provider-aws/issues/17031)) +* resource/aws_vpn_connection: Mark `customer_gateway_configuration` as [`Sensitive`](https://www.terraform.io/plugin/sdkv2/best-practices/sensitive-state#using-the-sensitive-flag) ([#15806](https://github.com/hashicorp/terraform-provider-aws/issues/15806)) + +BUG FIXES: + +* data-source/aws_vpc_peering_connections: Return empty array instead of error when no connections found. ([#17382](https://github.com/hashicorp/terraform-provider-aws/issues/17382)) +* resource/aws_route_table_association: Handle nil 'AssociationState' in ISO regions ([#22806](https://github.com/hashicorp/terraform-provider-aws/issues/22806)) + ## 3.75.0 (Unreleased) ENHANCEMENTS: From 3b9388413d6e83d6dbbcd044e72bde8f26614157 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Mon, 31 Jan 2022 15:09:50 -0500 Subject: [PATCH 113/116] run gofmt after rebase --- internal/service/ec2/errors.go | 110 ++++++++++++++++----------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/internal/service/ec2/errors.go b/internal/service/ec2/errors.go index 6c4bf62c7da..a3459abd609 100644 --- a/internal/service/ec2/errors.go +++ b/internal/service/ec2/errors.go @@ -10,65 +10,65 @@ import ( ) const ( - ErrCodeAuthFailure = "AuthFailure" - ErrCodeClientInvalidHostIDNotFound = "Client.InvalidHostID.NotFound" + ErrCodeAuthFailure = "AuthFailure" + ErrCodeClientInvalidHostIDNotFound = "Client.InvalidHostID.NotFound" ErrCodeDefaultSubnetAlreadyExistsInAvailabilityZone = "DefaultSubnetAlreadyExistsInAvailabilityZone" - ErrCodeDependencyViolation = "DependencyViolation" - ErrCodeGatewayNotAttached = "Gateway.NotAttached" - ErrCodeIncorrectState = "IncorrectState" + ErrCodeDependencyViolation = "DependencyViolation" + ErrCodeGatewayNotAttached = "Gateway.NotAttached" + ErrCodeIncorrectState = "IncorrectState" ErrCodeInvalidAddressNotFound = "InvalidAddress.NotFound" ErrCodeInvalidAllocationIDNotFound = "InvalidAllocationID.NotFound" - ErrCodeInvalidAssociationIDNotFound = "InvalidAssociationID.NotFound" - ErrCodeInvalidAttachmentIDNotFound = "InvalidAttachmentID.NotFound" - ErrCodeInvalidCarrierGatewayIDNotFound = "InvalidCarrierGatewayID.NotFound" - ErrCodeInvalidClientVpnAssociationIdNotFound = "InvalidClientVpnAssociationId.NotFound" - ErrCodeInvalidClientVpnAuthorizationRuleNotFound = "InvalidClientVpnEndpointAuthorizationRuleNotFound" - ErrCodeInvalidClientVpnEndpointIdNotFound = "InvalidClientVpnEndpointId.NotFound" - ErrCodeInvalidClientVpnRouteNotFound = "InvalidClientVpnRouteNotFound" - ErrCodeInvalidCustomerGatewayIDNotFound = "InvalidCustomerGatewayID.NotFound" - ErrCodeInvalidDhcpOptionIDNotFound = "InvalidDhcpOptionID.NotFound" - ErrCodeInvalidFlowLogIdNotFound = "InvalidFlowLogId.NotFound" - ErrCodeInvalidGatewayIDNotFound = "InvalidGatewayID.NotFound" - ErrCodeInvalidGroupNotFound = "InvalidGroup.NotFound" - ErrCodeInvalidHostIDNotFound = "InvalidHostID.NotFound" - ErrCodeInvalidInstanceIDNotFound = "InvalidInstanceID.NotFound" - ErrCodeInvalidInternetGatewayIDNotFound = "InvalidInternetGatewayID.NotFound" - ErrCodeInvalidKeyPairNotFound = "InvalidKeyPair.NotFound" - ErrCodeInvalidNetworkAclIDNotFound = "InvalidNetworkAclID.NotFound" - ErrCodeInvalidNetworkInterfaceIDNotFound = "InvalidNetworkInterfaceID.NotFound" - ErrCodeInvalidParameter = "InvalidParameter" - ErrCodeInvalidParameterException = "InvalidParameterException" - ErrCodeInvalidParameterValue = "InvalidParameterValue" - ErrCodeInvalidPermissionDuplicate = "InvalidPermission.Duplicate" - ErrCodeInvalidPermissionMalformed = "InvalidPermission.Malformed" - ErrCodeInvalidPermissionNotFound = "InvalidPermission.NotFound" - ErrCodeInvalidPlacementGroupUnknown = "InvalidPlacementGroup.Unknown" + ErrCodeInvalidAssociationIDNotFound = "InvalidAssociationID.NotFound" + ErrCodeInvalidAttachmentIDNotFound = "InvalidAttachmentID.NotFound" + ErrCodeInvalidCarrierGatewayIDNotFound = "InvalidCarrierGatewayID.NotFound" + ErrCodeInvalidClientVpnAssociationIdNotFound = "InvalidClientVpnAssociationId.NotFound" + ErrCodeInvalidClientVpnAuthorizationRuleNotFound = "InvalidClientVpnEndpointAuthorizationRuleNotFound" + ErrCodeInvalidClientVpnEndpointIdNotFound = "InvalidClientVpnEndpointId.NotFound" + ErrCodeInvalidClientVpnRouteNotFound = "InvalidClientVpnRouteNotFound" + ErrCodeInvalidCustomerGatewayIDNotFound = "InvalidCustomerGatewayID.NotFound" + ErrCodeInvalidDhcpOptionIDNotFound = "InvalidDhcpOptionID.NotFound" + ErrCodeInvalidFlowLogIdNotFound = "InvalidFlowLogId.NotFound" + ErrCodeInvalidGatewayIDNotFound = "InvalidGatewayID.NotFound" + ErrCodeInvalidGroupNotFound = "InvalidGroup.NotFound" + ErrCodeInvalidHostIDNotFound = "InvalidHostID.NotFound" + ErrCodeInvalidInstanceIDNotFound = "InvalidInstanceID.NotFound" + ErrCodeInvalidInternetGatewayIDNotFound = "InvalidInternetGatewayID.NotFound" + ErrCodeInvalidKeyPairNotFound = "InvalidKeyPair.NotFound" + ErrCodeInvalidNetworkAclIDNotFound = "InvalidNetworkAclID.NotFound" + ErrCodeInvalidNetworkInterfaceIDNotFound = "InvalidNetworkInterfaceID.NotFound" + ErrCodeInvalidParameter = "InvalidParameter" + ErrCodeInvalidParameterException = "InvalidParameterException" + ErrCodeInvalidParameterValue = "InvalidParameterValue" + ErrCodeInvalidPermissionDuplicate = "InvalidPermission.Duplicate" + ErrCodeInvalidPermissionMalformed = "InvalidPermission.Malformed" + ErrCodeInvalidPermissionNotFound = "InvalidPermission.NotFound" + ErrCodeInvalidPlacementGroupUnknown = "InvalidPlacementGroup.Unknown" ErrCodeInvalidPoolIDNotFound = "InvalidPoolID.NotFound" - ErrCodeInvalidPrefixListIDNotFound = "InvalidPrefixListID.NotFound" - ErrCodeInvalidRouteNotFound = "InvalidRoute.NotFound" - ErrCodeInvalidRouteTableIDNotFound = "InvalidRouteTableID.NotFound" - ErrCodeInvalidRouteTableIdNotFound = "InvalidRouteTableId.NotFound" - ErrCodeInvalidSecurityGroupIDNotFound = "InvalidSecurityGroupID.NotFound" - ErrCodeInvalidSnapshotInUse = "InvalidSnapshot.InUse" - ErrCodeInvalidSnapshotNotFound = "InvalidSnapshot.NotFound" - ErrCodeInvalidSpotInstanceRequestIDNotFound = "InvalidSpotInstanceRequestID.NotFound" - ErrCodeInvalidSubnetCidrReservationIDNotFound = "InvalidSubnetCidrReservationID.NotFound" - ErrCodeInvalidSubnetIDNotFound = "InvalidSubnetID.NotFound" - ErrCodeInvalidSubnetIdNotFound = "InvalidSubnetId.NotFound" - ErrCodeInvalidTransitGatewayAttachmentIDNotFound = "InvalidTransitGatewayAttachmentID.NotFound" - ErrCodeInvalidTransitGatewayIDNotFound = "InvalidTransitGatewayID.NotFound" - ErrCodeInvalidVolumeNotFound = "InvalidVolume.NotFound" - ErrCodeInvalidVpcCidrBlockAssociationIDNotFound = "InvalidVpcCidrBlockAssociationID.NotFound" - ErrCodeInvalidVpcEndpointIdNotFound = "InvalidVpcEndpointId.NotFound" - ErrCodeInvalidVpcEndpointNotFound = "InvalidVpcEndpoint.NotFound" - ErrCodeInvalidVpcEndpointServiceIdNotFound = "InvalidVpcEndpointServiceId.NotFound" - ErrCodeInvalidVpcIDNotFound = "InvalidVpcID.NotFound" - ErrCodeInvalidVpcPeeringConnectionIDNotFound = "InvalidVpcPeeringConnectionID.NotFound" - ErrCodeInvalidVpnConnectionIDNotFound = "InvalidVpnConnectionID.NotFound" - ErrCodeInvalidVpnGatewayAttachmentNotFound = "InvalidVpnGatewayAttachment.NotFound" - ErrCodeInvalidVpnGatewayIDNotFound = "InvalidVpnGatewayID.NotFound" - ErrCodeNatGatewayNotFound = "NatGatewayNotFound" - ErrCodeUnsupportedOperation = "UnsupportedOperation" + ErrCodeInvalidPrefixListIDNotFound = "InvalidPrefixListID.NotFound" + ErrCodeInvalidRouteNotFound = "InvalidRoute.NotFound" + ErrCodeInvalidRouteTableIDNotFound = "InvalidRouteTableID.NotFound" + ErrCodeInvalidRouteTableIdNotFound = "InvalidRouteTableId.NotFound" + ErrCodeInvalidSecurityGroupIDNotFound = "InvalidSecurityGroupID.NotFound" + ErrCodeInvalidSnapshotInUse = "InvalidSnapshot.InUse" + ErrCodeInvalidSnapshotNotFound = "InvalidSnapshot.NotFound" + ErrCodeInvalidSpotInstanceRequestIDNotFound = "InvalidSpotInstanceRequestID.NotFound" + ErrCodeInvalidSubnetCidrReservationIDNotFound = "InvalidSubnetCidrReservationID.NotFound" + ErrCodeInvalidSubnetIDNotFound = "InvalidSubnetID.NotFound" + ErrCodeInvalidSubnetIdNotFound = "InvalidSubnetId.NotFound" + ErrCodeInvalidTransitGatewayAttachmentIDNotFound = "InvalidTransitGatewayAttachmentID.NotFound" + ErrCodeInvalidTransitGatewayIDNotFound = "InvalidTransitGatewayID.NotFound" + ErrCodeInvalidVolumeNotFound = "InvalidVolume.NotFound" + ErrCodeInvalidVpcCidrBlockAssociationIDNotFound = "InvalidVpcCidrBlockAssociationID.NotFound" + ErrCodeInvalidVpcEndpointIdNotFound = "InvalidVpcEndpointId.NotFound" + ErrCodeInvalidVpcEndpointNotFound = "InvalidVpcEndpoint.NotFound" + ErrCodeInvalidVpcEndpointServiceIdNotFound = "InvalidVpcEndpointServiceId.NotFound" + ErrCodeInvalidVpcIDNotFound = "InvalidVpcID.NotFound" + ErrCodeInvalidVpcPeeringConnectionIDNotFound = "InvalidVpcPeeringConnectionID.NotFound" + ErrCodeInvalidVpnConnectionIDNotFound = "InvalidVpnConnectionID.NotFound" + ErrCodeInvalidVpnGatewayAttachmentNotFound = "InvalidVpnGatewayAttachment.NotFound" + ErrCodeInvalidVpnGatewayIDNotFound = "InvalidVpnGatewayID.NotFound" + ErrCodeNatGatewayNotFound = "NatGatewayNotFound" + ErrCodeUnsupportedOperation = "UnsupportedOperation" ) func UnsuccessfulItemError(apiObject *ec2.UnsuccessfulItemError) error { From 0f8ee5649f92bfd1eae1fde809cde6d63953df38 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Mon, 31 Jan 2022 15:44:04 -0500 Subject: [PATCH 114/116] fix link in changelog entry --- .changelog/17031.txt | 2 +- CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.changelog/17031.txt b/.changelog/17031.txt index 3d63f7be1cb..bfab8bf79bc 100644 --- a/.changelog/17031.txt +++ b/.changelog/17031.txt @@ -1,3 +1,3 @@ ```release-note:enhancement -resource/aws_vpn_connection: Add the ability to revert changes to unconfigured tunnel options made outside of Terraform to their (documented default values)[(https://docs.aws.amazon.com/vpn/latest/s2svpn/VPNTunnels.html)] +resource/aws_vpn_connection: Add the ability to revert changes to unconfigured tunnel options made outside of Terraform to their [documented default values](https://docs.aws.amazon.com/vpn/latest/s2svpn/VPNTunnels.html) ``` \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index d3bf4ed3292..1a105a6a06a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,7 @@ FEATURES: ENHANCEMENTS: * data-source/aws_cloudwatch_log_group: Automatically trim `:*` suffix from `arn` attribute ([#22043](https://github.com/hashicorp/terraform-provider-aws/issues/22043)) -* resource/aws_vpn_connection: Add the ability to revert changes to unconfigured tunnel options made outside of Terraform to their (documented default values)[(https://docs.aws.amazon.com/vpn/latest/s2svpn/VPNTunnels.html)] ([#17031](https://github.com/hashicorp/terraform-provider-aws/issues/17031)) +* resource/aws_vpn_connection: Add the ability to revert changes to unconfigured tunnel options made outside of Terraform to their [documented default values](https://docs.aws.amazon.com/vpn/latest/s2svpn/VPNTunnels.html) ([#17031](https://github.com/hashicorp/terraform-provider-aws/issues/17031)) * resource/aws_vpn_connection: Mark `customer_gateway_configuration` as [`Sensitive`](https://www.terraform.io/plugin/sdkv2/best-practices/sensitive-state#using-the-sensitive-flag) ([#15806](https://github.com/hashicorp/terraform-provider-aws/issues/15806)) BUG FIXES: From 36ce5ae5f0b1d8ae1b6af64019a4943dc6ddbfc7 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Mon, 31 Jan 2022 16:15:51 -0500 Subject: [PATCH 115/116] add changelog entry for renamed resource/data-source --- .changelog/22850.txt | 11 +++++++++++ CHANGELOG.md | 3 +++ 2 files changed, 14 insertions(+) create mode 100644 .changelog/22850.txt diff --git a/.changelog/22850.txt b/.changelog/22850.txt new file mode 100644 index 00000000000..c19e2ea16c0 --- /dev/null +++ b/.changelog/22850.txt @@ -0,0 +1,11 @@ +```release-note:note +data-source/aws_s3_bucket_object: The data source has been renamed. Use `aws_s3_object` instead +``` + +```release-note:note +data-source/aws_s3_bucket_objects: The data source has been renamed. Use `aws_s3_objects` instead +``` + +```release-note:note +resource/aws_s3_bucket_object: The resource has been renamed. Use `aws_s3_object` instead +``` diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a105a6a06a..4ab89d9840d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ NOTES: * data-source/aws_network_acls: The type of the `ids` attribute has changed from Set to List. If no NACLs match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) * data-source/aws_network_interfaces: The type of the `ids` attribute has changed from Set to List. If no network interfaces match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) * data-source/aws_route_tables: The type of the `ids` attribute has changed from Set to List. If no route tables match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) +* data-source/aws_s3_bucket_object: The data source has been renamed. Use `aws_s3_object` instead ([#22850](https://github.com/hashicorp/terraform-provider-aws/issues/22850)) +* data-source/aws_s3_bucket_objects: The data source has been renamed. Use `aws_s3_objects` instead ([#22850](https://github.com/hashicorp/terraform-provider-aws/issues/22850)) * data-source/aws_security_groups: If no security groups match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) * data-source/aws_ssoadmin_instances: The type of the `identity_store_ids` and `arns` attributes has changed from Set to List. If no instances match the specified criteria an empty list is returned (previously an error was raised) ([#21219](https://github.com/hashicorp/terraform-provider-aws/issues/21219)) * data-source/aws_vpcs: The type of the `ids` attributes has changed from Set to List. If no VPCs match the specified criteria an empty list is returned (previously an error was raised) ([#22253](https://github.com/hashicorp/terraform-provider-aws/issues/22253)) @@ -26,6 +28,7 @@ NOTES: * resource/aws_ecs_cluster: The `capacity_providers` and `default_capacity_provider_strategy` arguments have been deprecated. Use the `aws_ecs_cluster_capacity_providers` resource instead. ([#22783](https://github.com/hashicorp/terraform-provider-aws/issues/22783)) * resource/aws_route: The `instance_id` argument has been deprecated. All configurations using `instance_id` should be updated to use the `network_interface_id` argument instead ([#22664](https://github.com/hashicorp/terraform-provider-aws/issues/22664)) * resource/aws_route_table: The `instance_id` argument of the `route` configuration block has been deprecated. All configurations using `route` `instance_id` should be updated to use the `route` `network_interface_id` argument instead ([#22664](https://github.com/hashicorp/terraform-provider-aws/issues/22664)) +* resource/aws_s3_bucket_object: The resource has been renamed. Use `aws_s3_object` instead ([#22850](https://github.com/hashicorp/terraform-provider-aws/issues/22850)) FEATURES: From b6c3481e99f1925cd17a7ed584b132fd15181576 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Mon, 31 Jan 2022 17:11:27 -0500 Subject: [PATCH 116/116] remove 3.75.0 section to allow those entries be regenerated into the upcoming 4.0.0 release --- CHANGELOG.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ab89d9840d..9229b42ff04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,18 +47,6 @@ BUG FIXES: * data-source/aws_vpc_peering_connections: Return empty array instead of error when no connections found. ([#17382](https://github.com/hashicorp/terraform-provider-aws/issues/17382)) * resource/aws_route_table_association: Handle nil 'AssociationState' in ISO regions ([#22806](https://github.com/hashicorp/terraform-provider-aws/issues/22806)) -## 3.75.0 (Unreleased) - -ENHANCEMENTS: - -* data-source/aws_imagebuilder_distribution_configuration: Add `container_distribution_configuration` attribute to the `distribution` configuration block ([#22838](https://github.com/hashicorp/terraform-provider-aws/issues/22838)) -* resource/aws_imagebuilder_image_recipe: Add `parameter` argument to the `component` configuration block ([#22837](https://github.com/hashicorp/terraform-provider-aws/issues/22837)) - -BUG FIXES: - -* resource/aws_cloudformation_stack: Retry resource Create and Update for IAM eventual consistency ([#22840](https://github.com/hashicorp/terraform-provider-aws/issues/22840)) -* resource/aws_route_table_association: Handle nil 'AssociationState' in ISO regions ([#22806](https://github.com/hashicorp/terraform-provider-aws/issues/22806)) - ## 3.74.0 (January 28, 2022) FEATURES: