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..007aed3 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
@@ -46,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)."
+ }
}
}
@@ -176,8 +188,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..e7fb0d3 100644
--- a/elasticache-redis/replication-group/variables.tf
+++ b/elasticache-redis/replication-group/variables.tf
@@ -48,6 +48,22 @@ 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."
+ }
+}
+
variable "parameter_group_name" {
type = string
description = "Parameter group name for the Redis cluster"
@@ -66,6 +82,17 @@ 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."
+ }
+}
+
variable "replication_group_id" {
description = "Override the ID for the replication group"
type = string