From c53a9b8f03ee359180610000b2d6ba434b83213f Mon Sep 17 00:00:00 2001 From: Matthew Long Date: Mon, 27 Oct 2025 09:57:04 +0000 Subject: [PATCH 01/12] fix: suppresses diffs for redis 8 --- .../pro/resource_rediscloud_pro_database.go | 29 ++++++++++++++++-- ...rediscloud_pro_database_validation_test.go | 30 +++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/provider/pro/resource_rediscloud_pro_database.go b/provider/pro/resource_rediscloud_pro_database.go index 5e72be5d..1ff10941 100644 --- a/provider/pro/resource_rediscloud_pro_database.go +++ b/provider/pro/resource_rediscloud_pro_database.go @@ -251,8 +251,9 @@ func ResourceRedisCloudProDatabase() *schema.Resource { ConfigMode: schema.SchemaConfigModeAttr, Optional: true, // The API doesn't allow updating/delete modules. Unless we recreate the database. - ForceNew: true, - MinItems: 1, + ForceNew: true, + MinItems: 1, + DiffSuppressFunc: modulesDiffSuppressFunc, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { @@ -1068,6 +1069,30 @@ func shouldWarnRedis8Modules(version string, hasModules bool) bool { return false } +// shouldSuppressModuleDiffsForRedis8 checks if module diffs should be suppressed for Redis 8.0 or higher +// In Redis 8.0+, modules are bundled by default, so we should ignore changes to explicitly configured modules +func shouldSuppressModuleDiffsForRedis8(version string) bool { + if len(version) == 0 { + return false + } + majorVersionStr := strings.Split(version, ".")[0] + if majorVersion, err := strconv.Atoi(majorVersionStr); err == nil { + return majorVersion >= 8 + } + return false +} + +// modulesDiffSuppressFunc returns a DiffSuppressFunc that suppresses module diffs for Redis 8.0+ +// This prevents Terraform from showing module changes as "forces replacement" when upgrading to Redis 8.0+ +func modulesDiffSuppressFunc(k, oldValue, newValue string, d *schema.ResourceData) bool { + redisVersion, ok := d.GetOk("redis_version") + if !ok { + return false + } + version := redisVersion.(string) + return shouldSuppressModuleDiffsForRedis8(version) +} + func validateModulesForRedis8() schema.CustomizeDiffFunc { return func(ctx context.Context, diff *schema.ResourceDiff, meta interface{}) error { redisVersion, versionExists := diff.GetOk("redis_version") diff --git a/provider/pro/resource_rediscloud_pro_database_validation_test.go b/provider/pro/resource_rediscloud_pro_database_validation_test.go index a1a9c6a4..de32f786 100644 --- a/provider/pro/resource_rediscloud_pro_database_validation_test.go +++ b/provider/pro/resource_rediscloud_pro_database_validation_test.go @@ -65,3 +65,33 @@ func TestUnitShouldWarnRedis8Modules_Redis10WithModules(t *testing.T) { result := shouldWarnRedis8Modules("10.0.0", true) assert.True(t, result, "should warn for Redis 10.0.0 with modules (modules bundled in 8.0+)") } + +// TestUnitShouldSuppressModuleDiffsForRedis8_Redis8 tests that module diffs are suppressed for Redis 8.0 +func TestUnitShouldSuppressModuleDiffsForRedis8_Redis8(t *testing.T) { + result := shouldSuppressModuleDiffsForRedis8("8.0") + assert.True(t, result, "should suppress module diffs for Redis 8.0") +} + +// TestUnitShouldSuppressModuleDiffsForRedis8_Redis82 tests that module diffs are suppressed for Redis 8.2 +func TestUnitShouldSuppressModuleDiffsForRedis8_Redis82(t *testing.T) { + result := shouldSuppressModuleDiffsForRedis8("8.2") + assert.True(t, result, "should suppress module diffs for Redis 8.2") +} + +// TestUnitShouldSuppressModuleDiffsForRedis8_Redis9 tests that module diffs are suppressed for Redis 9.0 +func TestUnitShouldSuppressModuleDiffsForRedis8_Redis9(t *testing.T) { + result := shouldSuppressModuleDiffsForRedis8("9.0") + assert.True(t, result, "should suppress module diffs for Redis 9.0") +} + +// TestUnitShouldSuppressModuleDiffsForRedis8_Redis7 tests that module diffs are NOT suppressed for Redis 7.x +func TestUnitShouldSuppressModuleDiffsForRedis8_Redis7(t *testing.T) { + result := shouldSuppressModuleDiffsForRedis8("7.4") + assert.False(t, result, "should not suppress module diffs for Redis 7.4") +} + +// TestUnitShouldSuppressModuleDiffsForRedis8_Redis6 tests that module diffs are NOT suppressed for Redis 6.x +func TestUnitShouldSuppressModuleDiffsForRedis8_Redis6(t *testing.T) { + result := shouldSuppressModuleDiffsForRedis8("6.2") + assert.False(t, result, "should not suppress module diffs for Redis 6.2") +} From 57c069324601cebf0aafecf9e2d9ff438c549fa5 Mon Sep 17 00:00:00 2001 From: Matthew Long Date: Mon, 27 Oct 2025 10:29:08 +0000 Subject: [PATCH 02/12] fix: query performance factor is no longer forcenew --- provider/pro/resource_rediscloud_pro_database.go | 1 - provider/resource_rediscloud_pro_database_qpf_test.go | 9 ++++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/provider/pro/resource_rediscloud_pro_database.go b/provider/pro/resource_rediscloud_pro_database.go index 1ff10941..f042ba61 100644 --- a/provider/pro/resource_rediscloud_pro_database.go +++ b/provider/pro/resource_rediscloud_pro_database.go @@ -230,7 +230,6 @@ func ResourceRedisCloudProDatabase() *schema.Resource { Type: schema.TypeString, Optional: true, Computed: true, - ForceNew: true, ValidateFunc: func(val interface{}, key string) (warns []string, errs []error) { v := val.(string) matched, err := regexp.MatchString(`^([2468])x$`, v) diff --git a/provider/resource_rediscloud_pro_database_qpf_test.go b/provider/resource_rediscloud_pro_database_qpf_test.go index 4faeb814..b553fd58 100644 --- a/provider/resource_rediscloud_pro_database_qpf_test.go +++ b/provider/resource_rediscloud_pro_database_qpf_test.go @@ -130,12 +130,11 @@ func TestAccResourceRedisCloudProDatabase_qpf(t *testing.T) { ), }, - // Test plan to ensure query_performance_factor change forces a new resource + // Test that query_performance_factor can be updated without forcing replacement { - Config: formatDatabaseConfig(name, testCloudAccountName, password, "2x", `modules = [{ name = "RediSearch" }]`), - PlanOnly: true, // Runs terraform plan without applying - ExpectNonEmptyPlan: true, // Ensures that a change is detected - Check: resource.ComposeTestCheckFunc( + Config: formatDatabaseConfig(name, testCloudAccountName, password, "2x", `modules = [{ name = "RediSearch" }]`), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("rediscloud_subscription_database.example", "name", "example"), resource.TestCheckResourceAttr("rediscloud_subscription_database.example", "query_performance_factor", "2x"), ), }, From 9a6db6acc7e50f1b7540a433236a4c17e094df66 Mon Sep 17 00:00:00 2001 From: Matthew Long Date: Mon, 27 Oct 2025 10:39:41 +0000 Subject: [PATCH 03/12] fix: tests using incorrect paths --- provider/rediscloud_active_active_private_link_test.go | 2 +- provider/rediscloud_active_active_subscription_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/provider/rediscloud_active_active_private_link_test.go b/provider/rediscloud_active_active_private_link_test.go index 93620660..60675500 100644 --- a/provider/rediscloud_active_active_private_link_test.go +++ b/provider/rediscloud_active_active_private_link_test.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -const testActiveActivePrivateLinkConfigFile = "../privatelink/testdata/active_active_private_link.tf" +const testActiveActivePrivateLinkConfigFile = "./privatelink/testdata/active_active_private_link.tf" func TestAccResourceRedisCloudActiveActivePrivateLink_CRUDI(t *testing.T) { diff --git a/provider/rediscloud_active_active_subscription_test.go b/provider/rediscloud_active_active_subscription_test.go index 7617f586..907b1aeb 100644 --- a/provider/rediscloud_active_active_subscription_test.go +++ b/provider/rediscloud_active_active_subscription_test.go @@ -486,21 +486,21 @@ resource "rediscloud_active_active_subscription" "example" { ` func testAccResourceRedisCloudActiveActiveSubscription(t *testing.T, subscriptionName string) string { - content := utils.GetTestConfig(t, "./activeactive/testdata/testAccResourceRedisCloudActiveActiveSubscription.tf") + content := utils.GetTestConfig(t, "./activeactive/testdata/active_active_sub.tf") return fmt.Sprintf(content, subscriptionName) } func testAccResourceRedisCloudActiveActiveSubscriptionUpdate(t *testing.T, subscriptionName string, cloudProvider string) string { - content := utils.GetTestConfig(t, "./activeactive/testdata/testAccResourceRedisCloudActiveActiveSubscriptionUpdate.tf") + content := utils.GetTestConfig(t, "./activeactive/testdata/subscription_update.tf") return fmt.Sprintf(content, subscriptionName, cloudProvider) } func testAccResourceRedisCloudActiveActiveSubscriptionPublicEndpointDisabled(t *testing.T, subscriptionName string) string { - content := utils.GetTestConfig(t, "./activeactive/testdata/testAccResourceRedisCloudActiveActiveSubscription_PublicEndpointDisabled.tf") + content := utils.GetTestConfig(t, "./activeactive/testdata/public_endpoint_disabled.tf") return fmt.Sprintf(content, subscriptionName) } func testAccResourceRedisCloudActiveActiveSubscriptionPublicEndpointEnabled(t *testing.T, subscriptionName string) string { - content := utils.GetTestConfig(t, "./activeactive/testdata/testAccResourceRedisCloudActiveActiveSubscription_PublicEndpointEnabled.tf") + content := utils.GetTestConfig(t, "./activeactive/testdata/public_endpoint_enabled.tf") return fmt.Sprintf(content, subscriptionName) } From 89e84aee1e6a0a1e7a8dcc007899463ec0939139 Mon Sep 17 00:00:00 2001 From: Matthew Long Date: Mon, 27 Oct 2025 13:01:34 +0000 Subject: [PATCH 04/12] docs: CHANGELOG.md --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bbc777cc..a3eec528 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file. See updating [Changelog example here](https://keepachangelog.com/en/1.0.0/) + +# 2.7.1 (27th October 2025) + +## Fixed +- rediscloud_subscription_database: The query_performance_factor attribute can now be updated in-place without recreating the database. Previously, any changes to this attribute would force resource replacement. +- rediscloud_subscription_database (Redis 8.0+): Fixed drift detection issues where explicitly configured modules would incorrectly show as changes requiring resource replacement after upgrading to Redis 8.0 or higher. Modules are bundled + by default in Redis 8.0+, so configuration differences are now properly suppressed. +- Test Suite: Fixed incorrect file path references in acceptance tests. + # 2.7.0 (22nd October 2025) ## Added: From 11578651876262c6f8dea381eee20ce8fb06a39c Mon Sep 17 00:00:00 2001 From: Matthew Long Date: Mon, 27 Oct 2025 13:27:36 +0000 Subject: [PATCH 05/12] test: adding qpf to smoke tests and temporarily disabling essentials dbs until fix is available --- .github/workflows/terraform_provider_pr.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/terraform_provider_pr.yml b/.github/workflows/terraform_provider_pr.yml index 1a41b313..8fadb84e 100644 --- a/.github/workflows/terraform_provider_pr.yml +++ b/.github/workflows/terraform_provider_pr.yml @@ -126,6 +126,7 @@ jobs: go_test_smoke_essentials_db: + if: false # Temporarily disabled - waiting on client fixes name: go test smoke essentials db needs: go_test_smoke_essentials_sub runs-on: ubuntu-latest @@ -193,6 +194,17 @@ jobs: go-version-file: go.mod - run: EXECUTE_TESTS=true make testacc TESTARGS='-run="TestAcc(RedisCloudProDatabaseBlockPublicEndpoints|ActiveActiveSubscriptionDatabaseBlockPublicEndpoints)"' + go_test_smoke_qpf: + name: go test smoke query performance factor + needs: [ go_build ] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0 + with: + go-version-file: go.mod + - run: EXECUTE_TESTS=true make testacc TESTARGS='-run="TestAccResourceRedisCloudProDatabase_qpf"' + go_unit_test: name: go unit test needs: [go_build] From 47a2c857757ff2b0da6f00c5fc62b09b7efefef3 Mon Sep 17 00:00:00 2001 From: Matthew Long Date: Mon, 27 Oct 2025 14:36:13 +0000 Subject: [PATCH 06/12] fix: adding another new pending status for database updates --- provider/utils/wait.go | 1 + 1 file changed, 1 insertion(+) diff --git a/provider/utils/wait.go b/provider/utils/wait.go index 92244de8..dd913e0b 100644 --- a/provider/utils/wait.go +++ b/provider/utils/wait.go @@ -52,6 +52,7 @@ func WaitForDatabaseToBeActive(ctx context.Context, subId, id int, api *client.A databases.StatusProxyPolicyChangeDraft, databases.StatusDynamicEndpointsCreationPending, databases.StatusActiveUpgradePending, + "bdb-update-pending", // Database update in progress }, Target: []string{databases.StatusActive}, Timeout: SafetyTimeout, From 2f49bce4d98f6f248002d05a7bcdcb6c854c4d10 Mon Sep 17 00:00:00 2001 From: Matthew Long Date: Mon, 27 Oct 2025 14:37:46 +0000 Subject: [PATCH 07/12] fix: adding pending status not previously seen --- provider/utils/wait.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/provider/utils/wait.go b/provider/utils/wait.go index dd913e0b..a183104e 100644 --- a/provider/utils/wait.go +++ b/provider/utils/wait.go @@ -52,7 +52,8 @@ func WaitForDatabaseToBeActive(ctx context.Context, subId, id int, api *client.A databases.StatusProxyPolicyChangeDraft, databases.StatusDynamicEndpointsCreationPending, databases.StatusActiveUpgradePending, - "bdb-update-pending", // Database update in progress + "bdb-update-pending", // Database update in progress. + // TODO replace with api model string in next release }, Target: []string{databases.StatusActive}, Timeout: SafetyTimeout, From 9bf229b8607fc868d2ed29fc26da070556229905 Mon Sep 17 00:00:00 2001 From: Matthew Long Date: Mon, 27 Oct 2025 17:22:41 +0000 Subject: [PATCH 08/12] fix: adding diff suppress to subscription redis version, and give proper warning to user about 8.0 modules --- .../pro/resource_rediscloud_pro_database.go | 68 ++++++++++++------- .../resource_rediscloud_pro_subscription.go | 14 ++-- 2 files changed, 52 insertions(+), 30 deletions(-) diff --git a/provider/pro/resource_rediscloud_pro_database.go b/provider/pro/resource_rediscloud_pro_database.go index f042ba61..81ab6283 100644 --- a/provider/pro/resource_rediscloud_pro_database.go +++ b/provider/pro/resource_rediscloud_pro_database.go @@ -418,6 +418,17 @@ func resourceRedisCloudProDatabaseCreate(ctx context.Context, d *schema.Resource createDatabase.RedisVersion = s }) + // Warn if modules are explicitly configured for Redis 8.0+ + var diags diag.Diagnostics + redisVersion := d.Get("redis_version").(string) + if shouldWarnRedis8Modules(redisVersion, len(createModules) > 0) { + diags = append(diags, diag.Diagnostic{ + Severity: diag.Warning, + Summary: "Modules are bundled by default in Redis 8.0+", + Detail: fmt.Sprintf("The 'modules' block is deprecated for Redis %s and later versions, as modules (RediSearch, RedisJSON, RedisBloom, RedisTimeSeries) are bundled by default. You should remove the 'modules' block from your configuration.", redisVersion), + }) + } + utils.SetStringIfNotEmpty(d, "password", func(s *string) { createDatabase.Password = s }) @@ -449,13 +460,13 @@ func resourceRedisCloudProDatabaseCreate(ctx context.Context, d *schema.Resource // Confirm sub is ready to accept a db request if err := utils.WaitForSubscriptionToBeActive(ctx, subId, api); err != nil { utils.SubscriptionMutex.Unlock(subId) - return diag.FromErr(err) + return append(diags, diag.FromErr(err)...) } dbId, err := api.Client.Database.Create(ctx, subId, createDatabase) if err != nil { utils.SubscriptionMutex.Unlock(subId) - return diag.FromErr(err) + return append(diags, diag.FromErr(err)...) } d.SetId(utils.BuildResourceId(subId, dbId)) @@ -463,17 +474,18 @@ func resourceRedisCloudProDatabaseCreate(ctx context.Context, d *schema.Resource // Confirm db + sub active status if err := utils.WaitForDatabaseToBeActive(ctx, subId, dbId, api); err != nil { utils.SubscriptionMutex.Unlock(subId) - return diag.FromErr(err) + return append(diags, diag.FromErr(err)...) } if err := utils.WaitForSubscriptionToBeActive(ctx, subId, api); err != nil { utils.SubscriptionMutex.Unlock(subId) - return diag.FromErr(err) + return append(diags, diag.FromErr(err)...) } // Some attributes on a database are not accessible by the subscription creation API. // Run the subscription update function to apply any additional changes to the databases, such as password, enableDefaultUser and so on. utils.SubscriptionMutex.Unlock(subId) - return resourceRedisCloudProDatabaseUpdate(ctx, d, meta) + updateDiags := resourceRedisCloudProDatabaseUpdate(ctx, d, meta) + return append(diags, updateDiags...) } func resourceRedisCloudProDatabaseRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { @@ -714,6 +726,7 @@ func resourceRedisCloudProDatabaseDelete(ctx context.Context, d *schema.Resource func resourceRedisCloudProDatabaseUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { api := meta.(*client.ApiClient) + var diags diag.Diagnostics _, dbId, err := ToDatabaseId(d.Id()) if err != nil { @@ -821,7 +834,7 @@ func resourceRedisCloudProDatabaseUpdate(ctx context.Context, d *schema.Resource update.ClientSSLCertificate = redis.String(clientSSLCertificate) } else if len(clientTLSCertificates) > 0 { utils.SubscriptionMutex.Unlock(subId) - return diag.Errorf("TLS certificates may not be provided while enable_tls is false") + return append(diags, diag.Errorf("TLS certificates may not be provided while enable_tls is false")...) } else { // Default: enable_tls=false, client_ssl_certificate="" update.EnableTls = redis.Bool(enableTLS) @@ -845,14 +858,25 @@ func resourceRedisCloudProDatabaseUpdate(ctx context.Context, d *schema.Resource update.RespVersion = redis.String(respVersion) } + // Warn if modules are explicitly configured for Redis 8.0+ + redisVersion := d.Get("redis_version").(string) + modules := d.Get("modules").(*schema.Set) + if shouldWarnRedis8Modules(redisVersion, modules.Len() > 0) { + diags = append(diags, diag.Diagnostic{ + Severity: diag.Warning, + Summary: "Modules are bundled by default in Redis 8.0+", + Detail: fmt.Sprintf("The 'modules' block is deprecated for Redis %s and later versions, as modules (RediSearch, RedisJSON, RedisBloom, RedisTimeSeries) are bundled by default. You should remove the 'modules' block from your configuration.", redisVersion), + }) + } + // Confirm sub + db are ready to accept a db request if err := utils.WaitForSubscriptionToBeActive(ctx, subId, api); err != nil { utils.SubscriptionMutex.Unlock(subId) - return diag.FromErr(err) + return append(diags, diag.FromErr(err)...) } if err := utils.WaitForDatabaseToBeActive(ctx, subId, dbId, api); err != nil { utils.SubscriptionMutex.Unlock(subId) - return diag.FromErr(err) + return append(diags, diag.FromErr(err)...) } // if redis_version has changed, then upgrade first @@ -863,11 +887,11 @@ func resourceRedisCloudProDatabaseUpdate(ctx context.Context, d *schema.Resource // if either version is blank, it could attempt to upgrade unnecessarily. // only upgrade when a known version goes to another known version if originalVersion.(string) != "" && newVersion.(string) != "" { - if diags, unlocked := upgradeRedisVersion(ctx, api, subId, dbId, newVersion.(string)); diags != nil { + if upgradeDiags, unlocked := upgradeRedisVersion(ctx, api, subId, dbId, newVersion.(string)); upgradeDiags != nil { if !unlocked { utils.SubscriptionMutex.Unlock(subId) } - return diags + return append(diags, upgradeDiags...) } } } @@ -876,26 +900,27 @@ func resourceRedisCloudProDatabaseUpdate(ctx context.Context, d *schema.Resource if err := api.Client.Database.Update(ctx, subId, dbId, update); err != nil { utils.SubscriptionMutex.Unlock(subId) - return diag.FromErr(err) + return append(diags, diag.FromErr(err)...) } // Confirm db + sub active status if err := utils.WaitForDatabaseToBeActive(ctx, subId, dbId, api); err != nil { utils.SubscriptionMutex.Unlock(subId) - return diag.FromErr(err) + return append(diags, diag.FromErr(err)...) } if err := utils.WaitForSubscriptionToBeActive(ctx, subId, api); err != nil { utils.SubscriptionMutex.Unlock(subId) - return diag.FromErr(err) + return append(diags, diag.FromErr(err)...) } // The Tags API is synchronous so we shouldn't have to wait for anything if err := WriteTags(ctx, api, subId, dbId, d); err != nil { - return diag.FromErr(err) + return append(diags, diag.FromErr(err)...) } utils.SubscriptionMutex.Unlock(subId) - return resourceRedisCloudProDatabaseRead(ctx, d, meta) + readDiags := resourceRedisCloudProDatabaseRead(ctx, d, meta) + return append(diags, readDiags...) } func upgradeRedisVersion(ctx context.Context, api *client.ApiClient, subId int, dbId int, newVersion string) (diag.Diagnostics, bool) { @@ -1094,17 +1119,8 @@ func modulesDiffSuppressFunc(k, oldValue, newValue string, d *schema.ResourceDat func validateModulesForRedis8() schema.CustomizeDiffFunc { return func(ctx context.Context, diff *schema.ResourceDiff, meta interface{}) error { - redisVersion, versionExists := diff.GetOk("redis_version") - modules, modulesExists := diff.GetOkExists("modules") - - if versionExists && modulesExists { - version := redisVersion.(string) - moduleSet := modules.(*schema.Set) - - if shouldWarnRedis8Modules(version, moduleSet.Len() > 0) { - log.Printf("[WARN] Modules are bundled by default in Redis %s. You should remove the modules block as it is deprecated for this version.", version) - } - } + // Module warnings are now shown to users in Create/Update functions + // This function is kept for potential future validation logic return nil } } diff --git a/provider/pro/resource_rediscloud_pro_subscription.go b/provider/pro/resource_rediscloud_pro_subscription.go index ff3a008a..91c7a4ac 100644 --- a/provider/pro/resource_rediscloud_pro_subscription.go +++ b/provider/pro/resource_rediscloud_pro_subscription.go @@ -371,12 +371,18 @@ func ResourceRedisCloudProSubscription() *schema.Resource { return false } - if old != new { - // The user is requesting a change - return false + // Suppress diff if user removes the deprecated attribute + if new == "" { + return true } - return true + // Suppress diff if no actual change + if old == new { + return true + } + + // User is requesting a version change - don't suppress + return false }, }, "maintenance_windows": { From 121ce054652d35f0f4709ce0e79936355112d2e2 Mon Sep 17 00:00:00 2001 From: Matthew Long Date: Mon, 27 Oct 2025 17:40:54 +0000 Subject: [PATCH 09/12] fix: comparison for redis versions works better with helper function (especially for redis 10+) --- provider/pro/resource_rediscloud_pro_database.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provider/pro/resource_rediscloud_pro_database.go b/provider/pro/resource_rediscloud_pro_database.go index 81ab6283..ffcbaf6b 100644 --- a/provider/pro/resource_rediscloud_pro_database.go +++ b/provider/pro/resource_rediscloud_pro_database.go @@ -571,7 +571,7 @@ func resourceRedisCloudProDatabaseRead(ctx context.Context, d *schema.ResourceDa // For Redis 8.0+, modules are bundled by default and returned by the API // Only set modules in state if they were explicitly defined in the config redisVersion := redis.StringValue(db.RedisVersion) - if redisVersion >= "8.0" { + if shouldSuppressModuleDiffsForRedis8(redisVersion) { // Only set modules if they were explicitly configured by the user if _, ok := d.GetOk("modules"); ok { if err := d.Set("modules", FlattenModules(db.Modules)); err != nil { From c5d7bbcee7d4a9ed8abc81e990153b48b5103ab8 Mon Sep 17 00:00:00 2001 From: Matthew Long Date: Mon, 27 Oct 2025 17:52:41 +0000 Subject: [PATCH 10/12] docs: changelog update --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3eec528..56c9e183 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ See updating [Changelog example here](https://keepachangelog.com/en/1.0.0/) - rediscloud_subscription_database: The query_performance_factor attribute can now be updated in-place without recreating the database. Previously, any changes to this attribute would force resource replacement. - rediscloud_subscription_database (Redis 8.0+): Fixed drift detection issues where explicitly configured modules would incorrectly show as changes requiring resource replacement after upgrading to Redis 8.0 or higher. Modules are bundled by default in Redis 8.0+, so configuration differences are now properly suppressed. +- rediscloud_subscription_database (Redis 8.0+): The warning for modules has been made more prominent. - Test Suite: Fixed incorrect file path references in acceptance tests. # 2.7.0 (22nd October 2025) From 233d23fc5596c928606e871b8723c934f5e8c4a2 Mon Sep 17 00:00:00 2001 From: Matthew Long Date: Mon, 27 Oct 2025 17:53:42 +0000 Subject: [PATCH 11/12] docs: changelog update --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56c9e183..d71914aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ See updating [Changelog example here](https://keepachangelog.com/en/1.0.0/) - rediscloud_subscription_database (Redis 8.0+): Fixed drift detection issues where explicitly configured modules would incorrectly show as changes requiring resource replacement after upgrading to Redis 8.0 or higher. Modules are bundled by default in Redis 8.0+, so configuration differences are now properly suppressed. - rediscloud_subscription_database (Redis 8.0+): The warning for modules has been made more prominent. +- Support for a new pending status for subscription and database updates. - Test Suite: Fixed incorrect file path references in acceptance tests. # 2.7.0 (22nd October 2025) From a47ce348b85da49882a9d62b43f2065c095c5603 Mon Sep 17 00:00:00 2001 From: Matthew Long Date: Tue, 28 Oct 2025 09:53:18 +0000 Subject: [PATCH 12/12] fix: adding logs for invalid database modules in redis 8 --- .../pro/resource_rediscloud_pro_database.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/provider/pro/resource_rediscloud_pro_database.go b/provider/pro/resource_rediscloud_pro_database.go index ffcbaf6b..9e04c16d 100644 --- a/provider/pro/resource_rediscloud_pro_database.go +++ b/provider/pro/resource_rediscloud_pro_database.go @@ -1119,8 +1119,23 @@ func modulesDiffSuppressFunc(k, oldValue, newValue string, d *schema.ResourceDat func validateModulesForRedis8() schema.CustomizeDiffFunc { return func(ctx context.Context, diff *schema.ResourceDiff, meta interface{}) error { - // Module warnings are now shown to users in Create/Update functions - // This function is kept for potential future validation logic + // Check if modules are configured for Redis 8.0+ + redisVersionRaw, ok := diff.GetOk("redis_version") + if !ok { + return nil + } + redisVersion := redisVersionRaw.(string) + + modulesRaw, ok := diff.GetOk("modules") + if !ok { + return nil + } + modules := modulesRaw.(*schema.Set) + + if shouldWarnRedis8Modules(redisVersion, modules.Len() > 0) { + log.Printf("[WARN] Modules are bundled by default in Redis %s and later versions. The 'modules' block is deprecated for Redis 8.0+ as modules (RediSearch, RedisJSON, RedisBloom, RedisTimeSeries) are bundled by default. You should remove the 'modules' block from your configuration.", redisVersion) + } + return nil } }