Skip to content

[bugfix] aws_elasticache_cluster plan time validation for transit_encryption_enabled - #49114

Open
sukumaar wants to merge 4 commits into
hashicorp:mainfrom
sukumaar:f-elasticache-cluster-transit-encryption
Open

[bugfix] aws_elasticache_cluster plan time validation for transit_encryption_enabled#49114
sukumaar wants to merge 4 commits into
hashicorp:mainfrom
sukumaar:f-elasticache-cluster-transit-encryption

Conversation

@sukumaar

@sukumaar sukumaar commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Rollback Plan

If a change needs to be reverted, we will publish an updated version of the library.

Changes to Security Controls

Are there any changes to security controls (access controls, encryption, logging) in this pull request? If so, explain.

Description

Adds plan-time validation to aws_elasticache_cluster that rejects transit_encryption_enabled = true when the engine is Redis or Valkey. The AWS CreateCacheCluster API does not support transit encryption for these engines; it's only supported via CreateReplicationGroup (i.e., aws_elasticache_replication_group).

Previously, users would get a confusing API error during terraform apply:

InvalidParameterCombination: Encryption feature is not supported for engine REDIS.

Now they get a clear error at terraform plan time:

engine "redis" does not support transit_encryption_enabled on standalone clusters, use aws_elasticache_replication_group instead

Why this PR over #49103

#49103 is docs-only. It fixes the wording but users can still pass the invalid config through plan and only fail at apply. This PR adds plan-time validation (the standard pattern in this provider for known API incompatibilities), covers Valkey, includes test coverage, and adds a changelog entry.

Relations

Closes #49066
Relates #22123

References

Output from Acceptance Testing

