Skip to content

Commit 6bcc833

Browse files
authored
Feat/valkey elasticache (#76)
* feat: introducing valkey elasticache * feat: add argument to control auth_token update strategy * add new outputs for valkey, update existing output names and their descriptions * tf-check: fix unsupported attribute redis_endpoint * update tf-check github-actions for valkey example
1 parent 7b16032 commit 6bcc833

File tree

9 files changed

+250
-18
lines changed

9 files changed

+250
-18
lines changed

.github/workflows/tf-checks.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,7 @@ jobs:
1717
uses: clouddrove/github-shared-workflows/.github/workflows/tf-checks.yml@master
1818
with:
1919
working_directory: './examples/redis-cluster/'
20+
valkey:
21+
uses: clouddrove/github-shared-workflows/.github/workflows/tf-checks.yml@master
22+
with:
23+
working_directory: './examples/valkey/'

examples/redis-cluster/outputs.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ output "tags" {
99
}
1010

1111
output "redis_endpoint" {
12-
value = module.redis-cluster[*].redis_endpoint
12+
value = module.redis-cluster[*].elasticache_endpoint
1313
description = "Redis endpoint address."
1414
}
1515

examples/redis/outputs.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ output "tags" {
99
}
1010

1111
output "redis_endpoint" {
12-
value = module.redis.redis_endpoint
12+
value = module.redis.elasticache_endpoint
1313
description = "Redis endpoint address."
1414
}
1515

examples/valkey/example.tf

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
####----------------------------------------------------------------------------------
2+
## Provider block added, Use the Amazon Web Services (AWS) provider to interact with the many resources supported by AWS.
3+
####----------------------------------------------------------------------------------
4+
provider "aws" {
5+
region = local.region
6+
}
7+
locals {
8+
name = "valkey"
9+
environment = "test"
10+
region = "us-east-1"
11+
}
12+
####----------------------------------------------------------------------------------
13+
## A VPC is a virtual network that closely resembles a traditional network that you'd operate in your own data center.
14+
####----------------------------------------------------------------------------------
15+
module "vpc" {
16+
source = "clouddrove/vpc/aws"
17+
version = "2.0.0"
18+
19+
name = "${local.name}-vpc"
20+
environment = local.environment
21+
cidr_block = "10.0.0.0/16"
22+
}
23+
24+
####----------------------------------------------------------------------------------
25+
## A subnet is a range of IP addresses in your VPC.
26+
####----------------------------------------------------------------------------------
27+
module "subnets" {
28+
source = "clouddrove/subnet/aws"
29+
version = "2.0.0"
30+
31+
name = "${local.name}-subnets"
32+
environment = local.environment
33+
availability_zones = ["${local.region}a", "${local.region}b", "${local.region}c"]
34+
vpc_id = module.vpc.vpc_id
35+
type = "public"
36+
igw_id = module.vpc.igw_id
37+
cidr_block = module.vpc.vpc_cidr_block
38+
ipv6_cidr_block = module.vpc.ipv6_cidr_block
39+
}
40+
41+
##----------------------------------------------------------------------------------
42+
## VALKEY MODULE CALL
43+
##----------------------------------------------------------------------------------
44+
module "secrets_manager" {
45+
source = "clouddrove/secrets-manager/aws"
46+
version = "2.0.0"
47+
48+
name = local.name
49+
environment = local.environment
50+
51+
unmanaged = true
52+
secrets = [
53+
{
54+
name = "aws/elasticache/auth-tokens"
55+
description = "Elasticache AUTH Token"
56+
recovery_window_in_days = 7
57+
secret_string = "{ \"auth_token\": \"UseSomethingSecure*1234\"}" # -- The Secret can be changed with any DUMMY_VALUE after `terraform apply`. Terraform will not show any changes for `secret_string` in future plans.
58+
}
59+
]
60+
}
61+
62+
data "aws_secretsmanager_secret" "auth_token" {
63+
depends_on = [module.secrets_manager]
64+
name = "aws/elasticache/auth-tokens"
65+
}
66+
67+
data "aws_secretsmanager_secret_version" "auth_token" {
68+
secret_id = data.aws_secretsmanager_secret.auth_token.id
69+
}
70+
71+
##----------------------------------------------------------------------------------
72+
## VALKEY MODULE CALL
73+
##----------------------------------------------------------------------------------
74+
module "valkey" {
75+
source = "./../../"
76+
77+
name = local.name
78+
environment = local.environment
79+
80+
vpc_id = module.vpc.vpc_id
81+
allowed_ip = [module.vpc.vpc_cidr_block]
82+
allowed_ports = [6379]
83+
subnet_ids = concat(module.subnets.private_subnet_id, module.subnets.public_subnet_id)
84+
subnet_group_description = "${local.environment}-${local.name} subnet group."
85+
availability_zones = ["${local.region}a", "${local.region}c"]
86+
87+
cluster_replication_enabled = true
88+
replication_group = {
89+
engine = "valkey"
90+
engine_version = "8.1"
91+
parameter_group_name = "default.valkey8"
92+
port = 6379
93+
num_cache_clusters = 2
94+
apply_immediately = true
95+
node_type = "cache.t3.micro"
96+
replication_group_description = "${local.environment}-${local.name} replication group."
97+
maintenance_window = "sat:03:30-sat:04:30"
98+
}
99+
az_mode = "single-az"
100+
kms_key_id = null # -- AWS Owned KMS Key
101+
auto_generate_auth_token = false # -- To Provide your own auth_token
102+
auth_token = jsondecode(data.aws_secretsmanager_secret_version.auth_token.secret_string)["auth_token"]
103+
auth_token_update_strategy = "SET"
104+
sg_ids = [module.vpc.vpc_default_security_group_id]
105+
106+
}

examples/valkey/outputs.tf

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
### ---------- aws_elasticache_replication_group --------------------
2+
output "valkey_elasticache_arn" {
3+
description = "ARN of the created ElastiCache Replication Group."
4+
value = module.valkey.elasticache_arn
5+
}
6+
7+
output "valkey_elasticache_engine_version" {
8+
description = "Running version of the cache engine."
9+
value = module.valkey.elasticache_engine_version
10+
}
11+
12+
output "valkey_elasticache_cluster_enabled" {
13+
description = "Indicates if cluster mode is enabled."
14+
value = module.valkey.elasticache_cluster_enabled
15+
}
16+
17+
output "valkey_elasticache_configuration_endpoint_address" {
18+
description = "Address of the replication group configuration endpoint when cluster mode is enabled."
19+
value = module.valkey.elasticache_configuration_endpoint_address
20+
}
21+
22+
output "valkey_elasticache_id" {
23+
description = "ID of the ElastiCache Replication Group."
24+
value = module.valkey.id
25+
}
26+
27+
output "valkey_elasticache_member_clusters" {
28+
description = "Identifiers of all the nodes that are part of this replication group."
29+
value = module.valkey.elasticache_member_clusters
30+
}
31+
32+
output "valkey_elasticache_primary_endpoint_address" {
33+
description = "Address of the endpoint for the primary node in the replication group, if cluster mode is disabled."
34+
value = module.valkey.elasticache_endpoint
35+
}
36+
37+
output "valkey_elasticache_reader_endpoint_address" {
38+
description = "Address of the endpoint for the reader node in the replication group, if cluster mode is disabled."
39+
value = module.valkey.elasticache_reader_endpoint_address
40+
}
41+
42+
output "valkey_elasticache_tags_all" {
43+
description = "Map of tags assigned to the resource, including inherited ones."
44+
value = module.valkey.elasticache_tags_all
45+
}

examples/valkey/versions.tf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Terraform version
2+
terraform {
3+
required_version = ">= 1.6.5"
4+
5+
required_providers {
6+
aws = {
7+
source = "hashicorp/aws"
8+
version = ">= 5.31.0"
9+
}
10+
}
11+
}

main.tf

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ resource "aws_elasticache_subnet_group" "default" {
142142
##----------------------------------------------------------------------------------
143143

144144
resource "random_password" "auth_token" {
145-
count = var.enable && var.auth_token_enable && var.auth_token == null ? 1 : 0
145+
count = var.enable && var.auth_token_enable && var.auto_generate_auth_token ? 1 : 0
146146
length = var.length
147147
special = var.special
148148
}
@@ -178,11 +178,12 @@ resource "aws_elasticache_replication_group" "cluster" {
178178
multi_az_enabled = lookup(var.replication_group, "multi_az_enabled", false)
179179
network_type = var.network_type
180180

181-
auth_token = var.auth_token_enable ? (var.auth_token == null ? random_password.auth_token[0].result : var.auth_token) : ""
182-
kms_key_id = var.kms_key_id == "" ? join("", aws_kms_key.default[*].arn) : var.kms_key_id
183-
tags = module.labels.tags
184-
num_cache_clusters = lookup(var.replication_group, "num_cache_clusters", 1)
185-
user_group_ids = var.user_group_ids
181+
auth_token = var.auth_token_enable ? (var.auto_generate_auth_token ? random_password.auth_token[0].result : var.auth_token) : ""
182+
auth_token_update_strategy = var.auth_token_enable ? var.auth_token_update_strategy : null
183+
kms_key_id = var.kms_key_id == "" ? join("", aws_kms_key.default[*].arn) : var.kms_key_id
184+
tags = module.labels.tags
185+
num_cache_clusters = lookup(var.replication_group, "num_cache_clusters", 1)
186+
user_group_ids = var.user_group_ids
186187

187188
dynamic "log_delivery_configuration" {
188189
for_each = var.log_delivery_configuration
@@ -241,20 +242,20 @@ resource "aws_route53_record" "elasticache" {
241242
## Below resource will create ssm-parameter resource for redis and memcached with auth-token.
242243
##----------------------------------------------------------------------------------
243244
resource "aws_ssm_parameter" "secret" {
244-
count = var.enable && var.auth_token_enable ? 1 : 0
245+
count = var.enable && var.enable_aws_ssm_parameter && var.auth_token_enable ? 1 : 0
245246

246247
name = format("/%s/%s/auth-token", var.environment, var.name)
247248
description = var.ssm_parameter_description
248249
type = var.ssm_parameter_type
249-
value = var.auth_token == null ? random_password.auth_token[0].result : var.auth_token
250+
value = var.auto_generate_auth_token ? random_password.auth_token[0].result : var.auth_token
250251
key_id = var.kms_key_id == "" ? join("", aws_kms_key.default[*].arn) : var.kms_key_id
251252
}
252253

253254
##----------------------------------------------------------------------------------
254255
## Below resource will create ssm-parameter resource for redis with endpoint.
255256
##----------------------------------------------------------------------------------
256257
resource "aws_ssm_parameter" "secret-endpoint" {
257-
count = var.enable && var.ssm_parameter_endpoint_enabled ? 1 : 0
258+
count = var.enable && var.enable_aws_ssm_parameter && var.ssm_parameter_endpoint_enabled ? 1 : 0
258259

259260
name = format("/%s/%s/endpoint", var.environment, var.name)
260261
description = var.ssm_parameter_description
@@ -280,7 +281,7 @@ resource "aws_route53_record" "memcached_route_53" {
280281
## Below resource will create ssm-parameter resource for memcached with endpoint.
281282
##----------------------------------------------------------------------------------
282283
resource "aws_ssm_parameter" "memcached_secret-endpoint" {
283-
count = var.enable && var.memcached_ssm_parameter_endpoint_enabled ? 1 : 0
284+
count = var.enable && var.enable_aws_ssm_parameter && var.memcached_ssm_parameter_endpoint_enabled ? 1 : 0
284285

285286
name = format("/%s/%s/memcached-endpoint", var.environment, var.name)
286287
description = var.ssm_parameter_description

outputs.tf

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Description : Terraform module to create Elasticache Cluster and replica for Redis.
33
output "id" {
44
value = var.cluster_enabled ? "" : (var.cluster_replication_enabled ? join("", aws_elasticache_replication_group.cluster[*].id) : join("", aws_elasticache_replication_group.cluster[*].id))
5-
description = "Redis cluster id."
5+
description = "Elasticache cluster id."
66
}
77

88
output "port" {
@@ -16,14 +16,14 @@ output "tags" {
1616
description = "A mapping of tags to assign to the resource."
1717
}
1818

19-
output "redis_endpoint" {
19+
output "elasticache_endpoint" {
2020
value = var.cluster_replication_enabled ? "" : (var.cluster_replication_enabled ? join("", aws_elasticache_replication_group.cluster[*].primary_endpoint_address) : join("", aws_elasticache_cluster.default[*].configuration_endpoint))
21-
description = "Redis endpoint address."
21+
description = "Elasticache endpoint address."
2222
}
2323

24-
output "redis_arn" {
24+
output "elasticache_arn" {
2525
value = var.enable && length(aws_elasticache_replication_group.cluster) > 0 ? aws_elasticache_replication_group.cluster[0].arn : length(aws_elasticache_replication_group.cluster) > 0 ? aws_elasticache_replication_group.cluster[0].arn : null
26-
description = "Redis arn"
26+
description = "Elasticache arn"
2727
}
2828

2929
output "memcached_endpoint" {
@@ -61,7 +61,55 @@ output "Memcached_ssm_name" {
6161
}
6262

6363
output "auth_token" {
64-
value = var.enable && var.auth_token_enable ? random_password.auth_token[0].result : null
64+
value = var.enable && var.auth_token_enable && var.auto_generate_auth_token ? random_password.auth_token[0].result : null
6565
sensitive = true
6666
description = "Auth token generated value"
6767
}
68+
69+
### ---------- aws_elasticache_cluster ------------------------------
70+
output "elasticache_engine_version_actual" {
71+
value = try(aws_elasticache_cluster.default[0].engine_version_actual, null)
72+
description = "Running version of the cache engine"
73+
}
74+
75+
output "elasticache_cache_nodes" {
76+
value = try(aws_elasticache_cluster.default[0].cache_nodes, [])
77+
description = "List of node objects"
78+
}
79+
80+
output "elasticache_cluster_address" {
81+
value = try(aws_elasticache_cluster.default[0].cluster_address, null)
82+
description = "(Memcached only) DNS name of the cache cluster"
83+
}
84+
85+
### ---------- aws_elasticache_replication_group --------------------
86+
87+
output "elasticache_engine_version" {
88+
description = "Running version of the cache engine."
89+
value = try(aws_elasticache_replication_group.cluster[0].engine_version_actual, null)
90+
}
91+
92+
output "elasticache_cluster_enabled" {
93+
description = "Indicates if cluster mode is enabled."
94+
value = try(aws_elasticache_replication_group.cluster[0].cluster_enabled, null)
95+
}
96+
97+
output "elasticache_configuration_endpoint_address" {
98+
description = "Address of the replication group configuration endpoint when cluster mode is enabled."
99+
value = try(aws_elasticache_replication_group.cluster[0].configuration_endpoint_address, null)
100+
}
101+
102+
output "elasticache_member_clusters" {
103+
description = "Identifiers of all the nodes that are part of this replication group."
104+
value = try([for c in aws_elasticache_replication_group.cluster[0].member_clusters : c], null)
105+
}
106+
107+
output "elasticache_reader_endpoint_address" {
108+
description = "Address of the endpoint for the reader node in the replication group, if cluster mode is disabled."
109+
value = try(aws_elasticache_replication_group.cluster[0].reader_endpoint_address, null)
110+
}
111+
112+
output "elasticache_tags_all" {
113+
description = "Map of tags assigned to the resource, including inherited ones."
114+
value = try(aws_elasticache_replication_group.cluster[0].tags_all, null)
115+
}

variables.tf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,24 @@ variable "auth_token_enable" {
9393
description = "Flag to specify whether to create auth token (password) protected cluster. Can be specified only if transit_encryption_enabled = true."
9494
}
9595

96+
variable "auto_generate_auth_token" {
97+
type = bool
98+
default = true
99+
description = "Whether to automatically generate the authentication token using Terraform. If set to false, you must provide your own token via the 'auth_token' variable."
100+
}
101+
96102
variable "auth_token" {
97103
type = string
98104
default = null
99105
description = "The password used to access a password protected server. Can be specified only if transit_encryption_enabled = true. Find auto generated auth_token in terraform.tfstate or in AWS SSM Parameter Store."
100106
}
101107

108+
variable "auth_token_update_strategy" {
109+
type = string
110+
default = null
111+
description = "(Optional) Strategy to use when updating the auth_token. Valid values are SET, ROTATE, and DELETE. Required if auth_token is set. Defaults to ROTATE"
112+
}
113+
102114
variable "cluster_replication_enabled" {
103115
type = bool
104116
default = false
@@ -297,6 +309,11 @@ variable "route53" {
297309
}
298310

299311
###------------------------------- ssm_parameter----------------------------
312+
variable "enable_aws_ssm_parameter" {
313+
description = "Whether to create the AWS SSM parameter for the auth token"
314+
type = bool
315+
default = false
316+
}
300317

301318
variable "ssm_parameter_endpoint_enabled" {
302319
type = bool

0 commit comments

Comments
 (0)