Skip to content

Commit d27d632

Browse files
authored
Use Security Group rules instead of inline rule blocks. Fix example. Fix README. Update to latest versions of modules. Change region for tests (#54)
* Use Security Group rules instead of inline rule blocks. Fix example. Fix README. Update to latest versions of modules. Change region for tests * Use Security Group rules instead of inline rule blocks. Fix example. Fix README. Update to latest versions of modules. Change region for tests * Use Security Group rules instead of inline rule blocks. Fix example. Fix README. Update to latest versions of modules. Change region for tests
1 parent 94f19dd commit d27d632

File tree

12 files changed

+326
-178
lines changed

12 files changed

+326
-178
lines changed

README.md

Lines changed: 151 additions & 78 deletions
Large diffs are not rendered by default.

README.yaml

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -49,38 +49,62 @@ description: |-
4949
# How to use this project
5050
usage: |-
5151
52+
For a complete example, see [examples/complete](examples/complete).
53+
54+
For automated tests of the complete example using [bats](https://github.com/bats-core/bats-core) and [Terratest](https://github.com/gruntwork-io/terratest) (which tests and deploys the example on AWS), see [test](test).
55+
5256
```hcl
53-
// Generate a random string for auth token, no special chars
54-
resource "random_string" "auth_token" {
55-
length = 64
56-
special = false
57-
}
58-
59-
module "example_redis" {
60-
source = "git::https://github.com/cloudposse/terraform-aws-elasticache-redis.git?ref=master"
61-
namespace = "eg"
62-
stage = "dev"
63-
name = "redis"
64-
zone_id = var.route53_zone_id
65-
security_groups = [var.security_group_id]
66-
67-
auth_token = random_string.auth_token.result
68-
vpc_id = var.vpc_id
69-
subnets = var.private_subnets
70-
maintenance_window = "wed:03:00-wed:04:00"
71-
cluster_size = 2
72-
instance_type = "cache.t2.micro"
73-
engine_version = "4.0.10"
74-
alarm_cpu_threshold_percent = var.cache_alarm_cpu_threshold_percent
75-
alarm_memory_threshold_bytes = var.cache_alarm_memory_threshold_bytes
76-
apply_immediately = true
77-
availability_zones = var.availability_zones
78-
automatic_failover = false
79-
}
80-
81-
output "auth_token" {
82-
value = random_string.auth_token.result
83-
}
57+
provider "aws" {
58+
region = var.region
59+
}
60+
61+
module "vpc" {
62+
source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.8.1"
63+
namespace = var.namespace
64+
stage = var.stage
65+
name = var.name
66+
cidr_block = "172.16.0.0/16"
67+
}
68+
69+
module "subnets" {
70+
source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.18.1"
71+
availability_zones = var.availability_zones
72+
namespace = var.namespace
73+
stage = var.stage
74+
name = var.name
75+
vpc_id = module.vpc.vpc_id
76+
igw_id = module.vpc.igw_id
77+
cidr_block = module.vpc.vpc_cidr_block
78+
nat_gateway_enabled = true
79+
nat_instance_enabled = false
80+
}
81+
82+
module "redis" {
83+
source = "git::https://github.com/cloudposse/terraform-aws-elasticache-redis.git?ref=master"
84+
availability_zones = var.availability_zones
85+
namespace = var.namespace
86+
stage = var.stage
87+
name = var.name
88+
zone_id = var.zone_id
89+
vpc_id = module.vpc.vpc_id
90+
allowed_security_groups = [module.vpc.vpc_default_security_group_id]
91+
subnets = module.subnets.private_subnet_ids
92+
cluster_size = var.cluster_size
93+
instance_type = var.instance_type
94+
apply_immediately = true
95+
automatic_failover = false
96+
engine_version = var.engine_version
97+
family = var.family
98+
at_rest_encryption_enabled = var.at_rest_encryption_enabled
99+
transit_encryption_enabled = var.transit_encryption_enabled
100+
101+
parameter = [
102+
{
103+
name = "notify-keyspace-events"
104+
value = "lK"
105+
}
106+
]
107+
}
84108
```
85109
86110
examples: |-

docs/terraform.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,23 @@
55
| alarm_actions | Alarm action list | list(string) | `<list>` | no |
66
| alarm_cpu_threshold_percent | CPU threshold alarm level | number | `75` | no |
77
| alarm_memory_threshold_bytes | Ram threshold alarm level | number | `10000000` | no |
8+
| allowed_cidr_blocks | List of CIDR blocks that are allowed ingress to the cluster's Security Group created in the module | list(string) | `<list>` | no |
9+
| allowed_security_groups | List of Security Group IDs that are allowed ingress to the cluster's Security Group created in the module | list(string) | `<list>` | no |
810
| apply_immediately | Apply changes immediately | bool | `true` | no |
911
| at_rest_encryption_enabled | Enable encryption at rest | bool | `false` | no |
1012
| attributes | Additional attributes (_e.g._ "1") | list(string) | `<list>` | no |
11-
| auth_token | Auth token for password protecting redis, `transit_encryption_enabled` must be set to `true`. Password must be longer than 16 chars | string | `` | no |
12-
| automatic_failover | Automatic failover (Not available for T1/T2 instances) | bool | `false` | no |
13+
| auth_token | Auth token for password protecting redis, `transit_encryption_enabled` must be set to `true`. Password must be longer than 16 chars | string | `null` | no |
14+
| automatic_failover_enabled | Automatic failover (Not available for T1/T2 instances) | bool | `false` | no |
1315
| availability_zones | Availability zone IDs | list(string) | `<list>` | no |
14-
| cluster_size | Count of nodes in cluster | number | `1` | no |
16+
| cluster_mode_enabled | Flag to enable/disable creation of a native redis cluster. `automatic_failover_enabled` must be set to `true`. Only 1 `cluster_mode` block is allowed | bool | `false` | no |
17+
| cluster_mode_num_node_groups | Number of node groups (shards) for this Redis replication group. Changing this number will trigger an online resizing operation before other settings modifications | number | `0` | no |
18+
| cluster_mode_replicas_per_node_group | Number of replica nodes in each node group. Valid values are 0 to 5. Changing this number will force a new resource | number | `0` | no |
19+
| cluster_size | Number of nodes in cluster | number | `1` | no |
1520
| delimiter | Delimiter between `name`, `namespace`, `stage` and `attributes` | string | `-` | no |
1621
| elasticache_subnet_group_name | Subnet group name for the ElastiCache instance | string | `` | no |
1722
| enabled | Set to false to prevent the module from creating any resources | bool | `true` | no |
1823
| engine_version | Redis engine version | string | `4.0.10` | no |
24+
| existing_security_groups | List of existing Security Group IDs to place the cluster into. Set `use_existing_security_groups` to `true` to enable using `existing_security_groups` as Security Groups for the cluster | list(string) | `<list>` | no |
1925
| family | Redis family | string | `redis4.0` | no |
2026
| instance_type | Elastic cache instance type | string | `cache.t2.micro` | no |
2127
| maintenance_window | Maintenance window | string | `wed:03:00-wed:04:00` | no |
@@ -26,21 +32,22 @@
2632
| parameter | A list of Redis parameters to apply. Note that parameters may differ from one Redis family to another | object | `<list>` | no |
2733
| port | Redis port | number | `6379` | no |
2834
| replication_group_id | Replication group ID with the following constraints: A name must contain from 1 to 20 alphanumeric characters or hyphens. The first character must be a letter. A name cannot end with a hyphen or contain two consecutive hyphens. | string | `` | no |
29-
| security_groups | Security Group IDs | list(string) | `<list>` | no |
3035
| snapshot_retention_limit | The number of days for which ElastiCache will retain automatic cache cluster snapshots before deleting them. | number | `0` | no |
3136
| snapshot_window | The daily time range (in UTC) during which ElastiCache will begin taking a daily snapshot of your cache cluster. | string | `06:30-07:30` | no |
3237
| stage | Stage (e.g. `prod`, `dev`, `staging`) | string | `` | no |
3338
| subnets | Subnet IDs | list(string) | `<list>` | no |
3439
| tags | Additional tags (_e.g._ map("BusinessUnit","ABC") | map(string) | `<map>` | no |
3540
| transit_encryption_enabled | Enable TLS | bool | `true` | no |
41+
| use_existing_security_groups | Flag to enable/disable creation of Security Group in the module. Set to `true` to disable Security Group creation and provide a list of existing security Group IDs in `existing_security_groups` to place the cluster into | bool | `false` | no |
3642
| vpc_id | VPC ID | string | - | yes |
3743
| zone_id | Route53 DNS Zone ID | string | `` | no |
3844

3945
## Outputs
4046

4147
| Name | Description |
4248
|------|-------------|
43-
| host | Redis host |
49+
| endpoint | Redis primary endpoint |
50+
| host | Redis hostname |
4451
| id | Redis cluster ID |
4552
| port | Redis port |
4653
| security_group_id | Security group ID |

examples/basic/main.tf

Lines changed: 0 additions & 22 deletions
This file was deleted.

examples/complete/fixtures.us-west-1.tfvars renamed to examples/complete/fixtures.us-east-2.tfvars

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
region = "us-west-1"
1+
region = "us-east-2"
22

3-
availability_zones = ["us-west-1b", "us-west-1c"]
3+
availability_zones = ["us-east-2a", "us-east-2b"]
44

55
namespace = "eg"
66

examples/complete/main.tf

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ provider "aws" {
33
}
44

55
module "vpc" {
6-
source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.7.0"
6+
source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.8.1"
77
namespace = var.namespace
88
stage = var.stage
99
name = var.name
1010
cidr_block = "172.16.0.0/16"
1111
}
1212

1313
module "subnets" {
14-
source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.16.0"
14+
source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.18.1"
1515
availability_zones = var.availability_zones
1616
namespace = var.namespace
1717
stage = var.stage
@@ -31,12 +31,12 @@ module "redis" {
3131
name = var.name
3232
zone_id = var.zone_id
3333
vpc_id = module.vpc.vpc_id
34-
security_groups = [module.vpc.vpc_default_security_group_id]
34+
allowed_security_groups = [module.vpc.vpc_default_security_group_id]
3535
subnets = module.subnets.private_subnet_ids
3636
cluster_size = var.cluster_size
3737
instance_type = var.instance_type
3838
apply_immediately = true
39-
automatic_failover = false
39+
automatic_failover_enabled = false
4040
engine_version = var.engine_version
4141
family = var.family
4242
at_rest_encryption_enabled = var.at_rest_encryption_enabled

examples/complete/outputs.tf

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@ output "cluster_security_group_id" {
2323
description = "Cluster Security Group ID"
2424
}
2525

26+
output "cluster_endpoint" {
27+
value = module.redis.endpoint
28+
description = "Redis primary endpoint"
29+
}
30+
2631
output "cluster_host" {
2732
value = module.redis.host
28-
description = "Redis host"
33+
description = "Redis hostname"
2934
}

examples/complete/variables.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ variable "name" {
2525

2626
variable "cluster_size" {
2727
type = number
28-
description = "Count of nodes in cluster"
28+
description = "Number of nodes in cluster"
2929
}
3030

3131
variable "instance_type" {

main.tf

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module "label" {
2-
source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.14.1"
2+
source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.16.0"
33
enabled = var.enabled
44
namespace = var.namespace
55
name = var.name
@@ -13,25 +13,43 @@ module "label" {
1313
# Security Group Resources
1414
#
1515
resource "aws_security_group" "default" {
16-
count = var.enabled ? 1 : 0
16+
count = var.enabled && var.use_existing_security_groups == false ? 1 : 0
1717
vpc_id = var.vpc_id
1818
name = module.label.id
19+
tags = module.label.tags
20+
}
1921

20-
ingress {
21-
from_port = var.port # Redis
22-
to_port = var.port
23-
protocol = "tcp"
24-
security_groups = var.security_groups
25-
}
22+
resource "aws_security_group_rule" "egress" {
23+
count = var.enabled && var.use_existing_security_groups == false ? 1 : 0
24+
description = "Allow all egress traffic"
25+
from_port = 0
26+
to_port = 0
27+
protocol = "-1"
28+
cidr_blocks = ["0.0.0.0/0"]
29+
security_group_id = join("", aws_security_group.default.*.id)
30+
type = "egress"
31+
}
2632

27-
egress {
28-
from_port = 0
29-
to_port = 0
30-
protocol = "-1"
31-
cidr_blocks = ["0.0.0.0/0"]
32-
}
33+
resource "aws_security_group_rule" "ingress_security_groups" {
34+
count = var.enabled && var.use_existing_security_groups == false ? length(var.allowed_security_groups) : 0
35+
description = "Allow inbound traffic from existing Security Groups"
36+
from_port = var.port
37+
to_port = var.port
38+
protocol = "tcp"
39+
source_security_group_id = var.allowed_security_groups[count.index]
40+
security_group_id = join("", aws_security_group.default.*.id)
41+
type = "ingress"
42+
}
3343

34-
tags = module.label.tags
44+
resource "aws_security_group_rule" "ingress_cidr_blocks" {
45+
count = var.enabled && var.use_existing_security_groups == false && length(var.allowed_cidr_blocks) > 0 ? 1 : 0
46+
description = "Allow inbound traffic from CIDR blocks"
47+
from_port = var.port
48+
to_port = var.port
49+
protocol = "tcp"
50+
cidr_blocks = var.allowed_cidr_blocks
51+
security_group_id = join("", aws_security_group.default.*.id)
52+
type = "ingress"
3553
}
3654

3755
locals {
@@ -61,17 +79,17 @@ resource "aws_elasticache_parameter_group" "default" {
6179
resource "aws_elasticache_replication_group" "default" {
6280
count = var.enabled ? 1 : 0
6381

64-
auth_token = var.auth_token
82+
auth_token = var.transit_encryption_enabled ? var.auth_token : null
6583
replication_group_id = var.replication_group_id == "" ? module.label.id : var.replication_group_id
6684
replication_group_description = module.label.id
6785
node_type = var.instance_type
6886
number_cache_clusters = var.cluster_size
6987
port = var.port
7088
parameter_group_name = join("", aws_elasticache_parameter_group.default.*.name)
7189
availability_zones = slice(var.availability_zones, 0, var.cluster_size)
72-
automatic_failover_enabled = var.automatic_failover
90+
automatic_failover_enabled = var.automatic_failover_enabled
7391
subnet_group_name = local.elasticache_subnet_group_name
74-
security_group_ids = [join("", aws_security_group.default.*.id)]
92+
security_group_ids = var.use_existing_security_groups ? var.existing_security_groups : [join("", aws_security_group.default.*.id)]
7593
maintenance_window = var.maintenance_window
7694
notification_topic_arn = var.notification_topic_arn
7795
engine_version = var.engine_version
@@ -81,6 +99,14 @@ resource "aws_elasticache_replication_group" "default" {
8199
snapshot_retention_limit = var.snapshot_retention_limit
82100

83101
tags = module.label.tags
102+
103+
dynamic "cluster_mode" {
104+
for_each = var.cluster_mode_enabled ? ["true"] : []
105+
content {
106+
replicas_per_node_group = var.cluster_mode_replicas_per_node_group
107+
num_node_groups = var.cluster_mode_num_node_groups
108+
}
109+
}
84110
}
85111

86112
#

outputs.tf

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,12 @@ output "port" {
1313
description = "Redis port"
1414
}
1515

16+
output "endpoint" {
17+
value = join("", aws_elasticache_replication_group.default.*.primary_endpoint_address)
18+
description = "Redis primary endpoint"
19+
}
20+
1621
output "host" {
17-
value = coalesce(
18-
module.dns.hostname,
19-
join(
20-
"",
21-
aws_elasticache_replication_group.default.*.primary_endpoint_address
22-
)
23-
)
24-
description = "Redis host"
22+
value = module.dns.hostname
23+
description = "Redis hostname"
2524
}

0 commit comments

Comments
 (0)