% make testacc TESTS=TestAccElastiCacheCluster PKG=elasticache ACCTEST_PARALLELISM=1 ACCTEST_TIMEOUT=4880m
make: Verifying source code with gofmt...
==> Checking that code complies with gofmt requirements...
xargs: gofmt: No such file or directory
make: Validating schemas
ok  	github.com/hashicorp/terraform-provider-aws/internal/provider/sdkv2	0.249s
ok  	github.com/hashicorp/terraform-provider-aws/internal/provider/framework	0.228s
make: Running acceptance tests on branch: 🌿 f-elasticache-cluster-transit-encryption 🌿...
TF_ACC=1 go1.26.5 test ./internal/service/elasticache/... -v -count 1 -parallel 1 -run='TestAccElastiCacheCluster'  -timeout 4880m -vet=off -buildvcs=false
2026/07/28 15:36:19 Creating Terraform AWS Provider (SDKv2-style)...
2026/07/28 15:36:19 Initializing Terraform AWS Provider (SDKv2-style)...
=== RUN   TestAccElastiCacheClusterDataSource_basic
=== PAUSE TestAccElastiCacheClusterDataSource_basic
=== RUN   TestAccElastiCacheClusterDataSource_Engine_Redis_LogDeliveryConfigurations
=== PAUSE TestAccElastiCacheClusterDataSource_Engine_Redis_LogDeliveryConfigurations
=== RUN   TestAccElastiCacheCluster_Engine_memcached
=== PAUSE TestAccElastiCacheCluster_Engine_memcached
=== RUN   TestAccElastiCacheCluster_Engine_redis
=== PAUSE TestAccElastiCacheCluster_Engine_redis
=== RUN   TestAccElastiCacheCluster_Engine_valkey
=== PAUSE TestAccElastiCacheCluster_Engine_valkey
=== RUN   TestAccElastiCacheCluster_disappears
=== PAUSE TestAccElastiCacheCluster_disappears
=== RUN   TestAccElastiCacheCluster_Engine_redis_v5
=== PAUSE TestAccElastiCacheCluster_Engine_redis_v5
=== RUN   TestAccElastiCacheCluster_Engine_None
=== PAUSE TestAccElastiCacheCluster_Engine_None
=== RUN   TestAccElastiCacheCluster_PortRedis_default
=== PAUSE TestAccElastiCacheCluster_PortRedis_default
=== RUN   TestAccElastiCacheCluster_ParameterGroupName_default
=== PAUSE TestAccElastiCacheCluster_ParameterGroupName_default
=== RUN   TestAccElastiCacheCluster_ipDiscovery
=== PAUSE TestAccElastiCacheCluster_ipDiscovery
=== RUN   TestAccElastiCacheCluster_port
=== PAUSE TestAccElastiCacheCluster_port
=== RUN   TestAccElastiCacheCluster_snapshotsWithUpdates
=== PAUSE TestAccElastiCacheCluster_snapshotsWithUpdates
=== RUN   TestAccElastiCacheCluster_NumCacheNodes_decrease
=== PAUSE TestAccElastiCacheCluster_NumCacheNodes_decrease
=== RUN   TestAccElastiCacheCluster_NumCacheNodes_increase
=== PAUSE TestAccElastiCacheCluster_NumCacheNodes_increase
=== RUN   TestAccElastiCacheCluster_NumCacheNodes_increaseWithPreferredAvailabilityZones
=== PAUSE TestAccElastiCacheCluster_NumCacheNodes_increaseWithPreferredAvailabilityZones
=== RUN   TestAccElastiCacheCluster_vpc
=== PAUSE TestAccElastiCacheCluster_vpc
=== RUN   TestAccElastiCacheCluster_multiAZInVPC
=== PAUSE TestAccElastiCacheCluster_multiAZInVPC
=== RUN   TestAccElastiCacheCluster_AZMode_memcached
=== PAUSE TestAccElastiCacheCluster_AZMode_memcached
=== RUN   TestAccElastiCacheCluster_AZMode_redis
=== PAUSE TestAccElastiCacheCluster_AZMode_redis
=== RUN   TestAccElastiCacheCluster_EngineVersion_memcached
=== PAUSE TestAccElastiCacheCluster_EngineVersion_memcached
=== RUN   TestAccElastiCacheCluster_EngineVersion_redis
=== PAUSE TestAccElastiCacheCluster_EngineVersion_redis
=== RUN   TestAccElastiCacheCluster_NodeTypeResize_memcached
=== PAUSE TestAccElastiCacheCluster_NodeTypeResize_memcached
=== RUN   TestAccElastiCacheCluster_NodeTypeResize_redis
=== PAUSE TestAccElastiCacheCluster_NodeTypeResize_redis
=== RUN   TestAccElastiCacheCluster_NumCacheNodes_redis
=== PAUSE TestAccElastiCacheCluster_NumCacheNodes_redis
=== RUN   TestAccElastiCacheCluster_ReplicationGroupID_availabilityZone
=== PAUSE TestAccElastiCacheCluster_ReplicationGroupID_availabilityZone
=== RUN   TestAccElastiCacheCluster_ReplicationGroupID_transitEncryption
=== PAUSE TestAccElastiCacheCluster_ReplicationGroupID_transitEncryption
=== RUN   TestAccElastiCacheCluster_ReplicationGroupID_singleReplica
=== PAUSE TestAccElastiCacheCluster_ReplicationGroupID_singleReplica
=== RUN   TestAccElastiCacheCluster_ReplicationGroupID_multipleReplica
=== PAUSE TestAccElastiCacheCluster_ReplicationGroupID_multipleReplica
=== RUN   TestAccElastiCacheCluster_Memcached_finalSnapshot
=== PAUSE TestAccElastiCacheCluster_Memcached_finalSnapshot
=== RUN   TestAccElastiCacheCluster_Redis_finalSnapshot
=== PAUSE TestAccElastiCacheCluster_Redis_finalSnapshot
=== RUN   TestAccElastiCacheCluster_Redis_autoMinorVersionUpgrade
=== PAUSE TestAccElastiCacheCluster_Redis_autoMinorVersionUpgrade
=== RUN   TestAccElastiCacheCluster_Engine_Redis_LogDeliveryConfigurations
=== PAUSE TestAccElastiCacheCluster_Engine_Redis_LogDeliveryConfigurations
=== RUN   TestAccElastiCacheCluster_tags
=== PAUSE TestAccElastiCacheCluster_tags
=== RUN   TestAccElastiCacheCluster_tagWithOtherModification
=== PAUSE TestAccElastiCacheCluster_tagWithOtherModification
=== RUN   TestAccElastiCacheCluster_TransitEncryption
=== PAUSE TestAccElastiCacheCluster_TransitEncryption
=== RUN   TestAccElastiCacheCluster_TransitEncryption_redisVPC
=== PAUSE TestAccElastiCacheCluster_TransitEncryption_redisVPC
=== RUN   TestAccElastiCacheCluster_outpost_memcached
=== PAUSE TestAccElastiCacheCluster_outpost_memcached
=== RUN   TestAccElastiCacheCluster_outpost_redis
=== PAUSE TestAccElastiCacheCluster_outpost_redis
=== RUN   TestAccElastiCacheCluster_outpostID_memcached
=== PAUSE TestAccElastiCacheCluster_outpostID_memcached
=== RUN   TestAccElastiCacheCluster_outpostID_redis
=== PAUSE TestAccElastiCacheCluster_outpostID_redis
=== CONT  TestAccElastiCacheClusterDataSource_basic
--- PASS: TestAccElastiCacheClusterDataSource_basic (461.29s)
=== CONT  TestAccElastiCacheCluster_Memcached_finalSnapshot
--- PASS: TestAccElastiCacheCluster_Memcached_finalSnapshot (2.65s)
=== CONT  TestAccElastiCacheCluster_outpostID_redis
    cluster_test.go:1481: skipping since no Outposts found
