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

r/aws_elasticache_cluster: Add support for in-transit encryption #26987

Merged
11 changes: 11 additions & 0 deletions internal/service/elasticache/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,12 @@ func ResourceCluster() *schema.Resource {
Computed: true,
ForceNew: true,
},
"transit_encryption_enabled": {
Type: schema.TypeBool,
ForceNew: true,
Optional: true,
Default: false,
},
names.AttrTags: tftags.TagsSchema(),
names.AttrTagsAll: tftags.TagsSchemaComputed(),
},
Expand All @@ -334,6 +340,7 @@ func ResourceCluster() *schema.Resource {
CustomizeDiffValidateClusterNumCacheNodes,
CustomizeDiffClusterMemcachedNodeType,
CustomizeDiffValidateClusterMemcachedSnapshotIdentifier,
CustomizeDiffValidateTransitEncryptionEnabled,
verify.SetTagsDiff,
),
}
Expand Down Expand Up @@ -434,6 +441,10 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta int
input.SnapshotName = aws.String(v.(string))
}

if v, ok := d.GetOk("transit_encryption_enabled"); ok {
input.TransitEncryptionEnabled = aws.Bool(v.(bool))
}

if v, ok := d.GetOk("az_mode"); ok {
input.AZMode = aws.String(v.(string))
}
Expand Down
45 changes: 45 additions & 0 deletions internal/service/elasticache/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,37 @@ func TestAccElastiCacheCluster_tagWithOtherModification(t *testing.T) {
})
}

func TestAccElastiCacheCluster_TransitEncryption(t *testing.T) {
ctx := acctest.Context(t)
if testing.Short() {
t.Skip("skipping long-running test in short mode")
}
var cluster elasticache.CacheCluster
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_elasticache_cluster.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, elasticache.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckClusterDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccClusterConfig_transitEncryption(rName, "memcached", "1.6.11"),
ExpectError: regexp.MustCompile(`Transit encryption is not supported for memcached version 1.6.11`),
},
{
Config: testAccClusterConfig_transitEncryption(rName, "redis", "6.2"),
ExpectError: regexp.MustCompile(`aws_elasticache_cluster does not support transit encryption using the redis engine, use aws_elasticache_replication_group instead`),
},
{
Config: testAccClusterConfig_transitEncryption(rName, "memcached", "1.6.12"),
Check: testAccCheckClusterExists(ctx, resourceName, &cluster),
},
},
})
}

func TestAccElastiCacheCluster_outpost_memcached(t *testing.T) {
ctx := acctest.Context(t)
if testing.Short() {
Expand Down Expand Up @@ -2152,3 +2183,17 @@ resource "aws_elasticache_cluster" "test" {
}
`, rName, version, tagKey1, tagValue1)
}

func testAccClusterConfig_transitEncryption(rName, engine, version string) string {
return fmt.Sprintf(`
resource "aws_elasticache_cluster" "test" {
apply_immediately = true
cluster_id = "%[1]s"
engine = "%[2]s"
engine_version = "%[3]s"
node_type = "cache.t3.medium"
num_cache_nodes = 1
transit_encryption_enabled = true
}
`, rName, engine, version)
}
39 changes: 39 additions & 0 deletions internal/service/elasticache/transit_encryption.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package elasticache

import (
"context"
"fmt"

gversion "github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

var minMemcachedTransitEncryptionVersion = gversion.Must(gversion.NewVersion("1.6.12"))

func CustomizeDiffValidateTransitEncryptionEnabled(_ context.Context, diff *schema.ResourceDiff, _ interface{}) error {
engine := diff.Get("engine").(string)

transitEncryptionEnabled, ok := diff.GetOk("transit_encryption_enabled")
if !ok || !transitEncryptionEnabled.(bool) {
return nil
}

if engine == engineRedis {
return fmt.Errorf("aws_elasticache_cluster does not support transit encryption using the redis engine, use aws_elasticache_replication_group instead")
}

engineVersion, ok := diff.GetOk("engine_version")
if !ok {
return nil
}

version, err := normalizeEngineVersion(engineVersion.(string))
if err != nil {
return err
}

if version.LessThan(minMemcachedTransitEncryptionVersion) {
return fmt.Errorf("Transit encryption is not supported for memcached version %v", version)
}
return nil
}
1 change: 1 addition & 0 deletions website/docs/r/elasticache_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ The minimum maintenance window is a 60 minute period. Example: `sun:05:00-sun:09
* `snapshot_window` - (Optional, Redis only) Daily time range (in UTC) during which ElastiCache will begin taking a daily snapshot of your cache cluster. Example: 05:00-09:00
* `subnet_group_name` – (Optional, VPC only) Name of the subnet group to be used for the cache cluster. Changing this value will re-create the resource.
* `tags` - (Optional) Map of tags to assign to the resource. 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 Memcached only, VPC Only) If true, enable encryption in transit. See the documentation for [ElastiCache in-transit encryption](https://docs.aws.amazon.com/AmazonElastiCache/latest/mem-ug/in-transit-encryption-mc.html).

## Attributes Reference

Expand Down