Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #137 bad output when cluster_mode_enabled=true #139

Merged
merged 2 commits into from
Oct 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ the registry shows many of our inputs as required when in fact they are optional
The table below correctly indicates which inputs are required.


_**Disruptive changes introduced at version 0.41.0**. If upgrading from an earlier version, see
[migration notes](https://github.com/cloudposse/terraform-aws-elasticache-redis/blob/master/docs/migration-notes-0.41.0.md) for details._

Note that this uses secure defaults. One of the ways this module can trip users up is with `transit_encryption_enabled`
which is `true` by default. With this enabled, one does not simply `redis-cli` in without setting up an `stunnel`.
Amazon provides [good documentation on how to connect with it enabled](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/in-transit-encryption.html#connect-tls).
Expand Down
6 changes: 6 additions & 0 deletions README.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,13 @@ description: |-
Terraform module to provision an [`ElastiCache`](https://aws.amazon.com/elasticache/) Redis Cluster

# How to use this project
# Note: use absolute rather than relative URLs because Hashicorp will copy the README to
# its Terraform Registry website but will not fix relative URLs in the process, leading
# to broken links in the official Terraform documentation.
usage: |-
_**Disruptive changes introduced at version 0.41.0**. If upgrading from an earlier version, see
[migration notes](https://github.com/cloudposse/terraform-aws-elasticache-redis/blob/master/docs/migration-notes-0.41.0.md) for details._

Note that this uses secure defaults. One of the ways this module can trip users up is with `transit_encryption_enabled`
which is `true` by default. With this enabled, one does not simply `redis-cli` in without setting up an `stunnel`.
Amazon provides [good documentation on how to connect with it enabled](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/in-transit-encryption.html#connect-tls).
Expand Down
50 changes: 50 additions & 0 deletions docs/migration-notes-0.41.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Migration Notes

Upgrading this module from a version before 0.41.0 to version
0.41.0 or later will cause the existing security group for
the Elasticache Redis cluster to be deleted and a new one
to be created, unless you had set ` use_existing_security_groups = true` (which prevents this module from creating and managing a security group for the cluster). There will be some consequences to this, but in most cases the consequences will be tolerable and the
benefits worth upgrading to the new version and leaving
the new `security_group_create_before_destroy` input at the default value of `true`.

##### Consequences

- Any references to the existing managed security group, such as in other security group rules, will become invalid and probably need to be updated with references to the new security group.
- There will be a brief outage (cluster inaccessible) during the period after the existing managed security group has its rules removed and before the cluster is associated with the new security group. This outage is typically under 10 seconds, but there are no guarantees. If you run `terraform apply` with `-parallelism=1` then the first `apply` will probably fail (trying to destroy the existing security group before removing the cluster from it), leaving the cluster inaccessible until you run `apply` again to restore access. This will not happen if you use the default `parallelism` setting of 10.

**If these consequences are acceptable**, then you do not need to take any special actions to upgrade to the newer version of this module.

**If you need the security group ID to remain stable** over time, for example because you want to reference the ID elsewhere, then you should not have this module managing the security group, and should have already set `use_existing_security_groups = true`. If you failed to do that before but now want that option:

- Update the reference to this module to point to the current version.
- Replace the existing `use_existing_security_groups` input, if any, with the new `create_security_group` input and set it to `false`.
- Run `terraform plan` and make note of the resource addresses of the `aws_security_group` and `aws_security_group_rule` resources that Terraform plans to destroy. Use `terraform state rm` to remove them from the Terraform state.
- Update the ` associated_security_group_ids` input to include the ID of the existing security group. Note that this ID will no longer be output as the `cluster_security_group_id`, so adjust anything that was relying on that output.
- (Optional) Use the [terraform-aws-security-group](https://github.com/cloudposse/terraform-aws-security-group) module to manage the existing security group, setting the `target_security_group_id` to the existing security group's ID. Manually (via `aws` CLI or AWS web console) delete the abandoned security group rules after `terraform-aws-security-group` creates the new ones.

**If you are OK with the security group ID changing but need absolutely zero downtime** you will benefit from the module's new "create before destroy" behavior for the managed security group, but want to do a targeted `terraform apply` to ensure zero downtime.

- Update the reference to this module to point to the current version.

- Run `terraform plan` and take note of the resource addresses of the `aws_security_group` and `aws_security_group_rule` resources that will be created.

- Run `terraform apply -target <address1> -target <address2>...` with those addresses. Your resource addresses will vary depending on your root module and rules, but it will be something like

```hcl
tf apply \
-target='module.x.module.aws_security_group.aws_security_group.cbd[0]' \
-target='module.x.module.aws_security_group.aws_security_group_rule.keyed["_allow_all_egress_"]' \
-target='module.x.module.aws_security_group.aws_security_group_rule.keyed["in#in#sg#0"]'
```

- Run `terraform plan`, verify that there are no resources to be added, and take note of the resource address of the `aws_elasticache_replication_group` resource that will be updated.

- Run `terraform apply -target <address>` with the address of the `aws_elasticache_replication_group`. Your resource address will vary depending on your root module, but it will be something like

```hcl
tf apply -target='module.x.aws_elasticache_replication_group.default[0]'

```

- Run `terraform apply` one last time to finish any other tasks.

20 changes: 20 additions & 0 deletions examples/complete/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ output "cluster_id" {
description = "Redis cluster ID"
}

output "cluster_arn" {
value = module.redis.arn
description = "Elasticache Replication Group ARN"
}

output "cluster_enabled" {
value = module.redis.cluster_enabled
description = "Indicates if cluster mode is enabled"
}

output "engine_version_actual" {
value = module.redis.engine_version_actual
description = "The running version of the cache engine"
}

output "cluster_security_group_id" {
value = module.redis.security_group_id
description = "Cluster Security Group ID"
Expand All @@ -28,6 +43,11 @@ output "cluster_endpoint" {
description = "Redis primary endpoint"
}

output "cluster_reader_endpoint_address" {
value = module.redis.reader_endpoint_address
description = "Redis non-cluster reader endpoint"
}

output "cluster_host" {
value = module.redis.host
description = "Redis hostname"
Expand Down
2 changes: 1 addition & 1 deletion outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ output "endpoint" {
}

output "reader_endpoint_address" {
value = join("", aws_elasticache_replication_group.default.*.reader_endpoint_address)
value = join("", compact(aws_elasticache_replication_group.default.*.reader_endpoint_address))
description = "The address of the endpoint for the reader node in the replication group, if the cluster mode is disabled."
}

Expand Down