Commit 008367aa authored by Chris Merrett's avatar Chris Merrett

Initial commit

parents
Pipeline #1787 passed with stage
in 16 seconds
.DS_Store
image: alpine:latest
variables:
TERRAFORM_URL: "https://releases.hashicorp.com/terraform/0.7.13/terraform_0.7.13_linux_amd64.zip"
before_script:
- apk update && apk add ca-certificates && update-ca-certificates && apk add openssl
- wget -O /tmp/terraform.zip $TERRAFORM_URL
- unzip /tmp/terraform.zip -d /usr/local/bin
test:
script: terraform validate
tf_mod_aws_elasticache_redis
==============
A Terraform module for creating an ElastiCache Redis cluster of between 1 and 9 nodes. Generally works without any modification,
but has some restrictions. Creates CloudWatch metrics for each node individually.
Noteworthy Restrictions
-----------------------
1. If using a `cache_clusters` count of 1, snapshots are not available via this module. We assume that a 1 node is dev/staging.
2. The T1/T2 families of instances are only available when using a `cache_cluster` count of 1 (default). We disable failover and snapshots for 1 node, as we assume that is dev/staging.
3. We assume that you will select a production-grade instance type for any `cache_cluster` count between 2-9. Using T1/T2 instances with a count of between 2-9 will cause an error. We enable failover and snapshots for clusters of this size and assume production.
4. At this moment, replication groups of more than 9 nodes are not available without user modification of the module.
Input Variables (TBC)
---------------------
- `vpc_id` - Typically ${module.vpc.vpc_id}. *Required*.
- `security_groups` - Typically ["${module.bastion.security_group}"], and any other security groups required. *Required*.
- `subnet_ids` - Subnet ID(s) that the cluster should have instances created within. *Required*.
- `cache_name` - Name of the cluster(s) replciation group. Filters down to instances. *Required*.
- `cache_clusters` - Number of cache clusters within the replication group. Defaults to "1". Optional. _Please refer to the restrictions above_.
- `automatic_failover_enabled` - Whether automatic failover happens in the event of a primary node failure. Defaults to "false". Optional.
- `engine_version` - Redis engine version number. Defaults to "2.8.24". Optional.
- `parameter_group_name` - Redis parameter group name. Defaults to "default.redis2.8". Optional.
- `instance_type` - Instance type for all nodes within the replication group. Defaults to "t2.micro". Optional. _Please refer to the restrictions above_.
- `port` - Redis port. Defaults to "6379". Optional.
- `maintenance_window` - Desired weekly cluster maintenance window. Defaults to "sun:01:00-sun:02:00". Optional.
- `snapshot_window` - Desired daily cluster snapshot window. Defaults to "03:00-04:00". Optional. _Please refer to the restrictions above_.
- `snapshot_retention_limit` - Number of snapshots to keep. Defaults to "1". Optional. _Please refer to the restrictions above_.
- `dns_zone` - Route53 zone ID. Works best with a module. *Required*.
Outputs
-------
None.
Usage
-----
You can use this module in your Terraform template with the following steps. Most variables have defaults set, so setting variables is optional in most cases.
1.) Adding a module resource to your template, e.g. `main.tf`
```
variable "vpc_id" {}
variable "security_groups" {}
variable "subnet_ids" {}
variable "redis_cache_name" {}
variable "redis_cache_clusters" {}
variable "redis_automatic_failover_enabled" {}
variable "redis_engine_version" {}
variable "redis_parameter_group_name" {}
variable "redis_instance_type" {}
variable "redis_port" {}
variable "redis_maintenance_window" {}
variable "redis_snapshot_window" {}
variable "redis_snapshot_retention_limit" {}
variable "dns_zone" {}
#############################################################################################################
# ElastiCache (Redis)
#############################################################################################################
module "redis" {
source = "git::https://git.steamhaus.co.uk/steamhaus/tf_mod_aws_elasticache_redis"
vpc_id = "${var.vpc_id}"
security_groups = "${var.security_groups}"
subnet_ids = "${var.subnet_ids}"
cache_name = "${var.redis_cache_name}"
cache_clusters = "${var.redis_cache_clusters}"
automatic_failover_enabled = "${var.redis_automatic_failover_enabled}"
engine_version = "${var.redis_engine_version}"
parameter_group_name = "${var.redis_parameter_group_name}"
instance_type = "${var.redis_instance_type}"
port = "${var.redis_port}"
maintenance_window = "${var.redis_maintenance_window}"
snapshot_window = "${var.redis_snapshot_window}"
snapshot_retention_limit = "${var.redis_snapshot_retention_limit}"
dns_zone = "${var.dns_zone}"
}
```
#############################################################################################################
# Variables
#############################################################################################################
variable "vpc_id" {}
variable "security_groups" {
type = "list"
}
variable "subnet_ids" {
type = "list"
}
variable "cache_name" {}
variable "cache_clusters" {
default = "1"
}
variable "automatic_failover_enabled" {
default = "false"
}
variable "engine_version" {
default = "2.8.24"
}
variable "parameter_group_name" {
default = "default.redis2.8"
}
variable "instance_type" {
default = "cache.t2.micro"
}
variable "port" {
default = "6379"
}
variable "maintenance_window" {
default = "sun:01:00-sun:02:00"
}
variable "snapshot_window" {
default = "03:00-04:00"
}
variable "snapshot_retention_limit" {
default = "1"
}
variable "dns_zone" {}
# variable "alarm_actions" {}
############################################################################################################
# Security Group
############################################################################################################
resource "aws_security_group" "redis" {
vpc_id = "${var.vpc_id}"
description = "ElastiCache Redis SG"
ingress {
from_port = "${var.port}"
to_port = "${var.port}"
protocol = "tcp"
security_groups = ["${var.security_groups}"]
}
tags = {
Name = "${var.cache_name}"
}
}
#############################################################################################################
# Subnet Group
#############################################################################################################
resource "aws_elasticache_subnet_group" "default" {
name = "${var.cache_name}-redis-subnet-group"
description = "Private subnets for the ElastiCache Redis instances"
subnet_ids = ["${var.subnet_ids}"]
}
############################################################################################################
# Elasticache (Redis) Single
############################################################################################################
resource "aws_elasticache_replication_group" "redis-single" {
count = "${replace(replace(var.cache_clusters, "/^[2-9]$/", "0"), "/^1$/", "1")}"
replication_group_id = "${var.cache_name}"
replication_group_description = "${var.cache_name}"
engine_version = "${var.engine_version}"
node_type = "${var.instance_type}"
number_cache_clusters = "1"
port = "${var.port}"
parameter_group_name = "${var.parameter_group_name}"
subnet_group_name = "${aws_elasticache_subnet_group.default.name}"
security_group_ids = ["${aws_security_group.redis.id}"]
maintenance_window = "${var.maintenance_window}"
auto_minor_version_upgrade = true
tags {
Name = "${var.cache_name}-redis"
}
}
############################################################################################################
# Elasticache (Redis) Cluster
############################################################################################################
resource "aws_elasticache_replication_group" "redis-cluster" {
count = "${replace(replace(var.cache_clusters, "/^1$/", "0"), "/^[2-9]$/", "1")}"
replication_group_id = "${var.cache_name}"
replication_group_description = "${var.cache_name}"
engine_version = "${var.engine_version}"
node_type = "${var.instance_type}"
number_cache_clusters = "${var.cache_clusters}"
port = "${var.port}"
parameter_group_name = "${var.parameter_group_name}"
subnet_group_name = "${aws_elasticache_subnet_group.default.name}"
security_group_ids = ["${aws_security_group.redis.id}"]
maintenance_window = "${var.maintenance_window}"
snapshot_window = "${var.snapshot_window}"
snapshot_retention_limit = "${var.snapshot_retention_limit}"
automatic_failover_enabled = "${var.automatic_failover_enabled}"
auto_minor_version_upgrade = true
tags {
Name = "${var.cache_name}-redis"
}
}
#############################################################################################################
# Route53 records
#############################################################################################################
resource "aws_route53_record" "redis-single-pri" {
count = "${replace(replace(var.cache_clusters, "/^[2-9]$/", "0"), "/^1$/", "1")}"
zone_id = "${var.dns_zone}"
name = "redis.pri.${var.cache_name}.aws"
type = "CNAME"
ttl = "60"
records = ["${aws_elasticache_replication_group.redis-single.primary_endpoint_address}"]
}
resource "aws_route53_record" "redis-cluster-pri" {
count = "${replace(replace(var.cache_clusters, "/^1$/", "0"), "/^[2-9]$/", "1")}"
zone_id = "${var.dns_zone}"
name = "redis.pri.${var.cache_name}.aws"
type = "CNAME"
ttl = "60"
records = ["${aws_elasticache_replication_group.redis-cluster.primary_endpoint_address}"]
}
resource "aws_route53_record" "redis-cluster-cfg" {
count = "${replace(replace(var.cache_clusters, "/^1$/", "0"), "/^[2-9]$/", "1")}"
zone_id = "${var.dns_zone}"
name = "redis.cfg.${var.cache_name}.aws"
type = "CNAME"
ttl = "60"
records = ["${aws_elasticache_replication_group.redis-cluster.configuration_endpoint_address}"]
}
##############################################################################################################
## Cloudwatch resources
##############################################################################################################
resource "aws_cloudwatch_metric_alarm" "cpu-single" {
count = "${replace(replace(var.cache_clusters, "/^[2-9]$/", "0"), "/^1$/", "1")}"
alarm_name = "alarmRedisCacheClusterCPUUtilization"
alarm_description = "Redis cache cluster CPU utilization"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = "1"
metric_name = "CPUUtilization"
namespace = "AWS/ElastiCache"
period = "300"
statistic = "Average"
threshold = "75"
dimensions {
CacheClusterId = "${var.cache_name}-00${count.index + 1}"
}
}
resource "aws_cloudwatch_metric_alarm" "memory-free-single" {
count = "${replace(replace(var.cache_clusters, "/^[2-9]$/", "0"), "/^1$/", "1")}"
alarm_name = "alarmRedisCacheClusterFreeableMemory"
alarm_description = "Redis cache cluster freeable memory"
comparison_operator = "LessThanThreshold"
evaluation_periods = "1"
metric_name = "FreeableMemory"
namespace = "AWS/ElastiCache"
period = "60"
statistic = "Average"
# 25MB in bytes
threshold = "25000000"
dimensions {
CacheClusterId = "${var.cache_name}-00${count.index + 1}"
}
}
resource "aws_cloudwatch_metric_alarm" "cpu-cluster" {
count = "${replace(replace(var.cache_clusters, "/^1$/", "0"), "/^[2-9]$/", "${var.cache_clusters}")}"
alarm_name = "alarmRedisCacheCluster00${count.index + 1}CPUUtilization"
alarm_description = "Redis cache cluster 00${count.index + 1} CPU utilization"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = "1"
metric_name = "CPUUtilization"
namespace = "AWS/ElastiCache"
period = "300"
statistic = "Average"
threshold = "75"
dimensions {
CacheClusterId = "${var.cache_name}-00${count.index + 1}"
}
}
resource "aws_cloudwatch_metric_alarm" "memory-free-cluster" {
count = "${replace(replace(var.cache_clusters, "/^1$/", "0"), "/^[2-9]$/", "${var.cache_clusters}")}"
alarm_name = "alarmRedisCacheCluster00${count.index + 1}FreeableMemory"
alarm_description = "Redis cache cluster 00${count.index + 1} freeable memory"
comparison_operator = "LessThanThreshold"
evaluation_periods = "1"
metric_name = "FreeableMemory"
namespace = "AWS/ElastiCache"
period = "60"
statistic = "Average"
# 25MB in bytes
threshold = "25000000"
dimensions {
CacheClusterId = "${var.cache_name}-00${count.index + 1}"
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment