Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement]: aws elasticache redis - support redis v7 #31264

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changelog/31264.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
```release-note:bug
resource/aws_elasticache_cluster: Correctly supports ElastiCache Redis version 7+
```

```release-note:bug
resource/aws_elasticache_global_replication_group: Correctly supports ElastiCache Redis version 7+
```

```release-note:bug
resource/aws_elasticache_replication_group: Correctly supports ElastiCache Redis version 7+
```
20 changes: 7 additions & 13 deletions internal/service/elasticache/engine_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,10 @@ func validMemcachedVersionString(v interface{}, k string) (ws []string, errors [
}

const (
redisVersionPreV6RegexpRaw = `[1-5](\.[[:digit:]]+){2}`
redisVersionPostV6RegexpRaw = `(([6-9])\.x)|([6-9]\.[[:digit:]]+)`
redisVersionPreV6RegexpPattern = `^[1-5](\.[[:digit:]]+){2}$`
redisVersionPostV6RegexpPattern = `^((6)\.x)|([6-9]\.[[:digit:]]+)$`

redisVersionRegexpRaw = redisVersionPreV6RegexpRaw + "|" + redisVersionPostV6RegexpRaw
)

const (
redisVersionRegexpPattern = "^" + redisVersionRegexpRaw + "$"
redisVersionPostV6RegexpPattern = "^" + redisVersionPostV6RegexpRaw + "$"
redisVersionRegexpPattern = redisVersionPreV6RegexpPattern + "|" + redisVersionPostV6RegexpPattern
)

var (
Expand Down Expand Up @@ -128,15 +123,14 @@ func engineVersionForceNewOnDowngrade(diff forceNewDiffer) error {
return diff.ForceNew("engine_version")
}

// normalizeEngineVersion returns a github.com/hashicorp/go-version Version
// that can handle a regular 1.2.3 version number or either the 6.x or 6.0 version number used for
// ElastiCache Redis version 6 and higher. 6.x will sort to 6.<maxint>
// normalizeEngineVersion returns a github.com/hashicorp/go-version Version from:
// - a regular 1.2.3 version number
// - either the 6.x or 6.0 version number used for ElastiCache Redis version 6. 6.x will sort to 6.<maxint>
// - a 7.0 version number used from version 7
func normalizeEngineVersion(version string) (*gversion.Version, error) {
if matches := redisVersionPostV6Regexp.FindStringSubmatch(version); matches != nil {
if matches[1] != "" {
version = fmt.Sprintf("%s.%d", matches[2], math.MaxInt)
} else if matches[3] != "" {
version = matches[3]
}
}
return gversion.NewVersion(version)
Expand Down
128 changes: 100 additions & 28 deletions internal/service/elasticache/engine_version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,42 @@ func TestValidRedisVersionString(t *testing.T) {
version: "6.y",
valid: false,
},
{
version: "7.0",
valid: true,
},
{
version: "7.2",
valid: true,
},
{
version: "7.x",
valid: false,
},
{
version: "7.2.x",
valid: false,
},
{
version: "7.5.0",
valid: false,
},
{
version: "7.5.",
valid: false,
},
{
version: "7.",
valid: false,
},
{
version: "7",
valid: false,
},
{
version: "7.y",
valid: false,
},
}

for _, testcase := range testcases {
Expand Down Expand Up @@ -191,6 +227,11 @@ func TestValidateClusterEngineVersion(t *testing.T) {
version: "6.0",
valid: false,
},
{
engine: "",
version: "7.0",
valid: false,
},

{
engine: engineMemcached,
Expand All @@ -207,6 +248,11 @@ func TestValidateClusterEngineVersion(t *testing.T) {
version: "6.0",
valid: false,
},
{
engine: engineMemcached,
version: "7.0",
valid: false,
},

{
engine: engineRedis,
Expand All @@ -223,6 +269,11 @@ func TestValidateClusterEngineVersion(t *testing.T) {
version: "6.0",
valid: true,
},
{
engine: engineRedis,
version: "7.0",
valid: true,
},
}

for _, testcase := range testcases {
Expand Down Expand Up @@ -277,17 +328,17 @@ func TestCustomizeDiffEngineVersionIsDowngrade(t *testing.T) {
expected: false,
},

// "upgrade major 6.x": {
// old: "5.0.6",
// new: "6.x",
// expectForceNew: false,
// },
"upgrade major 6.x": {
old: "5.0.6",
new: "6.x",
expected: false,
},

// "upgrade major 6.digit": {
// old: "5.0.6",
// new: "6.0",
// expectForceNew: false,
// },
"upgrade major 6.digit": {
old: "5.0.6",
new: "6.0",
expected: false,
},

"downgrade minor versions": {
old: "1.3.5",
Expand Down Expand Up @@ -319,15 +370,15 @@ func TestCustomizeDiffEngineVersionIsDowngrade(t *testing.T) {
expected: false,
},

"downgrade from major 7.x to 6.x": {
old: "7.x",
"downgrade from major 7.digit to 6.x": {
old: "7.2",
new: "6.x",
expected: true,
},

"downgrade from major 7.digit to 6.x": {
"downgrade from major 7.digit to 6.digit": {
old: "7.2",
new: "6.x",
new: "6.2",
expected: true,
},
}
Expand Down Expand Up @@ -419,17 +470,23 @@ func TestCustomizeDiffEngineVersionForceNewOnDowngrade(t *testing.T) {
expectForceNew: false,
},

// "upgrade major 6.x": {
// old: "5.0.6",
// new: "6.x",
// expectForceNew: false,
// },
"upgrade major 6.x": {
old: "5.0.6",
new: "6.x",
expectForceNew: false,
},

"upgrade major 6.digit": {
old: "5.0.6",
new: "6.0",
expectForceNew: false,
},

// "upgrade major 6.digit": {
// old: "5.0.6",
// new: "6.0",
// expectForceNew: false,
// },
"upgrade major 7.digit": {
old: "6.x",
new: "7.0",
expectForceNew: false,
},

"downgrade minor versions": {
old: "1.3.5",
Expand Down Expand Up @@ -461,15 +518,21 @@ func TestCustomizeDiffEngineVersionForceNewOnDowngrade(t *testing.T) {
expectForceNew: false,
},

"downgrade from major 7.x to 6.x": {
old: "7.x",
"downgrade from major 7.digit to 6.x": {
old: "7.2",
new: "6.x",
expectForceNew: true,
},

"downgrade from major 7.digit to 6.x": {
"downgrade from major 7.digit to 6.digit": {
old: "7.2",
new: "6.x",
new: "6.2",
expectForceNew: true,
},

"downgrade major 7.digit": {
old: "7.2",
new: "7.0",
expectForceNew: true,
},
}
Expand Down Expand Up @@ -529,10 +592,19 @@ func TestNormalizeEngineVersion(t *testing.T) {
normalized: fmt.Sprintf("6.%d.0", math.MaxInt),
valid: true,
},
{
version: "7.2",
normalized: "7.2.0",
valid: true,
},
{
version: "5.x",
valid: false,
},
{
version: "7.x",
valid: false,
},
}

for _, testcase := range testcases {
Expand Down
46 changes: 46 additions & 0 deletions internal/service/elasticache/replication_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,41 @@ func TestAccElastiCacheReplicationGroup_uppercase(t *testing.T) {
})
}

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

var rg 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, elasticache.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckReplicationGroupDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccReplicationGroupConfig_v7(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckReplicationGroupExists(ctx, resourceName, &rg),
resource.TestCheckResourceAttr(resourceName, "engine", "redis"),
resource.TestCheckResourceAttr(resourceName, "engine_version", "7.0"),
resource.TestMatchResourceAttr(resourceName, "engine_version_actual", regexp.MustCompile(`^7\.[[:digit:]]+\.[[:digit:]]+$`)),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"apply_immediately"}, //not in the API
},
},
})
}

func TestAccElastiCacheReplicationGroup_EngineVersion_update(t *testing.T) {
ctx := acctest.Context(t)
if testing.Short() {
Expand Down Expand Up @@ -2802,6 +2837,17 @@ resource "aws_elasticache_replication_group" "test" {
`, rName)
}

func testAccReplicationGroupConfig_v7(rName string) string {
return fmt.Sprintf(`
resource "aws_elasticache_replication_group" "test" {
replication_group_id = %[1]q
replication_group_description = "test description"
node_type = "cache.t3.small"
engine_version = "7.0"
}
`, rName)
}

func testAccReplicationGroupConfig_uppercase(rName string) string {
return acctest.ConfigCompose(
acctest.ConfigVPCWithSubnets(rName, 2),
Expand Down
3 changes: 2 additions & 1 deletion website/docs/r/elasticache_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ The following arguments are optional:
* `engine_version` – (Optional) Version number of the cache engine to be used.
If not set, defaults to the latest version.
See [Describe Cache Engine Versions](https://docs.aws.amazon.com/cli/latest/reference/elasticache/describe-cache-engine-versions.html) in the AWS Documentation for supported versions.
When `engine` is `redis` and the version is 6 or higher, the major and minor version can be set, e.g., `6.2`,
When `engine` is `redis` and the version is 7 or higher, the major and minor version should be set, e.g., `7.2`.
When the version is 6, the major and minor version can be set, e.g., `6.2`,
or the minor version can be unspecified which will use the latest version at creation time, e.g., `6.x`.
Otherwise, specify the full version desired, e.g., `5.0.6`.
The actual engine version used is returned in the attribute `engine_version_actual`, see [Attributes Reference](#attributes-reference) below.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ The following arguments are supported:
When creating, by default the Global Replication Group inherits the version of the primary replication group.
If a version is specified, the Global Replication Group and all member replication groups will be upgraded to this version.
Cannot be downgraded without replacing the Global Replication Group and all member replication groups.
If the version is 6 or higher, the major and minor version can be set, e.g., `6.2`,
When the version is 7 or higher, the major and minor version should be set, e.g., `7.2`.
When the version is 6, the major and minor version can be set, e.g., `6.2`,
or the minor version can be unspecified which will use the latest version at creation time, e.g., `6.x`.
The actual engine version used is returned in the attribute `engine_version_actual`, see [Attributes Reference](#attributes-reference) below.
* `global_replication_group_id_suffix` – (Required) The suffix name of a Global Datastore. If `global_replication_group_id_suffix` is changed, creates a new resource.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ The following arguments are optional:
* `data_tiering_enabled` - (Optional) Enables data tiering. Data tiering is only supported for replication groups using the r6gd node type. This parameter must be set to `true` when using r6gd nodes.
* `engine` - (Optional) Name of the cache engine to be used for the clusters in this replication group. The only valid value is `redis`.
* `engine_version` - (Optional) Version number of the cache engine to be used for the cache clusters in this replication group.
If the version is 6 or higher, the major and minor version can be set, e.g., `6.2`,
If the version is 7 or higher, the major and minor version should be set, e.g., `7.2`.
If the version is 6, the major and minor version can be set, e.g., `6.2`,
or the minor version can be unspecified which will use the latest version at creation time, e.g., `6.x`.
Otherwise, specify the full version desired, e.g., `5.0.6`.
The actual engine version used is returned in the attribute `engine_version_actual`, see [Attributes Reference](#attributes-reference) below.
Expand Down