Skip to content

Commit 202bad8

Browse files
authored
Merge pull request #7 from SPHTech-Platform/feat/add-elasticache-serverless-support
Add elasticache redis serverless support with awscc resource
2 parents a22e0bd + 7705b83 commit 202bad8

File tree

6 files changed

+216
-9
lines changed

6 files changed

+216
-9
lines changed

Diff for: README.md

+16-2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
|------|---------|
66
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
77
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.0 |
8+
| <a name="requirement_awscc"></a> [awscc](#requirement\_awscc) | >= 0.67.0 |
89

910
## Providers
1011

1112
| Name | Version |
1213
|------|---------|
1314
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.5.0 |
15+
| <a name="provider_awscc"></a> [awscc](#provider\_awscc) | 0.67.0 |
1416

1517
## Modules
1618

@@ -22,45 +24,57 @@ No modules.
2224
|------|------|
2325
| [aws_cloudwatch_metric_alarm.cache_cpu](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm) | resource |
2426
| [aws_cloudwatch_metric_alarm.cache_memory](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm) | resource |
27+
| [aws_cloudwatch_metric_alarm.cache_serverless_data](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm) | resource |
28+
| [aws_cloudwatch_metric_alarm.cache_serverless_ecpu](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm) | resource |
29+
| [aws_cloudwatch_metric_alarm.cache_serverless_throttled_commands](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_metric_alarm) | resource |
2530
| [aws_elasticache_parameter_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticache_parameter_group) | resource |
2631
| [aws_elasticache_replication_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticache_replication_group) | resource |
2732
| [aws_elasticache_subnet_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticache_subnet_group) | resource |
33+
| [awscc_elasticache_serverless_cache.this](https://registry.terraform.io/providers/hashicorp/awscc/latest/docs/resources/elasticache_serverless_cache) | resource |
2834

2935
## Inputs
3036

3137
| Name | Description | Type | Default | Required |
3238
|------|-------------|------|---------|:--------:|
3339
| <a name="input_alarm_actions"></a> [alarm\_actions](#input\_alarm\_actions) | The list of actions to execute when this alarm transitions into an ALARM state from any other state. | `list(string)` | `[]` | no |
3440
| <a name="input_alarm_cpu_threshold_percent"></a> [alarm\_cpu\_threshold\_percent](#input\_alarm\_cpu\_threshold\_percent) | CPU threshold alarm level | `number` | `75` | no |
41+
| <a name="input_alarm_data_threshold_percent"></a> [alarm\_data\_threshold\_percent](#input\_alarm\_data\_threshold\_percent) | Data threshold alarm level for elasticache serverless | `number` | `75` | no |
42+
| <a name="input_alarm_ecpu_threshold_percent"></a> [alarm\_ecpu\_threshold\_percent](#input\_alarm\_ecpu\_threshold\_percent) | ECPU threshold alarm level for elasticache serverless | `number` | `75` | no |
3543
| <a name="input_alarm_memory_threshold_bytes"></a> [alarm\_memory\_threshold\_bytes](#input\_alarm\_memory\_threshold\_bytes) | Alarm memory threshold bytes | `number` | `10000000` | no |
3644
| <a name="input_apply_immediately"></a> [apply\_immediately](#input\_apply\_immediately) | Specifies whether any database modifications are applied immediately, or during the next maintenance window | `bool` | `true` | no |
3745
| <a name="input_auth_token"></a> [auth\_token](#input\_auth\_token) | Password used to access a password protected server. Can be specified only if `transit_encryption_enabled = true` | `string` | `null` | no |
3846
| <a name="input_cluster_id"></a> [cluster\_id](#input\_cluster\_id) | Cluster ID | `string` | `null` | no |
3947
| <a name="input_cluster_mode_enabled"></a> [cluster\_mode\_enabled](#input\_cluster\_mode\_enabled) | Set to false to diable cluster module | `bool` | `false` | no |
4048
| <a name="input_cluster_size"></a> [cluster\_size](#input\_cluster\_size) | Cluster size | `number` | `1` | no |
4149
| <a name="input_create_elasticache_subnet_group"></a> [create\_elasticache\_subnet\_group](#input\_create\_elasticache\_subnet\_group) | Create Elasticache Subnet Group | `bool` | `true` | no |
50+
| <a name="input_daily_snapshot_time"></a> [daily\_snapshot\_time](#input\_daily\_snapshot\_time) | The daily time range (in UTC) during which the service takes automatic snapshot of the Serverless Cache | `string` | `"18:00"` | no |
4251
| <a name="input_elasticache_parameter_group_family"></a> [elasticache\_parameter\_group\_family](#input\_elasticache\_parameter\_group\_family) | ElastiCache parameter group family | `string` | `"redis7"` | no |
4352
| <a name="input_enabled"></a> [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `true` | no |
44-
| <a name="input_engine_version"></a> [engine\_version](#input\_engine\_version) | Redis engine version. https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/supported-engine-versions.html | `string` | `"redis7.0"` | no |
53+
| <a name="input_engine_version"></a> [engine\_version](#input\_engine\_version) | Redis engine version. https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/supported-engine-versions.html | `string` | `"7.0"` | no |
4554
| <a name="input_instance_type"></a> [instance\_type](#input\_instance\_type) | Elastic cache instance type | `string` | `"cache.t2.micro"` | no |
4655
| <a name="input_kms_key_id"></a> [kms\_key\_id](#input\_kms\_key\_id) | The ARN of the key that you wish to use if encrypting at rest. If not supplied, uses service managed encryption. Can be specified only if `at_rest_encryption_enabled = true` | `string` | `null` | no |
4756
| <a name="input_maintenance_window"></a> [maintenance\_window](#input\_maintenance\_window) | Maintenance window | `string` | `"wed:03:00-wed:04:00"` | no |
57+
| <a name="input_max_data_storage"></a> [max\_data\_storage](#input\_max\_data\_storage) | The maximun cached data capacity of the Serverless Cache in GB | `number` | `10` | no |
58+
| <a name="input_max_ecpu_per_second"></a> [max\_ecpu\_per\_second](#input\_max\_ecpu\_per\_second) | The maximum ECPU per second of the Serverless Cache | `number` | `1000` | no |
4859
| <a name="input_name"></a> [name](#input\_name) | Name of the application | `string` | `"value"` | no |
4960
| <a name="input_notification_topic_arn"></a> [notification\_topic\_arn](#input\_notification\_topic\_arn) | ARN of an SNS topic to send ElastiCache notifications | `string` | `""` | no |
5061
| <a name="input_num_node_groups"></a> [num\_node\_groups](#input\_num\_node\_groups) | Number of node groups (shards) for this Redis replication group. Changing this number will trigger an online resizing operation before other settings modifications. Required unless `global_replication_group_id` is set | `number` | `2` | no |
5162
| <a name="input_ok_actions"></a> [ok\_actions](#input\_ok\_actions) | The list of actions to execute when this alarm transitions into an OK state from any other state. | `list(string)` | `[]` | no |
52-
| <a name="input_parameter_group_name"></a> [parameter\_group\_name](#input\_parameter\_group\_name) | Excisting Parameter Group name | `string` | `""` | no |
63+
| <a name="input_parameter_group_name"></a> [parameter\_group\_name](#input\_parameter\_group\_name) | Existing Parameter Group name | `string` | `""` | no |
5364
| <a name="input_parameters"></a> [parameters](#input\_parameters) | A list of Redis parameters to apply. Note that parameters may differ from one Redis family to another | <pre>list(object({<br> name = string<br> value = string<br> }))</pre> | `[]` | no |
5465
| <a name="input_port"></a> [port](#input\_port) | Redis port | `number` | `6379` | no |
5566
| <a name="input_preferred_cache_cluster_azs"></a> [preferred\_cache\_cluster\_azs](#input\_preferred\_cache\_cluster\_azs) | List of EC2 availability zones in which the replication group's cache clusters will be created. The order of the availability zones in the list is considered. The first item in the list will be the primary node. Ignored when updating | `list(string)` | <pre>[<br> "ap-southeast-1a",<br> "ap-southeast-1b"<br>]</pre> | no |
5667
| <a name="input_replicas_per_node_group"></a> [replicas\_per\_node\_group](#input\_replicas\_per\_node\_group) | Number of replica nodes in each node group. Valid values are 0 to 5. Changing this number will trigger an online resizing operation before other settings modifications. | `number` | `1` | no |
5768
| <a name="input_replication_enabled"></a> [replication\_enabled](#input\_replication\_enabled) | Set to false to diable replication in redis cluster | `bool` | `false` | no |
5869
| <a name="input_replication_group_id"></a> [replication\_group\_id](#input\_replication\_group\_id) | ElastiCache replication\_group\_id | `string` | `""` | no |
5970
| <a name="input_security_groups"></a> [security\_groups](#input\_security\_groups) | List of Security Group IDs to place the cluster into | `list(string)` | `[]` | no |
71+
| <a name="input_serverless_user_group_id"></a> [serverless\_user\_group\_id](#input\_serverless\_user\_group\_id) | The ID of the user group for Serverless Cache | `string` | `""` | no |
72+
| <a name="input_snapshot_arns_to_restore"></a> [snapshot\_arns\_to\_restore](#input\_snapshot\_arns\_to\_restore) | The ARN's of snapshot to restore Serverless Cache | `list(string)` | `[]` | no |
6073
| <a name="input_snapshot_retention_limit"></a> [snapshot\_retention\_limit](#input\_snapshot\_retention\_limit) | Number of days for which ElastiCache will retain automatic cache cluster snapshots before deleting them. For example, if you set SnapshotRetentionLimit to 5, then a snapshot that was taken today will be retained for 5 days before being deleted. If the value of snapshot\_retention\_limit is set to zero (0), backups are turned off. Please note that setting a snapshot\_retention\_limit is not supported on cache.t1.micro cache nodes | `number` | `5` | no |
6174
| <a name="input_subnet_group_name"></a> [subnet\_group\_name](#input\_subnet\_group\_name) | Subnet group name for the ElastiCache instance | `string` | `""` | no |
6275
| <a name="input_subnets"></a> [subnets](#input\_subnets) | AWS subnet ids | `list(string)` | `[]` | no |
6376
| <a name="input_tags"></a> [tags](#input\_tags) | Additional tags (\_e.g.\_ map("BusinessUnit","ABC") | `map(string)` | `{}` | no |
77+
| <a name="input_use_serverless"></a> [use\_serverless](#input\_use\_serverless) | Use serverless ElastiCache service | `bool` | `false` | no |
6478

6579
## Outputs
6680

Diff for: alarms.tf

+95-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
resource "aws_cloudwatch_metric_alarm" "cache_cpu" {
2-
count = var.enabled ? local.num_nodes : 0
2+
count = var.enabled && !var.use_serverless ? local.num_nodes : 0
33

44
alarm_name = "${tolist(aws_elasticache_replication_group.this[0].member_clusters)[count.index]}-cpu-utilization"
55
alarm_description = "Redis cluster CPU utilization"
@@ -30,7 +30,7 @@ resource "aws_cloudwatch_metric_alarm" "cache_cpu" {
3030
}
3131

3232
resource "aws_cloudwatch_metric_alarm" "cache_memory" {
33-
count = var.enabled ? local.num_nodes : 0
33+
count = var.enabled && !var.use_serverless ? local.num_nodes : 0
3434

3535
alarm_name = "${tolist(aws_elasticache_replication_group.this[0].member_clusters)[count.index]}-freeable-memory"
3636
alarm_description = "Redis cluster freeable memory"
@@ -59,3 +59,96 @@ resource "aws_cloudwatch_metric_alarm" "cache_memory" {
5959
aws_elasticache_replication_group.this
6060
]
6161
}
62+
63+
# ElastiCache Serverless
64+
resource "aws_cloudwatch_metric_alarm" "cache_serverless_ecpu" {
65+
count = var.enabled && var.use_serverless ? 1 : 0
66+
67+
alarm_name = "${awscc_elasticache_serverless_cache.this[0].serverless_cache_name}-ecpu-utilization"
68+
alarm_description = "Redis serverless ECPU utilization"
69+
70+
comparison_operator = "GreaterThanThreshold"
71+
evaluation_periods = 1
72+
73+
metric_name = "ElastiCacheProcessingUnits"
74+
namespace = "AWS/ElastiCache"
75+
76+
period = 300
77+
statistic = "Average"
78+
79+
tags = var.tags
80+
81+
threshold = ceil(var.max_ecpu_per_second * var.alarm_ecpu_threshold_percent / 100)
82+
83+
dimensions = {
84+
CacheClusterId = awscc_elasticache_serverless_cache.this[0].serverless_cache_name
85+
}
86+
87+
alarm_actions = var.alarm_actions
88+
ok_actions = var.ok_actions
89+
90+
depends_on = [
91+
awscc_elasticache_serverless_cache.this
92+
]
93+
}
94+
95+
resource "aws_cloudwatch_metric_alarm" "cache_serverless_data" {
96+
count = var.enabled && var.use_serverless ? 1 : 0
97+
98+
alarm_name = "${awscc_elasticache_serverless_cache.this[0].serverless_cache_name}-data-storage"
99+
alarm_description = "Redis serverless data storage"
100+
101+
comparison_operator = "GreaterThanThreshold"
102+
evaluation_periods = 1
103+
104+
metric_name = "BytesUsedForCache"
105+
namespace = "AWS/ElastiCache"
106+
107+
period = 60
108+
statistic = "Average"
109+
110+
threshold = ceil((var.max_data_storage * 1000 * 1000 * 1000) * var.alarm_data_threshold_percent / 100)
111+
112+
tags = var.tags
113+
114+
dimensions = {
115+
CacheClusterId = awscc_elasticache_serverless_cache.this[0].serverless_cache_name
116+
}
117+
118+
alarm_actions = var.alarm_actions
119+
ok_actions = var.ok_actions
120+
121+
depends_on = [
122+
aws_elasticache_replication_group.this
123+
]
124+
}
125+
126+
resource "aws_cloudwatch_metric_alarm" "cache_serverless_throttled_commands" {
127+
count = var.enabled && var.use_serverless ? 1 : 0
128+
129+
alarm_name = "${awscc_elasticache_serverless_cache.this[0].serverless_cache_name}-throttled-commands"
130+
alarm_description = "Redis serverless throttled commands"
131+
132+
comparison_operator = "GreaterThanThreshold"
133+
evaluation_periods = 1
134+
135+
metric_name = "ThrottledCmds"
136+
namespace = "AWS/ElastiCache"
137+
138+
period = 60
139+
statistic = "Average"
140+
141+
threshold = 0
142+
143+
tags = var.tags
144+
dimensions = {
145+
CacheClusterId = awscc_elasticache_serverless_cache.this[0].serverless_cache_name
146+
}
147+
148+
alarm_actions = var.alarm_actions
149+
ok_actions = var.ok_actions
150+
151+
depends_on = [
152+
awscc_elasticache_serverless_cache.this
153+
]
154+
}

Diff for: main.tf

+39-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ locals {
1515
}
1616

1717
resource "aws_elasticache_parameter_group" "this" {
18-
count = var.enabled && var.parameter_group_name == "" || var.parameter_group_name == null ? 1 : 0
18+
count = var.enabled && var.parameter_group_name == "" && !var.use_serverless || var.parameter_group_name == null ? 1 : 0
1919

2020
name = var.name
2121
family = var.elasticache_parameter_group_family
@@ -38,7 +38,7 @@ resource "aws_elasticache_subnet_group" "this" {
3838
}
3939

4040
resource "aws_elasticache_replication_group" "this" {
41-
count = var.enabled ? 1 : 0
41+
count = var.enabled && !var.use_serverless ? 1 : 0
4242

4343
replication_group_id = var.replication_group_id == "" ? local.cluster_id : var.replication_group_id
4444
description = "Redis Cluster Rep"
@@ -73,3 +73,40 @@ resource "aws_elasticache_replication_group" "this" {
7373

7474
tags = var.tags
7575
}
76+
77+
resource "awscc_elasticache_serverless_cache" "this" {
78+
count = var.enabled && var.use_serverless ? 1 : 0
79+
80+
serverless_cache_name = var.name
81+
description = "${var.name} ElastiCache Redis Serverless"
82+
engine = "redis"
83+
major_engine_version = var.engine_version
84+
85+
cache_usage_limits = {
86+
data_storage = {
87+
maximum = var.max_data_storage
88+
unit = "GB"
89+
}
90+
ecpu_per_second = {
91+
maximum = var.max_ecpu_per_second
92+
}
93+
}
94+
95+
user_group_id = var.serverless_user_group_id
96+
97+
final_snapshot_name = "${var.name}-elasticache-serverless-final-snapshot"
98+
kms_key_id = var.kms_key_id
99+
security_group_ids = var.security_groups
100+
subnet_ids = var.subnets
101+
102+
daily_snapshot_time = var.daily_snapshot_time
103+
snapshot_arns_to_restore = var.snapshot_arns_to_restore
104+
snapshot_retention_limit = var.snapshot_retention_limit
105+
106+
tags = [
107+
for key, value in var.tags : {
108+
key = key
109+
value = value
110+
}
111+
]
112+
}

Diff for: outputs.tf

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
output "endpoint" {
22
description = "Redis primary or configuration endpoint, whichever is appropriate for the given cluster mode"
3-
value = try(aws_elasticache_replication_group.this[0].primary_endpoint_address, null)
3+
value = var.use_serverless ? try(awscc_elasticache_serverless_cache.this[0].endpoint.address, null) : try(aws_elasticache_replication_group.this[0].primary_endpoint_address, null)
44
}
55

66
output "reader_endpoint_address" {
@@ -15,7 +15,7 @@ output "member_clusters" {
1515

1616
output "arn" {
1717
description = "Elasticache Replication Group ARN"
18-
value = try(aws_elasticache_replication_group.this[0].arn, null)
18+
value = var.use_serverless ? try(awscc_elasticache_serverless_cache.this[0].arn, null) : try(aws_elasticache_replication_group.this[0].arn, null)
1919
}
2020

2121
output "cluster_enabled" {

Diff for: variables.tf

+60-1
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,24 @@ variable "alarm_cpu_threshold_percent" {
6464
default = 75
6565
}
6666

67+
variable "alarm_ecpu_threshold_percent" {
68+
description = "ECPU threshold alarm level for elasticache serverless"
69+
type = number
70+
default = 75
71+
}
72+
6773
variable "alarm_memory_threshold_bytes" {
6874
description = "Alarm memory threshold bytes"
6975
type = number
7076
default = 10000000 # 10MB
7177
}
7278

79+
variable "alarm_data_threshold_percent" {
80+
description = "Data threshold alarm level for elasticache serverless"
81+
type = number
82+
default = 75
83+
}
84+
7385
variable "notification_topic_arn" {
7486
description = "ARN of an SNS topic to send ElastiCache notifications"
7587
type = string
@@ -155,7 +167,7 @@ variable "preferred_cache_cluster_azs" {
155167
}
156168

157169
variable "parameter_group_name" {
158-
description = "Excisting Parameter Group name"
170+
description = "Existing Parameter Group name"
159171
type = string
160172
default = ""
161173
}
@@ -189,3 +201,50 @@ variable "replicas_per_node_group" {
189201
type = number
190202
default = 1
191203
}
204+
205+
# ElastiCache Serverless
206+
variable "use_serverless" {
207+
description = "Use serverless ElastiCache service"
208+
type = bool
209+
default = false
210+
}
211+
212+
variable "max_data_storage" {
213+
type = number
214+
description = "The maximun cached data capacity of the Serverless Cache in GB"
215+
default = 10
216+
217+
validation {
218+
condition = var.max_data_storage >= 1 && var.max_data_storage <= 5000
219+
error_message = "The max_data_storage in GB value must be between 1 and 5,000."
220+
}
221+
}
222+
223+
variable "max_ecpu_per_second" {
224+
type = number
225+
description = "The maximum ECPU per second of the Serverless Cache"
226+
default = 1000
227+
228+
validation {
229+
condition = var.max_ecpu_per_second >= 1000 && var.max_ecpu_per_second <= 15000000
230+
error_message = "The max_ecpu_per_second value must be between 1,000 and 15,000,000."
231+
}
232+
}
233+
234+
variable "daily_snapshot_time" {
235+
type = string
236+
description = "The daily time range (in UTC) during which the service takes automatic snapshot of the Serverless Cache"
237+
default = "18:00"
238+
}
239+
240+
variable "snapshot_arns_to_restore" {
241+
type = list(string)
242+
description = "The ARN's of snapshot to restore Serverless Cache"
243+
default = []
244+
}
245+
246+
variable "serverless_user_group_id" {
247+
type = string
248+
description = "The ID of the user group for Serverless Cache"
249+
default = ""
250+
}

Diff for: versions.tf

+4
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,9 @@ terraform {
55
source = "hashicorp/aws"
66
version = ">= 4.0"
77
}
8+
awscc = {
9+
source = "hashicorp/awscc"
10+
version = ">= 0.67.0"
11+
}
812
}
913
}

0 commit comments

Comments
 (0)