Skip to content

Commit f6a3469

Browse files
authored
Merge pull request #7 from geekcell/optional-kms
feat: refactor encryption and param groups
2 parents 637ed19 + 62fb720 commit f6a3469

File tree

6 files changed

+156
-38
lines changed

6 files changed

+156
-38
lines changed

README.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,23 +58,35 @@ difference it can make in your AWS setup!
5858
|------|-------------|------|---------|:--------:|
5959
| <a name="input_apply_immediately"></a> [apply\_immediately](#input\_apply\_immediately) | Specifies whether any modifications are applied immediately, or during the next maintenance window. | `bool` | `true` | no |
6060
| <a name="input_at_rest_encryption_enabled"></a> [at\_rest\_encryption\_enabled](#input\_at\_rest\_encryption\_enabled) | Whether to enable encryption at rest. | `bool` | `true` | no |
61+
| <a name="input_auth_token_length"></a> [auth\_token\_length](#input\_auth\_token\_length) | The length of the generated auth token. | `number` | `24` | no |
62+
| <a name="input_auth_token_special_characters"></a> [auth\_token\_special\_characters](#input\_auth\_token\_special\_characters) | Whether to include special characters in the generated auth token. | `bool` | `false` | no |
6163
| <a name="input_auto_minor_version_upgrade"></a> [auto\_minor\_version\_upgrade](#input\_auto\_minor\_version\_upgrade) | Specifies whether minor version engine upgrades will be applied automatically to the underlying Cache Cluster instances during the maintenance window. | `string` | `false` | no |
6264
| <a name="input_data_tearing_enabled"></a> [data\_tearing\_enabled](#input\_data\_tearing\_enabled) | Enables data tiering. Data tiering is only supported for replication groups using the r6gd node type. | `bool` | `false` | no |
6365
| <a name="input_description"></a> [description](#input\_description) | The description of the all resources. | `string` | `"Managed by Terraform"` | no |
64-
| <a name="input_destination_type"></a> [destination\_type](#input\_destination\_type) | For CloudWatch Logs use `cloudwatch-logs` or for Kinesis Data Firehose use `kinesis-firehose`. | `string` | `"cloudwatch-logs"` | no |
65-
| <a name="input_elasticache_event_recipients"></a> [elasticache\_event\_recipients](#input\_elasticache\_event\_recipients) | Recipients of the elasticache events. | `list(string)` | `[]` | no |
66+
| <a name="input_enable_customer_managed_kms"></a> [enable\_customer\_managed\_kms](#input\_enable\_customer\_managed\_kms) | If enabled, will create a customer managed KMS key for at-rest encryption. | `bool` | `false` | no |
67+
| <a name="input_enable_sns_sse_encryption"></a> [enable\_sns\_sse\_encryption](#input\_enable\_sns\_sse\_encryption) | Enable SSE Encryption for SNS Topic. | `bool` | `true` | no |
6668
| <a name="input_engine"></a> [engine](#input\_engine) | Name of the cache engine to be used for the clusters in this replication group. | `string` | `"redis"` | no |
6769
| <a name="input_engine_version"></a> [engine\_version](#input\_engine\_version) | The version number of the cache engine to be used for the cache clusters in this replication group. | `string` | `"7.0"` | no |
70+
| <a name="input_kms_key_id"></a> [kms\_key\_id](#input\_kms\_key\_id) | The ARN of the AWS KMS to encrypt data at rest. Uses the AWS service managed encryption if not specified. | `string` | `null` | no |
71+
| <a name="input_log_destination_type"></a> [log\_destination\_type](#input\_log\_destination\_type) | For CloudWatch Logs use `cloudwatch-logs` or for Kinesis Data Firehose use `kinesis-firehose`. Only 'cloudwatch-logs' supported at the moment. | `string` | `"cloudwatch-logs"` | no |
72+
| <a name="input_log_enable_customer_managed_kms"></a> [log\_enable\_customer\_managed\_kms](#input\_log\_enable\_customer\_managed\_kms) | Whether to enable customer managed KMS key for CloudWatch Logs encryption. | `bool` | `false` | no |
6873
| <a name="input_log_format"></a> [log\_format](#input\_log\_format) | Valid values are `json` or `text`. | `string` | `"text"` | no |
74+
| <a name="input_log_retention_in_days"></a> [log\_retention\_in\_days](#input\_log\_retention\_in\_days) | The number of days log events are kept in CloudWatch Logs. | `number` | `30` | no |
75+
| <a name="input_log_skip_destroy"></a> [log\_skip\_destroy](#input\_log\_skip\_destroy) | Whether to skip the deletion of the log groups when deleting the log group resources. | `bool` | `false` | no |
6976
| <a name="input_log_type"></a> [log\_type](#input\_log\_type) | Type of logs, slow-log and engine-log | `list(string)` | <pre>[<br> "slow-log",<br> "engine-log"<br>]</pre> | no |
7077
| <a name="input_maintenance_window"></a> [maintenance\_window](#input\_maintenance\_window) | Specifies the weekly time range for when maintenance on the cache cluster is performed. | `string` | `"Mon:00:00-Mon:03:00"` | no |
7178
| <a name="input_node_type"></a> [node\_type](#input\_node\_type) | The cluster identifier. If omitted, Terraform will assign a random, unique identifier. | `string` | n/a | yes |
7279
| <a name="input_num_cache_clusters"></a> [num\_cache\_clusters](#input\_num\_cache\_clusters) | Number of cache clusters (primary and replicas) this replication group will have. If Multi-AZ is enabled, the value of this parameter must be at least 2 | `number` | n/a | yes |
80+
| <a name="input_parameter_group_family"></a> [parameter\_group\_family](#input\_parameter\_group\_family) | The family of the ElastiCache parameter group. Defaults to engine and engine\_version. | `string` | `null` | no |
81+
| <a name="input_parameter_group_name"></a> [parameter\_group\_name](#input\_parameter\_group\_name) | The name of the ElastiCache parameter group. Defaults to the cluster name. | `string` | `null` | no |
82+
| <a name="input_parameters"></a> [parameters](#input\_parameters) | Set custom parameters via a parameter group. | <pre>list(object({<br> name = string<br> value = string<br> }))</pre> | `[]` | no |
7383
| <a name="input_port"></a> [port](#input\_port) | Port number on which each of the cache nodes will accept connections. | `number` | `6379` | no |
7484
| <a name="input_replication_group_id"></a> [replication\_group\_id](#input\_replication\_group\_id) | ID of the replication group to which this cluster should belong. | `string` | n/a | yes |
7585
| <a name="input_security_group_ids"></a> [security\_group\_ids](#input\_security\_group\_ids) | A list of security group IDs to associate with this replication group. | `list(string)` | n/a | yes |
7686
| <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. | `number` | `7` | no |
7787
| <a name="input_snapshot_window"></a> [snapshot\_window](#input\_snapshot\_window) | Daily time range (in UTC) during which ElastiCache will begin taking a daily snapshot of your cache cluster. | `string` | `"03:30-05:30"` | no |
88+
| <a name="input_sns_event_recipients"></a> [sns\_event\_recipients](#input\_sns\_event\_recipients) | Recipients of the ElastiCache SNS event topic. Should be a list of E-Mails. | `list(string)` | `[]` | no |
89+
| <a name="input_sns_kms_master_key_id"></a> [sns\_kms\_master\_key\_id](#input\_sns\_kms\_master\_key\_id) | The ID of an AWS KMS key for the SNS topic. | `string` | `"alias/aws/sns"` | no |
7890
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to all resources. | `map(string)` | `{}` | no |
7991
| <a name="input_transit_encryption_enabled"></a> [transit\_encryption\_enabled](#input\_transit\_encryption\_enabled) | Whether to enable encryption in transit. | `bool` | `true` | no |
8092
| <a name="input_vpc_subnet_group_name"></a> [vpc\_subnet\_group\_name](#input\_vpc\_subnet\_group\_name) | Subnet group name for the Elasticache cluster. | `string` | n/a | yes |
@@ -83,6 +95,7 @@ difference it can make in your AWS setup!
8395

8496
| Name | Description |
8597
|------|-------------|
98+
| <a name="output_auth_token"></a> [auth\_token](#output\_auth\_token) | The generate auth token used to access the Redis cluster. |
8699
| <a name="output_primary_endpoint_address"></a> [primary\_endpoint\_address](#output\_primary\_endpoint\_address) | Address of the endpoint for the primary node in the replication group, if the cluster mode is disabled. |
87100
| <a name="output_reader_endpoint_address"></a> [reader\_endpoint\_address](#output\_reader\_endpoint\_address) | Address of the endpoint for the reader node in the replication group, if the cluster mode is disabled. |
88101

@@ -96,7 +109,7 @@ difference it can make in your AWS setup!
96109
## Resources
97110

98111
- resource.aws_elasticache_replication_group.redis (main.tf#20)
99-
- resource.random_password.main_password (main.tf#118)
112+
- resource.random_password.main_password (main.tf#85)
100113

101114
# Examples
102115
### Basic Example

main.tf

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
* difference it can make in your AWS setup!
1919
*/
2020
resource "aws_elasticache_replication_group" "redis" {
21-
2221
# Naming
2322
replication_group_id = var.replication_group_id
2423
description = var.description
@@ -33,7 +32,7 @@ resource "aws_elasticache_replication_group" "redis" {
3332
num_cache_clusters = var.num_cache_clusters
3433

3534
# Parameters
36-
parameter_group_name = module.elasticache_parameter_group.name
35+
parameter_group_name = length(var.parameters) > 0 ? module.elasticache_parameter_group[0].name : null
3736

3837
# Auto failover
3938
automatic_failover_enabled = var.num_cache_clusters >= 2 ? true : false
@@ -42,8 +41,9 @@ resource "aws_elasticache_replication_group" "redis" {
4241
multi_az_enabled = var.num_cache_clusters >= 2 ? true : false
4342

4443
# Encryption
45-
at_rest_encryption_enabled = var.at_rest_encryption_enabled
4644
transit_encryption_enabled = var.transit_encryption_enabled
45+
at_rest_encryption_enabled = var.at_rest_encryption_enabled
46+
kms_key_id = var.enable_customer_managed_kms ? module.kms[0].key_arn : var.kms_key_id
4747

4848
# Network
4949
port = var.port
@@ -63,42 +63,60 @@ resource "aws_elasticache_replication_group" "redis" {
6363
# Token
6464
auth_token = random_password.main_password.result
6565

66-
# KMS
67-
kms_key_id = module.kms.key_arn
68-
6966
# SNS Notification
7067
notification_topic_arn = module.sns.arn
7168

69+
# Log Delivery
7270
dynamic "log_delivery_configuration" {
7371
for_each = var.log_type
72+
7473
content {
7574
destination = module.cloudwatch_log_group[log_delivery_configuration.value].name
76-
destination_type = var.destination_type
77-
log_format = var.log_format
78-
log_type = log_delivery_configuration.value
75+
destination_type = var.log_destination_type
76+
77+
log_format = var.log_format
78+
log_type = log_delivery_configuration.value
7979
}
8080
}
8181

8282
tags = var.tags
8383
}
8484

85+
resource "random_password" "main_password" {
86+
length = var.auth_token_length
87+
special = var.auth_token_special_characters
88+
}
89+
8590
module "elasticache_parameter_group" {
91+
count = length(var.parameters) > 0 ? 1 : 0
92+
8693
source = "./modules/elasticache_parameter_group/"
8794

88-
name = var.replication_group_id
95+
name = coalesce(var.parameter_group_name, var.replication_group_id)
96+
family = coalesce(var.parameter_group_family, "${var.engine}${var.engine_version}")
97+
parameters = var.parameters
98+
99+
tags = var.tags
89100
}
90101

91102
module "cloudwatch_log_group" {
92-
for_each = toset(var.log_type)
103+
for_each = var.log_destination_type == "cloudwatch-logs" ? toset(var.log_type) : []
93104

94105
source = "geekcell/cloudwatch-log-group/aws"
95-
version = ">= 1.0.0, < 2.0.0"
106+
version = ">= 2.0.0, < 3.0.0"
96107

97108
name = "/elasticache-${var.engine}/cluster/${var.replication_group_id}/log/${each.key}"
109+
110+
retention_in_days = var.log_retention_in_days
111+
skip_destroy = var.log_skip_destroy
112+
enable_customer_managed_kms = var.log_enable_customer_managed_kms
113+
98114
tags = var.tags
99115
}
100116

101117
module "kms" {
118+
count = var.enable_customer_managed_kms ? 1 : 0
119+
102120
source = "geekcell/kms/aws"
103121
version = ">= 1.0.0, < 2.0.0"
104122

@@ -110,12 +128,11 @@ module "sns" {
110128
source = "geekcell/sns-email-notification/aws"
111129
version = ">= 1.0.0, < 2.0.0"
112130

113-
name = var.replication_group_id
114-
email_addresses = var.elasticache_event_recipients
115-
tags = var.tags
116-
}
131+
name = "${var.replication_group_id}-elasticache"
132+
email_addresses = var.sns_event_recipients
117133

118-
resource "random_password" "main_password" {
119-
length = 24
120-
special = false
134+
enable_sns_sse_encryption = var.enable_sns_sse_encryption
135+
sns_kms_master_key_id = var.sns_kms_master_key_id
136+
137+
tags = var.tags
121138
}

modules/elasticache_parameter_group/main.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,6 @@ resource "aws_elasticache_parameter_group" "main" {
1010
value = parameter.value.value
1111
}
1212
}
13+
14+
tags = var.tags
1315
}

modules/elasticache_parameter_group/variables.tf

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@ variable "name" {
1010
}
1111

1212
variable "parameters" {
13-
default = [
14-
{
15-
name = "maxmemory-policy"
16-
value = "volatile-lru"
17-
}
18-
]
13+
default = []
1914
description = "The name and Values of the Elasticache parameters."
2015
type = list(object({
2116
name = string
2217
value = string
2318
}))
2419
}
20+
21+
variable "tags" {
22+
default = {}
23+
description = "A mapping of tags to assign to all resources."
24+
type = map(string)
25+
}

outputs.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@ output "reader_endpoint_address" {
77
value = aws_elasticache_replication_group.redis.reader_endpoint_address
88
description = "Address of the endpoint for the reader node in the replication group, if the cluster mode is disabled."
99
}
10+
11+
output "auth_token" {
12+
value = random_password.main_password.result
13+
description = "The generate auth token used to access the Redis cluster."
14+
sensitive = true
15+
}

variables.tf

Lines changed: 89 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ variable "at_rest_encryption_enabled" {
1818
type = bool
1919
}
2020

21+
variable "kms_key_id" {
22+
description = "The ARN of the AWS KMS to encrypt data at rest. Uses the AWS service managed encryption if not specified."
23+
default = null
24+
type = string
25+
}
26+
27+
variable "enable_customer_managed_kms" {
28+
description = "If enabled, will create a customer managed KMS key for at-rest encryption."
29+
default = false
30+
type = bool
31+
}
32+
2133
variable "auto_minor_version_upgrade" {
2234
default = false
2335
description = "Specifies whether minor version engine upgrades will be applied automatically to the underlying Cache Cluster instances during the maintenance window."
@@ -36,12 +48,6 @@ variable "description" {
3648
type = string
3749
}
3850

39-
variable "elasticache_event_recipients" {
40-
default = []
41-
description = "Recipients of the elasticache events."
42-
type = list(string)
43-
}
44-
4551
variable "engine" {
4652
default = "redis"
4753
description = " Name of the cache engine to be used for the clusters in this replication group."
@@ -109,10 +115,45 @@ variable "vpc_subnet_group_name" {
109115
type = string
110116
}
111117

112-
# Cloudwatch log group delivery
113-
variable "destination_type" {
118+
# Auth Token
119+
variable "auth_token_length" {
120+
description = "The length of the generated auth token."
121+
default = 24
122+
type = number
123+
}
124+
125+
variable "auth_token_special_characters" {
126+
description = "Whether to include special characters in the generated auth token."
127+
default = false
128+
type = bool
129+
}
130+
131+
# Parameter Group
132+
variable "parameter_group_name" {
133+
description = "The name of the ElastiCache parameter group. Defaults to the cluster name."
134+
default = null
135+
type = string
136+
}
137+
138+
variable "parameter_group_family" {
139+
description = "The family of the ElastiCache parameter group. Defaults to engine and engine_version."
140+
default = null
141+
type = string
142+
}
143+
144+
variable "parameters" {
145+
description = "Set custom parameters via a parameter group."
146+
default = []
147+
type = list(object({
148+
name = string
149+
value = string
150+
}))
151+
}
152+
153+
# Logging
154+
variable "log_destination_type" {
114155
default = "cloudwatch-logs"
115-
description = "For CloudWatch Logs use `cloudwatch-logs` or for Kinesis Data Firehose use `kinesis-firehose`."
156+
description = "For CloudWatch Logs use `cloudwatch-logs` or for Kinesis Data Firehose use `kinesis-firehose`. Only 'cloudwatch-logs' supported at the moment."
116157
type = string
117158
}
118159

@@ -126,10 +167,48 @@ variable "log_type" {
126167
default = ["slow-log", "engine-log"]
127168
type = list(string)
128169
description = "Type of logs, slow-log and engine-log"
170+
129171
validation {
130172
condition = alltrue([
131173
for type in var.log_type : contains(["slow-log", "engine-log"], type)
132174
])
133-
error_message = "The log_type allowed are only slow-log and engine-log."
175+
error_message = "The allowed log types are 'slow-log' and 'engine-log'."
134176
}
135177
}
178+
179+
variable "log_retention_in_days" {
180+
description = "The number of days log events are kept in CloudWatch Logs."
181+
default = 30
182+
type = number
183+
}
184+
185+
variable "log_skip_destroy" {
186+
description = "Whether to skip the deletion of the log groups when deleting the log group resources."
187+
default = false
188+
type = bool
189+
}
190+
191+
variable "log_enable_customer_managed_kms" {
192+
description = "Whether to enable customer managed KMS key for CloudWatch Logs encryption."
193+
default = false
194+
type = bool
195+
}
196+
197+
# SNS Topic
198+
variable "enable_sns_sse_encryption" {
199+
description = "Enable SSE Encryption for SNS Topic."
200+
default = true
201+
type = bool
202+
}
203+
204+
variable "sns_kms_master_key_id" {
205+
description = "The ID of an AWS KMS key for the SNS topic."
206+
default = "alias/aws/sns"
207+
type = string
208+
}
209+
210+
variable "sns_event_recipients" {
211+
default = []
212+
description = "Recipients of the ElastiCache SNS event topic. Should be a list of E-Mails."
213+
type = list(string)
214+
}

0 commit comments

Comments
 (0)