From fda740c6abcd178d05c587e8e64f2bc7fef08a82 Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Mon, 11 Dec 2023 22:14:18 +0200 Subject: [PATCH 01/25] Add file system id attribute to destination block of aws_efs_replication_configuration resource Signed-off-by: Yaron Yarimi --- internal/service/efs/replication_configuration.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/service/efs/replication_configuration.go b/internal/service/efs/replication_configuration.go index f8783a732d1b..deebe6dd6d05 100644 --- a/internal/service/efs/replication_configuration.go +++ b/internal/service/efs/replication_configuration.go @@ -55,7 +55,8 @@ func ResourceReplicationConfiguration() *schema.Resource { }, "file_system_id": { Type: schema.TypeString, - Computed: true, + Optional: true, + ForceNew: true, }, "kms_key_id": { Type: schema.TypeString, @@ -220,6 +221,10 @@ func expandDestinationToCreate(tfMap map[string]interface{}) *efs.DestinationToC apiObject.Region = aws.String(v) } + if v, ok := tfMap["file_system_id"].(string); ok && v != "" { + apiObject.FileSystemId = aws.String(v) + } + return apiObject } From a3aea41b15bf06c29e699f6be7b2daaa510cf03b Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Sat, 16 Dec 2023 22:09:40 +0200 Subject: [PATCH 02/25] Update docs Signed-off-by: Yaron Yarimi --- .../efs_replication_configuration.html.markdown | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/website/docs/r/efs_replication_configuration.html.markdown b/website/docs/r/efs_replication_configuration.html.markdown index f37cf52d0294..9adccc92aee9 100644 --- a/website/docs/r/efs_replication_configuration.html.markdown +++ b/website/docs/r/efs_replication_configuration.html.markdown @@ -42,6 +42,21 @@ resource "aws_efs_replication_configuration" "example" { } ``` +Will create a replica on top of the existing file system with id `fs-1234567890` in us-west-2. + +```terraform +resource "aws_efs_file_system" "example" {} + +resource "aws_efs_replication_configuration" "example" { + source_file_system_id = aws_efs_file_system.example.id + + destination { + availability_zone_name = "fs-1234567890" + region = "us-west-2" + } +} +``` + ## Argument Reference This resource supports the following arguments: @@ -56,6 +71,7 @@ This resource supports the following arguments: * `availability_zone_name` - (Optional) The availability zone in which the replica should be created. If specified, the replica will be created with One Zone storage. If omitted, regional storage will be used. * `kms_key_id` - (Optional) The Key ID, ARN, alias, or alias ARN of the KMS key that should be used to encrypt the replica file system. If omitted, the default KMS key for EFS `/aws/elasticfilesystem` will be used. * `region` - (Optional) The region in which the replica should be created. +* `file_system_id` - (Optional) The ID of the destination file system for the replication. If no ID is provided, then EFS creates a new file system with the default settings. ## Attribute Reference From 3cacabb791e23216521fc0d6f1c83090cc1e574b Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Sat, 16 Dec 2023 22:41:33 +0200 Subject: [PATCH 03/25] set the destination.file_system_id attribute as computed again Signed-off-by: Yaron Yarimi --- internal/service/efs/replication_configuration.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/service/efs/replication_configuration.go b/internal/service/efs/replication_configuration.go index deebe6dd6d05..5daf8b017a57 100644 --- a/internal/service/efs/replication_configuration.go +++ b/internal/service/efs/replication_configuration.go @@ -55,6 +55,7 @@ func ResourceReplicationConfiguration() *schema.Resource { }, "file_system_id": { Type: schema.TypeString, + Computed: true, Optional: true, ForceNew: true, }, From 3d043a415958630ac7839651381abef91d50ba9b Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Sat, 16 Dec 2023 22:44:00 +0200 Subject: [PATCH 04/25] Add small note about `destination.file_system_id` attr Signed-off-by: Yaron Yarimi --- website/docs/r/efs_replication_configuration.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/efs_replication_configuration.html.markdown b/website/docs/r/efs_replication_configuration.html.markdown index 9adccc92aee9..cdb4e824e6d8 100644 --- a/website/docs/r/efs_replication_configuration.html.markdown +++ b/website/docs/r/efs_replication_configuration.html.markdown @@ -7,7 +7,7 @@ description: Provides an Elastic File System (EFS) Replication Configuration. # Resource: aws_efs_replication_configuration -Creates a replica of an existing EFS file system in the same or another region. Creating this resource causes the source EFS file system to be replicated to a new read-only destination EFS file system. Deleting this resource will cause the replication from source to destination to stop and the destination file system will no longer be read only. +Creates a replica of an existing EFS file system in the same or another region. Creating this resource causes the source EFS file system to be replicated to a new read-only destination EFS file system (unless using the `destination.file_system_id` attribute). Deleting this resource will cause the replication from source to destination to stop and the destination file system will no longer be read only. ~> **NOTE:** Deleting this resource does **not** delete the destination file system that was created. From 86cbc1d7f1179b8f0daf89dcf0f41462a9f68fb2 Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Sat, 16 Dec 2023 22:44:42 +0200 Subject: [PATCH 05/25] Refine docs about `destination.file_system_id` Signed-off-by: Yaron Yarimi --- website/docs/r/efs_replication_configuration.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/efs_replication_configuration.html.markdown b/website/docs/r/efs_replication_configuration.html.markdown index cdb4e824e6d8..2af318a7ca62 100644 --- a/website/docs/r/efs_replication_configuration.html.markdown +++ b/website/docs/r/efs_replication_configuration.html.markdown @@ -42,7 +42,7 @@ resource "aws_efs_replication_configuration" "example" { } ``` -Will create a replica on top of the existing file system with id `fs-1234567890` in us-west-2. +Will create a replica on and set the existing file system with id `fs-1234567890` in us-west-2 as destination. ```terraform resource "aws_efs_file_system" "example" {} From 8087b6795d0f8f89fb4b6b6c5fb19e4af4ab1b78 Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Sat, 16 Dec 2023 23:05:26 +0200 Subject: [PATCH 06/25] Add tests for destination.file_system_id attr usage Signed-off-by: Yaron Yarimi --- .../efs/replication_configuration_test.go | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/internal/service/efs/replication_configuration_test.go b/internal/service/efs/replication_configuration_test.go index 11f136a707f8..e6d4f9e876cc 100644 --- a/internal/service/efs/replication_configuration_test.go +++ b/internal/service/efs/replication_configuration_test.go @@ -129,6 +129,39 @@ func TestAccEFSReplicationConfiguration_allAttributes(t *testing.T) { }) } +func TestAccEFSReplicationConfiguration_existingDestination(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + resourceName := "aws_efs_replication_configuration.test" + destinationFsResourceName := "aws_efs_file_system.destination" + var providers []*schema.Provider + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckMultipleRegion(t, 2) + }, + ErrorCheck: acctest.ErrorCheck(t, efs.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5FactoriesPlusProvidersAlternate(ctx, t, &providers), + CheckDestroy: acctest.CheckWithProviders(testAccCheckReplicationConfigurationDestroyWithProvider(ctx), &providers), + Steps: []resource.TestStep{ + { + Config: testAccReplicationConfigurationConfig_existingDestination(), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckReplicationConfigurationExists(ctx, resourceName), + resource.TestCheckResourceAttrSet(resourceName, "creation_time"), + resource.TestCheckResourceAttr(resourceName, "destination.#", "1"), + resource.TestCheckResourceAttrPair(resourceName, "destination.0.file_system_id", destinationFsResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "destination.0.status", efs.ReplicationStatusEnabled), + ), + }, + }, + }) +} + func testAccCheckReplicationConfigurationExists(ctx context.Context, n string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] @@ -188,6 +221,22 @@ resource "aws_efs_replication_configuration" "test" { `, region) } +func testAccReplicationConfigurationConfig_existingDestination() string { + return fmt.Sprintf(` +resource "aws_efs_file_system" "source" {} + +resource "aws_efs_file_system" "destination" {} + +resource "aws_efs_replication_configuration" "test" { + source_file_system_id = aws_efs_file_system.source.id + + destination { + file_system_id = aws_efs_file_system.destination.id + } +} +`) +} + func testAccReplicationConfigurationConfig_full(region string) string { return acctest.ConfigCompose(acctest.ConfigAlternateRegionProvider(), fmt.Sprintf(` resource "aws_kms_key" "test" { From f4443e3dd989d64ab40f1043af97b27ab534ae9e Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Sat, 16 Dec 2023 23:06:17 +0200 Subject: [PATCH 07/25] Fix typo Signed-off-by: Yaron Yarimi --- website/docs/r/efs_replication_configuration.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/efs_replication_configuration.html.markdown b/website/docs/r/efs_replication_configuration.html.markdown index 2af318a7ca62..135bbd0daa14 100644 --- a/website/docs/r/efs_replication_configuration.html.markdown +++ b/website/docs/r/efs_replication_configuration.html.markdown @@ -42,7 +42,7 @@ resource "aws_efs_replication_configuration" "example" { } ``` -Will create a replica on and set the existing file system with id `fs-1234567890` in us-west-2 as destination. +Will create a replica and set the existing file system with id `fs-1234567890` in us-west-2 as destination. ```terraform resource "aws_efs_file_system" "example" {} From 8b05dc2558ee5c0e41562cbea2901cd09a3098e1 Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Sat, 16 Dec 2023 23:25:55 +0200 Subject: [PATCH 08/25] Fix test to include the region attribute Signed-off-by: Yaron Yarimi --- internal/service/efs/replication_configuration_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/service/efs/replication_configuration_test.go b/internal/service/efs/replication_configuration_test.go index e6d4f9e876cc..0485b790c99f 100644 --- a/internal/service/efs/replication_configuration_test.go +++ b/internal/service/efs/replication_configuration_test.go @@ -149,7 +149,7 @@ func TestAccEFSReplicationConfiguration_existingDestination(t *testing.T) { CheckDestroy: acctest.CheckWithProviders(testAccCheckReplicationConfigurationDestroyWithProvider(ctx), &providers), Steps: []resource.TestStep{ { - Config: testAccReplicationConfigurationConfig_existingDestination(), + Config: testAccReplicationConfigurationConfig_existingDestination(acctest.Region()), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckReplicationConfigurationExists(ctx, resourceName), resource.TestCheckResourceAttrSet(resourceName, "creation_time"), @@ -221,7 +221,7 @@ resource "aws_efs_replication_configuration" "test" { `, region) } -func testAccReplicationConfigurationConfig_existingDestination() string { +func testAccReplicationConfigurationConfig_existingDestination(region string) string { return fmt.Sprintf(` resource "aws_efs_file_system" "source" {} @@ -232,9 +232,10 @@ resource "aws_efs_replication_configuration" "test" { destination { file_system_id = aws_efs_file_system.destination.id + region = %[1]q } } -`) +`, region) } func testAccReplicationConfigurationConfig_full(region string) string { From a7d50118dd5584ef3c39c0666b22993c135fdb21 Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Thu, 4 Jan 2024 22:42:28 +0200 Subject: [PATCH 09/25] Disable efs replication overwrite protection for existing EFS replication test Signed-off-by: Yaron Yarimi --- internal/service/efs/replication_configuration_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/service/efs/replication_configuration_test.go b/internal/service/efs/replication_configuration_test.go index 0485b790c99f..e8e813fa348b 100644 --- a/internal/service/efs/replication_configuration_test.go +++ b/internal/service/efs/replication_configuration_test.go @@ -225,7 +225,11 @@ func testAccReplicationConfigurationConfig_existingDestination(region string) st return fmt.Sprintf(` resource "aws_efs_file_system" "source" {} -resource "aws_efs_file_system" "destination" {} +resource "aws_efs_file_system" "destination" { + protection { + replication_overwrite = "DISABLED" + } +} resource "aws_efs_replication_configuration" "test" { source_file_system_id = aws_efs_file_system.source.id From 6915fa569c1b096fa129d9496416bfc7db226b33 Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Thu, 4 Jan 2024 22:49:47 +0200 Subject: [PATCH 10/25] Format EFS replication test using terrafmt Signed-off-by: Yaron Yarimi --- internal/service/efs/replication_configuration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/efs/replication_configuration_test.go b/internal/service/efs/replication_configuration_test.go index e8e813fa348b..7e8b60b3ebcc 100644 --- a/internal/service/efs/replication_configuration_test.go +++ b/internal/service/efs/replication_configuration_test.go @@ -236,7 +236,7 @@ resource "aws_efs_replication_configuration" "test" { destination { file_system_id = aws_efs_file_system.destination.id - region = %[1]q + region = %[1]q } } `, region) From 8ba3534cf226948e7f30ff7144fa0bd4ab7ee369 Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Sat, 6 Jan 2024 23:33:02 +0200 Subject: [PATCH 11/25] Increase default time out of EFS replication creation to 20m Signed-off-by: Yaron Yarimi --- internal/service/efs/replication_configuration.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/efs/replication_configuration.go b/internal/service/efs/replication_configuration.go index 5daf8b017a57..61650861d8ab 100644 --- a/internal/service/efs/replication_configuration.go +++ b/internal/service/efs/replication_configuration.go @@ -31,7 +31,7 @@ func ResourceReplicationConfiguration() *schema.Resource { }, Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(10 * time.Minute), + Create: schema.DefaultTimeout(20 * time.Minute), Delete: schema.DefaultTimeout(20 * time.Minute), }, From 8562c73c0cf5aacec046c1d12468669bc1702843 Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Sat, 6 Jan 2024 23:33:34 +0200 Subject: [PATCH 12/25] Fix EFS replication existing file system test to ignore changes Signed-off-by: Yaron Yarimi --- internal/service/efs/replication_configuration_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/service/efs/replication_configuration_test.go b/internal/service/efs/replication_configuration_test.go index 7e8b60b3ebcc..fbb050eb9f0f 100644 --- a/internal/service/efs/replication_configuration_test.go +++ b/internal/service/efs/replication_configuration_test.go @@ -229,6 +229,9 @@ resource "aws_efs_file_system" "destination" { protection { replication_overwrite = "DISABLED" } + lifecycle { + ignore_changes = [protection] + } } resource "aws_efs_replication_configuration" "test" { From bbbedd8a1cdd567cd490086bc2aa37ce8a071909 Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Sat, 6 Jan 2024 23:45:26 +0200 Subject: [PATCH 13/25] Run terrafmt to lint test file Signed-off-by: Yaron Yarimi --- internal/service/efs/replication_configuration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/efs/replication_configuration_test.go b/internal/service/efs/replication_configuration_test.go index fbb050eb9f0f..6e33cf241a4f 100644 --- a/internal/service/efs/replication_configuration_test.go +++ b/internal/service/efs/replication_configuration_test.go @@ -239,7 +239,7 @@ resource "aws_efs_replication_configuration" "test" { destination { file_system_id = aws_efs_file_system.destination.id - region = %[1]q + region = %[1]q } } `, region) From 9df713d8d57f7534cab738c11513c7392a3c948b Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Sun, 7 Jan 2024 00:46:24 +0200 Subject: [PATCH 14/25] Have the destination file system of the replication created on the alternate region Signed-off-by: Yaron Yarimi --- internal/service/efs/replication_configuration_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/service/efs/replication_configuration_test.go b/internal/service/efs/replication_configuration_test.go index 6e33cf241a4f..6962c8d0ab46 100644 --- a/internal/service/efs/replication_configuration_test.go +++ b/internal/service/efs/replication_configuration_test.go @@ -226,6 +226,7 @@ func testAccReplicationConfigurationConfig_existingDestination(region string) st resource "aws_efs_file_system" "source" {} resource "aws_efs_file_system" "destination" { + provider = "awsalternate" protection { replication_overwrite = "DISABLED" } From 13b9fa2c145ff391b2e52c41da1aab82a480c43f Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Sun, 7 Jan 2024 00:50:58 +0200 Subject: [PATCH 15/25] Fix file_system_id EFS replication usage docs example Signed-off-by: Yaron Yarimi --- website/docs/r/efs_replication_configuration.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/docs/r/efs_replication_configuration.html.markdown b/website/docs/r/efs_replication_configuration.html.markdown index 135bbd0daa14..0baae1e20ccd 100644 --- a/website/docs/r/efs_replication_configuration.html.markdown +++ b/website/docs/r/efs_replication_configuration.html.markdown @@ -51,8 +51,8 @@ resource "aws_efs_replication_configuration" "example" { source_file_system_id = aws_efs_file_system.example.id destination { - availability_zone_name = "fs-1234567890" - region = "us-west-2" + file_system_id = "fs-1234567890" + region = "us-west-2" } } ``` From e7fc7c3dfb24819b5eed3faee78bb1fb29eba893 Mon Sep 17 00:00:00 2001 From: Yaron Yarimi Date: Sun, 7 Jan 2024 12:18:36 +0200 Subject: [PATCH 16/25] Run terrafmt to lint html markdown docs Signed-off-by: Yaron Yarimi --- website/docs/r/efs_replication_configuration.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/efs_replication_configuration.html.markdown b/website/docs/r/efs_replication_configuration.html.markdown index 0baae1e20ccd..d49ea2f81f60 100644 --- a/website/docs/r/efs_replication_configuration.html.markdown +++ b/website/docs/r/efs_replication_configuration.html.markdown @@ -52,7 +52,7 @@ resource "aws_efs_replication_configuration" "example" { destination { file_system_id = "fs-1234567890" - region = "us-west-2" + region = "us-west-2" } } ``` From d9bca164e10246a4092675e5ea91153637134af1 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 11 Jan 2024 08:11:54 -0500 Subject: [PATCH 17/25] r/aws_efs_replication_configuration: Update documentation with new default Create timeout value. --- website/docs/r/efs_replication_configuration.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/efs_replication_configuration.html.markdown b/website/docs/r/efs_replication_configuration.html.markdown index d49ea2f81f60..7488738ab3ff 100644 --- a/website/docs/r/efs_replication_configuration.html.markdown +++ b/website/docs/r/efs_replication_configuration.html.markdown @@ -88,7 +88,7 @@ This resource exports the following attributes in addition to the arguments abov [Configuration options](https://developer.hashicorp.com/terraform/language/resources/syntax#operation-timeouts): -* `create` - (Default `10m`) +* `create` - (Default `20m`) * `delete` - (Default `20m`) ## Import From aedbeede398790add79a2d096449c52dac816f95 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 11 Jan 2024 08:18:04 -0500 Subject: [PATCH 18/25] Add CHANGELOG entry. --- .changelog/34955.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changelog/34955.txt diff --git a/.changelog/34955.txt b/.changelog/34955.txt new file mode 100644 index 000000000000..0d0b463a6840 --- /dev/null +++ b/.changelog/34955.txt @@ -0,0 +1,7 @@ +```release-note:enhancement +resource/aws_efs_replication_configuration: Increase Create timeout to 20 minutes +``` + +```release-note:enhancement +resource/aws_efs_replication_configuration: Mark `destination.file_system_id` as Optional, enabling [EFS replication fallback](https://docs.aws.amazon.com/efs/latest/ug/replication-use-cases.html#replicate-existing-destination) +``` \ No newline at end of file From f278f366c6680165c8f27f5e068ecf9e1ba6bc4e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 11 Jan 2024 08:29:58 -0500 Subject: [PATCH 19/25] r/aws_efs_replication_configuration: Cosmetics. --- internal/service/efs/replication_configuration.go | 2 +- .../docs/r/efs_replication_configuration.html.markdown | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/service/efs/replication_configuration.go b/internal/service/efs/replication_configuration.go index 61650861d8ab..d7a18c24ea70 100644 --- a/internal/service/efs/replication_configuration.go +++ b/internal/service/efs/replication_configuration.go @@ -55,8 +55,8 @@ func ResourceReplicationConfiguration() *schema.Resource { }, "file_system_id": { Type: schema.TypeString, - Computed: true, Optional: true, + Computed: true, ForceNew: true, }, "kms_key_id": { diff --git a/website/docs/r/efs_replication_configuration.html.markdown b/website/docs/r/efs_replication_configuration.html.markdown index 7488738ab3ff..60cc4a343837 100644 --- a/website/docs/r/efs_replication_configuration.html.markdown +++ b/website/docs/r/efs_replication_configuration.html.markdown @@ -61,28 +61,28 @@ resource "aws_efs_replication_configuration" "example" { This resource supports the following arguments: -* `source_file_system_id` - (Required) The ID of the file system that is to be replicated. * `destination` - (Required) A destination configuration block (documented below). +* `source_file_system_id` - (Required) The ID of the file system that is to be replicated. ### Destination Arguments `destination` supports the following arguments: * `availability_zone_name` - (Optional) The availability zone in which the replica should be created. If specified, the replica will be created with One Zone storage. If omitted, regional storage will be used. +* `file_system_id` - (Optional) The ID of the destination file system for the replication. If no ID is provided, then EFS creates a new file system with the default settings. * `kms_key_id` - (Optional) The Key ID, ARN, alias, or alias ARN of the KMS key that should be used to encrypt the replica file system. If omitted, the default KMS key for EFS `/aws/elasticfilesystem` will be used. * `region` - (Optional) The region in which the replica should be created. -* `file_system_id` - (Optional) The ID of the destination file system for the replication. If no ID is provided, then EFS creates a new file system with the default settings. ## Attribute Reference This resource exports the following attributes in addition to the arguments above: * `creation_time` - When the replication configuration was created. +* `destination[0].file_system_id` - The fs ID of the replica. +* `destination[0].status` - The status of the replication. * `original_source_file_system_arn` - The Amazon Resource Name (ARN) of the original source Amazon EFS file system in the replication configuration. * `source_file_system_arn` - The Amazon Resource Name (ARN) of the current source file system in the replication configuration. * `source_file_system_region` - The AWS Region in which the source Amazon EFS file system is located. -* `destination[0].file_system_id` - The fs ID of the replica. -* `destination[0].status` - The status of the replication. ## Timeouts From 126e5d39d263600972aa261b0b14dcd5ab733f89 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 11 Jan 2024 08:30:31 -0500 Subject: [PATCH 20/25] r/aws_efs_replication_configuration: Tidy up acceptance tests. --- .../efs/replication_configuration_test.go | 69 ++++++++++++------- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/internal/service/efs/replication_configuration_test.go b/internal/service/efs/replication_configuration_test.go index 6962c8d0ab46..4f49e15e9f58 100644 --- a/internal/service/efs/replication_configuration_test.go +++ b/internal/service/efs/replication_configuration_test.go @@ -11,6 +11,7 @@ import ( "github.com/YakDriver/regexache" "github.com/aws/aws-sdk-go/service/efs" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" "github.com/hashicorp/terraform-provider-aws/internal/acctest" @@ -27,7 +28,7 @@ func TestAccEFSReplicationConfiguration_basic(t *testing.T) { resourceName := "aws_efs_replication_configuration.test" fsResourceName := "aws_efs_file_system.test" - region := acctest.Region() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) var providers []*schema.Provider resource.ParallelTest(t, resource.TestCase{ @@ -37,18 +38,18 @@ func TestAccEFSReplicationConfiguration_basic(t *testing.T) { CheckDestroy: acctest.CheckWithProviders(testAccCheckReplicationConfigurationDestroyWithProvider(ctx), &providers), Steps: []resource.TestStep{ { - Config: testAccReplicationConfigurationConfig_basic(region), + Config: testAccReplicationConfigurationConfig_basic(rName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckReplicationConfigurationExists(ctx, resourceName), resource.TestCheckResourceAttrSet(resourceName, "creation_time"), resource.TestCheckResourceAttr(resourceName, "destination.#", "1"), resource.TestMatchResourceAttr(resourceName, "destination.0.file_system_id", regexache.MustCompile(`fs-.+`)), - resource.TestCheckResourceAttr(resourceName, "destination.0.region", region), + resource.TestCheckResourceAttr(resourceName, "destination.0.region", acctest.Region()), resource.TestCheckResourceAttr(resourceName, "destination.0.status", efs.ReplicationStatusEnabled), resource.TestCheckResourceAttrPair(resourceName, "original_source_file_system_arn", fsResourceName, "arn"), resource.TestCheckResourceAttrPair(resourceName, "source_file_system_arn", fsResourceName, "arn"), resource.TestCheckResourceAttrPair(resourceName, "source_file_system_id", fsResourceName, "id"), - resource.TestCheckResourceAttr(resourceName, "source_file_system_region", region), + resource.TestCheckResourceAttr(resourceName, "source_file_system_region", acctest.Region()), ), }, { @@ -63,7 +64,7 @@ func TestAccEFSReplicationConfiguration_basic(t *testing.T) { func TestAccEFSReplicationConfiguration_disappears(t *testing.T) { ctx := acctest.Context(t) resourceName := "aws_efs_replication_configuration.test" - region := acctest.Region() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) var providers []*schema.Provider resource.ParallelTest(t, resource.TestCase{ @@ -76,7 +77,7 @@ func TestAccEFSReplicationConfiguration_disappears(t *testing.T) { CheckDestroy: acctest.CheckWithProviders(testAccCheckReplicationConfigurationDestroyWithProvider(ctx), &providers), Steps: []resource.TestStep{ { - Config: testAccReplicationConfigurationConfig_basic(region), + Config: testAccReplicationConfigurationConfig_basic(rName), Check: resource.ComposeTestCheckFunc( testAccCheckReplicationConfigurationExists(ctx, resourceName), acctest.CheckResourceDisappears(ctx, acctest.Provider, tfefs.ResourceReplicationConfiguration(), resourceName), @@ -96,7 +97,7 @@ func TestAccEFSReplicationConfiguration_allAttributes(t *testing.T) { resourceName := "aws_efs_replication_configuration.test" fsResourceName := "aws_efs_file_system.test" kmsKeyResourceName := "aws_kms_key.test" - alternateRegion := acctest.AlternateRegion() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) var providers []*schema.Provider resource.ParallelTest(t, resource.TestCase{ @@ -109,7 +110,7 @@ func TestAccEFSReplicationConfiguration_allAttributes(t *testing.T) { CheckDestroy: acctest.CheckWithProviders(testAccCheckReplicationConfigurationDestroyWithProvider(ctx), &providers), Steps: []resource.TestStep{ { - Config: testAccReplicationConfigurationConfig_full(alternateRegion), + Config: testAccReplicationConfigurationConfig_full(rName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckReplicationConfigurationExists(ctx, resourceName), resource.TestCheckResourceAttrSet(resourceName, "creation_time"), @@ -117,7 +118,7 @@ func TestAccEFSReplicationConfiguration_allAttributes(t *testing.T) { resource.TestCheckResourceAttrPair(resourceName, "destination.0.availability_zone_name", "data.aws_availability_zones.available", "names.0"), resource.TestMatchResourceAttr(resourceName, "destination.0.file_system_id", regexache.MustCompile(`fs-.+`)), resource.TestCheckResourceAttrPair(resourceName, "destination.0.kms_key_id", kmsKeyResourceName, "key_id"), - resource.TestCheckResourceAttr(resourceName, "destination.0.region", alternateRegion), + resource.TestCheckResourceAttr(resourceName, "destination.0.region", acctest.AlternateRegion()), resource.TestCheckResourceAttr(resourceName, "destination.0.status", efs.ReplicationStatusEnabled), resource.TestCheckResourceAttrPair(resourceName, "original_source_file_system_arn", fsResourceName, "arn"), resource.TestCheckResourceAttrPair(resourceName, "source_file_system_arn", fsResourceName, "arn"), @@ -137,6 +138,7 @@ func TestAccEFSReplicationConfiguration_existingDestination(t *testing.T) { resourceName := "aws_efs_replication_configuration.test" destinationFsResourceName := "aws_efs_file_system.destination" + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) var providers []*schema.Provider resource.ParallelTest(t, resource.TestCase{ @@ -149,7 +151,7 @@ func TestAccEFSReplicationConfiguration_existingDestination(t *testing.T) { CheckDestroy: acctest.CheckWithProviders(testAccCheckReplicationConfigurationDestroyWithProvider(ctx), &providers), Steps: []resource.TestStep{ { - Config: testAccReplicationConfigurationConfig_existingDestination(acctest.Region()), + Config: testAccReplicationConfigurationConfig_existingDestination(rName), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckReplicationConfigurationExists(ctx, resourceName), resource.TestCheckResourceAttrSet(resourceName, "creation_time"), @@ -207,29 +209,43 @@ func testAccCheckReplicationConfigurationDestroyWithProvider(ctx context.Context } } -func testAccReplicationConfigurationConfig_basic(region string) string { +func testAccReplicationConfigurationConfig_basic(rName string) string { return fmt.Sprintf(` -resource "aws_efs_file_system" "test" {} +resource "aws_efs_file_system" "test" { + tags = { + Name = %[1]q + } +} resource "aws_efs_replication_configuration" "test" { source_file_system_id = aws_efs_file_system.test.id destination { - region = %[1]q + region = %[2]q } } -`, region) +`, rName, acctest.Region()) } -func testAccReplicationConfigurationConfig_existingDestination(region string) string { - return fmt.Sprintf(` -resource "aws_efs_file_system" "source" {} +func testAccReplicationConfigurationConfig_existingDestination(rName string) string { + return acctest.ConfigCompose(acctest.ConfigAlternateRegionProvider(), fmt.Sprintf(` +resource "aws_efs_file_system" "source" { + tags = { + Name = %[1]q + } +} resource "aws_efs_file_system" "destination" { provider = "awsalternate" + protection { replication_overwrite = "DISABLED" } + + tags = { + Name = %[1]q + } + lifecycle { ignore_changes = [protection] } @@ -240,16 +256,19 @@ resource "aws_efs_replication_configuration" "test" { destination { file_system_id = aws_efs_file_system.destination.id - region = %[1]q + region = %[2]q } } -`, region) +`, rName, acctest.AlternateRegion())) } -func testAccReplicationConfigurationConfig_full(region string) string { +func testAccReplicationConfigurationConfig_full(rName string) string { return acctest.ConfigCompose(acctest.ConfigAlternateRegionProvider(), fmt.Sprintf(` resource "aws_kms_key" "test" { provider = "awsalternate" + + description = %[1]q + deletion_window_in_days = 7 } data "aws_availability_zones" "available" { @@ -263,7 +282,11 @@ data "aws_availability_zones" "available" { } } -resource "aws_efs_file_system" "test" {} +resource "aws_efs_file_system" "test" { + tags = { + Name = %[1]q + } +} resource "aws_efs_replication_configuration" "test" { source_file_system_id = aws_efs_file_system.test.id @@ -271,8 +294,8 @@ resource "aws_efs_replication_configuration" "test" { destination { availability_zone_name = data.aws_availability_zones.available.names[0] kms_key_id = aws_kms_key.test.key_id - region = %[1]q + region = %[2]q } } -`, region)) +`, rName, acctest.AlternateRegion())) } From 2c75d3ae8079dff80148f58fcf88cb5f8b9443c0 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 11 Jan 2024 10:28:24 -0500 Subject: [PATCH 21/25] r/aws_efs_replication_configuration: Tidy up. --- internal/service/efs/find.go | 29 ----- .../service/efs/replication_configuration.go | 111 ++++++++++++++++++ internal/service/efs/status.go | 16 --- internal/service/efs/wait.go | 35 ------ 4 files changed, 111 insertions(+), 80 deletions(-) diff --git a/internal/service/efs/find.go b/internal/service/efs/find.go index 9204154dfb89..4cbf9a45aba1 100644 --- a/internal/service/efs/find.go +++ b/internal/service/efs/find.go @@ -62,32 +62,3 @@ func FindFileSystemPolicyByID(ctx context.Context, conn *efs.EFS, id string) (*e return output, nil } - -func FindReplicationConfigurationByID(ctx context.Context, conn *efs.EFS, id string) (*efs.ReplicationConfigurationDescription, error) { - input := &efs.DescribeReplicationConfigurationsInput{ - FileSystemId: aws.String(id), - } - - output, err := conn.DescribeReplicationConfigurationsWithContext(ctx, input) - - if tfawserr.ErrCodeEquals(err, efs.ErrCodeFileSystemNotFound) || tfawserr.ErrCodeEquals(err, efs.ErrCodeReplicationNotFound) { - return nil, &retry.NotFoundError{ - LastError: err, - LastRequest: input, - } - } - - if err != nil { - return nil, err - } - - if output == nil || - len(output.Replications) == 0 || - output.Replications[0] == nil || - len(output.Replications[0].Destinations) == 0 || - output.Replications[0].Destinations[0] == nil { - return nil, tfresource.NewEmptyResultError(input) - } - - return output.Replications[0], nil -} diff --git a/internal/service/efs/replication_configuration.go b/internal/service/efs/replication_configuration.go index d7a18c24ea70..5680f3c04fff 100644 --- a/internal/service/efs/replication_configuration.go +++ b/internal/service/efs/replication_configuration.go @@ -12,6 +12,7 @@ import ( "github.com/aws/aws-sdk-go/service/efs" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" "github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag" @@ -203,6 +204,116 @@ func resourceReplicationConfigurationDelete(ctx context.Context, d *schema.Resou return diags } +func findReplicationConfiguration(ctx context.Context, conn *efs.EFS, input *efs.DescribeReplicationConfigurationsInput) (*efs.ReplicationConfigurationDescription, error) { + output, err := findReplicationConfigurations(ctx, conn, input) + + if err != nil { + return nil, err + } + + return tfresource.AssertSinglePtrResult(output) +} + +func findReplicationConfigurations(ctx context.Context, conn *efs.EFS, input *efs.DescribeReplicationConfigurationsInput) ([]*efs.ReplicationConfigurationDescription, error) { + var output []*efs.ReplicationConfigurationDescription + + err := conn.DescribeReplicationConfigurationsPagesWithContext(ctx, input, func(page *efs.DescribeReplicationConfigurationsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.Replications { + if v != nil { + output = append(output, v) + } + } + + return !lastPage + }) + + if tfawserr.ErrCodeEquals(err, efs.ErrCodeFileSystemNotFound, efs.ErrCodeReplicationNotFound) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + + if err != nil { + return nil, err + } + + return output, nil +} + +func FindReplicationConfigurationByID(ctx context.Context, conn *efs.EFS, id string) (*efs.ReplicationConfigurationDescription, error) { + input := &efs.DescribeReplicationConfigurationsInput{ + FileSystemId: aws.String(id), + } + + output, err := findReplicationConfiguration(ctx, conn, input) + + if err != nil { + return nil, err + } + + if len(output.Destinations) == 0 || output.Destinations[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + return output, nil +} + +func statusReplicationConfiguration(ctx context.Context, conn *efs.EFS, id string) retry.StateRefreshFunc { + return func() (interface{}, string, error) { + output, err := FindReplicationConfigurationByID(ctx, conn, id) + + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return output, aws.StringValue(output.Destinations[0].Status), nil + } +} + +func waitReplicationConfigurationCreated(ctx context.Context, conn *efs.EFS, id string, timeout time.Duration) (*efs.ReplicationConfigurationDescription, error) { + stateConf := &retry.StateChangeConf{ + Pending: []string{efs.ReplicationStatusEnabling}, + Target: []string{efs.ReplicationStatusEnabled}, + Refresh: statusReplicationConfiguration(ctx, conn, id), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*efs.ReplicationConfigurationDescription); ok { + return output, err + } + + return nil, err +} + +func waitReplicationConfigurationDeleted(ctx context.Context, conn *efs.EFS, id string, timeout time.Duration) (*efs.ReplicationConfigurationDescription, error) { + stateConf := &retry.StateChangeConf{ + Pending: []string{efs.ReplicationStatusDeleting}, + Target: []string{}, + Refresh: statusReplicationConfiguration(ctx, conn, id), + Timeout: timeout, + ContinuousTargetOccurence: 2, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + + if output, ok := outputRaw.(*efs.ReplicationConfigurationDescription); ok { + return output, err + } + + return nil, err +} + func expandDestinationToCreate(tfMap map[string]interface{}) *efs.DestinationToCreate { if tfMap == nil { return nil diff --git a/internal/service/efs/status.go b/internal/service/efs/status.go index f9083d2dd198..6b73cc469389 100644 --- a/internal/service/efs/status.go +++ b/internal/service/efs/status.go @@ -50,19 +50,3 @@ func statusBackupPolicy(ctx context.Context, conn *efs.EFS, id string) retry.Sta return output, aws.StringValue(output.Status), nil } } - -func statusReplicationConfiguration(ctx context.Context, conn *efs.EFS, id string) retry.StateRefreshFunc { - return func() (interface{}, string, error) { - output, err := FindReplicationConfigurationByID(ctx, conn, id) - - if tfresource.NotFound(err) { - return nil, "", nil - } - - if err != nil { - return nil, "", err - } - - return output, aws.StringValue(output.Destinations[0].Status), nil - } -} diff --git a/internal/service/efs/wait.go b/internal/service/efs/wait.go index 77f0d95dcdd1..27a792befef3 100644 --- a/internal/service/efs/wait.go +++ b/internal/service/efs/wait.go @@ -89,38 +89,3 @@ func waitBackupPolicyEnabled(ctx context.Context, conn *efs.EFS, id string) (*ef return nil, err } - -func waitReplicationConfigurationCreated(ctx context.Context, conn *efs.EFS, id string, timeout time.Duration) (*efs.ReplicationConfigurationDescription, error) { - stateConf := &retry.StateChangeConf{ - Pending: []string{efs.ReplicationStatusEnabling}, - Target: []string{efs.ReplicationStatusEnabled}, - Refresh: statusReplicationConfiguration(ctx, conn, id), - Timeout: timeout, - } - - outputRaw, err := stateConf.WaitForStateContext(ctx) - - if output, ok := outputRaw.(*efs.ReplicationConfigurationDescription); ok { - return output, err - } - - return nil, err -} - -func waitReplicationConfigurationDeleted(ctx context.Context, conn *efs.EFS, id string, timeout time.Duration) (*efs.ReplicationConfigurationDescription, error) { - stateConf := &retry.StateChangeConf{ - Pending: []string{efs.ReplicationStatusDeleting}, - Target: []string{}, - Refresh: statusReplicationConfiguration(ctx, conn, id), - Timeout: timeout, - ContinuousTargetOccurence: 2, - } - - outputRaw, err := stateConf.WaitForStateContext(ctx) - - if output, ok := outputRaw.(*efs.ReplicationConfigurationDescription); ok { - return output, err - } - - return nil, err -} From 0a7d0e56560effcca631dd07e320f20fb3071b4f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 11 Jan 2024 10:38:15 -0500 Subject: [PATCH 22/25] r/aws_efs_mount_target: Fix 'MountTargetNotFound' errors on Delete. --- internal/service/efs/mount_target.go | 46 ++++++++++++++++----- internal/service/efs/service_package_gen.go | 1 + 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/internal/service/efs/mount_target.go b/internal/service/efs/mount_target.go index 2d1bb3bd25b0..e6ce26fbb27e 100644 --- a/internal/service/efs/mount_target.go +++ b/internal/service/efs/mount_target.go @@ -25,7 +25,7 @@ import ( // nosemgrep:ci.semgrep.aws.multiple-service-imports "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) -// @SDKResource("aws_efs_mount_target") +// @SDKResource("aws_efs_mount_target", name="Mount Target") func ResourceMountTarget() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceMountTargetCreate, @@ -222,6 +222,10 @@ func resourceMountTargetDelete(ctx context.Context, d *schema.ResourceData, meta MountTargetId: aws.String(d.Id()), }) + if tfawserr.ErrCodeEquals(err, efs.ErrCodeMountTargetNotFound) { + return diags + } + if err != nil { return sdkdiag.AppendErrorf(diags, "deleting EFS Mount Target (%s): %s", d.Id(), err) } @@ -243,12 +247,32 @@ func getAZFromSubnetID(ctx context.Context, conn *ec2.EC2, subnetID string) (str return aws.StringValue(subnet.AvailabilityZone), nil } -func FindMountTargetByID(ctx context.Context, conn *efs.EFS, id string) (*efs.MountTargetDescription, error) { - input := &efs.DescribeMountTargetsInput{ - MountTargetId: aws.String(id), +func findMountTarget(ctx context.Context, conn *efs.EFS, input *efs.DescribeMountTargetsInput) (*efs.MountTargetDescription, error) { + output, err := findMountTargets(ctx, conn, input) + + if err != nil { + return nil, err } - output, err := conn.DescribeMountTargetsWithContext(ctx, input) + return tfresource.AssertSinglePtrResult(output) +} + +func findMountTargets(ctx context.Context, conn *efs.EFS, input *efs.DescribeMountTargetsInput) ([]*efs.MountTargetDescription, error) { + var output []*efs.MountTargetDescription + + err := conn.DescribeMountTargetsPagesWithContext(ctx, input, func(page *efs.DescribeMountTargetsOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, v := range page.MountTargets { + if v != nil { + output = append(output, v) + } + } + + return !lastPage + }) if tfawserr.ErrCodeEquals(err, efs.ErrCodeMountTargetNotFound) { return nil, &retry.NotFoundError{ @@ -261,15 +285,15 @@ func FindMountTargetByID(ctx context.Context, conn *efs.EFS, id string) (*efs.Mo return nil, err } - if output == nil || len(output.MountTargets) == 0 || output.MountTargets[0] == nil { - return nil, tfresource.NewEmptyResultError(input) - } + return output, nil +} - if count := len(output.MountTargets); count > 1 { - return nil, tfresource.NewTooManyResultsError(count, input) +func FindMountTargetByID(ctx context.Context, conn *efs.EFS, id string) (*efs.MountTargetDescription, error) { + input := &efs.DescribeMountTargetsInput{ + MountTargetId: aws.String(id), } - return output.MountTargets[0], nil + return findMountTarget(ctx, conn, input) } func statusMountTargetLifeCycleState(ctx context.Context, conn *efs.EFS, id string) retry.StateRefreshFunc { diff --git a/internal/service/efs/service_package_gen.go b/internal/service/efs/service_package_gen.go index 1a99347b9811..d029c86a5af3 100644 --- a/internal/service/efs/service_package_gen.go +++ b/internal/service/efs/service_package_gen.go @@ -73,6 +73,7 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka { Factory: ResourceMountTarget, TypeName: "aws_efs_mount_target", + Name: "Mount Target", }, { Factory: ResourceReplicationConfiguration, From f234faa118fbc3737ada7f2b7aa7dbfdeb363d2d Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 11 Jan 2024 10:43:54 -0500 Subject: [PATCH 23/25] Cosmetics. --- internal/service/efs/replication_configuration.go | 2 +- internal/service/efs/service_package_gen.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/service/efs/replication_configuration.go b/internal/service/efs/replication_configuration.go index 5680f3c04fff..b87e977bd18e 100644 --- a/internal/service/efs/replication_configuration.go +++ b/internal/service/efs/replication_configuration.go @@ -20,7 +20,7 @@ import ( "github.com/hashicorp/terraform-provider-aws/internal/verify" ) -// @SDKResource("aws_efs_replication_configuration") +// @SDKResource("aws_efs_replication_configuration", name="Replication Configuration") func ResourceReplicationConfiguration() *schema.Resource { return &schema.Resource{ CreateWithoutTimeout: resourceReplicationConfigurationCreate, diff --git a/internal/service/efs/service_package_gen.go b/internal/service/efs/service_package_gen.go index d029c86a5af3..3368bda399d1 100644 --- a/internal/service/efs/service_package_gen.go +++ b/internal/service/efs/service_package_gen.go @@ -78,6 +78,7 @@ func (p *servicePackage) SDKResources(ctx context.Context) []*types.ServicePacka { Factory: ResourceReplicationConfiguration, TypeName: "aws_efs_replication_configuration", + Name: "Replication Configuration", }, } } From ec6180d498ef3c4aa9f1f5b2f53995974c37ccc9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 11 Jan 2024 11:12:42 -0500 Subject: [PATCH 24/25] Fix 'TestAccEFSReplicationConfiguration_basic' and 'TestAccEFSReplicationConfiguration_disappears' (prevent panic). --- .../efs/replication_configuration_test.go | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/internal/service/efs/replication_configuration_test.go b/internal/service/efs/replication_configuration_test.go index 4f49e15e9f58..43147bb72e13 100644 --- a/internal/service/efs/replication_configuration_test.go +++ b/internal/service/efs/replication_configuration_test.go @@ -29,13 +29,12 @@ func TestAccEFSReplicationConfiguration_basic(t *testing.T) { resourceName := "aws_efs_replication_configuration.test" fsResourceName := "aws_efs_file_system.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - var providers []*schema.Provider resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t) }, ErrorCheck: acctest.ErrorCheck(t, efs.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, - CheckDestroy: acctest.CheckWithProviders(testAccCheckReplicationConfigurationDestroyWithProvider(ctx), &providers), + CheckDestroy: testAccCheckReplicationConfigurationDestroy(ctx), Steps: []resource.TestStep{ { Config: testAccReplicationConfigurationConfig_basic(rName), @@ -44,7 +43,7 @@ func TestAccEFSReplicationConfiguration_basic(t *testing.T) { resource.TestCheckResourceAttrSet(resourceName, "creation_time"), resource.TestCheckResourceAttr(resourceName, "destination.#", "1"), resource.TestMatchResourceAttr(resourceName, "destination.0.file_system_id", regexache.MustCompile(`fs-.+`)), - resource.TestCheckResourceAttr(resourceName, "destination.0.region", acctest.Region()), + resource.TestCheckResourceAttr(resourceName, "destination.0.region", acctest.AlternateRegion()), resource.TestCheckResourceAttr(resourceName, "destination.0.status", efs.ReplicationStatusEnabled), resource.TestCheckResourceAttrPair(resourceName, "original_source_file_system_arn", fsResourceName, "arn"), resource.TestCheckResourceAttrPair(resourceName, "source_file_system_arn", fsResourceName, "arn"), @@ -65,7 +64,6 @@ func TestAccEFSReplicationConfiguration_disappears(t *testing.T) { ctx := acctest.Context(t) resourceName := "aws_efs_replication_configuration.test" rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) - var providers []*schema.Provider resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { @@ -73,8 +71,8 @@ func TestAccEFSReplicationConfiguration_disappears(t *testing.T) { acctest.PreCheckMultipleRegion(t, 2) }, ErrorCheck: acctest.ErrorCheck(t, efs.EndpointsID), - ProtoV5ProviderFactories: acctest.ProtoV5FactoriesPlusProvidersAlternate(ctx, t, &providers), - CheckDestroy: acctest.CheckWithProviders(testAccCheckReplicationConfigurationDestroyWithProvider(ctx), &providers), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckReplicationConfigurationDestroy(ctx), Steps: []resource.TestStep{ { Config: testAccReplicationConfigurationConfig_basic(rName), @@ -171,10 +169,6 @@ func testAccCheckReplicationConfigurationExists(ctx context.Context, n string) r return fmt.Errorf("Not found: %s", n) } - if rs.Primary.ID == "" { - return fmt.Errorf("No EFS Replication Configuration ID is set") - } - conn := acctest.Provider.Meta().(*conns.AWSClient).EFSConn(ctx) _, err := tfefs.FindReplicationConfigurationByID(ctx, conn, rs.Primary.ID) @@ -183,6 +177,12 @@ func testAccCheckReplicationConfigurationExists(ctx context.Context, n string) r } } +func testAccCheckReplicationConfigurationDestroy(ctx context.Context) resource.TestCheckFunc { + return func(s *terraform.State) error { + return testAccCheckReplicationConfigurationDestroyWithProvider(ctx)(s, acctest.Provider) + } +} + func testAccCheckReplicationConfigurationDestroyWithProvider(ctx context.Context) acctest.TestCheckWithProviderFunc { return func(s *terraform.State, provider *schema.Provider) error { conn := provider.Meta().(*conns.AWSClient).EFSConn(ctx) @@ -224,7 +224,7 @@ resource "aws_efs_replication_configuration" "test" { region = %[2]q } } -`, rName, acctest.Region()) +`, rName, acctest.AlternateRegion()) } func testAccReplicationConfigurationConfig_existingDestination(rName string) string { From a27f18e84c2b1abded93f51e2d7fff6989bdaadc Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 11 Jan 2024 11:29:14 -0500 Subject: [PATCH 25/25] r/aws_efs_replication_configuration: Delete from both sides. --- .../service/efs/replication_configuration.go | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/internal/service/efs/replication_configuration.go b/internal/service/efs/replication_configuration.go index b87e977bd18e..eaf5693a0046 100644 --- a/internal/service/efs/replication_configuration.go +++ b/internal/service/efs/replication_configuration.go @@ -5,6 +5,7 @@ package efs import ( "context" + "fmt" "log" "time" @@ -173,35 +174,46 @@ func resourceReplicationConfigurationDelete(ctx context.Context, d *schema.Resou var diags diag.Diagnostics conn := meta.(*conns.AWSClient).EFSConn(ctx) - // Deletion of the replication configuration must be done from the - // Region in which the destination file system is located. + // Deletion of the replication configuration must be done from the Region in which the destination file system is located. destination := expandDestinationsToCreate(d.Get("destination").([]interface{}))[0] - session, err := conns.NewSessionForRegion(&conn.Config, aws.StringValue(destination.Region), meta.(*conns.AWSClient).TerraformVersion) + region := aws.StringValue(destination.Region) + session, err := conns.NewSessionForRegion(&conn.Config, region, meta.(*conns.AWSClient).TerraformVersion) if err != nil { - return sdkdiag.AppendErrorf(diags, "creating AWS session: %s", err) + return sdkdiag.AppendErrorf(diags, "creating AWS session (%s): %s", region, err) } - deleteConn := efs.New(session) - log.Printf("[DEBUG] Deleting EFS Replication Configuration: %s", d.Id()) - _, err = deleteConn.DeleteReplicationConfigurationWithContext(ctx, &efs.DeleteReplicationConfigurationInput{ - SourceFileSystemId: aws.String(d.Id()), + if err := deleteReplicationConfiguration(ctx, efs.New(session), d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil { + return sdkdiag.AppendFromErr(diags, err) + } + + // Delete also in the source Region. + if err := deleteReplicationConfiguration(ctx, conn, d.Id(), d.Timeout(schema.TimeoutDelete)); err != nil { + return sdkdiag.AppendFromErr(diags, err) + } + + return diags +} + +func deleteReplicationConfiguration(ctx context.Context, conn *efs.EFS, fsID string, timeout time.Duration) error { + _, err := conn.DeleteReplicationConfigurationWithContext(ctx, &efs.DeleteReplicationConfigurationInput{ + SourceFileSystemId: aws.String(fsID), }) if tfawserr.ErrCodeEquals(err, efs.ErrCodeFileSystemNotFound, efs.ErrCodeReplicationNotFound) { - return diags + return nil } if err != nil { - return sdkdiag.AppendErrorf(diags, "deleting EFS Replication Configuration (%s): %s", d.Id(), err) + return fmt.Errorf("deleting EFS Replication Configuration (%s): %w", fsID, err) } - if _, err := waitReplicationConfigurationDeleted(ctx, conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { - return sdkdiag.AppendErrorf(diags, "waiting for EFS Replication Configuration (%s) delete: %s", d.Id(), err) + if _, err := waitReplicationConfigurationDeleted(ctx, conn, fsID, timeout); err != nil { + return fmt.Errorf("waiting for EFS Replication Configuration (%s) delete: %w", fsID, err) } - return diags + return nil } func findReplicationConfiguration(ctx context.Context, conn *efs.EFS, input *efs.DescribeReplicationConfigurationsInput) (*efs.ReplicationConfigurationDescription, error) {