--- SKIP: TestAccElastiCacheCluster_outpostID_redis (0.12s)
=== CONT  TestAccElastiCacheCluster_outpostID_memcached
    cluster_test.go:1448: skipping since no Outposts found
--- SKIP: TestAccElastiCacheCluster_outpostID_memcached (0.11s)
=== CONT  TestAccElastiCacheCluster_tags
--- PASS: TestAccElastiCacheCluster_tags (470.58s)
=== CONT  TestAccElastiCacheCluster_Engine_Redis_LogDeliveryConfigurations
--- PASS: TestAccElastiCacheCluster_Engine_Redis_LogDeliveryConfigurations (949.40s)
=== CONT  TestAccElastiCacheCluster_Redis_autoMinorVersionUpgrade
--- PASS: TestAccElastiCacheCluster_Redis_autoMinorVersionUpgrade (469.07s)
=== CONT  TestAccElastiCacheCluster_Redis_finalSnapshot
--- PASS: TestAccElastiCacheCluster_Redis_finalSnapshot (611.30s)
=== CONT  TestAccElastiCacheCluster_NumCacheNodes_increaseWithPreferredAvailabilityZones
--- PASS: TestAccElastiCacheCluster_NumCacheNodes_increaseWithPreferredAvailabilityZones (836.93s)
=== CONT  TestAccElastiCacheCluster_ReplicationGroupID_multipleReplica
--- PASS: TestAccElastiCacheCluster_ReplicationGroupID_multipleReplica (992.67s)
=== CONT  TestAccElastiCacheCluster_ReplicationGroupID_singleReplica
--- PASS: TestAccElastiCacheCluster_ReplicationGroupID_singleReplica (997.51s)
=== CONT  TestAccElastiCacheCluster_ReplicationGroupID_transitEncryption
--- PASS: TestAccElastiCacheCluster_ReplicationGroupID_transitEncryption (959.02s)
=== CONT  TestAccElastiCacheCluster_ReplicationGroupID_availabilityZone
--- PASS: TestAccElastiCacheCluster_ReplicationGroupID_availabilityZone (978.01s)
=== CONT  TestAccElastiCacheCluster_NumCacheNodes_redis
--- PASS: TestAccElastiCacheCluster_NumCacheNodes_redis (2.66s)
=== CONT  TestAccElastiCacheCluster_tagWithOtherModification
--- PASS: TestAccElastiCacheCluster_tagWithOtherModification (1097.52s)
=== CONT  TestAccElastiCacheCluster_NodeTypeResize_redis
--- PASS: TestAccElastiCacheCluster_NodeTypeResize_redis (1071.94s)
=== CONT  TestAccElastiCacheCluster_outpost_redis
    cluster_test.go:1408: skipping since no Outposts found
--- SKIP: TestAccElastiCacheCluster_outpost_redis (0.12s)
=== CONT  TestAccElastiCacheCluster_NodeTypeResize_memcached
--- PASS: TestAccElastiCacheCluster_NodeTypeResize_memcached (842.30s)
=== CONT  TestAccElastiCacheCluster_TransitEncryption
--- PASS: TestAccElastiCacheCluster_TransitEncryption (467.93s)
=== CONT  TestAccElastiCacheCluster_EngineVersion_redis
--- PASS: TestAccElastiCacheCluster_EngineVersion_redis (3277.70s)
=== CONT  TestAccElastiCacheCluster_EngineVersion_memcached
--- PASS: TestAccElastiCacheCluster_EngineVersion_memcached (929.14s)
=== CONT  TestAccElastiCacheCluster_AZMode_memcached
--- PASS: TestAccElastiCacheCluster_AZMode_memcached (525.34s)
=== CONT  TestAccElastiCacheCluster_multiAZInVPC
--- PASS: TestAccElastiCacheCluster_multiAZInVPC (606.61s)
=== CONT  TestAccElastiCacheCluster_AZMode_redis
--- PASS: TestAccElastiCacheCluster_AZMode_redis (433.64s)
=== CONT  TestAccElastiCacheCluster_vpc
--- PASS: TestAccElastiCacheCluster_vpc (405.98s)
=== CONT  TestAccElastiCacheCluster_outpost_memcached
    cluster_test.go:1368: skipping since no Outposts found
