Skip to content
This repository was archived by the owner on Oct 8, 2022. It is now read-only.

Commit 5e88bee

Browse files
author
Hector Castro
committed
Use aws_elasticache_replication_group resource
Instead of using the more primitive `aws_elasticache_cluster` resource, create a Redis ElastiCache replication group with the `aws_elasticache_replication_group` resource. This comes with a hot-standby and support for automatic failover. Also, follow the pattern set forth by the RDS module: - Remove all resources other than cache cluster and CloudWatch alarms - Add empty security group resource and emit its ID as an output
1 parent f44cee1 commit 5e88bee

File tree

4 files changed

+127
-74
lines changed

4 files changed

+127
-74
lines changed

README.md

+42-24
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,62 @@ A Terraform module to create an Amazon Web Services (AWS) Redis ElastiCache clus
55
## Usage
66

77
```hcl
8-
resource "aws_security_group" "redis" {
9-
vpc_id = "${vpc.foo.id}"
8+
resource "aws_sns_topic" "global" {
9+
...
10+
}
1011
11-
tags {
12-
Name = "sgCacheCluster"
13-
}
12+
resource "aws_elasticache_subnet_group" "redis" {
13+
...
1414
}
1515
16-
module "redis_elasticache" {
17-
source = "github.com/azavea/terraform-aws-redis-elasticache"
16+
resource "aws_elasticache_parameter_group" "redis" {
17+
...
18+
}
1819
19-
vpc_id = "vpc-20f74844"
20+
module "cache" {
21+
source = "github.com/azavea/terraform-aws-redis-elasticache"
2022
21-
cache_name = "cache"
22-
engine_version = "2.8.22"
23-
instance_type = "cache.t2.micro"
24-
maintenance_window = "sun:05:00-sun:06:00"
23+
vpc_id = "vpc-20f74844"
24+
cache_identifier = "cache"
25+
automatic_failover_enabled = "false"
26+
desired_clusters = "1"
27+
instance_type = "cache.t2.micro"
28+
engine_version = "3.2.4"
29+
parameter_group = "${aws_elasticache_parameter_group.redis.name}"
30+
subnet_group = "${aws_elasticache_subnet_group.redis.name}"
31+
maintenance_window = "sun:02:30-sun:03:30"
32+
notification_topic_arn = "${aws_sns_topic.global.arn}"
2533
26-
private_subnet_ids = ["subnet-4a887f3c","subnet-76dae35d"]
27-
security_group_ids = ["${aws_security_group.redis.id}"]
34+
alarm_cpu_threshold = "75"
35+
alarm_memory_threshold = "10000000"
36+
alarm_actions = ["${aws_sns_topic.global.arn}"]
2837
29-
alarm_action = "arn:aws:sns..."
38+
project = "Unknown"
39+
environment = "Unknown"
3040
}
3141
```
3242

3343
## Variables
3444

3545
- `vpc_id` - ID of VPC meant to house the cache
36-
- `cache_name` - Name used as ElastiCache cluster ID
37-
- `engine_version` - Cache engine version (default: `2.8.22`)
46+
- `project` - Name of the project making use of the cluster (default: `Unknown`)
47+
- `environment` - Name of environment the cluster is targeted for (default: `Unknown`)
48+
- `cache_identifier` - Name used as ElastiCache cluster ID
49+
- `automatic_failover_enabled` - Flag to determine if automatic failover should be enabled
50+
- `desired_clusters` - Number of cache clusters in replication group
3851
- `instance_type` - Instance type for cache instance (default: `cache.t2.micro`)
39-
- `maintenance_window` - 60 minute time window to reserve for maintenance
40-
(default: `sun:05:00-sun:06:00`)
41-
- `private_subnet_ids` - Comma delimited list of private subnet IDs
42-
- `alarm_action` - ARN to be notified via CloudWatch
52+
- `engine_version` - Cache engine version (default: `3.2.4`)
53+
- `parameter_group` - Cache parameter group name (default: `redis3.2`)
54+
- `subnet_group` - Cache subnet group name
55+
- `maintenance_window` - Time window to reserve for maintenance
56+
- `notification_topic_arn` - ARN to notify when cache events occur
57+
- `alarm_cpu_threshold` - CPU alarm threshold as a percentage (default: `75`)
58+
- `alarm_memory_threshold` - Free memory alarm threshold in bytes (default: `10000000`)
59+
- `alarm_actions` - ARN to be notified via CloudWatch when alarm thresholds are triggered
4360

