From 5a2fce230e2c9e592319490ce31897685fa21cd1 Mon Sep 17 00:00:00 2001 From: Olamide Date: Thu, 30 Apr 2026 11:08:04 +0100 Subject: [PATCH 1/2] Enable cache to use cluster mode with node groups --- elasticache-redis/replication-group/README.md | 2 + elasticache-redis/replication-group/main.tf | 7 +++- .../replication-group/variables.tf | 37 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/elasticache-redis/replication-group/README.md b/elasticache-redis/replication-group/README.md index 2ac44c8..8666f2f 100644 --- a/elasticache-redis/replication-group/README.md +++ b/elasticache-redis/replication-group/README.md @@ -53,9 +53,11 @@ Provision a Redis cluster using AWS ElastiCache. | [kms\_key](#input\_kms\_key) | Custom KMS key to encrypt data at rest | `object({ arn = string })` | `null` | no | | [name](#input\_name) | Name for this cluster | `string` | n/a | yes | | [node\_type](#input\_node\_type) | Node type for the Elasticache instance | `string` | n/a | yes | +| [num\_node\_groups](#input\_num\_node\_groups) | Number of node groups (shards) to create when sharding is enabled | `number` | `null` | no | | [parameter\_group\_name](#input\_parameter\_group\_name) | Parameter group name for the Redis cluster | `string` | `null` | no | | [port](#input\_port) | Port on which to listen | `number` | `6379` | no | | [replica\_count](#input\_replica\_count) | Number of read-only replicas to add to the cluster | `number` | `1` | no | +| [replicas\_per\_node\_group](#input\_replicas\_per\_node\_group) | Number of replicas to create in each node group when num\_node\_groups is set | `number` | `null` | no | | [replication\_group\_id](#input\_replication\_group\_id) | Override the ID for the replication group | `string` | `""` | no | | [server\_security\_group\_ids](#input\_server\_security\_group\_ids) | IDs of VPC security groups for this instance. One of vpc\_id or server\_security\_group\_ids is required | `list(string)` | `[]` | no | | [server\_security\_group\_name](#input\_server\_security\_group\_name) | Override the name for the security group; defaults to identifer | `string` | `""` | no | diff --git a/elasticache-redis/replication-group/main.tf b/elasticache-redis/replication-group/main.tf index 74d0630..4b1624d 100644 --- a/elasticache-redis/replication-group/main.tf +++ b/elasticache-redis/replication-group/main.tf @@ -8,9 +8,11 @@ resource "aws_elasticache_replication_group" "this" { kms_key_id = var.kms_key == null ? null : var.kms_key.id multi_az_enabled = local.replica_enabled node_type = var.node_type - num_cache_clusters = local.instance_count + num_cache_clusters = local.use_num_node_groups ? null : local.instance_count + num_node_groups = local.num_node_groups parameter_group_name = var.parameter_group_name port = var.port + replicas_per_node_group = local.replicas_per_node_group description = var.description security_group_ids = local.server_security_group_ids snapshot_name = var.snapshot_name @@ -176,8 +178,11 @@ locals { instance_size = split(".", var.node_type)[2] instances = sort(aws_elasticache_replication_group.this.member_clusters) owned_security_group_ids = module.server_security_group.*.id + num_node_groups = local.use_num_node_groups ? var.num_node_groups : null replica_enabled = var.replica_count > 0 + replicas_per_node_group = local.use_num_node_groups ? coalesce(var.replicas_per_node_group, (local.instance_count / local.num_node_groups) - 1) : null shared_security_group_ids = var.server_security_group_ids + use_num_node_groups = local.replica_enabled && var.num_node_groups != null instance_size_thresholds = { micro = 128 diff --git a/elasticache-redis/replication-group/variables.tf b/elasticache-redis/replication-group/variables.tf index 91224ee..2a70d21 100644 --- a/elasticache-redis/replication-group/variables.tf +++ b/elasticache-redis/replication-group/variables.tf @@ -48,6 +48,27 @@ variable "node_type" { description = "Node type for the Elasticache instance" } +variable "num_node_groups" { + type = number + default = null + description = "Number of node groups (shards) to create when sharding is enabled" + + validation { + condition = var.num_node_groups == null || var.replica_count > 0 + error_message = "num_node_groups can only be set when replica_count is greater than 0." + } + + validation { + condition = var.num_node_groups == null || var.num_node_groups <= (var.replica_count + 1) + error_message = "num_node_groups cannot exceed the total instance count implied by replica_count + 1." + } + + validation { + condition = var.num_node_groups == null || var.replicas_per_node_group != null || ((var.replica_count + 1) % var.num_node_groups == 0) + error_message = "When num_node_groups is set without replicas_per_node_group, replica_count + 1 must divide evenly across node groups." + } +} + variable "parameter_group_name" { type = string description = "Parameter group name for the Redis cluster" @@ -66,6 +87,22 @@ variable "replica_count" { description = "Number of read-only replicas to add to the cluster" } +variable "replicas_per_node_group" { + type = number + default = null + description = "Number of replicas to create in each node group when num_node_groups is set" + + validation { + condition = var.replicas_per_node_group == null || var.num_node_groups != null + error_message = "replicas_per_node_group can only be set when num_node_groups is also set." + } + + validation { + condition = var.replicas_per_node_group == null || ((var.replica_count + 1) == (var.num_node_groups * (var.replicas_per_node_group + 1))) + error_message = "When replicas_per_node_group is set, replica_count + 1 must equal num_node_groups * (replicas_per_node_group + 1)." + } +} + variable "replication_group_id" { description = "Override the ID for the replication group" type = string From e8f1b30a4515f990475e85aeb6e0b4e23eecdf28 Mon Sep 17 00:00:00 2001 From: Olamide Date: Thu, 30 Apr 2026 11:15:22 +0100 Subject: [PATCH 2/2] Fix cycle error --- elasticache-redis/replication-group/main.tf | 10 ++++++++++ elasticache-redis/replication-group/variables.tf | 10 ---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/elasticache-redis/replication-group/main.tf b/elasticache-redis/replication-group/main.tf index 4b1624d..007aed3 100644 --- a/elasticache-redis/replication-group/main.tf +++ b/elasticache-redis/replication-group/main.tf @@ -48,6 +48,16 @@ resource "aws_elasticache_replication_group" "this" { # Minor upgrades will cause noise in diffs engine_version ] + + precondition { + condition = !local.use_num_node_groups || var.replicas_per_node_group != null || ((local.instance_count % var.num_node_groups) == 0) + error_message = "When num_node_groups is set without replicas_per_node_group, replica_count + 1 must divide evenly across node groups." + } + + precondition { + condition = var.replicas_per_node_group == null || (local.instance_count == (var.num_node_groups * (var.replicas_per_node_group + 1))) + error_message = "When replicas_per_node_group is set, replica_count + 1 must equal num_node_groups * (replicas_per_node_group + 1)." + } } } diff --git a/elasticache-redis/replication-group/variables.tf b/elasticache-redis/replication-group/variables.tf index 2a70d21..e7fb0d3 100644 --- a/elasticache-redis/replication-group/variables.tf +++ b/elasticache-redis/replication-group/variables.tf @@ -62,11 +62,6 @@ variable "num_node_groups" { condition = var.num_node_groups == null || var.num_node_groups <= (var.replica_count + 1) error_message = "num_node_groups cannot exceed the total instance count implied by replica_count + 1." } - - validation { - condition = var.num_node_groups == null || var.replicas_per_node_group != null || ((var.replica_count + 1) % var.num_node_groups == 0) - error_message = "When num_node_groups is set without replicas_per_node_group, replica_count + 1 must divide evenly across node groups." - } } variable "parameter_group_name" { @@ -96,11 +91,6 @@ variable "replicas_per_node_group" { condition = var.replicas_per_node_group == null || var.num_node_groups != null error_message = "replicas_per_node_group can only be set when num_node_groups is also set." } - - validation { - condition = var.replicas_per_node_group == null || ((var.replica_count + 1) == (var.num_node_groups * (var.replicas_per_node_group + 1))) - error_message = "When replicas_per_node_group is set, replica_count + 1 must equal num_node_groups * (replicas_per_node_group + 1)." - } } variable "replication_group_id" {