--- SKIP: TestAccElastiCacheCluster_outpost_memcached (0.11s)
=== CONT  TestAccElastiCacheCluster_PortRedis_default
--- PASS: TestAccElastiCacheCluster_PortRedis_default (431.46s)
=== CONT  TestAccElastiCacheCluster_NumCacheNodes_increase
--- PASS: TestAccElastiCacheCluster_NumCacheNodes_increase (796.32s)
=== CONT  TestAccElastiCacheCluster_TransitEncryption_redisVPC
--- PASS: TestAccElastiCacheCluster_TransitEncryption_redisVPC (2.71s)
=== CONT  TestAccElastiCacheCluster_Engine_valkey
--- PASS: TestAccElastiCacheCluster_Engine_valkey (2.44s)
=== CONT  TestAccElastiCacheCluster_Engine_None
--- PASS: TestAccElastiCacheCluster_Engine_None (2.41s)
=== CONT  TestAccElastiCacheCluster_NumCacheNodes_decrease
--- PASS: TestAccElastiCacheCluster_NumCacheNodes_decrease (614.68s)
=== CONT  TestAccElastiCacheCluster_Engine_memcached
--- PASS: TestAccElastiCacheCluster_Engine_memcached (404.35s)
=== CONT  TestAccElastiCacheCluster_snapshotsWithUpdates
--- PASS: TestAccElastiCacheCluster_snapshotsWithUpdates (454.28s)
=== CONT  TestAccElastiCacheCluster_Engine_redis
--- PASS: TestAccElastiCacheCluster_Engine_redis (395.20s)
=== CONT  TestAccElastiCacheCluster_Engine_redis_v5
--- PASS: TestAccElastiCacheCluster_Engine_redis_v5 (435.19s)
=== CONT  TestAccElastiCacheCluster_port
--- PASS: TestAccElastiCacheCluster_port (434.81s)
=== CONT  TestAccElastiCacheCluster_disappears
--- PASS: TestAccElastiCacheCluster_disappears (434.10s)
=== CONT  TestAccElastiCacheCluster_ipDiscovery
--- PASS: TestAccElastiCacheCluster_ipDiscovery (460.02s)
=== CONT  TestAccElastiCacheCluster_ParameterGroupName_default
--- PASS: TestAccElastiCacheCluster_ParameterGroupName_default (445.61s)
=== CONT  TestAccElastiCacheClusterDataSource_Engine_Redis_LogDeliveryConfigurations
--- PASS: TestAccElastiCacheClusterDataSource_Engine_Redis_LogDeliveryConfigurations (549.87s)
PASS
ok  	github.com/hashicorp/terraform-provider-aws/internal/service/elasticache	23253.255s

@github-actions

Copy link
Copy Markdown
Contributor

Community Guidelines

This comment is added to every new Pull Request to provide quick reference to how the Terraform AWS Provider is maintained. Please review the information below, and thank you for contributing to the community that keeps the provider thriving! 🚀

Voting for Prioritization

  • Please vote on this Pull Request by adding a 👍 reaction to the original post to help the community and maintainers prioritize it.
  • Please see our prioritization guide for additional information on how the maintainers handle prioritization.
  • Please do not leave +1 or other comments that do not add relevant new information or questions; they generate extra noise for others following the Pull Request and do not help prioritize the request.

Pull Request Authors

  • Review the contribution guide relating to the type of change you are making to ensure all of the necessary steps have been taken.
  • Whether or not the branch has been rebased will not impact prioritization, but doing so is always a welcome surprise.

@github-actions github-actions Bot added needs-triage Waiting for first response or review from a maintainer. documentation Introduces or discusses updates to documentation. tests PRs: expanded test coverage. Issues: expanded coverage, enhancements to test infrastructure. service/elasticache Issues and PRs that pertain to the elasticache service. size/S Managed by automation to categorize the size of a PR. partner Contribution from a partner. labels Jul 24, 2026
@github-actions github-actions Bot added size/M Managed by automation to categorize the size of a PR. and removed size/S Managed by automation to categorize the size of a PR. labels Jul 24, 2026
@sukumaar sukumaar changed the title [bugfix] aws_elasticache_cluster transit-encryption validation [bugfix] aws_elasticache_cluster plan time validation for transit_encryption_enabled Jul 24, 2026
@sukumaar
sukumaar marked this pull request as ready for review July 24, 2026 21:40
@sukumaar
sukumaar requested a review from a team as a code owner July 24, 2026 21:40
@dosubot dosubot Bot added the bug Addresses a defect in current functionality. label Jul 24, 2026
@justinretzolk justinretzolk removed the needs-triage Waiting for first response or review from a maintainer. label Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Addresses a defect in current functionality. documentation Introduces or discusses updates to documentation. partner Contribution from a partner. service/elasticache Issues and PRs that pertain to the elasticache service. size/M Managed by automation to categorize the size of a PR. tests PRs: expanded test coverage. Issues: expanded coverage, enhancements to test infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: aws_elasticache_cluster , redis oss does not support transit_encryption_enabled

2 participants