4461
## Outputs
4562

46-
- `hostname` - Public DNS name of cache node
47-
- `port` - Port of cache instance
48-
- `endpoint` - Public DNS name and port separated by a `:`
63+
- `id` - The replication group ID
64+
- `cache_security_group_id` - Security group ID of the cache cluster
65+
- `port` - Port of replication group leader
66+
- `endpoint` - Public DNS name of replication group leader

main.tf

+45-35
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,81 @@
11
#
2-
# ElastiCache resources
2+
# Security group resources
33
#
4-
5-
resource "aws_elasticache_cluster" "redis" {
6-
cluster_id = "${var.cache_name}"
7-
engine = "redis"
8-
engine_version = "${var.engine_version}"
9-
maintenance_window = "${var.maintenance_window}"
10-
node_type = "${var.instance_type}"
11-
num_cache_nodes = "1"
12-
parameter_group_name = "default.redis2.8"
13-
port = "6379"
14-
subnet_group_name = "${aws_elasticache_subnet_group.default.name}"
15-
security_group_ids = "${var.security_group_ids}"
4+
resource "aws_security_group" "redis" {
5+
vpc_id = "${var.vpc_id}"
166

177
tags {
18-
Name = "${var.cache_name}"
8+
Name = "sgCacheCluster"
9+
Project = "${var.project}"
10+
Environment = "${var.environment}"
1911
}
2012
}
2113

22-
resource "aws_elasticache_subnet_group" "default" {
23-
name = "${var.cache_name}-subnet-group"
24-
description = "Private subnets for the ElastiCache instances"
25-
subnet_ids = "${var.private_subnet_ids}"
14+
#
15+
# ElastiCache resources
16+
#
17+
resource "aws_elasticache_replication_group" "redis" {
18+
replication_group_id = "${lower(var.cache_identifier)}"
19+
replication_group_description = "Replication group for Redis"
20+
automatic_failover_enabled = "${var.automatic_failover_enabled}"
21+
number_cache_clusters = "${var.desired_clusters}"
22+
node_type = "${var.instance_type}"
23+
engine_version = "${var.engine_version}"
24+
parameter_group_name = "${var.parameter_group}"
25+
subnet_group_name = "${var.subnet_group}"
26+
security_group_ids = ["${aws_security_group.redis.id}"]
27+
maintenance_window = "${var.maintenance_window}"
28+
notification_topic_arn = "${var.notification_topic_arn}"
29+
port = "6379"
30+
31+
tags {
32+
Name = "CacheReplicationGroup"
33+
Project = "${var.project}"
34+
Environment = "${var.environment}"
35+
}
2636
}
2737

2838
#
2939
# CloudWatch resources
3040
#
31-
resource "aws_cloudwatch_metric_alarm" "cpu" {
32-
alarm_name = "alarmCacheClusterCPUUtilization-${var.cache_name}"
33-
alarm_description = "Cache cluster CPU utilization"
41+
resource "aws_cloudwatch_metric_alarm" "cache_cpu" {
42+
count = "${var.desired_clusters}"
43+
44+
alarm_name = "alarm${var.environment}CacheCluster00${count.index + 1}CPUUtilization"
45+
alarm_description = "Redis cluster CPU utilization"
3446
comparison_operator = "GreaterThanThreshold"
3547
evaluation_periods = "1"
3648
metric_name = "CPUUtilization"
3749
namespace = "AWS/ElastiCache"
3850
period = "300"
3951
statistic = "Average"
40-
threshold = "75"
52+
53+
threshold = "${var.alarm_cpu_threshold}"
4154

4255
dimensions {
43-
CacheClusterName = "${var.cache_name}"
56+
CacheClusterId = "${aws_elasticache_replication_group.redis.id}-00${count.index + 1}"
4457
}
4558

46-
# for some reason trying to pass a list here causes the error ` * aws_cloudwatch_metric_alarm.cpu: alarm_actions: should be a list` in terraform 0.7.5
47-
# passing lists elsewhere works fine
48-
alarm_actions = ["${var.alarm_action}"]
59+
alarm_actions = ["${var.alarm_actions}"]
4960
}
5061

51-
resource "aws_cloudwatch_metric_alarm" "memory_free" {
52-
alarm_name = "alarmCacheClusterFreeableMemory-${var.cache_name}"
53-
alarm_description = "Cache cluster freeable memory"
62+
resource "aws_cloudwatch_metric_alarm" "cache_memory" {
63+
count = "${var.desired_clusters}"
64+
65+
alarm_name = "alarm${var.environment}CacheCluster00${count.index + 1}FreeableMemory"
66+
alarm_description = "Redis cluster freeable memory"
5467
comparison_operator = "LessThanThreshold"
5568
evaluation_periods = "1"
5669
metric_name = "FreeableMemory"
5770
namespace = "AWS/ElastiCache"
5871
period = "60"
5972
statistic = "Average"
6073

61-
# 10MB in bytes
62-
threshold = "10000000"
74+
threshold = "${var.alarm_memory_threshold}"
6375

6476
dimensions {
65-
CacheClusterName = "${var.cache_name}"
77+
CacheClusterId = "${aws_elasticache_replication_group.redis.id}-00${count.index + 1}"
6678
}
6779

68-
# for some reason trying to pass a list here causes the error ` * aws_cloudwatch_metric_alarm.cpu: alarm_actions: should be a list` in terraform 0.7.5
69-
# passing lists elsewhere works fine
70-
alarm_actions = ["${var.alarm_action}"]
80+
alarm_actions = ["${var.alarm_actions}"]
7181
}

outputs.tf

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
output "hostname" {
2-
value = "${aws_elasticache_cluster.redis.cache_nodes.0.address}"
1+
output "id" {
2+
value = "${aws_elasticache_replication_group.redis.id}"
3+
}
4+
5+
output "cache_security_group_id" {
6+
value = "${aws_security_group.redis.id}"
37
}
48

59
output "port" {
6-
value = "${aws_elasticache_cluster.redis.cache_nodes.0.port}"
10+
value = "6379"
711
}
812

913
output "endpoint" {
10-
value = "${join(":", aws_elasticache_cluster.redis.cache_nodes.0.address, aws_elasticache_cluster.redis.cache_nodes.0.port)}"
14+
value = "${aws_elasticache_replication_group.redis.primary_endpoint_address}"
1115
}

variables.tf

+32-11
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,50 @@
1-
variable "vpc_id" {
1+
variable "project" {
2+
default = "Unknown"
23
}
34

4-
variable "cache_name" {
5+
variable "environment" {
6+
default = "Unknown"
57
}
68

7-
variable "engine_version" {
8-
default = "2.8.22"
9+
variable "vpc_id" {}
10+
11+
variable "cache_identifier" {}
12+
13+
variable "parameter_group" {
14+
default = "redis3.2"
15+
}
16+
17+
variable "subnet_group" {}
18+
19+
variable "maintenance_window" {}
20+
21+
variable "desired_clusters" {
22+
default = "1"
923
}
1024

1125
variable "instance_type" {
1226
default = "cache.t2.micro"
1327
}
1428

15-
variable "maintenance_window" {
16-
# SUN 01:00AM-02:00AM ET
17-
default = "sun:05:00-sun:06:00"
29+
variable "engine_version" {
30+
default = "3.2.4"
1831
}
1932

20-
variable "private_subnet_ids" {
21-
type = "list"
33+
variable "automatic_failover_enabled" {
34+
default = false
35+
}
36+
37+
variable "notification_topic_arn" {}
38+
39+
variable "alarm_cpu_threshold" {
40+
default = "75"
2241
}
2342

24-
variable "alarm_action" {
43+
variable "alarm_memory_threshold" {
44+
# 10MB
45+
default = "10000000"
2546
}
2647

27-
variable "security_group_ids" {
48+
variable "alarm_actions" {
2849
type = "list"
2950
}

0 commit comments

Comments
 (0)