Skip to content

Commit fe72275

Browse files
committed
Adding DNS record when creating cluster
1 parent 6e15689 commit fe72275

18 files changed

+218
-5
lines changed

README-HEADER.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Provisions an Elasticache Redis cluster (with Cluster Mode Disabled).
2222
2323
By default, it will provision one writer and one reader node, but that can be adjusted by setting the `nodes` variable to a different value.
2424

25+
This module also assumes that connections are established through a private DNS record created in Route53. This makes it so that replacement of the ElastiCache cluster can be made in a fashion that is transparent to application configurations. This can be adjusted by setting `create_dns` to `false`.
26+
2527
Integrate this module like so:
2628

2729
```hcl

README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
Use this URL for the source of the module. See the usage examples below for more details.
88

99
```hcl
10-
github.com/pbs/terraform-aws-elasticache-redis-standalone-module?ref=0.0.2
10+
github.com/pbs/terraform-aws-elasticache-redis-standalone-module?ref=x.y.z
1111
```
1212

1313
### Alternative Installation Methods
@@ -22,11 +22,13 @@ Provisions an Elasticache Redis cluster (with Cluster Mode Disabled).
2222
2323
By default, it will provision one writer and one reader node, but that can be adjusted by setting the `nodes` variable to a different value.
2424

25+
This module also assumes that connections are established through a private DNS record created in Route53. This makes it so that replacement of the ElastiCache cluster can be made in a fashion that is transparent to application configurations. This can be adjusted by setting `create_dns` to `false`.
26+
2527
Integrate this module like so:
2628

2729
```hcl
2830
module "elasticache-redis-standalone" {
29-
source = "github.com/pbs/terraform-aws-elasticache-redis-standalone-module?ref=0.0.2"
31+
source = "github.com/pbs/terraform-aws-elasticache-redis-standalone-module?ref=x.y.z"
3032
3133
# Tagging Parameters
3234
organization = var.organization
@@ -42,7 +44,7 @@ module "elasticache-redis-standalone" {
4244

4345
If this repo is added as a subtree, then the version of the module should be close to the version shown here:
4446

45-
`0.0.2`
47+
`x.y.z`
4648

4749
Note, however that subtrees can be altered as desired within repositories.
4850

@@ -78,8 +80,11 @@ No modules.
7880
| [aws_elasticache_parameter_group.parameter_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticache_parameter_group) | resource |
7981
| [aws_elasticache_replication_group.replication_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticache_replication_group) | resource |
8082
| [aws_elasticache_subnet_group.subnet_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticache_subnet_group) | resource |
83+
| [aws_route53_record.primary_endpoint](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
84+
| [aws_route53_record.reader_endpoint](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | resource |
8185
| [aws_security_group.sg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
8286
| [aws_security_group_rule.egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource |
87+
| [aws_route53_zone.private_hosted_zone](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source |
8388
| [aws_subnets.private_subnets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnets) | data source |
8489
| [aws_vpc.vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source |
8590

@@ -96,7 +101,10 @@ No modules.
96101
| <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 |
97102
| <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 nodes during the maintenance window. Only supported for engine type "redis" and if the engine version is 6 or higher. | `bool` | `true` | no |
98103
| <a name="input_automatic_failover_enabled"></a> [automatic\_failover\_enabled](#input\_automatic\_failover\_enabled) | Specifies whether a read-only replica will be automatically promoted to read/write primary if the existing primary fails. If null, will be enabled if `nodes` > 1. If true, `nodes` must be greater than 1. | `bool` | `null` | no |
104+
| <a name="input_cname"></a> [cname](#input\_cname) | The value to use for the CNAME record if `create_dns` is true. The primary endpoint will be <cname>.<private\_hosted\_zone>, and the reader endpoint will be <cname>-ro.<private\_hosted\_zone>. If null, the name variable will be used instead. | `string` | `null` | no |
105+
| <a name="input_create_dns"></a> [create\_dns](#input\_create\_dns) | Whether to create DNS records for the primary and reader endpoints. | `bool` | `true` | no |
99106
| <a name="input_data_tiering_enabled"></a> [data\_tiering\_enabled](#input\_data\_tiering\_enabled) | Enables data tiering. Data tiering is only supported for replication groups using the r6gd node type. This parameter must be set to true when using r6gd nodes. | `bool` | `false` | no |
107+
| <a name="input_dns_ttl"></a> [dns\_ttl](#input\_dns\_ttl) | TTL for DNS records. | `number` | `300` | no |
100108
| <a name="input_egress_cidr_blocks"></a> [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | List of CIDR blocks to assign to the egress rule of the security group. If null, `egress_security_group_ids` must be used. | `list(string)` | <pre>[<br> "10.0.0.0/8"<br>]</pre> | no |
101109
| <a name="input_egress_source_sg_id"></a> [egress\_source\_sg\_id](#input\_egress\_source\_sg\_id) | List of security group ID to assign to the egress rule of the security group. If null, `egress_cidr_blocks` must be used. | `string` | `null` | no |
102110
| <a name="input_engine_version"></a> [engine\_version](#input\_engine\_version) | Version number of the cache engine to be used. If not set, defaults to the latest version. See Describe Cache Engine Versions in the AWS Documentation for supported versions. When engine is redis and the version is 6 or higher, the major and minor version can be set, e.g., 6.2, or the minor version can be unspecified which will use the latest version at creation time, e.g., 6.x. Otherwise, specify the full version desired, e.g., 5.0.6. | `string` | `null` | no |
@@ -114,6 +122,7 @@ No modules.
114122
| <a name="input_parameters"></a> [parameters](#input\_parameters) | Additional parameters that will be added to parameter group. | `list(map(any))` | `[]` | no |
115123
| <a name="input_port"></a> [port](#input\_port) | The port number on which each of the cache nodes will accept connections. Cannot be provided with replication\_group\_id. Changing this value will re-create the resource. | `number` | `6379` | no |
116124
| <a name="input_preferred_cache_cluster_azs"></a> [preferred\_cache\_cluster\_azs](#input\_preferred\_cache\_cluster\_azs) | List of availability zones in which to create cluster. | `list(string)` | `null` | no |
125+
| <a name="input_private_hosted_zone"></a> [private\_hosted\_zone](#input\_private\_hosted\_zone) | Private hosted zone to create DNS records in. If null, `create_dns` must be set to false. | `string` | `null` | no |
117126
| <a name="input_replication_group_description"></a> [replication\_group\_description](#input\_replication\_group\_description) | Description of the replication group to be created. If null, one will be generated using the name of the nodes. | `string` | `null` | no |
118127
| <a name="input_replication_group_id"></a> [replication\_group\_id](#input\_replication\_group\_id) | Replication group identifier. This parameter is stored as a lowercase string. If null, the name of the nodes will be used. | `string` | `null` | no |
119128
| <a name="input_security_group_ids"></a> [security\_group\_ids](#input\_security\_group\_ids) | One or more VPC security groups associated with the nodes. If null, use the one provided by this module. | `list(string)` | `null` | no |

data.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,9 @@ data "aws_subnets" "private_subnets" {
1313
}
1414
}
1515
}
16+
17+
data "aws_route53_zone" "private_hosted_zone" {
18+
count = var.create_dns ? 1 : 0
19+
name = "${var.private_hosted_zone}."
20+
private_zone = true
21+
}

dns.tf

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
resource "aws_route53_record" "primary_endpoint" {
2+
count = var.create_dns ? 1 : 0
3+
zone_id = local.private_hosted_zone
4+
name = local.cname
5+
type = "CNAME"
6+
ttl = var.dns_ttl
7+
records = [aws_elasticache_replication_group.replication_group.primary_endpoint_address]
8+
}
9+
10+
resource "aws_route53_record" "reader_endpoint" {
11+
count = var.create_dns ? 1 : 0
12+
zone_id = local.private_hosted_zone
13+
name = "${local.cname}-ro"
14+
type = "CNAME"
15+
ttl = var.dns_ttl
16+
records = [aws_elasticache_replication_group.replication_group.reader_endpoint_address]
17+
}
18+

examples/basic/main.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
module "redis" {
22
source = "../.."
33

4+
private_hosted_zone = var.private_hosted_zone
5+
46
organization = var.organization
57
environment = var.environment
68
product = var.product

examples/basic/vars.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
variable "private_hosted_zone" {
2+
type = string
3+
description = "Private hosted zone for this ElastiCache Cluster. Populate `TF_VAR_private_hosted_zone` before running any tests to have this value populated."
4+
}

examples/lambda/main.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ module "lambda" {
2323
module "redis" {
2424
source = "../.."
2525

26+
private_hosted_zone = var.private_hosted_zone
27+
2628
organization = var.organization
2729
environment = var.environment
2830
product = var.product

examples/lambda/vars.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
variable "private_hosted_zone" {
2+
type = string
3+
description = "Private hosted zone for this ElastiCache Cluster. Populate `TF_VAR_private_hosted_zone` before running any tests to have this value populated."
4+
}

examples/no-dns/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
backend.tf
2+
provider.tf

examples/no-dns/.terraform.lock.hcl

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/no-dns/main.tf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module "redis" {
2+
source = "../.."
3+
4+
create_dns = false
5+
6+
organization = var.organization
7+
environment = var.environment
8+
product = var.product
9+
repo = var.repo
10+
}

examples/no-dns/outputs.tf

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
output "name" {
2+
description = "The name of the ElastiCache replication group"
3+
value = module.redis.name
4+
}
5+
6+
output "arn" {
7+
description = "The ARN of the ElastiCache replication group"
8+
value = module.redis.arn
9+
}
10+
11+
output "sg_ids" {
12+
description = "The security group ids"
13+
value = module.redis.sg_ids
14+
}
15+
16+
output "engine_version_actual" {
17+
description = "Because ElastiCache pulls the latest minor or patch for a version, this attribute returns the running version of the cache engine."
18+
value = module.redis.engine_version_actual
19+
}
20+
21+
output "member_clusters" {
22+
description = "Identifiers of all the nodes that are part of this replication group."
23+
value = module.redis.member_clusters
24+
}
25+
26+
output "primary_endpoint_address" {
27+
description = "Address of the endpoint for the primary node in the replication group."
28+
value = module.redis.primary_endpoint_address
29+
}
30+
31+
output "reader_endpoint_address" {
32+
description = "Address of the endpoint for the reader node in the replication group."
33+
value = module.redis.reader_endpoint_address
34+
}
35+
36+
output "tags" {
37+
description = "The tags"
38+
value = module.redis.tags
39+
}

examples/no-dns/sample-backend.tf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# terraform {
2+
# backend "s3" {
3+
# bucket = "my-bucket-tfstate"
4+
# key = "example-terraform-aws-elasticache-redis-standalone-no-dns"
5+
# profile = "my-profile"
6+
# region = "us-east-1"
7+
# dynamodb_table = "terraform-lock"
8+
# }
9+
# }

examples/no-dns/sample-provider.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# provider "aws" {
2+
# region = "us-east-1"
3+
# profile = "my-profile"
4+
# default_tags {
5+
# tags = {
6+
# product = var.product
7+
# environment = var.environment
8+
# repo = var.repo
9+
# organization = var.organization
10+
# }
11+
# }
12+
# }

examples/no-dns/tags.tf

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
variable "environment" {
2+
description = "Environment (sharedtools, dev, staging, prod)"
3+
type = string
4+
5+
default = "sharedtools"
6+
7+
validation {
8+
condition = contains(["sharedtools", "dev", "staging", "prod"], var.environment)
9+
error_message = "The environment variable must be one of [sharedtools, dev, staging, prod]."
10+
}
11+
}
12+
13+
variable "product" {
14+
description = "Tag used to group resources according to application"
15+
16+
default = "ex-tf-redis-no-dns"
17+
18+
validation {
19+
condition = can(regex("[a-z\\-]+", var.product))
20+
error_message = "The product variable violates approved regex."
21+
}
22+
}
23+
24+
variable "repo" {
25+
description = "Tag used to point to the repo using this module"
26+
27+
default = "https://github.com/pbs/terraform-elasticache-redis-standalone-module.git"
28+
29+
validation {
30+
condition = can(regex("(?:git|ssh|https?|git@[-\\w.]+):(\\/\\/)?(.*?)(\\.git)(\\/?|\\#[-\\d\\w._]+?)$", var.repo))
31+
error_message = "The repo variable violates approved regex."
32+
}
33+
}
34+
35+
variable "organization" {
36+
description = "Organization using this module. Used to prefix tags so that they are easily identified as being from your organization"
37+
type = string
38+
39+
default = "example"
40+
41+
validation {
42+
condition = can(regex("[a-z\\-]+", var.organization))
43+
error_message = "The organization variable violates approved regex."
44+
}
45+
}

locals.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ locals {
55
vpc_id = var.vpc_id != null ? var.vpc_id : data.aws_vpc.vpc[0].id
66
subnets = var.subnets != null ? var.subnets : data.aws_subnets.private_subnets[0].ids
77
parameter_group_name = var.parameter_group_name != null ? var.parameter_group_name : aws_elasticache_parameter_group.parameter_group.id
8+
cname = var.cname != null ? var.cname : "${local.name}-cache"
9+
private_hosted_zone = var.create_dns ? data.aws_route53_zone.private_hosted_zone[0].zone_id : null
810

911
vpc_data_lookup_tags = var.vpc_data_lookup_tags != null ? var.vpc_data_lookup_tags : {
1012
"environment" : var.environment

optional.tf

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,27 @@ variable "egress_source_sg_id" {
225225
default = null
226226
type = string
227227
}
228+
229+
variable "cname" {
230+
description = "The value to use for the CNAME record if `create_dns` is true. The primary endpoint will be <cname>.<private_hosted_zone>, and the reader endpoint will be <cname>-ro.<private_hosted_zone>. If null, the name variable will be used instead."
231+
default = null
232+
type = string
233+
}
234+
235+
variable "create_dns" {
236+
description = "Whether to create DNS records for the primary and reader endpoints."
237+
default = true
238+
type = bool
239+
}
240+
241+
variable "dns_ttl" {
242+
description = "TTL for DNS records."
243+
default = 300
244+
type = number
245+
}
246+
247+
variable "private_hosted_zone" {
248+
description = "Private hosted zone to create DNS records in. If null, `create_dns` must be set to false."
249+
default = null
250+
type = string
251+
}

outputs.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ output "member_clusters" {
2525

2626
output "primary_endpoint_address" {
2727
description = "Address of the endpoint for the primary node in the replication group."
28-
value = aws_elasticache_replication_group.replication_group.primary_endpoint_address
28+
value = var.create_dns ? aws_route53_record.primary_endpoint[0].fqdn : aws_elasticache_replication_group.replication_group.primary_endpoint_address
2929
}
3030

3131
output "reader_endpoint_address" {
3232
description = "Address of the endpoint for the reader node in the replication group."
33-
value = aws_elasticache_replication_group.replication_group.reader_endpoint_address
33+
value = var.create_dns ? aws_route53_record.reader_endpoint[0].fqdn : aws_elasticache_replication_group.replication_group.reader_endpoint_address
3434
}
3535

3636
output "tags" {

0 commit comments

Comments
 (0)