diff --git a/.changelog/30403.txt b/.changelog/30403.txt new file mode 100644 index 00000000000..9799053bc97 --- /dev/null +++ b/.changelog/30403.txt @@ -0,0 +1,9 @@ +```release-note:bug +resource/aws_elasticache_replication_group: Fix excessive delay on read +``` +```release-note:enhancement +resource/aws_elasticache_replication_group: Add `transit_encryption_mode` argument +``` +```release-note:enhancement +resource/aws_elasticache_replication_group: Changes to the `transit_encryption_enabled` argument can now be done in-place for engine versions > `7.0.5` +``` diff --git a/internal/service/elasticache/exports_test.go b/internal/service/elasticache/exports_test.go index a2b59b5891b..d269d88c87b 100644 --- a/internal/service/elasticache/exports_test.go +++ b/internal/service/elasticache/exports_test.go @@ -9,4 +9,6 @@ var ( ResourceSubnetGroup = resourceSubnetGroup FindCacheSubnetGroupByName = findCacheSubnetGroupByName + + ReplicationGroupAvailableModifyDelay = replicationGroupAvailableModifyDelay ) diff --git a/internal/service/elasticache/replication_group.go b/internal/service/elasticache/replication_group.go index c2f172b19e6..fb28ff1fad8 100644 --- a/internal/service/elasticache/replication_group.go +++ b/internal/service/elasticache/replication_group.go @@ -135,6 +135,7 @@ func ResourceReplicationGroup() *schema.Resource { "node_type", "security_group_names", "transit_encryption_enabled", + "transit_encryption_mode", "at_rest_encryption_enabled", "snapshot_arns", "snapshot_name", @@ -327,9 +328,14 @@ func ResourceReplicationGroup() *schema.Resource { "transit_encryption_enabled": { Type: schema.TypeBool, Optional: true, - ForceNew: true, Computed: true, }, + "transit_encryption_mode": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice(elasticache.TransitEncryptionMode_Values(), false), + }, "user_group_ids": { Type: schema.TypeSet, Optional: true, @@ -382,6 +388,11 @@ func ResourceReplicationGroup() *schema.Resource { diff.HasChange("num_node_groups") || diff.HasChange("replicas_per_node_group") }), + customdiff.ForceNewIf("transit_encryption_enabled", func(_ context.Context, d *schema.ResourceDiff, meta interface{}) bool { + // For Redis engine versions < 7.0.5, transit_encryption_enabled can only + // be configured during creation of the cluster. + return verify.SemVerLessThan(d.Get("engine_version_actual").(string), "7.0.5") + }), verify.SetTagsDiff, ), } @@ -505,6 +516,10 @@ func resourceReplicationGroupCreate(ctx context.Context, d *schema.ResourceData, input.TransitEncryptionEnabled = aws.Bool(d.Get("transit_encryption_enabled").(bool)) } + if v, ok := d.GetOk("transit_encryption_mode"); ok { + input.TransitEncryptionMode = aws.String(v.(string)) + } + if _, ok := d.GetOk("at_rest_encryption_enabled"); ok { input.AtRestEncryptionEnabled = aws.Bool(d.Get("at_rest_encryption_enabled").(bool)) } @@ -544,7 +559,7 @@ func resourceReplicationGroupCreate(ctx context.Context, d *schema.ResourceData, d.SetId(aws.StringValue(output.ReplicationGroup.ReplicationGroupId)) - if _, err := WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil { + if _, err := WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutCreate), replicationGroupAvailableCreateDelay); err != nil { return sdkdiag.AppendErrorf(diags, "waiting for ElastiCache Replication Group (%s) create: %s", d.Id(), err) } @@ -665,7 +680,7 @@ func resourceReplicationGroupRead(ctx context.Context, d *schema.ResourceData, m // Tags cannot be read when the replication group is not Available log.Printf("[DEBUG] Waiting for ElastiCache Replication Group (%s) to become available", d.Id()) - _, err = WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)) + _, err = WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate), replicationGroupAvailableReadDelay) if err != nil { return sdkdiag.AppendErrorf(diags, "waiting for ElastiCache Replication Group to be available (%s): %s", aws.StringValue(rgp.ARN), err) } @@ -696,6 +711,7 @@ func resourceReplicationGroupRead(ctx context.Context, d *schema.ResourceData, m d.Set("at_rest_encryption_enabled", c.AtRestEncryptionEnabled) d.Set("transit_encryption_enabled", c.TransitEncryptionEnabled) + d.Set("transit_encryption_mode", c.TransitEncryptionMode) if c.AuthTokenEnabled != nil && !aws.BoolValue(c.AuthTokenEnabled) { d.Set("auth_token", nil) @@ -861,9 +877,19 @@ func resourceReplicationGroupUpdate(ctx context.Context, d *schema.ResourceData, } } + if d.HasChange("transit_encryption_enabled") { + input.TransitEncryptionEnabled = aws.Bool(d.Get("transit_encryption_enabled").(bool)) + requestUpdate = true + } + + if d.HasChange("transit_encryption_mode") { + input.TransitEncryptionMode = aws.String(d.Get("transit_encryption_mode").(string)) + requestUpdate = true + } + if requestUpdate { // tagging may cause this resource to not yet be available, so wait for it to be available - _, err := WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)) + _, err := WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate), replicationGroupAvailableReadDelay) if err != nil { return sdkdiag.AppendErrorf(diags, "waiting for ElastiCache Replication Group (%s) to update: %s", d.Id(), err) } @@ -873,7 +899,7 @@ func resourceReplicationGroupUpdate(ctx context.Context, d *schema.ResourceData, return sdkdiag.AppendErrorf(diags, "updating ElastiCache Replication Group (%s): %s", d.Id(), err) } - _, err = WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)) + _, err = WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate), replicationGroupAvailableModifyDelay) if err != nil { return sdkdiag.AppendErrorf(diags, "waiting for ElastiCache Replication Group (%s) to update: %s", d.Id(), err) } @@ -888,7 +914,7 @@ func resourceReplicationGroupUpdate(ctx context.Context, d *schema.ResourceData, } // tagging may cause this resource to not yet be available, so wait for it to be available - _, err := WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)) + _, err := WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate), replicationGroupAvailableReadDelay) if err != nil { return sdkdiag.AppendErrorf(diags, "waiting for ElastiCache Replication Group (%s) to update: %s", d.Id(), err) } @@ -898,7 +924,7 @@ func resourceReplicationGroupUpdate(ctx context.Context, d *schema.ResourceData, return sdkdiag.AppendErrorf(diags, "changing auth_token for ElastiCache Replication Group (%s): %s", d.Id(), err) } - _, err = WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)) + _, err = WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate), replicationGroupAvailableModifyDelay) if err != nil { return sdkdiag.AppendErrorf(diags, "waiting for ElastiCache Replication Group (%s) auth_token change: %s", d.Id(), err) } @@ -1071,7 +1097,7 @@ func modifyReplicationGroupShardConfigurationNumNodeGroups(ctx context.Context, return fmt.Errorf("modifying ElastiCache Replication Group shard configuration: %w", err) } - _, err = WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)) + _, err = WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate), replicationGroupAvailableModifyDelay) if err != nil { return fmt.Errorf("waiting for ElastiCache Replication Group (%s) shard reconfiguration completion: %w", d.Id(), err) } @@ -1094,7 +1120,7 @@ func modifyReplicationGroupShardConfigurationReplicasPerNodeGroup(ctx context.Co if err != nil { return fmt.Errorf("adding ElastiCache Replication Group (%s) replicas: %w", d.Id(), err) } - _, err = WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)) + _, err = WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate), replicationGroupAvailableModifyDelay) if err != nil { return fmt.Errorf("waiting for ElastiCache Replication Group (%s) replica addition: %w", d.Id(), err) } @@ -1108,7 +1134,7 @@ func modifyReplicationGroupShardConfigurationReplicasPerNodeGroup(ctx context.Co if err != nil { return fmt.Errorf("removing ElastiCache Replication Group (%s) replicas: %w", d.Id(), err) } - _, err = WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate)) + _, err = WaitReplicationGroupAvailable(ctx, conn, d.Id(), d.Timeout(schema.TimeoutUpdate), replicationGroupAvailableModifyDelay) if err != nil { return fmt.Errorf("waiting for ElastiCache Replication Group (%s) replica removal: %w", d.Id(), err) } diff --git a/internal/service/elasticache/replication_group_test.go b/internal/service/elasticache/replication_group_test.go index 96c3f8a6588..40b05741c53 100644 --- a/internal/service/elasticache/replication_group_test.go +++ b/internal/service/elasticache/replication_group_test.go @@ -1370,7 +1370,7 @@ func TestAccElastiCacheReplicationGroup_enableSnapshotting(t *testing.T) { }) } -func TestAccElastiCacheReplicationGroup_enableAuthTokenTransitEncryption(t *testing.T) { +func TestAccElastiCacheReplicationGroup_transitEncryptionWithAuthToken(t *testing.T) { ctx := acctest.Context(t) if testing.Short() { t.Skip("skipping long-running test in short mode") @@ -1379,6 +1379,7 @@ func TestAccElastiCacheReplicationGroup_enableAuthTokenTransitEncryption(t *test var rg elasticache.ReplicationGroup rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_elasticache_replication_group.test" + authToken := sdkacctest.RandString(16) resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acctest.PreCheck(ctx, t) }, @@ -1387,10 +1388,12 @@ func TestAccElastiCacheReplicationGroup_enableAuthTokenTransitEncryption(t *test CheckDestroy: testAccCheckReplicationGroupDestroy(ctx), Steps: []resource.TestStep{ { - Config: testAccReplicationGroupConfig_enableAuthTokenTransitEncryption(rName, sdkacctest.RandString(16)), + Config: testAccReplicationGroupConfig_transitEncryptionWithAuthToken(rName, authToken), Check: resource.ComposeAggregateTestCheckFunc( testAccCheckReplicationGroupExists(ctx, resourceName, &rg), + resource.TestCheckResourceAttr(resourceName, "auth_token", authToken), resource.TestCheckResourceAttr(resourceName, "transit_encryption_enabled", "true"), + resource.TestCheckResourceAttrSet(resourceName, "transit_encryption_mode"), ), }, { @@ -1403,6 +1406,113 @@ func TestAccElastiCacheReplicationGroup_enableAuthTokenTransitEncryption(t *test }) } +func TestAccElastiCacheReplicationGroup_transitEncryption5x(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var rg1, rg2 elasticache.ReplicationGroup + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_elasticache_replication_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.ElastiCacheServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckReplicationGroupDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccReplicationGroupConfig_transitEncryptionEnabled5x(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckReplicationGroupExists(ctx, resourceName, &rg1), + resource.TestCheckResourceAttr(resourceName, "transit_encryption_enabled", "true"), + resource.TestCheckResourceAttrSet(resourceName, "transit_encryption_mode"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"apply_immediately", "auth_token", "auth_token_update_strategy", "preferred_cache_cluster_azs"}, + }, + { + // With Redis engine versions < 7.0.5, transit_encryption_enabled can only be set + // during cluster creation. Modifying the argument should force a replacement. + Config: testAccReplicationGroupConfig_transitEncryptionDisabled5x(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckReplicationGroupExists(ctx, resourceName, &rg2), + testAccCheckReplicationGroupRecreated(&rg1, &rg2), + resource.TestCheckResourceAttr(resourceName, "transit_encryption_enabled", "false"), + ), + }, + }, + }) +} + +func TestAccElastiCacheReplicationGroup_transitEncryption7x(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var rg1, rg2, rg3, rg4 elasticache.ReplicationGroup + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_elasticache_replication_group.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.ElastiCacheServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckReplicationGroupDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccReplicationGroupConfig_transitEncryptionEnabled7x(rName, elasticache.TransitEncryptionModePreferred), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckReplicationGroupExists(ctx, resourceName, &rg1), + resource.TestCheckResourceAttr(resourceName, "transit_encryption_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "transit_encryption_mode", elasticache.TransitEncryptionModePreferred), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"apply_immediately", "auth_token", "auth_token_update_strategy", "preferred_cache_cluster_azs"}, + }, + { + // With Redis engine versions >= 7.0.5, transit_encryption_mode can be modified in-place. + Config: testAccReplicationGroupConfig_transitEncryptionEnabled7x(rName, elasticache.TransitEncryptionModeRequired), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckReplicationGroupExists(ctx, resourceName, &rg2), + testAccCheckReplicationGroupNotRecreated(&rg1, &rg2), + resource.TestCheckResourceAttr(resourceName, "transit_encryption_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "transit_encryption_mode", elasticache.TransitEncryptionModeRequired), + ), + }, + { + // Before disabling transit encryption, mode must be transitioned back to "preferred" first. + Config: testAccReplicationGroupConfig_transitEncryptionEnabled7x(rName, elasticache.TransitEncryptionModePreferred), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckReplicationGroupExists(ctx, resourceName, &rg3), + testAccCheckReplicationGroupNotRecreated(&rg2, &rg3), + resource.TestCheckResourceAttr(resourceName, "transit_encryption_enabled", "true"), + resource.TestCheckResourceAttr(resourceName, "transit_encryption_mode", elasticache.TransitEncryptionModePreferred), + ), + }, + { + // With Redis engine versions >= 7.0.5, transit_encryption_enabled can be modified in-place. + Config: testAccReplicationGroupConfig_transitEncryptionDisabled7x(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckReplicationGroupExists(ctx, resourceName, &rg4), + testAccCheckReplicationGroupNotRecreated(&rg3, &rg4), + resource.TestCheckResourceAttr(resourceName, "transit_encryption_enabled", "false"), + ), + }, + }, + }) +} + func TestAccElastiCacheReplicationGroup_enableAtRestEncryption(t *testing.T) { ctx := acctest.Context(t) if testing.Short() { @@ -3496,24 +3606,11 @@ resource "aws_security_group" "test" { ) } -func testAccReplicationGroupConfig_enableAuthTokenTransitEncryption(rName string, authToken string) string { +// Dependencies shared across all tests exercising the transit_encryption_enabled argument +func testAccReplicationGroupConfig_transitEncryptionBase(rName string) string { return acctest.ConfigCompose( acctest.ConfigVPCWithSubnets(rName, 1), fmt.Sprintf(` -resource "aws_elasticache_replication_group" "test" { - replication_group_id = %[1]q - description = "test description" - node_type = "cache.t2.micro" - num_cache_clusters = "1" - port = 6379 - subnet_group_name = aws_elasticache_subnet_group.test.name - security_group_ids = [aws_security_group.test.id] - parameter_group_name = "default.redis5.0" - engine_version = "5.0.6" - transit_encryption_enabled = true - auth_token = %[2]q -} - resource "aws_elasticache_subnet_group" "test" { name = %[1]q subnet_ids = aws_subnet.test[*].id @@ -3531,10 +3628,117 @@ resource "aws_security_group" "test" { cidr_blocks = ["0.0.0.0/0"] } } +`, rName), + ) +} + +func testAccReplicationGroupConfig_transitEncryptionWithAuthToken(rName, authToken string) string { + return acctest.ConfigCompose( + testAccReplicationGroupConfig_transitEncryptionBase(rName), + fmt.Sprintf(` +resource "aws_elasticache_replication_group" "test" { + replication_group_id = %[1]q + description = "test description" + node_type = "cache.t2.micro" + num_cache_clusters = "1" + port = 6379 + subnet_group_name = aws_elasticache_subnet_group.test.name + security_group_ids = [aws_security_group.test.id] + parameter_group_name = "default.redis5.0" + engine_version = "5.0.6" + auth_token = %[2]q + transit_encryption_enabled = true + apply_immediately = true +} `, rName, authToken), ) } +func testAccReplicationGroupConfig_transitEncryptionEnabled5x(rName string) string { + return acctest.ConfigCompose( + testAccReplicationGroupConfig_transitEncryptionBase(rName), + fmt.Sprintf(` +resource "aws_elasticache_replication_group" "test" { + replication_group_id = %[1]q + description = "test description" + node_type = "cache.t2.micro" + num_cache_clusters = "1" + port = 6379 + subnet_group_name = aws_elasticache_subnet_group.test.name + security_group_ids = [aws_security_group.test.id] + parameter_group_name = "default.redis5.0" + engine_version = "5.0.6" + transit_encryption_enabled = true + apply_immediately = true +} +`, rName), + ) +} + +func testAccReplicationGroupConfig_transitEncryptionDisabled5x(rName string) string { + return acctest.ConfigCompose( + testAccReplicationGroupConfig_transitEncryptionBase(rName), + fmt.Sprintf(` +resource "aws_elasticache_replication_group" "test" { + replication_group_id = %[1]q + description = "test description" + node_type = "cache.t2.micro" + num_cache_clusters = "1" + port = 6379 + subnet_group_name = aws_elasticache_subnet_group.test.name + security_group_ids = [aws_security_group.test.id] + parameter_group_name = "default.redis5.0" + engine_version = "5.0.6" + transit_encryption_enabled = false + apply_immediately = true +} +`, rName), + ) +} + +func testAccReplicationGroupConfig_transitEncryptionEnabled7x(rName, transitEncryptionMode string) string { + return acctest.ConfigCompose( + testAccReplicationGroupConfig_transitEncryptionBase(rName), + fmt.Sprintf(` +resource "aws_elasticache_replication_group" "test" { + replication_group_id = %[1]q + description = "test description" + node_type = "cache.t2.micro" + num_cache_clusters = "1" + port = 6379 + subnet_group_name = aws_elasticache_subnet_group.test.name + security_group_ids = [aws_security_group.test.id] + parameter_group_name = "default.redis7" + engine_version = "7.0" + transit_encryption_enabled = true + transit_encryption_mode = %[2]q + apply_immediately = true +} +`, rName, transitEncryptionMode), + ) +} + +func testAccReplicationGroupConfig_transitEncryptionDisabled7x(rName string) string { + return acctest.ConfigCompose( + testAccReplicationGroupConfig_transitEncryptionBase(rName), + fmt.Sprintf(` +resource "aws_elasticache_replication_group" "test" { + replication_group_id = %[1]q + description = "test description" + node_type = "cache.t2.micro" + num_cache_clusters = "1" + port = 6379 + subnet_group_name = aws_elasticache_subnet_group.test.name + security_group_ids = [aws_security_group.test.id] + parameter_group_name = "default.redis7" + engine_version = "7.0" + transit_encryption_enabled = false + apply_immediately = true +} +`, rName), + ) +} + // Identical to the _authToken configutaion, but with no authorization yet // configured. This will execercise the case when authorization is added // to a replication group which previously had none. @@ -4165,7 +4369,7 @@ func resourceReplicationGroupModify(ctx context.Context, conn *elasticache.Elast return fmt.Errorf("error requesting modification: %w", err) } - _, err = tfelasticache.WaitReplicationGroupAvailable(ctx, conn, aws.StringValue(input.ReplicationGroupId), timeout) + _, err = tfelasticache.WaitReplicationGroupAvailable(ctx, conn, aws.StringValue(input.ReplicationGroupId), timeout, tfelasticache.ReplicationGroupAvailableModifyDelay) if err != nil { return fmt.Errorf("error waiting for modification: %w", err) } diff --git a/internal/service/elasticache/wait.go b/internal/service/elasticache/wait.go index 8cef54b4c3f..75537b46294 100644 --- a/internal/service/elasticache/wait.go +++ b/internal/service/elasticache/wait.go @@ -18,15 +18,17 @@ const ( ReplicationGroupDefaultUpdatedTimeout = 40 * time.Minute ReplicationGroupDefaultDeletedTimeout = 40 * time.Minute - replicationGroupAvailableMinTimeout = 10 * time.Second - replicationGroupAvailableDelay = 30 * time.Second + replicationGroupAvailableMinTimeout = 10 * time.Second + replicationGroupAvailableCreateDelay = 30 * time.Second + replicationGroupAvailableModifyDelay = 30 * time.Second + replicationGroupAvailableReadDelay = 0 * time.Second replicationGroupDeletedMinTimeout = 10 * time.Second replicationGroupDeletedDelay = 30 * time.Second ) // WaitReplicationGroupAvailable waits for a ReplicationGroup to return Available -func WaitReplicationGroupAvailable(ctx context.Context, conn *elasticache.ElastiCache, replicationGroupID string, timeout time.Duration) (*elasticache.ReplicationGroup, error) { +func WaitReplicationGroupAvailable(ctx context.Context, conn *elasticache.ElastiCache, replicationGroupID string, timeout time.Duration, delay time.Duration) (*elasticache.ReplicationGroup, error) { stateConf := &retry.StateChangeConf{ Pending: []string{ ReplicationGroupStatusCreating, @@ -37,7 +39,7 @@ func WaitReplicationGroupAvailable(ctx context.Context, conn *elasticache.Elasti Refresh: StatusReplicationGroup(ctx, conn, replicationGroupID), Timeout: timeout, MinTimeout: replicationGroupAvailableMinTimeout, - Delay: replicationGroupAvailableDelay, + Delay: delay, } outputRaw, err := stateConf.WaitForStateContext(ctx) diff --git a/website/docs/r/elasticache_replication_group.html.markdown b/website/docs/r/elasticache_replication_group.html.markdown index 48b970e6bc1..87b71649da2 100644 --- a/website/docs/r/elasticache_replication_group.html.markdown +++ b/website/docs/r/elasticache_replication_group.html.markdown @@ -237,6 +237,12 @@ The following arguments are optional: * `subnet_group_name` - (Optional) Name of the cache subnet group to be used for the replication group. * `tags` - (Optional) Map of tags to assign to the resource. Adding tags to this resource will add or overwrite any existing tags on the clusters in the replication group and not to the group itself. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. * `transit_encryption_enabled` - (Optional) Whether to enable encryption in transit. + Changing this argument with an `engine_version` < `7.0.5` will force a replacement. + Engine versions prior to `7.0.5` only allow this transit encryption to be configured during creation of the replication group. +* `transit_encryption_mode` - (Optional) A setting that enables clients to migrate to in-transit encryption with no downtime. + Valid values are `preferred` and `required`. + When enabling encryption on an existing replication group, this must first be set to `preferred` before setting it to `required` in a subsequent apply. + See the `TransitEncryptionMode` field in the [`CreateReplicationGroup` API documentation](https://docs.aws.amazon.com/AmazonElastiCache/latest/APIReference/API_CreateReplicationGroup.html) for additional details. * `user_group_ids` - (Optional) User Group ID to associate with the replication group. Only a maximum of one (1) user group ID is valid. **NOTE:** This argument _is_ a set because the AWS specification allows for multiple IDs. However, in practice, AWS only allows a maximum size of one. ### Log Delivery Configuration