Skip to content

Commit

Permalink
Handle redis -> valkey engine updates on aws_elasticache_serverless_c…
Browse files Browse the repository at this point in the history
…ache

Fixes hashicorp#39711

Signed-off-by: Aurel Canciu <aurel.canciu@nexhealth.com>
  • Loading branch information
relu committed Oct 17, 2024
1 parent f187158 commit 4b57a5a
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 45 deletions.
15 changes: 14 additions & 1 deletion internal/service/elasticache/serverless_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-provider-aws/internal/errs"
Expand Down Expand Up @@ -94,7 +95,11 @@ func (r *serverlessCacheResource) Schema(ctx context.Context, request resource.S
names.AttrEngine: schema.StringAttribute{
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
stringplanmodifier.RequiresReplaceIf(func(ctx context.Context, sr planmodifier.StringRequest, rrifr *stringplanmodifier.RequiresReplaceIfFuncResponse) {
configIsRedis := sr.ConfigValue.Equal(basetypes.NewStringValue(engineRedis))
planIsValkey := sr.PlanValue.Equal(basetypes.NewStringValue(engineValkey))
rrifr.RequiresReplace = !(configIsRedis && planIsValkey)
}, "Replace engine diff", "Replace engine diff"),
},
},
"full_engine_version": schema.StringAttribute{
Expand Down Expand Up @@ -338,6 +343,14 @@ func (r *serverlessCacheResource) Update(ctx context.Context, request resource.U
if serverlessCacheHasChanges(ctx, new, old) {
input := &elasticache.ModifyServerlessCacheInput{}
response.Diagnostics.Append(fwflex.Expand(ctx, new, input)...)
// Unset engine related stuff to prevent the following error:
// This API supports only cross-engine upgrades to Valkey engine currently.
if new.Engine.Equal(old.Engine) {
input.Engine = nil
}
if new.MajorEngineVersion.Equal(old.MajorEngineVersion) {
input.MajorEngineVersion = nil
}
if response.Diagnostics.HasError() {
return
}
Expand Down
90 changes: 46 additions & 44 deletions internal/service/elasticache/serverless_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,49 +21,6 @@ import (
"github.com/hashicorp/terraform-provider-aws/names"
)

func TestAccElastiCacheServerlessCache_basic(t *testing.T) {
ctx := acctest.Context(t)
if testing.Short() {
t.Skip("skipping long-running test in short mode")
}

rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_elasticache_serverless_cache.test"
var serverlessElasticCache awstypes.ServerlessCache

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.ElastiCacheServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: resource.ComposeAggregateTestCheckFunc(
testAccCheckServerlessCacheDestroy(ctx),
),
Steps: []resource.TestStep{
{
Config: testAccServerlessCacheConfig_basic(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckServerlessCacheExists(ctx, resourceName, &serverlessElasticCache),
resource.TestCheckResourceAttrSet(resourceName, names.AttrARN),
resource.TestCheckResourceAttrSet(resourceName, "cache_usage_limits.#"),
resource.TestCheckResourceAttrSet(resourceName, names.AttrCreateTime),
resource.TestCheckResourceAttrSet(resourceName, "endpoint.#"),
resource.TestCheckResourceAttrSet(resourceName, names.AttrEngine),
resource.TestCheckResourceAttrSet(resourceName, "full_engine_version"),
resource.TestCheckResourceAttrSet(resourceName, "reader_endpoint.#"),
resource.TestCheckResourceAttr(resourceName, names.AttrName, rName),
resource.TestCheckResourceAttrSet(resourceName, names.AttrStatus),
resource.TestCheckResourceAttrSet(resourceName, "subnet_ids.#"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccElastiCacheServerlessCache_basicRedis(t *testing.T) {
ctx := acctest.Context(t)
if testing.Short() {
Expand Down Expand Up @@ -449,6 +406,42 @@ func TestAccElastiCacheServerlessCache_updatesc(t *testing.T) {
})
}

func TestAccElastiCacheServerlessCache_update_RedisToValkey(t *testing.T) {
ctx := acctest.Context(t)
if testing.Short() {
t.Skip("skipping long-running test in short mode")
}

rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_elasticache_serverless_cache.test"
var v1, v2 awstypes.ServerlessCache

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.ElastiCacheServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: resource.ComposeAggregateTestCheckFunc(
testAccCheckServerlessCacheDestroy(ctx),
),
Steps: []resource.TestStep{
{
Config: testAccServerlessCacheConfig_basicRedis(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckServerlessCacheExists(ctx, resourceName, &v1),
resource.TestCheckResourceAttr(resourceName, names.AttrEngine, "redis"),
),
},
{
Config: testAccServerlessCacheConfig_updateValkey(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckServerlessCacheExists(ctx, resourceName, &v2),
resource.TestCheckResourceAttr(resourceName, names.AttrEngine, "valkey"),
),
},
},
})
}

func TestAccElastiCacheServerlessCache_disappears(t *testing.T) {
ctx := acctest.Context(t)
if testing.Short() {
Expand Down Expand Up @@ -624,6 +617,15 @@ resource "aws_elasticache_serverless_cache" "test" {
`, rName)
}

func testAccServerlessCacheConfig_updateValkey(rName string) string {
return fmt.Sprintf(`
resource "aws_elasticache_serverless_cache" "test" {
engine = "valkey"
name = %[1]q
}
`, rName)
}

func testAccServerlessCacheConfig_full(rName string) string {
return acctest.ConfigCompose(acctest.ConfigVPCWithSubnets(rName, 2), fmt.Sprintf(`
resource "aws_elasticache_serverless_cache" "test" {
Expand Down Expand Up @@ -739,7 +741,7 @@ resource "aws_elasticache_serverless_cache" "test" {
}
daily_snapshot_time = "09:00"
description = "Test Full Redis Attributes"
description = "Test Full Valkey Attributes"
kms_key_id = aws_kms_key.test.arn
major_engine_version = "7"
snapshot_retention_limit = 1
Expand Down

0 comments on commit 4b57a5a

Please sign in to comment.