From a580353a2ad35da4db3c12dabbc1750c16c47eb2 Mon Sep 17 00:00:00 2001
From: nitrocode <7775707+nitrocode@users.noreply.github.com>
Date: Tue, 14 Jun 2022 07:22:23 -0500
Subject: [PATCH 01/74] Add `log_delivery_configuration` (#168)
* Add log_delivery
Co-authored-by: cloudpossebot <11232728+cloudpossebot@users.noreply.github.com>
---
.github/renovate.json | 2 +-
README.md | 5 +++--
docs/terraform.md | 5 +++--
examples/complete/main.tf | 16 ++++++++++++++++
examples/complete/versions.tf | 8 ++------
main.tf | 12 +++++++++++-
variables.tf | 10 +++++++---
versions.tf | 2 +-
8 files changed, 44 insertions(+), 16 deletions(-)
diff --git a/.github/renovate.json b/.github/renovate.json
index ae4f0aa..a780298 100644
--- a/.github/renovate.json
+++ b/.github/renovate.json
@@ -4,9 +4,9 @@
":preserveSemverRanges"
],
"labels": ["auto-update"],
+ "dependencyDashboardAutoclose": true,
"enabledManagers": ["terraform"],
"terraform": {
"ignorePaths": ["**/context.tf", "examples/**"]
}
}
-
diff --git a/README.md b/README.md
index d5ee76b..5cc7c21 100644
--- a/README.md
+++ b/README.md
@@ -214,13 +214,13 @@ Available targets:
| Name | Version |
|------|---------|
| [terraform](#requirement\_terraform) | >= 0.14.0 |
-| [aws](#requirement\_aws) | >= 3.26 |
+| [aws](#requirement\_aws) | >= 4.18 |
## Providers
| Name | Version |
|------|---------|
-| [aws](#provider\_aws) | >= 3.26 |
+| [aws](#provider\_aws) | >= 4.18 |
## Modules
@@ -285,6 +285,7 @@ Available targets:
| [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no |
| [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,
set as tag values, and output by this module individually.
Does not affect values of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
Default value: `lower`. | `string` | `null` | no |
| [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.
Default is to include all labels.
Tags with empty values will not be included in the `tags` output.
Set to `[]` to suppress all generated tags.
**Notes:**
The value of the `name` tag, if included, will be the `id`, not the `name`.
Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be
changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` |
[
"default"
]
| no |
+| [log\_delivery\_configuration](#input\_log\_delivery\_configuration) | The log\_delivery\_configuration block allows the streaming of Redis SLOWLOG or Redis Engine Log to CloudWatch Logs or Kinesis Data Firehose. Max of 2 blocks. | `list(map(any))` | `[]` | no |
| [maintenance\_window](#input\_maintenance\_window) | Maintenance window | `string` | `"wed:03:00-wed:04:00"` | no |
| [multi\_az\_enabled](#input\_multi\_az\_enabled) | Multi AZ (Automatic Failover must also be enabled. If Cluster Mode is enabled, Multi AZ is on by default, and this setting is ignored) | `bool` | `false` | no |
| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
This is the only ID element not also included as a `tag`.
The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no |
diff --git a/docs/terraform.md b/docs/terraform.md
index a699613..4d468cd 100644
--- a/docs/terraform.md
+++ b/docs/terraform.md
@@ -4,13 +4,13 @@
| Name | Version |
|------|---------|
| [terraform](#requirement\_terraform) | >= 0.14.0 |
-| [aws](#requirement\_aws) | >= 3.26 |
+| [aws](#requirement\_aws) | >= 4.18 |
## Providers
| Name | Version |
|------|---------|
-| [aws](#provider\_aws) | >= 3.26 |
+| [aws](#provider\_aws) | >= 4.18 |
## Modules
@@ -75,6 +75,7 @@
| [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no |
| [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,
set as tag values, and output by this module individually.
Does not affect values of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.
Default value: `lower`. | `string` | `null` | no |
| [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.
Default is to include all labels.
Tags with empty values will not be included in the `tags` output.
Set to `[]` to suppress all generated tags.
**Notes:**
The value of the `name` tag, if included, will be the `id`, not the `name`.
Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be
changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` | [
"default"
]
| no |
+| [log\_delivery\_configuration](#input\_log\_delivery\_configuration) | The log\_delivery\_configuration block allows the streaming of Redis SLOWLOG or Redis Engine Log to CloudWatch Logs or Kinesis Data Firehose. Max of 2 blocks. | `list(map(any))` | `[]` | no |
| [maintenance\_window](#input\_maintenance\_window) | Maintenance window | `string` | `"wed:03:00-wed:04:00"` | no |
| [multi\_az\_enabled](#input\_multi\_az\_enabled) | Multi AZ (Automatic Failover must also be enabled. If Cluster Mode is enabled, Multi AZ is on by default, and this setting is ignored) | `bool` | `false` | no |
| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
This is the only ID element not also included as a `tag`.
The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no |
diff --git a/examples/complete/main.tf b/examples/complete/main.tf
index 3ce0336..5f62a7d 100644
--- a/examples/complete/main.tf
+++ b/examples/complete/main.tf
@@ -34,6 +34,13 @@ resource "aws_route53_zone" "private" {
}
}
+module "cloudwatch_logs" {
+ source = "cloudposse/cloudwatch-logs/aws"
+ version = "0.6.5"
+
+ context = module.this.context
+}
+
module "redis" {
source = "../../"
@@ -65,5 +72,14 @@ module "redis" {
security_group_delete_timeout = "5m"
+ log_delivery_configuration = [
+ {
+ destination = module.cloudwatch_logs.log_group_name
+ destination_type = "cloudwatch-logs"
+ log_format = "json"
+ log_type = "engine-log"
+ }
+ ]
+
context = module.this.context
}
diff --git a/examples/complete/versions.tf b/examples/complete/versions.tf
index 971ae24..6b5f390 100644
--- a/examples/complete/versions.tf
+++ b/examples/complete/versions.tf
@@ -1,14 +1,10 @@
terraform {
- required_version = ">= 0.13.0"
+ required_version = ">= 0.14.0"
required_providers {
aws = {
source = "hashicorp/aws"
- version = ">= 2.0"
- }
- null = {
- source = "hashicorp/null"
- version = ">= 2.0"
+ version = ">= 4.18"
}
}
}
diff --git a/main.tf b/main.tf
index 28ee895..6dd1b1f 100644
--- a/main.tf
+++ b/main.tf
@@ -102,7 +102,6 @@ resource "aws_elasticache_parameter_group" "default" {
}
}
-
tags = module.this.tags
# Ignore changes to the description since it will try to recreate the resource
@@ -144,6 +143,17 @@ resource "aws_elasticache_replication_group" "default" {
final_snapshot_identifier = var.final_snapshot_identifier
apply_immediately = var.apply_immediately
+ dynamic "log_delivery_configuration" {
+ for_each = var.log_delivery_configuration
+
+ content {
+ destination = lookup(log_delivery_configuration.value, "destination", null)
+ destination_type = lookup(log_delivery_configuration.value, "destination_type", null)
+ log_format = lookup(log_delivery_configuration.value, "log_format", null)
+ log_type = lookup(log_delivery_configuration.value, "log_type", null)
+ }
+ }
+
tags = module.this.tags
num_node_groups = var.cluster_mode_enabled ? var.cluster_mode_num_node_groups : null
diff --git a/variables.tf b/variables.tf
index f5ae0ed..54b957a 100644
--- a/variables.tf
+++ b/variables.tf
@@ -1,5 +1,3 @@
-
-
variable "vpc_id" {
type = string
description = "VPC ID"
@@ -225,4 +223,10 @@ variable "parameter_group_description" {
type = string
default = null
description = "Managed by Terraform"
-}
\ No newline at end of file
+}
+
+variable "log_delivery_configuration" {
+ type = list(map(any))
+ default = []
+ description = "The log_delivery_configuration block allows the streaming of Redis SLOWLOG or Redis Engine Log to CloudWatch Logs or Kinesis Data Firehose. Max of 2 blocks."
+}
diff --git a/versions.tf b/versions.tf
index 17eaf80..6b5f390 100644
--- a/versions.tf
+++ b/versions.tf
@@ -4,7 +4,7 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
- version = ">= 3.26"
+ version = ">= 4.18"
}
}
}
From b3ffb4168b76feb092e4670727000cbd3a7dbb02 Mon Sep 17 00:00:00 2001
From: pen-pal <61139563+pen-pal@users.noreply.github.com>
Date: Tue, 9 Aug 2022 06:42:55 +0545
Subject: [PATCH 02/74] description configurable (#170)
* make sure description of replication group is configurable.
* Auto Format
Co-authored-by: cloudpossebot <11232728+cloudpossebot@users.noreply.github.com>
Co-authored-by: Joe Niland
---
.github/auto-release.yml | 1 -
README.md | 1 +
docs/terraform.md | 1 +
main.tf | 2 +-
variables.tf | 6 ++++++
5 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/.github/auto-release.yml b/.github/auto-release.yml
index b45efb7..17cd39c 100644
--- a/.github/auto-release.yml
+++ b/.github/auto-release.yml
@@ -17,7 +17,6 @@ version-resolver:
- 'bugfix'
- 'bug'
- 'hotfix'
- - 'no-release'
default: 'minor'
categories:
diff --git a/README.md b/README.md
index 5cc7c21..68d0bc3 100644
--- a/README.md
+++ b/README.md
@@ -268,6 +268,7 @@ Available targets:
| [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` | {
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no |
| [create\_security\_group](#input\_create\_security\_group) | Set `true` to create and configure a new security group. If false, `associated_security_group_ids` must be provided. | `bool` | `true` | no |
| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
+| [description](#input\_description) | Description of elasticache replication group | `string` | `null` | no |
| [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no |
| [dns\_subdomain](#input\_dns\_subdomain) | The subdomain to use for the CNAME record. If not provided then the CNAME record will use var.name. | `string` | `""` | no |
| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | DEPRECATED: Use `allow_all_egress` and `additional_security_group_rules` instead.
Historical description: Outbound traffic address.
Historical default: ["0.0.0.0/0"] | `list(any)` | `null` | no |
diff --git a/docs/terraform.md b/docs/terraform.md
index 4d468cd..33f8394 100644
--- a/docs/terraform.md
+++ b/docs/terraform.md
@@ -58,6 +58,7 @@
| [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` | {
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no |
| [create\_security\_group](#input\_create\_security\_group) | Set `true` to create and configure a new security group. If false, `associated_security_group_ids` must be provided. | `bool` | `true` | no |
| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
+| [description](#input\_description) | Description of elasticache replication group | `string` | `null` | no |
| [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no |
| [dns\_subdomain](#input\_dns\_subdomain) | The subdomain to use for the CNAME record. If not provided then the CNAME record will use var.name. | `string` | `""` | no |
| [egress\_cidr\_blocks](#input\_egress\_cidr\_blocks) | DEPRECATED: Use `allow_all_egress` and `additional_security_group_rules` instead.
Historical description: Outbound traffic address.
Historical default: ["0.0.0.0/0"] | `list(any)` | `null` | no |
diff --git a/main.tf b/main.tf
index 6dd1b1f..206132c 100644
--- a/main.tf
+++ b/main.tf
@@ -117,7 +117,7 @@ resource "aws_elasticache_replication_group" "default" {
auth_token = var.transit_encryption_enabled ? var.auth_token : null
replication_group_id = var.replication_group_id == "" ? module.this.id : var.replication_group_id
- description = module.this.id
+ description = coalesce(var.description, module.this.id)
node_type = var.instance_type
num_cache_clusters = var.cluster_mode_enabled ? null : var.cluster_size
port = var.port
diff --git a/variables.tf b/variables.tf
index 54b957a..4e105d3 100644
--- a/variables.tf
+++ b/variables.tf
@@ -230,3 +230,9 @@ variable "log_delivery_configuration" {
default = []
description = "The log_delivery_configuration block allows the streaming of Redis SLOWLOG or Redis Engine Log to CloudWatch Logs or Kinesis Data Firehose. Max of 2 blocks."
}
+
+variable "description" {
+ type = string
+ default = null
+ description = "Description of elasticache replication group"
+}
From 928810290096581f871dcf0e4aabc7f84be06b6f Mon Sep 17 00:00:00 2001
From: nicholas-marchini <90906824+nicholas-marchini@users.noreply.github.com>
Date: Mon, 17 Oct 2022 16:38:29 +0100
Subject: [PATCH 03/74] Allow User groups ID to be passed to replication group
(#177)
Co-authored-by: cloudpossebot <11232728+cloudpossebot@users.noreply.github.com>
---
.github/workflows/validate-codeowners.yml | 1 +
README.md | 4 +++-
docs/terraform.md | 1 +
main.tf | 1 +
variables.tf | 6 ++++++
5 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/validate-codeowners.yml b/.github/workflows/validate-codeowners.yml
index 70f829e..4b4a226 100644
--- a/.github/workflows/validate-codeowners.yml
+++ b/.github/workflows/validate-codeowners.yml
@@ -10,6 +10,7 @@ jobs:
steps:
- name: "Checkout source code at current commit"
uses: actions/checkout@v2
+ # Leave pinned at 0.7.1 until https://github.com/mszostok/codeowners-validator/issues/173 is resolved
- uses: mszostok/codeowners-validator@v0.7.1
if: github.event.pull_request.head.repo.full_name == github.repository
name: "Full check of CODEOWNERS"
diff --git a/README.md b/README.md
index 68d0bc3..33b8f82 100644
--- a/README.md
+++ b/README.md
@@ -313,6 +313,7 @@ Available targets:
| [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no |
| [transit\_encryption\_enabled](#input\_transit\_encryption\_enabled) | Set `true` to enable encryption in transit. Forced `true` if `var.auth_token` is set.
If this is enabled, use the [following guide](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/in-transit-encryption.html#connect-tls) to access redis. | `bool` | `true` | no |
| [use\_existing\_security\_groups](#input\_use\_existing\_security\_groups) | DEPRECATED: Use `create_security_group` instead.
Historical description: 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.
Historical default: `false` | `bool` | `null` | no |
+| [user\_group\_ids](#input\_user\_group\_ids) | User Group ID to associate with the replication group | `list(string)` | `[]` | no |
| [vpc\_id](#input\_vpc\_id) | VPC ID | `string` | n/a | yes |
| [zone\_id](#input\_zone\_id) | Route53 DNS Zone ID as list of string (0 or 1 items). If empty, no custom DNS name will be published.
If the list contains a single Zone ID, a custom DNS name will be pulished in that zone.
Can also be a plain string, but that use is DEPRECATED because of Terraform issues. | `any` | `[]` | no |
@@ -500,7 +501,7 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply
[![README Footer][readme_footer_img]][readme_footer_link]
[![Beacon][beacon]][website]
-
+
[logo]: https://cloudposse.com/logo-300x69.svg
[docs]: https://cpco.io/docs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=docs
[website]: https://cpco.io/homepage?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=website
@@ -531,3 +532,4 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply
[share_googleplus]: https://plus.google.com/share?url=https://github.com/cloudposse/terraform-aws-elasticache-redis
[share_email]: mailto:?subject=terraform-aws-elasticache-redis&body=https://github.com/cloudposse/terraform-aws-elasticache-redis
[beacon]: https://ga-beacon.cloudposse.com/UA-76589703-4/cloudposse/terraform-aws-elasticache-redis?pixel&cs=github&cm=readme&an=terraform-aws-elasticache-redis
+
diff --git a/docs/terraform.md b/docs/terraform.md
index 33f8394..dea7fd8 100644
--- a/docs/terraform.md
+++ b/docs/terraform.md
@@ -103,6 +103,7 @@
| [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no |
| [transit\_encryption\_enabled](#input\_transit\_encryption\_enabled) | Set `true` to enable encryption in transit. Forced `true` if `var.auth_token` is set.
If this is enabled, use the [following guide](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/in-transit-encryption.html#connect-tls) to access redis. | `bool` | `true` | no |
| [use\_existing\_security\_groups](#input\_use\_existing\_security\_groups) | DEPRECATED: Use `create_security_group` instead.
Historical description: 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.
Historical default: `false` | `bool` | `null` | no |
+| [user\_group\_ids](#input\_user\_group\_ids) | User Group ID to associate with the replication group | `list(string)` | `[]` | no |
| [vpc\_id](#input\_vpc\_id) | VPC ID | `string` | n/a | yes |
| [zone\_id](#input\_zone\_id) | Route53 DNS Zone ID as list of string (0 or 1 items). If empty, no custom DNS name will be published.
If the list contains a single Zone ID, a custom DNS name will be pulished in that zone.
Can also be a plain string, but that use is DEPRECATED because of Terraform issues. | `any` | `[]` | no |
diff --git a/main.tf b/main.tf
index 206132c..bff55db 100644
--- a/main.tf
+++ b/main.tf
@@ -158,6 +158,7 @@ resource "aws_elasticache_replication_group" "default" {
num_node_groups = var.cluster_mode_enabled ? var.cluster_mode_num_node_groups : null
replicas_per_node_group = var.cluster_mode_enabled ? var.cluster_mode_replicas_per_node_group : null
+ user_group_ids = var.user_group_ids
}
#
diff --git a/variables.tf b/variables.tf
index 4e105d3..73205a9 100644
--- a/variables.tf
+++ b/variables.tf
@@ -236,3 +236,9 @@ variable "description" {
default = null
description = "Description of elasticache replication group"
}
+
+variable "user_group_ids" {
+ type = list(string)
+ default = []
+ description = "User Group ID to associate with the replication group"
+}
From 7ad8f0dddfa2eb91b38b3cda593ba01dc6df9c74 Mon Sep 17 00:00:00 2001
From: Liene Jansone
Date: Wed, 9 Nov 2022 05:58:05 +0200
Subject: [PATCH 04/74] Add `auto_minor_version_upgrade` parameter (#183)
* add auto_minor_version_upgrade parameter
* Auto Format
* Update variables.tf
* Auto Format
Co-authored-by: cloudpossebot <11232728+cloudpossebot@users.noreply.github.com>
Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>
---
README.md | 1 +
docs/terraform.md | 1 +
main.tf | 1 +
variables.tf | 6 ++++++
4 files changed, 9 insertions(+)
diff --git a/README.md b/README.md
index 33b8f82..fe91f13 100644
--- a/README.md
+++ b/README.md
@@ -258,6 +258,7 @@ Available targets:
| [at\_rest\_encryption\_enabled](#input\_at\_rest\_encryption\_enabled) | Enable encryption at rest | `bool` | `false` | no |
| [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
in the order they appear in the list. New attributes are appended to the
end of the list. The elements of the list are joined by the `delimiter`
and treated as a single ID element. | `list(string)` | `[]` | no |
| [auth\_token](#input\_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 |
+| [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. Only supported if the engine version is 6 or higher. | `bool` | `null` | no |
| [automatic\_failover\_enabled](#input\_automatic\_failover\_enabled) | Automatic failover (Not available for T1/T2 instances) | `bool` | `false` | no |
| [availability\_zones](#input\_availability\_zones) | Availability zone IDs | `list(string)` | `[]` | no |
| [cloudwatch\_metric\_alarms\_enabled](#input\_cloudwatch\_metric\_alarms\_enabled) | Boolean flag to enable/disable CloudWatch metrics alarms | `bool` | `false` | no |
diff --git a/docs/terraform.md b/docs/terraform.md
index dea7fd8..8f489ca 100644
--- a/docs/terraform.md
+++ b/docs/terraform.md
@@ -48,6 +48,7 @@
| [at\_rest\_encryption\_enabled](#input\_at\_rest\_encryption\_enabled) | Enable encryption at rest | `bool` | `false` | no |
| [attributes](#input\_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
in the order they appear in the list. New attributes are appended to the
end of the list. The elements of the list are joined by the `delimiter`
and treated as a single ID element. | `list(string)` | `[]` | no |
| [auth\_token](#input\_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 |
+| [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. Only supported if the engine version is 6 or higher. | `bool` | `null` | no |
| [automatic\_failover\_enabled](#input\_automatic\_failover\_enabled) | Automatic failover (Not available for T1/T2 instances) | `bool` | `false` | no |
| [availability\_zones](#input\_availability\_zones) | Availability zone IDs | `list(string)` | `[]` | no |
| [cloudwatch\_metric\_alarms\_enabled](#input\_cloudwatch\_metric\_alarms\_enabled) | Boolean flag to enable/disable CloudWatch metrics alarms | `bool` | `false` | no |
diff --git a/main.tf b/main.tf
index bff55db..fe8dd88 100644
--- a/main.tf
+++ b/main.tf
@@ -142,6 +142,7 @@ resource "aws_elasticache_replication_group" "default" {
snapshot_retention_limit = var.snapshot_retention_limit
final_snapshot_identifier = var.final_snapshot_identifier
apply_immediately = var.apply_immediately
+ auto_minor_version_upgrade = var.auto_minor_version_upgrade
dynamic "log_delivery_configuration" {
for_each = var.log_delivery_configuration
diff --git a/variables.tf b/variables.tf
index 73205a9..4d7480c 100644
--- a/variables.tf
+++ b/variables.tf
@@ -242,3 +242,9 @@ variable "user_group_ids" {
default = []
description = "User Group ID to associate with the replication group"
}
+
+variable "auto_minor_version_upgrade" {
+ type = bool
+ default = null
+ description = "Specifies whether minor version engine upgrades will be applied automatically to the underlying Cache Cluster instances during the maintenance window. Only supported if the engine version is 6 or higher."
+}
From c8abd68950cd24d375749fca5da9488c61b41610 Mon Sep 17 00:00:00 2001
From: Brendan Luchen
Date: Sat, 19 Nov 2022 12:47:54 -0500
Subject: [PATCH 05/74] feat: Add `data_tiering_enabled` (#175)
* Plumb through data_tiering_enabled (#2)
## what
* Introduce var.data_tiering_enabled and plumb it through to the aws provider
## why
* We need to set `data_tiering_enabled` true to provision our desired node type [](https://teikametrics.atlassian.net/browse/DEVOPS-2155)
* This flag `data_tiering_enabled` doesn't currently exist in the `terraform-aws-elasticache-redis` module
* After verifying this change, we plan to send it back upstream in a PR to https://github.com/cloudposse/terraform-aws-elasticache-redis
## testing
Against @teikametrics/bid-orchestrator#202, made locally the following changes:
```diff
diff --git a/terraform-redis-bidder-common/redis.tf b/terraform-redis-bidder-common/redis.tf
index fc582ae..1bdb9df 100644
--- a/terraform-redis-bidder-common/redis.tf
+++ b/terraform-redis-bidder-common/redis.tf
@@ -48,7 +48,7 @@ resource "random_password" "password" {
module "redis" {
# https://registry.terraform.io/modules/cloudposse/elasticache-redis/aws/latest
# source = "cloudposse/elasticache-redis/aws" ## FIXME: DEVOPS-2155
- source = "git@github.com:teikametrics/terraform-aws-elasticache-redis.git"
+ source = "git@github.com:teikametrics/terraform-aws-elasticache-redis.git?ref=bml.DEVOPS-2155.cloudposse-fork-data-tiering"
# Auth token for password protecting redis, `transit_encryption_enabled` must be set to `true`.
auth_token = random_password.password.result
name = var.redis_name
@@ -63,7 +63,7 @@ module "redis" {
automatic_failover_enabled = var.redis_automatic_failover
cluster_size = var.redis_cluster_size
# Must be set to true to enable data tiering
- # data_tiering_enabled = var.redis_data_tiering ## FIXME: DEVOPS-2155
+ data_tiering_enabled = var.redis_data_tiering
# The instance class used --> https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/CacheNodes.SupportedTypes.html
instance_type = var.redis_instance_type
# Apply changes immediately
```
Staging plan reports no changes (because `redis_data_tiering` is false in staging); production plan reports the same currently-unapplied changes as before, plus including `data_tiering_enabled`. Previously the plan errored out as this module did not support the flag.
## terraform plans
### Staging
`tm-terraform staging staging plan`
```
No changes. Infrastructure is up-to-date.
```
### Production
`tm-terraform production production plan`
```
Terraform will perform the following actions:
# module.redis.aws_elasticache_parameter_group.default[0] will be updated in-place
~ resource "aws_elasticache_parameter_group" "default" {
id = "bidder-redis-cluster-production"
name = "bidder-redis-cluster-production"
~ tags = {
+ "Name" = "bidder-redis-cluster-production"
+ "teikametrics.com/app" = "bid-orchestrator"
+ "teikametrics.com/deploy/stage" = "production"
+ "teikametrics.com/name" = "bidder-redis-cluster-production"
+ "teikametrics.com/team" = "artificial-intelligence"
+ "teikametrics.com/terraform/gitpath" = "teikametrics/bid-orchestrator/terraform-redis"
}
~ tags_all = {
+ "Name" = "bidder-redis-cluster-production"
+ "teikametrics.com/app" = "bid-orchestrator"
+ "teikametrics.com/deploy/stage" = "production"
+ "teikametrics.com/name" = "bidder-redis-cluster-production"
+ "teikametrics.com/team" = "artificial-intelligence"
+ "teikametrics.com/terraform/gitpath" = "teikametrics/bid-orchestrator/terraform-redis"
}
# (3 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# module.redis.aws_elasticache_replication_group.default[0] will be created
+ resource "aws_elasticache_replication_group" "default" {
+ apply_immediately = true
+ arn = (known after apply)
+ at_rest_encryption_enabled = false
+ auth_token = (sensitive value)
+ auto_minor_version_upgrade = (known after apply)
+ automatic_failover_enabled = true
+ cluster_enabled = (known after apply)
+ configuration_endpoint_address = (known after apply)
+ data_tiering_enabled = true
+ description = "bidder-redis-cluster-production"
+ engine = "redis"
+ engine_version = "6.x"
+ engine_version_actual = (known after apply)
+ global_replication_group_id = (known after apply)
+ id = (known after apply)
+ maintenance_window = "sun:03:00-sun:04:00"
+ member_clusters = (known after apply)
+ multi_az_enabled = false
+ node_type = "cache.r6gd.xlarge"
+ num_cache_clusters = (known after apply)
+ num_node_groups = 2
+ number_cache_clusters = (known after apply)
+ parameter_group_name = "bidder-redis-cluster-production"
+ port = 6379
+ primary_endpoint_address = (known after apply)
+ reader_endpoint_address = (known after apply)
+ replicas_per_node_group = 1
+ replication_group_description = (known after apply)
+ replication_group_id = "bidder-redis-cluster-production"
+ security_group_ids = (known after apply)
+ security_group_names = (known after apply)
+ snapshot_retention_limit = 7
+ snapshot_window = "04:00-05:00"
+ subnet_group_name = "bidder-redis-cluster-production"
+ tags = {
+ "Name" = "bidder-redis-cluster-production"
+ "teikametrics.com/app" = "bid-orchestrator"
+ "teikametrics.com/deploy/stage" = "production"
+ "teikametrics.com/name" = "bidder-redis-cluster-production"
+ "teikametrics.com/team" = "artificial-intelligence"
+ "teikametrics.com/terraform/gitpath" = "teikametrics/bid-orchestrator/terraform-redis"
}
+ tags_all = {
+ "Name" = "bidder-redis-cluster-production"
+ "teikametrics.com/app" = "bid-orchestrator"
+ "teikametrics.com/deploy/stage" = "production"
+ "teikametrics.com/name" = "bidder-redis-cluster-production"
+ "teikametrics.com/team" = "artificial-intelligence"
+ "teikametrics.com/terraform/gitpath" = "teikametrics/bid-orchestrator/terraform-redis"
}
+ transit_encryption_enabled = true
+ cluster_mode {
+ num_node_groups = (known after apply)
+ replicas_per_node_group = (known after apply)
}
}
# module.redis.aws_elasticache_subnet_group.default[0] will be updated in-place
~ resource "aws_elasticache_subnet_group" "default" {
~ description = "Managed by Terraform" -> "Elasticache subnet group for bidder-redis-cluster-production"
id = "bidder-redis-cluster-production"
name = "bidder-redis-cluster-production"
~ tags = {
+ "Name" = "bidder-redis-cluster-production"
+ "teikametrics.com/app" = "bid-orchestrator"
+ "teikametrics.com/deploy/stage" = "production"
+ "teikametrics.com/name" = "bidder-redis-cluster-production"
+ "teikametrics.com/team" = "artificial-intelligence"
+ "teikametrics.com/terraform/gitpath" = "teikametrics/bid-orchestrator/terraform-redis"
}
~ tags_all = {
+ "Name" = "bidder-redis-cluster-production"
+ "teikametrics.com/app" = "bid-orchestrator"
+ "teikametrics.com/deploy/stage" = "production"
+ "teikametrics.com/name" = "bidder-redis-cluster-production"
+ "teikametrics.com/team" = "artificial-intelligence"
+ "teikametrics.com/terraform/gitpath" = "teikametrics/bid-orchestrator/terraform-redis"
}
# (2 unchanged attributes hidden)
}
# module.redis.module.aws_security_group.aws_security_group.cbd[0] will be created
+ resource "aws_security_group" "cbd" {
+ arn = (known after apply)
+ description = "Security group for Elasticache Redis"
+ egress = (known after apply)
+ id = (known after apply)
+ ingress = (known after apply)
+ name = (known after apply)
+ name_prefix = "bidder-redis-cluster-production-"
+ owner_id = (known after apply)
+ revoke_rules_on_delete = false
+ tags = {
+ "Name" = "bidder-redis-cluster-production"
+ "teikametrics.com/app" = "bid-orchestrator"
+ "teikametrics.com/deploy/stage" = "production"
+ "teikametrics.com/name" = "bidder-redis-cluster-production"
+ "teikametrics.com/team" = "artificial-intelligence"
+ "teikametrics.com/terraform/gitpath" = "teikametrics/bid-orchestrator/terraform-redis"
}
+ tags_all = {
+ "Name" = "bidder-redis-cluster-production"
+ "teikametrics.com/app" = "bid-orchestrator"
+ "teikametrics.com/deploy/stage" = "production"
+ "teikametrics.com/name" = "bidder-redis-cluster-production"
+ "teikametrics.com/team" = "artificial-intelligence"
+ "teikametrics.com/terraform/gitpath" = "teikametrics/bid-orchestrator/terraform-redis"
}
+ vpc_id = "vpc-0134131a45fbf70e6"
+ timeouts {
+ create = "10m"
+ delete = "15m"
}
}
# module.redis.module.aws_security_group.aws_security_group_rule.keyed["_allow_all_egress_"] will be created
+ resource "aws_security_group_rule" "keyed" {
+ cidr_blocks = [
+ "0.0.0.0/0",
]
+ description = "Allow all egress"
+ from_port = 0
+ id = (known after apply)
+ ipv6_cidr_blocks = [
+ "::/0",
]
+ prefix_list_ids = []
+ protocol = "-1"
+ security_group_id = (known after apply)
+ self = false
+ source_security_group_id = (known after apply)
+ to_port = 0
+ type = "egress"
}
# module.redis.module.aws_security_group.aws_security_group_rule.keyed["extra[0]"] will be created
+ resource "aws_security_group_rule" "keyed" {
+ cidr_blocks = [
+ "10.76.0.0/16",
+ "10.60.0.0/16",
+ "10.78.0.0/16",
+ "10.30.0.0/16",
]
+ description = "Allow TCP inbound traffic on port 6379 from Convox and the vpc which is hosting this redis."
+ from_port = 6379
+ id = (known after apply)
+ prefix_list_ids = []
+ protocol = "tcp"
+ security_group_id = (known after apply)
+ self = false
+ source_security_group_id = (known after apply)
+ to_port = 6379
+ type = "ingress"
}
# module.redis.module.security_group.aws_security_group.default[0] will be destroyed
- resource "aws_security_group" "default" {
- arn = "arn:aws:ec2:us-east-1:659641375152:security-group/sg-02edcb2360f6895b0" -> null
- description = "ElastiCache Security Group" -> null
- egress = [
- {
- cidr_blocks = [
- "0.0.0.0/0",
]
- description = "Allow all outbound traffic"
- from_port = 0
- ipv6_cidr_blocks = []
- prefix_list_ids = []
- protocol = "-1"
- security_groups = []
- self = false
- to_port = 0
},
] -> null
- id = "sg-02edcb2360f6895b0" -> null
- ingress = [
- {
- cidr_blocks = [
- "10.76.0.0/16",
- "10.60.0.0/16",
- "10.78.0.0/16",
- "10.30.0.0/16",
]
- description = "Allow TCP inbound traffic on port 6379 from Convox and the vpc which is hosting this redis."
- from_port = 6379
- ipv6_cidr_blocks = []
- prefix_list_ids = []
- protocol = "tcp"
- security_groups = []
- self = false
- to_port = 6379
},
] -> null
- name = "bidder-redis-cluster-production" -> null
- owner_id = "659641375152" -> null
- revoke_rules_on_delete = false -> null
- tags = {
- "Name" = "bidder-redis-cluster-production"
- "teikametrics.com/app" = "bid-orchestrator"
- "teikametrics.com/deploy/stage" = "production"
- "teikametrics.com/name" = "bidder-redis-cluster-production"
- "teikametrics.com/team" = "artificial-intelligence"
- "teikametrics.com/terraform/gitpath" = "teikametrics/bid-orchestrator/terraform-redis"
} -> null
- tags_all = {
- "Name" = "bidder-redis-cluster-production"
- "teikametrics.com/app" = "bid-orchestrator"
- "teikametrics.com/deploy/stage" = "production"
- "teikametrics.com/name" = "bidder-redis-cluster-production"
- "teikametrics.com/team" = "artificial-intelligence"
- "teikametrics.com/terraform/gitpath" = "teikametrics/bid-orchestrator/terraform-redis"
} -> null
- vpc_id = "vpc-0134131a45fbf70e6" -> null
}
# module.redis.module.security_group.aws_security_group_rule.default["egress--1-0-0-9c87e5e1ed040a443ce1ac8e6d6cf159"] will be destroyed
- resource "aws_security_group_rule" "default" {
- cidr_blocks = [
- "0.0.0.0/0",
] -> null
- description = "Allow all outbound traffic" -> null
- from_port = 0 -> null
- id = "sgrule-3785251229" -> null
- protocol = "-1" -> null
- security_group_id = "sg-02edcb2360f6895b0" -> null
- self = false -> null
- to_port = 0 -> null
- type = "egress" -> null
}
# module.redis.module.security_group.aws_security_group_rule.default["ingress-tcp-6379-6379-c992040fb21cf75967d80aa440691f00"] will be destroyed
- resource "aws_security_group_rule" "default" {
- cidr_blocks = [
- "10.76.0.0/16",
- "10.60.0.0/16",
- "10.78.0.0/16",
- "10.30.0.0/16",
] -> null
- description = "Allow TCP inbound traffic on port 6379 from Convox and the vpc which is hosting this redis." -> null
- from_port = 6379 -> null
- id = "sgrule-236626820" -> null
- protocol = "tcp" -> null
- security_group_id = "sg-02edcb2360f6895b0" -> null
- self = false -> null
- to_port = 6379 -> null
- type = "ingress" -> null
}
Plan: 4 to add, 2 to change, 3 to destroy.
Changes to Outputs:
+ redis_master_endpoint = (known after apply)
```
## references
* https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/elasticache_replication_group#data_tiering_enabled
* make pr/auto-format
* Update variables.tf per @nitrocode
Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>
* make pr/auto-format
Co-authored-by: Brendan Luchen
Co-authored-by: nitrocode <7775707+nitrocode@users.noreply.github.com>
---
README.md | 1 +
docs/terraform.md | 1 +
main.tf | 1 +
variables.tf | 6 ++++++
4 files changed, 9 insertions(+)
diff --git a/README.md b/README.md
index fe91f13..79c5ed9 100644
--- a/README.md
+++ b/README.md
@@ -268,6 +268,7 @@ Available targets:
| [cluster\_size](#input\_cluster\_size) | Number of nodes in cluster. *Ignored when `cluster_mode_enabled` == `true`* | `number` | `1` | no |
| [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` | {
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no |
| [create\_security\_group](#input\_create\_security\_group) | Set `true` to create and configure a new security group. If false, `associated_security_group_ids` must be provided. | `bool` | `true` | no |
+| [data\_tiering\_enabled](#input\_data\_tiering\_enabled) | Enables data tiering. Data tiering is only supported for replication groups using the r6gd node type. | `bool` | `false` | no |
| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
| [description](#input\_description) | Description of elasticache replication group | `string` | `null` | no |
| [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no |
diff --git a/docs/terraform.md b/docs/terraform.md
index 8f489ca..b34f8dd 100644
--- a/docs/terraform.md
+++ b/docs/terraform.md
@@ -58,6 +58,7 @@
| [cluster\_size](#input\_cluster\_size) | Number of nodes in cluster. *Ignored when `cluster_mode_enabled` == `true`* | `number` | `1` | no |
| [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` | {
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no |
| [create\_security\_group](#input\_create\_security\_group) | Set `true` to create and configure a new security group. If false, `associated_security_group_ids` must be provided. | `bool` | `true` | no |
+| [data\_tiering\_enabled](#input\_data\_tiering\_enabled) | Enables data tiering. Data tiering is only supported for replication groups using the r6gd node type. | `bool` | `false` | no |
| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
| [description](#input\_description) | Description of elasticache replication group | `string` | `null` | no |
| [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.
Map of maps. Keys are names of descriptors. Values are maps of the form
`{
format = string
labels = list(string)
}`
(Type is `any` so the map values can later be enhanced to provide additional options.)
`format` is a Terraform format string to be passed to the `format()` function.
`labels` is a list of labels, in order, to pass to `format()` function.
Label values will be normalized before being passed to `format()` so they will be
identical to how they appear in `id`.
Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no |
diff --git a/main.tf b/main.tf
index fe8dd88..eddfdcc 100644
--- a/main.tf
+++ b/main.tf
@@ -142,6 +142,7 @@ resource "aws_elasticache_replication_group" "default" {
snapshot_retention_limit = var.snapshot_retention_limit
final_snapshot_identifier = var.final_snapshot_identifier
apply_immediately = var.apply_immediately
+ data_tiering_enabled = var.data_tiering_enabled
auto_minor_version_upgrade = var.auto_minor_version_upgrade
dynamic "log_delivery_configuration" {
diff --git a/variables.tf b/variables.tf
index 4d7480c..40b0c9c 100644
--- a/variables.tf
+++ b/variables.tf
@@ -112,6 +112,12 @@ variable "apply_immediately" {
description = "Apply changes immediately"
}
+variable "data_tiering_enabled" {
+ type = bool
+ default = false
+ description = "Enables data tiering. Data tiering is only supported for replication groups using the r6gd node type."
+}
+
variable "automatic_failover_enabled" {
type = bool
default = false
From 4d67f1ad9499394a82e7a0e1a8f76af7c8520115 Mon Sep 17 00:00:00 2001
From: Maksym Vlasov
Date: Tue, 20 Dec 2022 15:39:21 +0200
Subject: [PATCH 06/74] =?UTF-8?q?Fix=20breaking=20change=20introduced=20in?=
=?UTF-8?q?=200.46.0=20-=20`user=5Fgroup=5Fids`=20conflicts=E2=80=A6=20(#1?=
=?UTF-8?q?84)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Fix breaking chanke introduced in 0.46.0 - `user_group_ids` conflicts with `auth_token`
If you specify only `auth_token` - Terraform plan will fail because it interprets `user_group_ids = []` as specified value
* Auto Format
Co-authored-by: cloudpossebot <11232728+cloudpossebot@users.noreply.github.com>
---
README.md | 2 +-
docs/terraform.md | 2 +-
variables.tf | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 79c5ed9..22a8e37 100644
--- a/README.md
+++ b/README.md
@@ -315,7 +315,7 @@ Available targets:
| [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no |
| [transit\_encryption\_enabled](#input\_transit\_encryption\_enabled) | Set `true` to enable encryption in transit. Forced `true` if `var.auth_token` is set.
If this is enabled, use the [following guide](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/in-transit-encryption.html#connect-tls) to access redis. | `bool` | `true` | no |
| [use\_existing\_security\_groups](#input\_use\_existing\_security\_groups) | DEPRECATED: Use `create_security_group` instead.
Historical description: 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.
Historical default: `false` | `bool` | `null` | no |
-| [user\_group\_ids](#input\_user\_group\_ids) | User Group ID to associate with the replication group | `list(string)` | `[]` | no |
+| [user\_group\_ids](#input\_user\_group\_ids) | User Group ID to associate with the replication group | `list(string)` | `null` | no |
| [vpc\_id](#input\_vpc\_id) | VPC ID | `string` | n/a | yes |
| [zone\_id](#input\_zone\_id) | Route53 DNS Zone ID as list of string (0 or 1 items). If empty, no custom DNS name will be published.
If the list contains a single Zone ID, a custom DNS name will be pulished in that zone.
Can also be a plain string, but that use is DEPRECATED because of Terraform issues. | `any` | `[]` | no |
diff --git a/docs/terraform.md b/docs/terraform.md
index b34f8dd..cfca439 100644
--- a/docs/terraform.md
+++ b/docs/terraform.md
@@ -105,7 +105,7 @@
| [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no |
| [transit\_encryption\_enabled](#input\_transit\_encryption\_enabled) | Set `true` to enable encryption in transit. Forced `true` if `var.auth_token` is set.
If this is enabled, use the [following guide](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/in-transit-encryption.html#connect-tls) to access redis. | `bool` | `true` | no |
| [use\_existing\_security\_groups](#input\_use\_existing\_security\_groups) | DEPRECATED: Use `create_security_group` instead.
Historical description: 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.
Historical default: `false` | `bool` | `null` | no |
-| [user\_group\_ids](#input\_user\_group\_ids) | User Group ID to associate with the replication group | `list(string)` | `[]` | no |
+| [user\_group\_ids](#input\_user\_group\_ids) | User Group ID to associate with the replication group | `list(string)` | `null` | no |
| [vpc\_id](#input\_vpc\_id) | VPC ID | `string` | n/a | yes |
| [zone\_id](#input\_zone\_id) | Route53 DNS Zone ID as list of string (0 or 1 items). If empty, no custom DNS name will be published.
If the list contains a single Zone ID, a custom DNS name will be pulished in that zone.
Can also be a plain string, but that use is DEPRECATED because of Terraform issues. | `any` | `[]` | no |
diff --git a/variables.tf b/variables.tf
index 40b0c9c..a3731c3 100644
--- a/variables.tf
+++ b/variables.tf
@@ -245,7 +245,7 @@ variable "description" {
variable "user_group_ids" {
type = list(string)
- default = []
+ default = null
description = "User Group ID to associate with the replication group"
}
From e18c196855de07f353223628c62ec1a49f645516 Mon Sep 17 00:00:00 2001
From: Max Lobur
Date: Tue, 28 Mar 2023 13:12:05 +0300
Subject: [PATCH 07/74] Groundwork new workflows (#193)
* Baseline fixes
* Groundwork new workflows
* fix regex
---
README.md | 2 +-
examples/complete/variables.tf | 5 -----
main.tf | 8 ++++----
outputs.tf | 14 +++++++-------
4 files changed, 12 insertions(+), 17 deletions(-)
diff --git a/README.md b/README.md
index 22a8e37..5abd290 100644
--- a/README.md
+++ b/README.md
@@ -424,7 +424,7 @@ In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow.
## Copyright
-Copyright © 2017-2022 [Cloud Posse, LLC](https://cpco.io/copyright)
+Copyright © 2017-2023 [Cloud Posse, LLC](https://cpco.io/copyright)
diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf
index 26874e7..d5e2aa5 100644
--- a/examples/complete/variables.tf
+++ b/examples/complete/variables.tf
@@ -38,11 +38,6 @@ variable "transit_encryption_enabled" {
description = "Enable TLS"
}
-variable "zone_id" {
- type = string
- description = "Route53 DNS Zone ID"
-}
-
variable "cloudwatch_metric_alarms_enabled" {
type = bool
description = "Boolean flag to enable/disable CloudWatch metrics alarms"
diff --git a/main.tf b/main.tf
index eddfdcc..33010e3 100644
--- a/main.tf
+++ b/main.tf
@@ -66,7 +66,7 @@ module "aws_security_group" {
}
locals {
- elasticache_subnet_group_name = var.elasticache_subnet_group_name != "" ? var.elasticache_subnet_group_name : join("", aws_elasticache_subnet_group.default.*.name)
+ elasticache_subnet_group_name = var.elasticache_subnet_group_name != "" ? var.elasticache_subnet_group_name : join("", aws_elasticache_subnet_group.default[*].name)
# if !cluster, then node_count = replica cluster_size, if cluster then node_count = shard*(replica + 1)
# Why doing this 'The "count" value depends on resource attributes that cannot be determined until apply'. So pre-calculating
@@ -77,7 +77,7 @@ locals {
var.cluster_size
)
- elasticache_member_clusters = module.this.enabled ? tolist(aws_elasticache_replication_group.default.0.member_clusters) : []
+ elasticache_member_clusters = module.this.enabled ? tolist(aws_elasticache_replication_group.default[0].member_clusters) : []
}
resource "aws_elasticache_subnet_group" "default" {
@@ -121,7 +121,7 @@ resource "aws_elasticache_replication_group" "default" {
node_type = var.instance_type
num_cache_clusters = var.cluster_mode_enabled ? null : var.cluster_size
port = var.port
- parameter_group_name = join("", aws_elasticache_parameter_group.default.*.name)
+ parameter_group_name = join("", aws_elasticache_parameter_group.default[*].name)
availability_zones = length(var.availability_zones) == 0 ? null : [for n in range(0, var.cluster_size) : element(var.availability_zones, n)]
automatic_failover_enabled = var.cluster_mode_enabled ? true : var.automatic_failover_enabled
multi_az_enabled = var.multi_az_enabled
@@ -222,7 +222,7 @@ module "dns" {
dns_name = var.dns_subdomain != "" ? var.dns_subdomain : module.this.id
ttl = 60
zone_id = try(var.zone_id[0], tostring(var.zone_id), "")
- records = var.cluster_mode_enabled ? [join("", aws_elasticache_replication_group.default.*.configuration_endpoint_address)] : [join("", aws_elasticache_replication_group.default.*.primary_endpoint_address)]
+ records = var.cluster_mode_enabled ? [join("", aws_elasticache_replication_group.default[*].configuration_endpoint_address)] : [join("", aws_elasticache_replication_group.default[*].primary_endpoint_address)]
context = module.this.context
}
diff --git a/outputs.tf b/outputs.tf
index 016308a..3830fb9 100644
--- a/outputs.tf
+++ b/outputs.tf
@@ -1,5 +1,5 @@
output "id" {
- value = join("", aws_elasticache_replication_group.default.*.id)
+ value = join("", aws_elasticache_replication_group.default[*].id)
description = "Redis cluster ID"
}
@@ -19,17 +19,17 @@ output "port" {
}
output "endpoint" {
- value = var.cluster_mode_enabled ? join("", aws_elasticache_replication_group.default.*.configuration_endpoint_address) : join("", aws_elasticache_replication_group.default.*.primary_endpoint_address)
+ value = var.cluster_mode_enabled ? join("", aws_elasticache_replication_group.default[*].configuration_endpoint_address) : join("", aws_elasticache_replication_group.default[*].primary_endpoint_address)
description = "Redis primary or configuration endpoint, whichever is appropriate for the given cluster mode"
}
output "reader_endpoint_address" {
- value = join("", compact(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."
}
output "member_clusters" {
- value = aws_elasticache_replication_group.default.*.member_clusters
+ value = aws_elasticache_replication_group.default[*].member_clusters
description = "Redis cluster members"
}
@@ -39,16 +39,16 @@ output "host" {
}
output "arn" {
- value = join("", aws_elasticache_replication_group.default.*.arn)
+ value = join("", aws_elasticache_replication_group.default[*].arn)
description = "Elasticache Replication Group ARN"
}
output "engine_version_actual" {
- value = join("", aws_elasticache_replication_group.default.*.engine_version_actual)
+ value = join("", aws_elasticache_replication_group.default[*].engine_version_actual)
description = "The running version of the cache engine"
}
output "cluster_enabled" {
- value = join("", aws_elasticache_replication_group.default.*.cluster_enabled)
+ value = join("", aws_elasticache_replication_group.default[*].cluster_enabled)
description = "Indicates if cluster mode is enabled"
}
From 4b10d458443ab5d7ae246c3556a287e32e0113d1 Mon Sep 17 00:00:00 2001
From: Max Lobur
Date: Wed, 17 May 2023 15:30:38 +0300
Subject: [PATCH 08/74] Sync github (#196)
---
.github/ISSUE_TEMPLATE/bug_report.yml | 72 ++++++++++++++++
.github/ISSUE_TEMPLATE/feature_request.yml | 71 ++++++++++++++++
.github/PULL_REQUEST_TEMPLATE.md | 22 +++--
.github/auto-release.yml | 1 +
.github/mergify.yml | 17 +++-
.github/renovate.json | 1 +
.github/workflows/auto-context.yml | 57 -------------
.github/workflows/auto-format.yml | 88 --------------------
.github/workflows/auto-readme.yml | 71 ----------------
.github/workflows/auto-release.yml | 26 ------
.github/workflows/chatops.yml | 37 --------
.github/workflows/feature-branch-chatops.yml | 16 ++++
.github/workflows/feature-branch.yml | 19 +++++
.github/workflows/release-branch.yml | 22 +++++
.github/workflows/release-published.yml | 14 ++++
.github/workflows/scheduled.yml | 17 ++++
.github/workflows/validate-codeowners.yml | 30 -------
17 files changed, 262 insertions(+), 319 deletions(-)
create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml
create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml
delete mode 100644 .github/workflows/auto-context.yml
delete mode 100644 .github/workflows/auto-format.yml
delete mode 100644 .github/workflows/auto-readme.yml
delete mode 100644 .github/workflows/auto-release.yml
delete mode 100644 .github/workflows/chatops.yml
create mode 100644 .github/workflows/feature-branch-chatops.yml
create mode 100644 .github/workflows/feature-branch.yml
create mode 100644 .github/workflows/release-branch.yml
create mode 100644 .github/workflows/release-published.yml
create mode 100644 .github/workflows/scheduled.yml
delete mode 100644 .github/workflows/validate-codeowners.yml
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000..94d3246
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,72 @@
+---
+name: Bug report
+description: Create a report to help us improve
+labels: ["bug"]
+assignees: [""]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Found a bug?
+
+ Please checkout our [Slack Community](https://slack.cloudposse.com)
+ or visit our [Slack Archive](https://archive.sweetops.com/).
+
+ [](https://slack.cloudposse.com)
+
+ - type: textarea
+ id: concise-description
+ attributes:
+ label: Describe the Bug
+ description: A clear and concise description of what the bug is.
+ placeholder: What is the bug about?
+ validations:
+ required: true
+
+ - type: textarea
+ id: expected
+ attributes:
+ label: Expected Behavior
+ description: A clear and concise description of what you expected.
+ placeholder: What happened?
+ validations:
+ required: true
+
+ - type: textarea
+ id: reproduction-steps
+ attributes:
+ label: Steps to Reproduce
+ description: Steps to reproduce the behavior.
+ placeholder: How do we reproduce it?
+ validations:
+ required: true
+
+ - type: textarea
+ id: screenshots
+ attributes:
+ label: Screenshots
+ description: If applicable, add screenshots or logs to help explain.
+ validations:
+ required: false
+
+ - type: textarea
+ id: environment
+ attributes:
+ label: Environment
+ description: Anything that will help us triage the bug.
+ placeholder: |
+ - OS: [e.g. Linux, OSX, WSL, etc]
+ - Version [e.g. 10.15]
+ - Module version
+ - Terraform version
+ validations:
+ required: false
+
+ - type: textarea
+ id: additional
+ attributes:
+ label: Additional Context
+ description: |
+ Add any other context about the problem here.
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 0000000..7b86672
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,71 @@
+---
+name: Feature Request
+description: Suggest an idea for this project
+labels: ["feature request"]
+assignees: [""]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Have a question?
+
+ Please checkout our [Slack Community](https://slack.cloudposse.com)
+ or visit our [Slack Archive](https://archive.sweetops.com/).
+
+ [](https://slack.cloudposse.com)
+
+ - type: textarea
+ id: concise-description
+ attributes:
+ label: Describe the Feature
+ description: A clear and concise description of what the feature is.
+ placeholder: What is the feature about?
+ validations:
+ required: true
+
+ - type: textarea
+ id: expected
+ attributes:
+ label: Expected Behavior
+ description: A clear and concise description of what you expected.
+ placeholder: What happened?
+ validations:
+ required: true
+
+ - type: textarea
+ id: use-case
+ attributes:
+ label: Use Case
+ description: |
+ Is your feature request related to a problem/challenge you are trying
+ to solve?
+
+ Please provide some additional context of why this feature or
+ capability will be valuable.
+ validations:
+ required: true
+
+ - type: textarea
+ id: ideal-solution
+ attributes:
+ label: Describe Ideal Solution
+ description: A clear and concise description of what you want to happen.
+ validations:
+ required: true
+
+ - type: textarea
+ id: alternatives-considered
+ attributes:
+ label: Alternatives Considered
+ description: Explain alternative solutions or features considered.
+ validations:
+ required: false
+
+ - type: textarea
+ id: additional
+ attributes:
+ label: Additional Context
+ description: |
+ Add any other context about the problem here.
+ validations:
+ required: false
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 4b8f32d..8944933 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,13 +1,21 @@
## what
-* Describe high-level what changed as a result of these commits (i.e. in plain-english, what do these changes mean?)
-* Use bullet points to be concise and to the point.
+
+
## why
-* Provide the justifications for the changes (e.g. business case).
-* Describe why these changes were made (e.g. why do these commits fix the problem?)
-* Use bullet points to be concise and to the point.
+
+
## references
-* Link to any supporting github issues or helpful documentation to add some context (e.g. stackoverflow).
-* Use `closes #123`, if this PR closes a GitHub issue `#123`
+
diff --git a/.github/auto-release.yml b/.github/auto-release.yml
index 17cd39c..cc9bf05 100644
--- a/.github/auto-release.yml
+++ b/.github/auto-release.yml
@@ -18,6 +18,7 @@ version-resolver:
- 'bug'
- 'hotfix'
default: 'minor'
+filter-by-commitish: true
categories:
- title: '🚀 Enhancements'
diff --git a/.github/mergify.yml b/.github/mergify.yml
index ef15545..148d85c 100644
--- a/.github/mergify.yml
+++ b/.github/mergify.yml
@@ -4,13 +4,17 @@ pull_request_rules:
- name: "approve automated PRs that have passed checks"
conditions:
- "author~=^(cloudpossebot|renovate\\[bot\\])$"
- - "base=master"
- "-closed"
- "head~=^(auto-update|renovate)/.*"
- "check-success=test/bats"
- "check-success=test/readme"
- "check-success=test/terratest"
- "check-success=validate-codeowners"
+ - or:
+ - "base=master"
+ - "base=main"
+ - "base~=^release/v\\d{1,2}$"
+
actions:
review:
type: "APPROVE"
@@ -20,7 +24,6 @@ pull_request_rules:
- name: "merge automated PRs when approved and tests pass"
conditions:
- "author~=^(cloudpossebot|renovate\\[bot\\])$"
- - "base=master"
- "-closed"
- "head~=^(auto-update|renovate)/.*"
- "check-success=test/bats"
@@ -30,6 +33,11 @@ pull_request_rules:
- "#approved-reviews-by>=1"
- "#changes-requested-reviews-by=0"
- "#commented-reviews-by=0"
+ - or:
+ - "base=master"
+ - "base=main"
+ - "base~=^release/v\\d{1,2}$"
+
actions:
merge:
method: "squash"
@@ -50,7 +58,10 @@ pull_request_rules:
- name: "remove outdated reviews"
conditions:
- - "base=master"
+ - or:
+ - "base=master"
+ - "base=main"
+ - "base~=^release/v\\d{1,2}$"
actions:
dismiss_reviews:
changes_requested: true
diff --git a/.github/renovate.json b/.github/renovate.json
index a780298..b61ed24 100644
--- a/.github/renovate.json
+++ b/.github/renovate.json
@@ -3,6 +3,7 @@
"config:base",
":preserveSemverRanges"
],
+ "baseBranches": ["main", "master", "/^release\\/v\\d{1,2}$/"],
"labels": ["auto-update"],
"dependencyDashboardAutoclose": true,
"enabledManagers": ["terraform"],
diff --git a/.github/workflows/auto-context.yml b/.github/workflows/auto-context.yml
deleted file mode 100644
index 665833a..0000000
--- a/.github/workflows/auto-context.yml
+++ /dev/null
@@ -1,57 +0,0 @@
-name: "auto-context"
-on:
- schedule:
- # Update context.tf nightly
- - cron: '0 3 * * *'
-
-jobs:
- update:
- if: github.event_name == 'schedule'
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
-
- - name: Update context.tf
- shell: bash
- id: update
- env:
- GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
- run: |
- if [[ -f context.tf ]]; then
- echo "Discovered existing context.tf! Fetching most recent version to see if there is an update."
- curl -o context.tf -fsSL https://raw.githubusercontent.com/cloudposse/terraform-null-label/master/exports/context.tf
- if git diff --no-patch --exit-code context.tf; then
- echo "No changes detected! Exiting the job..."
- else
- echo "context.tf file has changed. Update examples and rebuild README.md."
- make init
- make github/init/context.tf
- make readme/build
- echo "::set-output name=create_pull_request::true"
- fi
- else
- echo "This module has not yet been updated to support the context.tf pattern! Please update in order to support automatic updates."
- fi
-
- - name: Create Pull Request
- if: steps.update.outputs.create_pull_request == 'true'
- uses: cloudposse/actions/github/create-pull-request@0.30.0
- with:
- token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
- committer: 'cloudpossebot <11232728+cloudpossebot@users.noreply.github.com>'
- author: 'cloudpossebot <11232728+cloudpossebot@users.noreply.github.com>'
- commit-message: Update context.tf from origin source
- title: Update context.tf
- body: |-
- ## what
- This is an auto-generated PR that updates the `context.tf` file to the latest version from `cloudposse/terraform-null-label`
-
- ## why
- To support all the features of the `context` interface.
-
- branch: auto-update/context.tf
- base: master
- delete-branch: true
- labels: |
- auto-update
- context
diff --git a/.github/workflows/auto-format.yml b/.github/workflows/auto-format.yml
deleted file mode 100644
index c600d60..0000000
--- a/.github/workflows/auto-format.yml
+++ /dev/null
@@ -1,88 +0,0 @@
-name: Auto Format
-on:
- pull_request_target:
- types: [opened, synchronize]
-
-jobs:
- auto-format:
- runs-on: ubuntu-latest
- container: cloudposse/build-harness:latest
- steps:
- # Checkout the pull request branch
- # "An action in a workflow run can’t trigger a new workflow run. For example, if an action pushes code using
- # the repository’s GITHUB_TOKEN, a new workflow will not run even when the repository contains
- # a workflow configured to run when push events occur."
- # However, using a personal access token will cause events to be triggered.
- # We need that to ensure a status gets posted after the auto-format commit.
- # We also want to trigger tests if the auto-format made no changes.
- - uses: actions/checkout@v2
- if: github.event.pull_request.state == 'open'
- name: Privileged Checkout
- with:
- token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
- repository: ${{ github.event.pull_request.head.repo.full_name }}
- # Check out the PR commit, not the merge commit
- # Use `ref` instead of `sha` to enable pushing back to `ref`
- ref: ${{ github.event.pull_request.head.ref }}
-
- # Do all the formatting stuff
- - name: Auto Format
- if: github.event.pull_request.state == 'open'
- shell: bash
- env:
- GITHUB_TOKEN: "${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}"
- run: make BUILD_HARNESS_PATH=/build-harness PACKAGES_PREFER_HOST=true -f /build-harness/templates/Makefile.build-harness pr/auto-format/host
-
- # Commit changes (if any) to the PR branch
- - name: Commit changes to the PR branch
- if: github.event.pull_request.state == 'open'
- shell: bash
- id: commit
- env:
- SENDER: ${{ github.event.sender.login }}
- run: |
- set -x
- output=$(git diff --name-only)
-
- if [ -n "$output" ]; then
- echo "Changes detected. Pushing to the PR branch"
- git config --global user.name 'cloudpossebot'
- git config --global user.email '11232728+cloudpossebot@users.noreply.github.com'
- git add -A
- git commit -m "Auto Format"
- # Prevent looping by not pushing changes in response to changes from cloudpossebot
- [[ $SENDER == "cloudpossebot" ]] || git push
- # Set status to fail, because the push should trigger another status check,
- # and we use success to indicate the checks are finished.
- printf "::set-output name=%s::%s\n" "changed" "true"
- exit 1
- else
- printf "::set-output name=%s::%s\n" "changed" "false"
- echo "No changes detected"
- fi
-
- - name: Auto Test
- uses: cloudposse/actions/github/repository-dispatch@0.30.0
- # match users by ID because logins (user names) are inconsistent,
- # for example in the REST API Renovate Bot is `renovate[bot]` but
- # in GraphQL it is just `renovate`, plus there is a non-bot
- # user `renovate` with ID 1832810.
- # Mergify bot: 37929162
- # Renovate bot: 29139614
- # Cloudpossebot: 11232728
- # Need to use space separators to prevent "21" from matching "112144"
- if: >
- contains(' 37929162 29139614 11232728 ', format(' {0} ', github.event.pull_request.user.id))
- && steps.commit.outputs.changed == 'false' && github.event.pull_request.state == 'open'
- with:
- token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
- repository: cloudposse/actions
- event-type: test-command
- client-payload: |-
- { "slash_command":{"args": {"unnamed": {"all": "all", "arg1": "all"}}},
- "pull_request": ${{ toJSON(github.event.pull_request) }},
- "github":{"payload":{"repository": ${{ toJSON(github.event.repository) }},
- "comment": {"id": ""}
- }
- }
- }
diff --git a/.github/workflows/auto-readme.yml b/.github/workflows/auto-readme.yml
deleted file mode 100644
index 6f25b8d..0000000
--- a/.github/workflows/auto-readme.yml
+++ /dev/null
@@ -1,71 +0,0 @@
-name: "auto-readme"
-on:
- workflow_dispatch:
-
- schedule:
- # Example of job definition:
- # .---------------- minute (0 - 59)
- # | .------------- hour (0 - 23)
- # | | .---------- day of month (1 - 31)
- # | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
- # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
- # | | | | |
- # * * * * * user-name command to be executed
-
- # Update README.md nightly at 4am UTC
- - cron: '0 4 * * *'
-
-jobs:
- update:
- if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
-
- - name: Find default branch name
- id: defaultBranch
- shell: bash
- env:
- GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
- run: |
- default_branch=$(gh repo view --json defaultBranchRef --jq .defaultBranchRef.name)
- printf "::set-output name=defaultBranch::%s\n" "${default_branch}"
- printf "defaultBranchRef.name=%s\n" "${default_branch}"
-
- - name: Update readme
- shell: bash
- id: update
- env:
- GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
- DEF: "${{ steps.defaultBranch.outputs.defaultBranch }}"
- run: |
- make init
- make readme/build
- # Ignore changes if they are only whitespace
- if ! git diff --quiet README.md && git diff --ignore-all-space --ignore-blank-lines --quiet README.md; then
- git restore README.md
- echo Ignoring whitespace-only changes in README
- fi
-
- - name: Create Pull Request
- # This action will not create or change a pull request if there are no changes to make.
- # If a PR of the auto-update/readme branch is open, this action will just update it, not create a new PR.
- uses: cloudposse/actions/github/create-pull-request@0.30.0
- with:
- token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
- commit-message: Update README.md and docs
- title: Update README.md and docs
- body: |-
- ## what
- This is an auto-generated PR that updates the README.md and docs
-
- ## why
- To have most recent changes of README.md and doc from origin templates
-
- branch: auto-update/readme
- base: ${{ steps.defaultBranch.outputs.defaultBranch }}
- delete-branch: true
- labels: |
- auto-update
- no-release
- readme
diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml
deleted file mode 100644
index 3a38fae..0000000
--- a/.github/workflows/auto-release.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: auto-release
-
-on:
- push:
- branches:
- - main
- - master
- - production
-
-jobs:
- publish:
- runs-on: ubuntu-latest
- steps:
- # Get PR from merged commit to master
- - uses: actions-ecosystem/action-get-merged-pull-request@v1
- id: get-merged-pull-request
- with:
- github_token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
- # Drafts your next Release notes as Pull Requests are merged into "main"
- - uses: release-drafter/release-drafter@v5
- with:
- publish: ${{ !contains(steps.get-merged-pull-request.outputs.labels, 'no-release') }}
- prerelease: false
- config-name: auto-release.yml
- env:
- GITHUB_TOKEN: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
diff --git a/.github/workflows/chatops.yml b/.github/workflows/chatops.yml
deleted file mode 100644
index 23f96d8..0000000
--- a/.github/workflows/chatops.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-name: chatops
-on:
- issue_comment:
- types: [created]
-
-jobs:
- default:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- - name: "Handle common commands"
- uses: cloudposse/actions/github/slash-command-dispatch@0.30.0
- with:
- token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
- reaction-token: ${{ secrets.GITHUB_TOKEN }}
- repository: cloudposse/actions
- commands: rebuild-readme, terraform-fmt
- permission: triage
- issue-type: pull-request
-
- test:
- runs-on: ubuntu-latest
- steps:
- - name: "Checkout commit"
- uses: actions/checkout@v2
- - name: "Run tests"
- uses: cloudposse/actions/github/slash-command-dispatch@0.30.0
- with:
- token: ${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}
- reaction-token: ${{ secrets.GITHUB_TOKEN }}
- repository: cloudposse/actions
- commands: test
- permission: triage
- issue-type: pull-request
- reactions: false
-
-
diff --git a/.github/workflows/feature-branch-chatops.yml b/.github/workflows/feature-branch-chatops.yml
new file mode 100644
index 0000000..9abfc61
--- /dev/null
+++ b/.github/workflows/feature-branch-chatops.yml
@@ -0,0 +1,16 @@
+---
+name: feature-branch-chatops
+on:
+ issue_comment:
+ types: [created]
+
+permissions:
+ pull-requests: write
+ id-token: write
+ contents: write
+
+jobs:
+ terraform-module:
+ uses: cloudposse/github-actions-workflows-terraform-module/.github/workflows/feature-branch-chatops.yml@main
+ secrets:
+ github_access_token: ${{ secrets.REPO_ACCESS_TOKEN }}
diff --git a/.github/workflows/feature-branch.yml b/.github/workflows/feature-branch.yml
new file mode 100644
index 0000000..8faa955
--- /dev/null
+++ b/.github/workflows/feature-branch.yml
@@ -0,0 +1,19 @@
+---
+name: feature-branch
+on:
+ pull_request:
+ branches:
+ - main
+ - release/**
+ types: [opened, synchronize, reopened, labeled, unlabeled]
+
+permissions:
+ pull-requests: write
+ id-token: write
+ contents: write
+
+jobs:
+ terraform-module:
+ uses: cloudposse/github-actions-workflows-terraform-module/.github/workflows/feature-branch.yml@main
+ secrets:
+ github_access_token: ${{ secrets.REPO_ACCESS_TOKEN }}
diff --git a/.github/workflows/release-branch.yml b/.github/workflows/release-branch.yml
new file mode 100644
index 0000000..3f8fe62
--- /dev/null
+++ b/.github/workflows/release-branch.yml
@@ -0,0 +1,22 @@
+---
+name: release-branch
+on:
+ push:
+ branches:
+ - main
+ - release/**
+ paths-ignore:
+ - '.github/**'
+ - 'docs/**'
+ - 'examples/**'
+ - 'test/**'
+
+permissions:
+ contents: write
+ id-token: write
+
+jobs:
+ terraform-module:
+ uses: cloudposse/github-actions-workflows-terraform-module/.github/workflows/release-branch.yml@main
+ secrets:
+ github_access_token: ${{ secrets.REPO_ACCESS_TOKEN }}
diff --git a/.github/workflows/release-published.yml b/.github/workflows/release-published.yml
new file mode 100644
index 0000000..f86352b
--- /dev/null
+++ b/.github/workflows/release-published.yml
@@ -0,0 +1,14 @@
+---
+name: release-published
+on:
+ release:
+ types:
+ - published
+
+permissions:
+ contents: write
+ id-token: write
+
+jobs:
+ terraform-module:
+ uses: cloudposse/github-actions-workflows-terraform-module/.github/workflows/release.yml@main
diff --git a/.github/workflows/scheduled.yml b/.github/workflows/scheduled.yml
new file mode 100644
index 0000000..163be0b
--- /dev/null
+++ b/.github/workflows/scheduled.yml
@@ -0,0 +1,17 @@
+---
+name: scheduled
+on:
+ workflow_dispatch: { } # Allows manually trigger this workflow
+ schedule:
+ - cron: "0 3 * * *"
+
+permissions:
+ pull-requests: write
+ id-token: write
+ contents: write
+
+jobs:
+ scheduled:
+ uses: cloudposse/github-actions-workflows-terraform-module/.github/workflows/scheduled.yml@main
+ secrets:
+ github_access_token: ${{ secrets.REPO_ACCESS_TOKEN }}
diff --git a/.github/workflows/validate-codeowners.yml b/.github/workflows/validate-codeowners.yml
deleted file mode 100644
index 4b4a226..0000000
--- a/.github/workflows/validate-codeowners.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: Validate Codeowners
-on:
- workflow_dispatch:
-
- pull_request:
-
-jobs:
- validate-codeowners:
- runs-on: ubuntu-latest
- steps:
- - name: "Checkout source code at current commit"
- uses: actions/checkout@v2
- # Leave pinned at 0.7.1 until https://github.com/mszostok/codeowners-validator/issues/173 is resolved
- - uses: mszostok/codeowners-validator@v0.7.1
- if: github.event.pull_request.head.repo.full_name == github.repository
- name: "Full check of CODEOWNERS"
- with:
- # For now, remove "files" check to allow CODEOWNERS to specify non-existent
- # files so we can use the same CODEOWNERS file for Terraform and non-Terraform repos
- # checks: "files,syntax,owners,duppatterns"
- checks: "syntax,owners,duppatterns"
- owner_checker_allow_unowned_patterns: "false"
- # GitHub access token is required only if the `owners` check is enabled
- github_access_token: "${{ secrets.PUBLIC_REPO_ACCESS_TOKEN }}"
- - uses: mszostok/codeowners-validator@v0.7.1
- if: github.event.pull_request.head.repo.full_name != github.repository
- name: "Syntax check of CODEOWNERS"
- with:
- checks: "syntax,duppatterns"
- owner_checker_allow_unowned_patterns: "false"
From 6d2fef2260147eaf5650d9c660fb9da892dc81cf Mon Sep 17 00:00:00 2001
From: Maksym Vlasov
Date: Tue, 30 May 2023 17:07:48 +0300
Subject: [PATCH 09/74] feat: Add support for aws provider 5.0 (#198)
* feat: Add support for aws provider 5.0
* update examples
* Apply suggestions from code review
Co-authored-by: Andriy Knysh
---------
Co-authored-by: Andriy Knysh
---
.github/workflows/release-branch.yml | 1 +
examples/complete/main.tf | 10 +++++-----
main.tf | 22 +++++++++++-----------
3 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/.github/workflows/release-branch.yml b/.github/workflows/release-branch.yml
index 3f8fe62..b30901e 100644
--- a/.github/workflows/release-branch.yml
+++ b/.github/workflows/release-branch.yml
@@ -10,6 +10,7 @@ on:
- 'docs/**'
- 'examples/**'
- 'test/**'
+ - 'README.*'
permissions:
contents: write
diff --git a/examples/complete/main.tf b/examples/complete/main.tf
index 5f62a7d..5f453a4 100644
--- a/examples/complete/main.tf
+++ b/examples/complete/main.tf
@@ -4,21 +4,21 @@ provider "aws" {
module "vpc" {
source = "cloudposse/vpc/aws"
- version = "0.28.0"
+ version = "2.1.0"
- cidr_block = "172.16.0.0/16"
+ ipv4_primary_cidr_block = "172.16.0.0/16"
context = module.this.context
}
module "subnets" {
source = "cloudposse/dynamic-subnets/aws"
- version = "0.39.7"
+ version = "2.3.0"
availability_zones = var.availability_zones
vpc_id = module.vpc.vpc_id
- igw_id = module.vpc.igw_id
- cidr_block = module.vpc.vpc_cidr_block
+ igw_id = [module.vpc.igw_id]
+ ipv4_cidr_block = [module.vpc.vpc_cidr_block]
nat_gateway_enabled = false
nat_instance_enabled = false
diff --git a/main.tf b/main.tf
index 33010e3..0525593 100644
--- a/main.tf
+++ b/main.tf
@@ -115,17 +115,17 @@ resource "aws_elasticache_parameter_group" "default" {
resource "aws_elasticache_replication_group" "default" {
count = module.this.enabled ? 1 : 0
- auth_token = var.transit_encryption_enabled ? var.auth_token : null
- replication_group_id = var.replication_group_id == "" ? module.this.id : var.replication_group_id
- description = coalesce(var.description, module.this.id)
- node_type = var.instance_type
- num_cache_clusters = var.cluster_mode_enabled ? null : var.cluster_size
- port = var.port
- parameter_group_name = join("", aws_elasticache_parameter_group.default[*].name)
- availability_zones = length(var.availability_zones) == 0 ? null : [for n in range(0, var.cluster_size) : element(var.availability_zones, n)]
- automatic_failover_enabled = var.cluster_mode_enabled ? true : var.automatic_failover_enabled
- multi_az_enabled = var.multi_az_enabled
- subnet_group_name = local.elasticache_subnet_group_name
+ auth_token = var.transit_encryption_enabled ? var.auth_token : null
+ replication_group_id = var.replication_group_id == "" ? module.this.id : var.replication_group_id
+ description = coalesce(var.description, module.this.id)
+ node_type = var.instance_type
+ num_cache_clusters = var.cluster_mode_enabled ? null : var.cluster_size
+ port = var.port
+ parameter_group_name = join("", aws_elasticache_parameter_group.default[*].name)
+ preferred_cache_cluster_azs = length(var.availability_zones) == 0 ? null : [for n in range(0, var.cluster_size) : element(var.availability_zones, n)]
+ automatic_failover_enabled = var.cluster_mode_enabled ? true : var.automatic_failover_enabled
+ multi_az_enabled = var.multi_az_enabled
+ subnet_group_name = local.elasticache_subnet_group_name
# It would be nice to remove null or duplicate security group IDs, if there are any, using `compact`,
# but that causes problems, and having duplicates does not seem to cause problems.
# See https://github.com/hashicorp/terraform/issues/29799
From 1bd0cf0f075afc1a11153c1980aaafc5e2f3c5fc Mon Sep 17 00:00:00 2001
From: Max Lobur
Date: Thu, 15 Jun 2023 21:54:38 +0300
Subject: [PATCH 10/74] Support AWS Provider V5 (#203)
* Support AWS Provider V5
* Update main.tf
* upd
* upd
* upd
---
.github/workflows/release-published.yml | 2 +-
README.md | 2 +-
docs/terraform.md | 2 +-
examples/complete/versions.tf | 2 +-
versions.tf | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/release-published.yml b/.github/workflows/release-published.yml
index f86352b..b31232b 100644
--- a/.github/workflows/release-published.yml
+++ b/.github/workflows/release-published.yml
@@ -11,4 +11,4 @@ permissions:
jobs:
terraform-module:
- uses: cloudposse/github-actions-workflows-terraform-module/.github/workflows/release.yml@main
+ uses: cloudposse/github-actions-workflows-terraform-module/.github/workflows/release-published.yml@main
diff --git a/README.md b/README.md
index 5abd290..7a77366 100644
--- a/README.md
+++ b/README.md
@@ -213,7 +213,7 @@ Available targets:
| Name | Version |
|------|---------|
-| [terraform](#requirement\_terraform) | >= 0.14.0 |
+| [terraform](#requirement\_terraform) | >= 1.3 |
| [aws](#requirement\_aws) | >= 4.18 |
## Providers
diff --git a/docs/terraform.md b/docs/terraform.md
index cfca439..2179026 100644
--- a/docs/terraform.md
+++ b/docs/terraform.md
@@ -3,7 +3,7 @@
| Name | Version |
|------|---------|
-| [terraform](#requirement\_terraform) | >= 0.14.0 |
+| [terraform](#requirement\_terraform) | >= 1.3 |
| [aws](#requirement\_aws) | >= 4.18 |
## Providers
diff --git a/examples/complete/versions.tf b/examples/complete/versions.tf
index 6b5f390..ae13755 100644
--- a/examples/complete/versions.tf
+++ b/examples/complete/versions.tf
@@ -1,5 +1,5 @@
terraform {
- required_version = ">= 0.14.0"
+ required_version = ">= 1.3"
required_providers {
aws = {
diff --git a/versions.tf b/versions.tf
index 6b5f390..ae13755 100644
--- a/versions.tf
+++ b/versions.tf
@@ -1,5 +1,5 @@
terraform {
- required_version = ">= 0.14.0"
+ required_version = ">= 1.3"
required_providers {
aws = {
From fea42bfd85ae3816edf9f7b01d2a77939258f8b5 Mon Sep 17 00:00:00 2001
From: Dan Miller
Date: Tue, 10 Oct 2023 11:43:52 -0700
Subject: [PATCH 11/74] Allow Module to Disable or Enable Cluster Mode for
Existing Deployment (#181)
* added compact for when resource dne
* make readme
---
README.md | 4 ----
main.tf | 2 +-
outputs.tf | 2 +-
3 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/README.md b/README.md
index 7a77366..bb7677e 100644
--- a/README.md
+++ b/README.md
@@ -88,10 +88,6 @@ We highly recommend that in your code you pin the version to the exact version y
using so that your infrastructure remains stable, and update versions in a
systematic way so that they do not catch you by surprise.
-Also, because of a bug in the Terraform registry ([hashicorp/terraform#21417](https://github.com/hashicorp/terraform/issues/21417)),
-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._
diff --git a/main.tf b/main.tf
index 0525593..723ade0 100644
--- a/main.tf
+++ b/main.tf
@@ -222,7 +222,7 @@ module "dns" {
dns_name = var.dns_subdomain != "" ? var.dns_subdomain : module.this.id
ttl = 60
zone_id = try(var.zone_id[0], tostring(var.zone_id), "")
- records = var.cluster_mode_enabled ? [join("", aws_elasticache_replication_group.default[*].configuration_endpoint_address)] : [join("", aws_elasticache_replication_group.default[*].primary_endpoint_address)]
+ records = var.cluster_mode_enabled ? [join("", compact(aws_elasticache_replication_group.default[*].configuration_endpoint_address))] : [join("", compact(aws_elasticache_replication_group.default[*].primary_endpoint_address))]
context = module.this.context
}
diff --git a/outputs.tf b/outputs.tf
index 3830fb9..55b345c 100644
--- a/outputs.tf
+++ b/outputs.tf
@@ -19,7 +19,7 @@ output "port" {
}
output "endpoint" {
- value = var.cluster_mode_enabled ? join("", aws_elasticache_replication_group.default[*].configuration_endpoint_address) : join("", aws_elasticache_replication_group.default[*].primary_endpoint_address)
+ value = var.cluster_mode_enabled ? join("", compact(aws_elasticache_replication_group.default[*].configuration_endpoint_address)) : join("", compact(aws_elasticache_replication_group.default[*].primary_endpoint_address))
description = "Redis primary or configuration endpoint, whichever is appropriate for the given cluster mode"
}
From 4a58a8066238c7527d4dd6b3674877642d36d910 Mon Sep 17 00:00:00 2001
From: Kamil Grabowski
Date: Fri, 1 Dec 2023 17:36:48 +0100
Subject: [PATCH 12/74] New variables: create_parameter_group and
parameter_group_name (#208)
* new variable: parameter_group_name
* new variable: create_parameter_group
* update README
* remove comment
* Update parameter group description
Co-authored-by: Andriy Knysh
* change module.this.enabled to local.enabled
* replace . with -
---------
Co-authored-by: Andriy Knysh
---
README.md | 192 ++++++++++++----------------------------------
docs/terraform.md | 2 +
main.tf | 41 +++++++---
variables.tf | 12 +++
4 files changed, 93 insertions(+), 154 deletions(-)
diff --git a/README.md b/README.md
index bb7677e..c73b112 100644
--- a/README.md
+++ b/README.md
@@ -33,16 +33,7 @@ Terraform module to provision an [`ElastiCache`](https://aws.amazon.com/elastica
---
This project is part of our comprehensive ["SweetOps"](https://cpco.io/sweetops) approach towards DevOps.
-[
][share_email]
-[
][share_googleplus]
-[
][share_facebook]
-[
][share_reddit]
-[
][share_linkedin]
-[
][share_twitter]
-
-
-[][terraform_modules]
-
+
It's 100% Open Source and licensed under the [APACHE2](LICENSE).
@@ -60,33 +51,18 @@ We literally have [*hundreds of terraform modules*][terraform_modules] that are
-## Security & Compliance [
](https://bridgecrew.io/)
-
-Security scanning is graciously provided by Bridgecrew. Bridgecrew is the leading fully hosted, cloud-native solution providing continuous Terraform security and compliance.
-
-| Benchmark | Description |
-|--------|---------------|
-| [](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-elasticache-redis&benchmark=INFRASTRUCTURE+SECURITY) | Infrastructure Security Compliance |
-| [](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-elasticache-redis&benchmark=CIS+KUBERNETES+V1.5) | Center for Internet Security, KUBERNETES Compliance |
-| [](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-elasticache-redis&benchmark=CIS+AWS+V1.2) | Center for Internet Security, AWS Compliance |
-| [](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-elasticache-redis&benchmark=CIS+AZURE+V1.1) | Center for Internet Security, AZURE Compliance |
-| [](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-elasticache-redis&benchmark=PCI-DSS+V3.2) | Payment Card Industry Data Security Standards Compliance |
-| [](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-elasticache-redis&benchmark=NIST-800-53) | National Institute of Standards and Technology Compliance |
-| [](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-elasticache-redis&benchmark=ISO27001) | Information Security Management System, ISO/IEC 27001 Compliance |
-| [](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-elasticache-redis&benchmark=SOC2)| Service Organization Control 2 Compliance |
-| [](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-elasticache-redis&benchmark=CIS+GCP+V1.1) | Center for Internet Security, GCP Compliance |
-| [](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-elasticache-redis&benchmark=HIPAA) | Health Insurance Portability and Accountability Compliance |
+## Usage
-## Usage
+> **Important**
+> We do not pin modules to versions in our examples because of the
+> difficulty of keeping the versions in the documentation in sync with the latest released versions.
+> We highly recommend that in your code you pin the version to the exact version you are
+> using so that your infrastructure remains stable, and update versions in a
+> systematic way so that they do not catch you by surprise.
-**IMPORTANT:** We do not pin modules to versions in our examples because of the
-difficulty of keeping the versions in the documentation in sync with the latest released versions.
-We highly recommend that in your code you pin the version to the exact version you are
-using so that your infrastructure remains stable, and update versions in a
-systematic way so that they do not catch you by surprise.
_**Disruptive changes introduced at version 0.41.0**. If upgrading from an earlier version, see
@@ -263,6 +239,7 @@ Available targets:
| [cluster\_mode\_replicas\_per\_node\_group](#input\_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 |
| [cluster\_size](#input\_cluster\_size) | Number of nodes in cluster. *Ignored when `cluster_mode_enabled` == `true`* | `number` | `1` | no |
| [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` | {
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no |
+| [create\_parameter\_group](#input\_create\_parameter\_group) | Whether new parameter group should be created. Set to false if you want to use existing parameter group | `bool` | `true` | no |
| [create\_security\_group](#input\_create\_security\_group) | Set `true` to create and configure a new security group. If false, `associated_security_group_ids` must be provided. | `bool` | `true` | no |
| [data\_tiering\_enabled](#input\_data\_tiering\_enabled) | Enables data tiering. Data tiering is only supported for replication groups using the r6gd node type. | `bool` | `false` | no |
| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
@@ -293,6 +270,7 @@ Available targets:
| [ok\_actions](#input\_ok\_actions) | The list of actions to execute when this alarm transitions into an OK state from any other state. Each action is specified as an Amazon Resource Number (ARN) | `list(string)` | `[]` | no |
| [parameter](#input\_parameter) | A list of Redis parameters to apply. Note that parameters may differ from one Redis family to another | list(object({
name = string
value = string
}))
| `[]` | no |
| [parameter\_group\_description](#input\_parameter\_group\_description) | Managed by Terraform | `string` | `null` | no |
+| [parameter\_group\_name](#input\_parameter\_group\_name) | Override the default parameter group name | `string` | `null` | no |
| [port](#input\_port) | Redis port | `number` | `6379` | no |
| [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| [replication\_group\_id](#input\_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 |
@@ -333,32 +311,56 @@ Available targets:
+## Related Projects
-## Share the Love
+Check out these related projects.
-Like this project? Please give it a ★ on [our GitHub](https://github.com/cloudposse/terraform-aws-elasticache-redis)! (it helps us **a lot**)
+- [terraform-aws-security-group](https://github.com/cloudposse/terraform-aws-security-group) - Terraform module to provision an AWS Security Group.
+- [terraform-null-label](https://github.com/cloudposse/terraform-null-label) - Terraform module designed to generate consistent names and tags for resources. Use terraform-null-label to implement a strict naming convention.
-Are you using this project or any of our other projects? Consider [leaving a testimonial][testimonial]. =)
+## ✨ Contributing
+This project is under active development, and we encourage contributions from our community.
+Many thanks to our outstanding contributors:
+
+
+
-## Related Projects
+### 🐛 Bug Reports & Feature Requests
-Check out these related projects.
+Please use the [issue tracker](https://github.com/cloudposse/terraform-aws-elasticache-redis/issues) to report any bugs or file feature requests.
-- [terraform-aws-security-group](https://github.com/cloudposse/terraform-aws-security-group) - Terraform module to provision an AWS Security Group.
-- [terraform-null-label](https://github.com/cloudposse/terraform-null-label) - Terraform module designed to generate consistent names and tags for resources. Use terraform-null-label to implement a strict naming convention.
+### 💻 Developing
-## Help
+If you are interested in being a contributor and want to get involved in developing this project or [help out](https://cpco.io/help-out) with our other projects, we would love to hear from you! Shoot us an [email][email].
-**Got a question?** We got answers.
+In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow.
-File a GitHub [issue](https://github.com/cloudposse/terraform-aws-elasticache-redis/issues), send us an [email][email] or join our [Slack Community][slack].
+ 1. **Fork** the repo on GitHub
+ 2. **Clone** the project to your own machine
+ 3. **Commit** changes to your own branch
+ 4. **Push** your work back up to your fork
+ 5. Submit a **Pull Request** so that we can review your changes
-[![README Commercial Support][readme_commercial_support_img]][readme_commercial_support_link]
+**NOTE:** Be sure to merge the latest changes from "upstream" before making a pull request!
+
+### 🌎 Slack Community
+
+Join our [Open Source Community][slack] on Slack. It's **FREE** for everyone! Our "SweetOps" community is where you get to talk with others who share a similar vision for how to rollout and manage infrastructure. This is the best place to talk shop, ask questions, solicit feedback, and work together as a community to build totally *sweet* infrastructure.
+
+### 📰 Newsletter
+
+Sign up for [our newsletter][newsletter] that covers everything on our technology radar. Receive updates on what we're up to on GitHub as well as awesome new projects we discover.
+
+### 📆 Office Hours
+
+[Join us every Wednesday via Zoom][office_hours] for our weekly "Lunch & Learn" sessions. It's **FREE** for everyone!
-## DevOps Accelerator for Startups
+## About
+This project is maintained and funded by [Cloud Posse, LLC][website].
+
We are a [**DevOps Accelerator**][commercial_support]. We'll help you build your cloud infrastructure from the ground up so you can own it. Then we'll show you how to operate it and stick around for as long as you need us.
@@ -379,51 +381,7 @@ We deliver 10x the value for a fraction of the cost of a full-time engineer. Our
- **Code Reviews.** You'll receive constructive feedback on Pull Requests.
- **Bug Fixes.** We'll rapidly work with you to fix any bugs in our projects.
-## Slack Community
-
-Join our [Open Source Community][slack] on Slack. It's **FREE** for everyone! Our "SweetOps" community is where you get to talk with others who share a similar vision for how to rollout and manage infrastructure. This is the best place to talk shop, ask questions, solicit feedback, and work together as a community to build totally *sweet* infrastructure.
-
-## Discourse Forums
-
-Participate in our [Discourse Forums][discourse]. Here you'll find answers to commonly asked questions. Most questions will be related to the enormous number of projects we support on our GitHub. Come here to collaborate on answers, find solutions, and get ideas about the products and services we value. It only takes a minute to get started! Just sign in with SSO using your GitHub account.
-
-## Newsletter
-
-Sign up for [our newsletter][newsletter] that covers everything on our technology radar. Receive updates on what we're up to on GitHub as well as awesome new projects we discover.
-
-## Office Hours
-
-[Join us every Wednesday via Zoom][office_hours] for our weekly "Lunch & Learn" sessions. It's **FREE** for everyone!
-
-[][office_hours]
-
-## Contributing
-
-### Bug Reports & Feature Requests
-
-Please use the [issue tracker](https://github.com/cloudposse/terraform-aws-elasticache-redis/issues) to report any bugs or file feature requests.
-
-### Developing
-
-If you are interested in being a contributor and want to get involved in developing this project or [help out](https://cpco.io/help-out) with our other projects, we would love to hear from you! Shoot us an [email][email].
-
-In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow.
-
- 1. **Fork** the repo on GitHub
- 2. **Clone** the project to your own machine
- 3. **Commit** changes to your own branch
- 4. **Push** your work back up to your fork
- 5. Submit a **Pull Request** so that we can review your changes
-
-**NOTE:** Be sure to merge the latest changes from "upstream" before making a pull request!
-
-
-## Copyright
-
-Copyright © 2017-2023 [Cloud Posse, LLC](https://cpco.io/copyright)
-
-
-
+[![README Commercial Support][readme_commercial_support_img]][readme_commercial_support_link]
## License
[](https://opensource.org/licenses/Apache-2.0)
@@ -449,54 +407,11 @@ specific language governing permissions and limitations
under the License.
```
-
-
-
-
-
-
-
-
## Trademarks
All other trademarks referenced herein are the property of their respective owners.
-
-## About
-
-This project is maintained and funded by [Cloud Posse, LLC][website]. Like it? Please let us know by [leaving a testimonial][testimonial]!
-
-[![Cloud Posse][logo]][website]
-
-We're a [DevOps Professional Services][hire] company based in Los Angeles, CA. We ❤️ [Open Source Software][we_love_open_source].
-
-We offer [paid support][commercial_support] on all of our projects.
-
-Check out [our other projects][github], [follow us on twitter][twitter], [apply for a job][jobs], or [hire us][hire] to help with your cloud strategy and implementation.
-
-
-
-### Contributors
-
-
-| [![Erik Osterman][osterman_avatar]][osterman_homepage]
[Erik Osterman][osterman_homepage] | [![Igor Rodionov][goruha_avatar]][goruha_homepage]
[Igor Rodionov][goruha_homepage] | [![Andriy Knysh][aknysh_avatar]][aknysh_homepage]
[Andriy Knysh][aknysh_homepage] | [![Daren Desjardins][darend_avatar]][darend_homepage]
[Daren Desjardins][darend_homepage] | [![Max Moon][MoonMoon1919_avatar]][MoonMoon1919_homepage]
[Max Moon][MoonMoon1919_homepage] | [![Christopher Riley][christopherriley_avatar]][christopherriley_homepage]
[Christopher Riley][christopherriley_homepage] | [![RB][nitrocode_avatar]][nitrocode_homepage]
[RB][nitrocode_homepage] |
-|---|---|---|---|---|---|---|
-
-
- [osterman_homepage]: https://github.com/osterman
- [osterman_avatar]: https://img.cloudposse.com/150x150/https://github.com/osterman.png
- [goruha_homepage]: https://github.com/goruha
- [goruha_avatar]: https://img.cloudposse.com/150x150/https://github.com/goruha.png
- [aknysh_homepage]: https://github.com/aknysh
- [aknysh_avatar]: https://img.cloudposse.com/150x150/https://github.com/aknysh.png
- [darend_homepage]: https://github.com/darend
- [darend_avatar]: https://img.cloudposse.com/150x150/https://github.com/darend.png
- [MoonMoon1919_homepage]: https://github.com/MoonMoon1919
- [MoonMoon1919_avatar]: https://img.cloudposse.com/150x150/https://github.com/MoonMoon1919.png
- [christopherriley_homepage]: https://github.com/christopherriley
- [christopherriley_avatar]: https://img.cloudposse.com/150x150/https://github.com/christopherriley.png
- [nitrocode_homepage]: https://github.com/nitrocode
- [nitrocode_avatar]: https://img.cloudposse.com/150x150/https://github.com/nitrocode.png
-
+---
+Copyright © 2017-2023 [Cloud Posse, LLC](https://cpco.io/copyright)
[![README Footer][readme_footer_img]][readme_footer_link]
[![Beacon][beacon]][website]
@@ -507,12 +422,9 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply
[jobs]: https://cpco.io/jobs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=jobs
[hire]: https://cpco.io/hire?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=hire
[slack]: https://cpco.io/slack?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=slack
- [linkedin]: https://cpco.io/linkedin?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=linkedin
[twitter]: https://cpco.io/twitter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=twitter
- [testimonial]: https://cpco.io/leave-testimonial?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=testimonial
[office_hours]: https://cloudposse.com/office-hours?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=office_hours
[newsletter]: https://cpco.io/newsletter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=newsletter
- [discourse]: https://ask.sweetops.com/?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=discourse
[email]: https://cpco.io/email?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=email
[commercial_support]: https://cpco.io/commercial-support?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=commercial_support
[we_love_open_source]: https://cpco.io/we-love-open-source?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=we_love_open_source
@@ -523,11 +435,5 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply
[readme_footer_link]: https://cloudposse.com/readme/footer/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=readme_footer_link
[readme_commercial_support_img]: https://cloudposse.com/readme/commercial-support/img
[readme_commercial_support_link]: https://cloudposse.com/readme/commercial-support/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=readme_commercial_support_link
- [share_twitter]: https://twitter.com/intent/tweet/?text=terraform-aws-elasticache-redis&url=https://github.com/cloudposse/terraform-aws-elasticache-redis
- [share_linkedin]: https://www.linkedin.com/shareArticle?mini=true&title=terraform-aws-elasticache-redis&url=https://github.com/cloudposse/terraform-aws-elasticache-redis
- [share_reddit]: https://reddit.com/submit/?url=https://github.com/cloudposse/terraform-aws-elasticache-redis
- [share_facebook]: https://facebook.com/sharer/sharer.php?u=https://github.com/cloudposse/terraform-aws-elasticache-redis
- [share_googleplus]: https://plus.google.com/share?url=https://github.com/cloudposse/terraform-aws-elasticache-redis
- [share_email]: mailto:?subject=terraform-aws-elasticache-redis&body=https://github.com/cloudposse/terraform-aws-elasticache-redis
[beacon]: https://ga-beacon.cloudposse.com/UA-76589703-4/cloudposse/terraform-aws-elasticache-redis?pixel&cs=github&cm=readme&an=terraform-aws-elasticache-redis
diff --git a/docs/terraform.md b/docs/terraform.md
index 2179026..7fb0a3e 100644
--- a/docs/terraform.md
+++ b/docs/terraform.md
@@ -57,6 +57,7 @@
| [cluster\_mode\_replicas\_per\_node\_group](#input\_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 |
| [cluster\_size](#input\_cluster\_size) | Number of nodes in cluster. *Ignored when `cluster_mode_enabled` == `true`* | `number` | `1` | no |
| [context](#input\_context) | Single object for setting entire context at once.
See description of individual variables for details.
Leave string and numeric variables as `null` to use default value.
Individual variable settings (non-null) override settings in context object,
except for attributes, tags, and additional\_tag\_map, which are merged. | `any` | {
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
| no |
+| [create\_parameter\_group](#input\_create\_parameter\_group) | Whether new parameter group should be created. Set to false if you want to use existing parameter group | `bool` | `true` | no |
| [create\_security\_group](#input\_create\_security\_group) | Set `true` to create and configure a new security group. If false, `associated_security_group_ids` must be provided. | `bool` | `true` | no |
| [data\_tiering\_enabled](#input\_data\_tiering\_enabled) | Enables data tiering. Data tiering is only supported for replication groups using the r6gd node type. | `bool` | `false` | no |
| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
@@ -87,6 +88,7 @@
| [ok\_actions](#input\_ok\_actions) | The list of actions to execute when this alarm transitions into an OK state from any other state. Each action is specified as an Amazon Resource Number (ARN) | `list(string)` | `[]` | no |
| [parameter](#input\_parameter) | A list of Redis parameters to apply. Note that parameters may differ from one Redis family to another | list(object({
name = string
value = string
}))
| `[]` | no |
| [parameter\_group\_description](#input\_parameter\_group\_description) | Managed by Terraform | `string` | `null` | no |
+| [parameter\_group\_name](#input\_parameter\_group\_name) | Override the default parameter group name | `string` | `null` | no |
| [port](#input\_port) | Redis port | `number` | `6379` | no |
| [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| [replication\_group\_id](#input\_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 |
diff --git a/main.tf b/main.tf
index 723ade0..16751c5 100644
--- a/main.tf
+++ b/main.tf
@@ -77,11 +77,24 @@ locals {
var.cluster_size
)
- elasticache_member_clusters = module.this.enabled ? tolist(aws_elasticache_replication_group.default[0].member_clusters) : []
+ elasticache_member_clusters = local.enabled ? tolist(aws_elasticache_replication_group.default[0].member_clusters) : []
+
+ # The name of the parameter group can’t include "."
+ safe_family = replace(var.family, ".", "-")
+
+ parameter_group_name = (
+ var.parameter_group_name != null ? var.parameter_group_name : (
+ var.create_parameter_group
+ ?
+ "${module.this.id}-${local.safe_family}" # The name of the new parameter group to be created
+ :
+ "default.${var.family}" # Default parameter group name created by AWS
+ )
+ )
}
resource "aws_elasticache_subnet_group" "default" {
- count = module.this.enabled && var.elasticache_subnet_group_name == "" && length(var.subnets) > 0 ? 1 : 0
+ count = local.enabled && var.elasticache_subnet_group_name == "" && length(var.subnets) > 0 ? 1 : 0
name = module.this.id
description = "Elasticache subnet group for ${module.this.id}"
subnet_ids = var.subnets
@@ -89,9 +102,9 @@ resource "aws_elasticache_subnet_group" "default" {
}
resource "aws_elasticache_parameter_group" "default" {
- count = module.this.enabled ? 1 : 0
- name = module.this.id
- description = var.parameter_group_description != null ? var.parameter_group_description : "Elasticache parameter group for ${module.this.id}"
+ count = local.enabled && var.create_parameter_group ? 1 : 0
+ name = local.parameter_group_name
+ description = var.parameter_group_description != null ? var.parameter_group_description : "Elasticache parameter group ${local.parameter_group_name}"
family = var.family
dynamic "parameter" {
@@ -104,8 +117,10 @@ resource "aws_elasticache_parameter_group" "default" {
tags = module.this.tags
- # Ignore changes to the description since it will try to recreate the resource
lifecycle {
+ create_before_destroy = true
+
+ # Ignore changes to the description since it will try to recreate the resource
ignore_changes = [
description,
]
@@ -113,7 +128,7 @@ resource "aws_elasticache_parameter_group" "default" {
}
resource "aws_elasticache_replication_group" "default" {
- count = module.this.enabled ? 1 : 0
+ count = local.enabled ? 1 : 0
auth_token = var.transit_encryption_enabled ? var.auth_token : null
replication_group_id = var.replication_group_id == "" ? module.this.id : var.replication_group_id
@@ -121,7 +136,7 @@ resource "aws_elasticache_replication_group" "default" {
node_type = var.instance_type
num_cache_clusters = var.cluster_mode_enabled ? null : var.cluster_size
port = var.port
- parameter_group_name = join("", aws_elasticache_parameter_group.default[*].name)
+ parameter_group_name = local.parameter_group_name
preferred_cache_cluster_azs = length(var.availability_zones) == 0 ? null : [for n in range(0, var.cluster_size) : element(var.availability_zones, n)]
automatic_failover_enabled = var.cluster_mode_enabled ? true : var.automatic_failover_enabled
multi_az_enabled = var.multi_az_enabled
@@ -161,13 +176,17 @@ resource "aws_elasticache_replication_group" "default" {
num_node_groups = var.cluster_mode_enabled ? var.cluster_mode_num_node_groups : null
replicas_per_node_group = var.cluster_mode_enabled ? var.cluster_mode_replicas_per_node_group : null
user_group_ids = var.user_group_ids
+
+ depends_on = [
+ aws_elasticache_parameter_group.default
+ ]
}
#
# CloudWatch Resources
#
resource "aws_cloudwatch_metric_alarm" "cache_cpu" {
- count = module.this.enabled && var.cloudwatch_metric_alarms_enabled ? local.member_clusters_count : 0
+ count = local.enabled && var.cloudwatch_metric_alarms_enabled ? local.member_clusters_count : 0
alarm_name = "${element(local.elasticache_member_clusters, count.index)}-cpu-utilization"
alarm_description = "Redis cluster CPU utilization"
comparison_operator = "GreaterThanThreshold"
@@ -191,7 +210,7 @@ resource "aws_cloudwatch_metric_alarm" "cache_cpu" {
}
resource "aws_cloudwatch_metric_alarm" "cache_memory" {
- count = module.this.enabled && var.cloudwatch_metric_alarms_enabled ? local.member_clusters_count : 0
+ count = local.enabled && var.cloudwatch_metric_alarms_enabled ? local.member_clusters_count : 0
alarm_name = "${element(local.elasticache_member_clusters, count.index)}-freeable-memory"
alarm_description = "Redis cluster freeable memory"
comparison_operator = "LessThanThreshold"
@@ -218,7 +237,7 @@ module "dns" {
source = "cloudposse/route53-cluster-hostname/aws"
version = "0.12.2"
- enabled = module.this.enabled && length(var.zone_id) > 0 ? true : false
+ enabled = local.enabled && length(var.zone_id) > 0 ? true : false
dns_name = var.dns_subdomain != "" ? var.dns_subdomain : module.this.id
ttl = 60
zone_id = try(var.zone_id[0], tostring(var.zone_id), "")
diff --git a/variables.tf b/variables.tf
index a3731c3..aa94519 100644
--- a/variables.tf
+++ b/variables.tf
@@ -225,12 +225,24 @@ variable "cloudwatch_metric_alarms_enabled" {
default = false
}
+variable "create_parameter_group" {
+ type = bool
+ default = true
+ description = "Whether new parameter group should be created. Set to false if you want to use existing parameter group"
+}
+
variable "parameter_group_description" {
type = string
default = null
description = "Managed by Terraform"
}
+variable "parameter_group_name" {
+ type = string
+ default = null
+ description = "Override the default parameter group name"
+}
+
variable "log_delivery_configuration" {
type = list(map(any))
default = []
From 8eb5183fc22fac1b1fce1930640ff4becf828de1 Mon Sep 17 00:00:00 2001
From: Andrew den Hertog
Date: Thu, 14 Dec 2023 13:28:21 -0500
Subject: [PATCH 13/74] chore: bump security group module version (#210)
* chore: bump security group module version
Signed-off-by: Andrew den Hertog
* chore: gen docs
Signed-off-by: Andrew den Hertog
* task: make new vars avaialbe
Signed-off-by: Andrew den Hertog
* chore: run format:
Signed-off-by: Andrew den Hertog
---------
Signed-off-by: Andrew den Hertog
---
.github/renovate.json | 7 +++--
README.md | 8 ++++--
docs/terraform.md | 8 ++++--
main.tf | 9 ++++--
security_group_inputs.tf | 60 ++++++++++++++++++++++++++++++++++++++--
5 files changed, 80 insertions(+), 12 deletions(-)
diff --git a/.github/renovate.json b/.github/renovate.json
index b61ed24..909df09 100644
--- a/.github/renovate.json
+++ b/.github/renovate.json
@@ -1,13 +1,14 @@
{
"extends": [
"config:base",
- ":preserveSemverRanges"
+ ":preserveSemverRanges",
+ ":rebaseStalePrs"
],
- "baseBranches": ["main", "master", "/^release\\/v\\d{1,2}$/"],
+ "baseBranches": ["main"],
"labels": ["auto-update"],
"dependencyDashboardAutoclose": true,
"enabledManagers": ["terraform"],
"terraform": {
- "ignorePaths": ["**/context.tf", "examples/**"]
+ "ignorePaths": ["**/context.tf"]
}
}
diff --git a/README.md b/README.md
index c73b112..e8ac716 100644
--- a/README.md
+++ b/README.md
@@ -198,7 +198,7 @@ Available targets:
| Name | Source | Version |
|------|--------|---------|
-| [aws\_security\_group](#module\_aws\_security\_group) | cloudposse/security-group/aws | 1.0.1 |
+| [aws\_security\_group](#module\_aws\_security\_group) | cloudposse/security-group/aws | 2.2.0 |
| [dns](#module\_dns) | cloudposse/route53-cluster-hostname/aws | 0.12.2 |
| [this](#module\_this) | cloudposse/label/null | 0.25.0 |
@@ -255,6 +255,7 @@ Available targets:
| [family](#input\_family) | Redis family | `string` | `"redis4.0"` | no |
| [final\_snapshot\_identifier](#input\_final\_snapshot\_identifier) | The name of your final node group (shard) snapshot. ElastiCache creates the snapshot from the primary node in the cluster. If omitted, no final snapshot will be made. | `string` | `null` | no |
| [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for keep the existing setting, which defaults to `0`.
Does not affect `id_full`. | `number` | `null` | no |
+| [inline\_rules\_enabled](#input\_inline\_rules\_enabled) | NOT RECOMMENDED. Create rules "inline" instead of as separate `aws_security_group_rule` resources.
See [#20046](https://github.com/hashicorp/terraform-provider-aws/issues/20046) for one of several issues with inline rules.
See [this post](https://github.com/hashicorp/terraform-provider-aws/pull/9032#issuecomment-639545250) for details on the difference between inline rules and rule resources. | `bool` | `false` | no |
| [instance\_type](#input\_instance\_type) | Elastic cache instance type | `string` | `"cache.t2.micro"` | no |
| [kms\_key\_id](#input\_kms\_key\_id) | The ARN of the key that you wish to use if encrypting at rest. If not supplied, uses service managed encryption. `at_rest_encryption_enabled` must be set to `true` | `string` | `null` | no |
| [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
Does not affect keys of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `null` | no |
@@ -272,13 +273,15 @@ Available targets:
| [parameter\_group\_description](#input\_parameter\_group\_description) | Managed by Terraform | `string` | `null` | no |
| [parameter\_group\_name](#input\_parameter\_group\_name) | Override the default parameter group name | `string` | `null` | no |
| [port](#input\_port) | Redis port | `number` | `6379` | no |
+| [preserve\_security\_group\_id](#input\_preserve\_security\_group\_id) | When `false` and `create_before_destroy` is `true`, changes to security group rules
cause a new security group to be created with the new rules, and the existing security group is then
replaced with the new one, eliminating any service interruption.
When `true` or when changing the value (from `false` to `true` or from `true` to `false`),
existing security group rules will be deleted before new ones are created, resulting in a service interruption,
but preserving the security group itself.
**NOTE:** Setting this to `true` does not guarantee the security group will never be replaced,
it only keeps changes to the security group rules from triggering a replacement.
See the README for further discussion. | `bool` | `false` | no |
| [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| [replication\_group\_id](#input\_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 |
+| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Group's attached ingress and egress rules before deleting
the security group itself. This is normally not needed. | `bool` | `false` | no |
| [security\_group\_create\_before\_destroy](#input\_security\_group\_create\_before\_destroy) | Set `true` to enable Terraform `create_before_destroy` behavior on the created security group.
We only recommend setting this `false` if you are upgrading this module and need to keep
the existing security group from being replaced.
Note that changing this value will always cause the security group to be replaced. | `bool` | `true` | no |
| [security\_group\_create\_timeout](#input\_security\_group\_create\_timeout) | How long to wait for the security group to be created. | `string` | `"10m"` | no |
| [security\_group\_delete\_timeout](#input\_security\_group\_delete\_timeout) | How long to retry on `DependencyViolation` errors during security group deletion. | `string` | `"15m"` | no |
| [security\_group\_description](#input\_security\_group\_description) | The description to assign to the created Security Group.
Warning: Changing the description causes the security group to be replaced.
Set this to `null` to maintain parity with releases <= `0.34.0`. | `string` | `"Security group for Elasticache Redis"` | no |
-| [security\_group\_name](#input\_security\_group\_name) | The name to assign to the created security group. Must be unique within the VPC.
If not provided, will be derived from the `null-label.context` passed in.
If `create_before_destroy` is true, will be used as a name prefix. | `list(string)` | `[]` | no |
+| [security\_group\_name](#input\_security\_group\_name) | The name to assign to the security group. Must be unique within the VPC.
If not provided, will be derived from the `null-label.context` passed in.
If `create_before_destroy` is true, will be used as a name prefix. | `list(string)` | `[]` | no |
| [snapshot\_arns](#input\_snapshot\_arns) | A single-element string list containing an Amazon Resource Name (ARN) of a Redis RDB snapshot file stored in Amazon S3. Example: arn:aws:s3:::my\_bucket/snapshot1.rdb | `list(string)` | `[]` | no |
| [snapshot\_name](#input\_snapshot\_name) | The name of a snapshot from which to restore data into the new node group. Changing the snapshot\_name forces a new resource. | `string` | `null` | no |
| [snapshot\_retention\_limit](#input\_snapshot\_retention\_limit) | The number of days for which ElastiCache will retain automatic cache cluster snapshots before deleting them. | `number` | `0` | no |
@@ -286,6 +289,7 @@ Available targets:
| [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| [subnets](#input\_subnets) | Subnet IDs | `list(string)` | `[]` | no |
| [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no |
+| [target\_security\_group\_id](#input\_target\_security\_group\_id) | The ID of an existing Security Group to which Security Group rules will be assigned.
The Security Group's name and description will not be changed.
Not compatible with `inline_rules_enabled` or `revoke_rules_on_delete`.
If not provided (the default), this module will create a security group. | `list(string)` | `[]` | no |
| [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no |
| [transit\_encryption\_enabled](#input\_transit\_encryption\_enabled) | Set `true` to enable encryption in transit. Forced `true` if `var.auth_token` is set.
If this is enabled, use the [following guide](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/in-transit-encryption.html#connect-tls) to access redis. | `bool` | `true` | no |
| [use\_existing\_security\_groups](#input\_use\_existing\_security\_groups) | DEPRECATED: Use `create_security_group` instead.
Historical description: 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.
Historical default: `false` | `bool` | `null` | no |
diff --git a/docs/terraform.md b/docs/terraform.md
index 7fb0a3e..2bdf23e 100644
--- a/docs/terraform.md
+++ b/docs/terraform.md
@@ -16,7 +16,7 @@
| Name | Source | Version |
|------|--------|---------|
-| [aws\_security\_group](#module\_aws\_security\_group) | cloudposse/security-group/aws | 1.0.1 |
+| [aws\_security\_group](#module\_aws\_security\_group) | cloudposse/security-group/aws | 2.2.0 |
| [dns](#module\_dns) | cloudposse/route53-cluster-hostname/aws | 0.12.2 |
| [this](#module\_this) | cloudposse/label/null | 0.25.0 |
@@ -73,6 +73,7 @@
| [family](#input\_family) | Redis family | `string` | `"redis4.0"` | no |
| [final\_snapshot\_identifier](#input\_final\_snapshot\_identifier) | The name of your final node group (shard) snapshot. ElastiCache creates the snapshot from the primary node in the cluster. If omitted, no final snapshot will be made. | `string` | `null` | no |
| [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for keep the existing setting, which defaults to `0`.
Does not affect `id_full`. | `number` | `null` | no |
+| [inline\_rules\_enabled](#input\_inline\_rules\_enabled) | NOT RECOMMENDED. Create rules "inline" instead of as separate `aws_security_group_rule` resources.
See [#20046](https://github.com/hashicorp/terraform-provider-aws/issues/20046) for one of several issues with inline rules.
See [this post](https://github.com/hashicorp/terraform-provider-aws/pull/9032#issuecomment-639545250) for details on the difference between inline rules and rule resources. | `bool` | `false` | no |
| [instance\_type](#input\_instance\_type) | Elastic cache instance type | `string` | `"cache.t2.micro"` | no |
| [kms\_key\_id](#input\_kms\_key\_id) | The ARN of the key that you wish to use if encrypting at rest. If not supplied, uses service managed encryption. `at_rest_encryption_enabled` must be set to `true` | `string` | `null` | no |
| [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.
Does not affect keys of tags passed in via the `tags` input.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `null` | no |
@@ -90,13 +91,15 @@
| [parameter\_group\_description](#input\_parameter\_group\_description) | Managed by Terraform | `string` | `null` | no |
| [parameter\_group\_name](#input\_parameter\_group\_name) | Override the default parameter group name | `string` | `null` | no |
| [port](#input\_port) | Redis port | `number` | `6379` | no |
+| [preserve\_security\_group\_id](#input\_preserve\_security\_group\_id) | When `false` and `create_before_destroy` is `true`, changes to security group rules
cause a new security group to be created with the new rules, and the existing security group is then
replaced with the new one, eliminating any service interruption.
When `true` or when changing the value (from `false` to `true` or from `true` to `false`),
existing security group rules will be deleted before new ones are created, resulting in a service interruption,
but preserving the security group itself.
**NOTE:** Setting this to `true` does not guarantee the security group will never be replaced,
it only keeps changes to the security group rules from triggering a replacement.
See the README for further discussion. | `bool` | `false` | no |
| [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.
Characters matching the regex will be removed from the ID elements.
If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| [replication\_group\_id](#input\_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 |
+| [revoke\_rules\_on\_delete](#input\_revoke\_rules\_on\_delete) | Instruct Terraform to revoke all of the Security Group's attached ingress and egress rules before deleting
the security group itself. This is normally not needed. | `bool` | `false` | no |
| [security\_group\_create\_before\_destroy](#input\_security\_group\_create\_before\_destroy) | Set `true` to enable Terraform `create_before_destroy` behavior on the created security group.
We only recommend setting this `false` if you are upgrading this module and need to keep
the existing security group from being replaced.
Note that changing this value will always cause the security group to be replaced. | `bool` | `true` | no |
| [security\_group\_create\_timeout](#input\_security\_group\_create\_timeout) | How long to wait for the security group to be created. | `string` | `"10m"` | no |
| [security\_group\_delete\_timeout](#input\_security\_group\_delete\_timeout) | How long to retry on `DependencyViolation` errors during security group deletion. | `string` | `"15m"` | no |
| [security\_group\_description](#input\_security\_group\_description) | The description to assign to the created Security Group.
Warning: Changing the description causes the security group to be replaced.
Set this to `null` to maintain parity with releases <= `0.34.0`. | `string` | `"Security group for Elasticache Redis"` | no |
-| [security\_group\_name](#input\_security\_group\_name) | The name to assign to the created security group. Must be unique within the VPC.
If not provided, will be derived from the `null-label.context` passed in.
If `create_before_destroy` is true, will be used as a name prefix. | `list(string)` | `[]` | no |
+| [security\_group\_name](#input\_security\_group\_name) | The name to assign to the security group. Must be unique within the VPC.
If not provided, will be derived from the `null-label.context` passed in.
If `create_before_destroy` is true, will be used as a name prefix. | `list(string)` | `[]` | no |
| [snapshot\_arns](#input\_snapshot\_arns) | A single-element string list containing an Amazon Resource Name (ARN) of a Redis RDB snapshot file stored in Amazon S3. Example: arn:aws:s3:::my\_bucket/snapshot1.rdb | `list(string)` | `[]` | no |
| [snapshot\_name](#input\_snapshot\_name) | The name of a snapshot from which to restore data into the new node group. Changing the snapshot\_name forces a new resource. | `string` | `null` | no |
| [snapshot\_retention\_limit](#input\_snapshot\_retention\_limit) | The number of days for which ElastiCache will retain automatic cache cluster snapshots before deleting them. | `number` | `0` | no |
@@ -104,6 +107,7 @@
| [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| [subnets](#input\_subnets) | Subnet IDs | `list(string)` | `[]` | no |
| [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).
Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no |
+| [target\_security\_group\_id](#input\_target\_security\_group\_id) | The ID of an existing Security Group to which Security Group rules will be assigned.
The Security Group's name and description will not be changed.
Not compatible with `inline_rules_enabled` or `revoke_rules_on_delete`.
If not provided (the default), this module will create a security group. | `list(string)` | `[]` | no |
| [tenant](#input\_tenant) | ID element \_(Rarely used, not included by default)\_. A customer identifier, indicating who this instance of a resource is for | `string` | `null` | no |
| [transit\_encryption\_enabled](#input\_transit\_encryption\_enabled) | Set `true` to enable encryption in transit. Forced `true` if `var.auth_token` is set.
If this is enabled, use the [following guide](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/in-transit-encryption.html#connect-tls) to access redis. | `bool` | `true` | no |
| [use\_existing\_security\_groups](#input\_use\_existing\_security\_groups) | DEPRECATED: Use `create_security_group` instead.
Historical description: 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.
Historical default: `false` | `bool` | `null` | no |
diff --git a/main.tf b/main.tf
index 16751c5..7eed8e6 100644
--- a/main.tf
+++ b/main.tf
@@ -32,10 +32,12 @@ locals {
module "aws_security_group" {
source = "cloudposse/security-group/aws"
- version = "1.0.1"
+ version = "2.2.0"
enabled = local.create_security_group
+ target_security_group_id = var.target_security_group_id
+
allow_all_egress = local.allow_all_egress
security_group_name = var.security_group_name
rules_map = local.sg_rules
@@ -57,7 +59,10 @@ module "aws_security_group" {
security_group_description = local.security_group_description
- create_before_destroy = var.security_group_create_before_destroy
+ create_before_destroy = var.security_group_create_before_destroy
+ preserve_security_group_id = var.preserve_security_group_id
+ inline_rules_enabled = var.inline_rules_enabled
+ revoke_rules_on_delete = var.revoke_rules_on_delete
security_group_create_timeout = var.security_group_create_timeout
security_group_delete_timeout = var.security_group_delete_timeout
diff --git a/security_group_inputs.tf b/security_group_inputs.tf
index 5958bad..ed02ac8 100644
--- a/security_group_inputs.tf
+++ b/security_group_inputs.tf
@@ -37,15 +37,18 @@ locals {
allowed_security_group_ids = concat(var.allowed_security_groups, var.allowed_security_group_ids)
}
-
variable "security_group_name" {
type = list(string)
- default = []
description = <<-EOT
- The name to assign to the created security group. Must be unique within the VPC.
+ The name to assign to the security group. Must be unique within the VPC.
If not provided, will be derived from the `null-label.context` passed in.
If `create_before_destroy` is true, will be used as a name prefix.
EOT
+ default = []
+ validation {
+ condition = length(var.security_group_name) < 2
+ error_message = "Only 1 security group name can be provided."
+ }
}
variable "security_group_description" {
@@ -110,3 +113,54 @@ variable "additional_security_group_rules" {
To get more info see https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule .
EOT
}
+
+# Security Group Inputs (v2)
+variable "target_security_group_id" {
+ type = list(string)
+ description = <<-EOT
+ The ID of an existing Security Group to which Security Group rules will be assigned.
+ The Security Group's name and description will not be changed.
+ Not compatible with `inline_rules_enabled` or `revoke_rules_on_delete`.
+ If not provided (the default), this module will create a security group.
+ EOT
+ default = []
+ validation {
+ condition = length(var.target_security_group_id) < 2
+ error_message = "Only 1 security group can be targeted."
+ }
+}
+
+variable "preserve_security_group_id" {
+ type = bool
+ description = <<-EOT
+ When `false` and `create_before_destroy` is `true`, changes to security group rules
+ cause a new security group to be created with the new rules, and the existing security group is then
+ replaced with the new one, eliminating any service interruption.
+ When `true` or when changing the value (from `false` to `true` or from `true` to `false`),
+ existing security group rules will be deleted before new ones are created, resulting in a service interruption,
+ but preserving the security group itself.
+ **NOTE:** Setting this to `true` does not guarantee the security group will never be replaced,
+ it only keeps changes to the security group rules from triggering a replacement.
+ See the README for further discussion.
+ EOT
+ default = false
+}
+
+variable "revoke_rules_on_delete" {
+ type = bool
+ description = <<-EOT
+ Instruct Terraform to revoke all of the Security Group's attached ingress and egress rules before deleting
+ the security group itself. This is normally not needed.
+ EOT
+ default = false
+}
+
+variable "inline_rules_enabled" {
+ type = bool
+ description = <<-EOT
+ NOT RECOMMENDED. Create rules "inline" instead of as separate `aws_security_group_rule` resources.
+ See [#20046](https://github.com/hashicorp/terraform-provider-aws/issues/20046) for one of several issues with inline rules.
+ See [this post](https://github.com/hashicorp/terraform-provider-aws/pull/9032#issuecomment-639545250) for details on the difference between inline rules and rule resources.
+ EOT
+ default = false
+}
From b7c841a0597412faaeaed1d0b06c28ef99828f98 Mon Sep 17 00:00:00 2001
From: Kamil Grabowski
Date: Thu, 21 Dec 2023 18:58:41 +0100
Subject: [PATCH 14/74] bugfix: import existing replication groups (#217)
---
main.tf | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/main.tf b/main.tf
index 7eed8e6..77d1fbd 100644
--- a/main.tf
+++ b/main.tf
@@ -182,6 +182,15 @@ resource "aws_elasticache_replication_group" "default" {
replicas_per_node_group = var.cluster_mode_enabled ? var.cluster_mode_replicas_per_node_group : null
user_group_ids = var.user_group_ids
+ # When importing an aws_elasticache_replication_group resource the attribute
+ # security_group_names is imported as null. More details:
+ # https://github.com/hashicorp/terraform-provider-aws/issues/32835
+ lifecycle {
+ ignore_changes = [
+ security_group_names,
+ ]
+ }
+
depends_on = [
aws_elasticache_parameter_group.default
]
From a49c8e6cc683000bdf39abc5268e6dc939258e21 Mon Sep 17 00:00:00 2001
From: Steve Louie <45601615+Steve-Louie-Bose@users.noreply.github.com>
Date: Thu, 22 Feb 2024 13:06:30 -0500
Subject: [PATCH 15/74] fix: remove transit_encryption != null, auth_token
rotation support (#195)
* fix: remove transit_encryption != null, auth_token rotation support
* docs: readme updated via makefile
---
README.md | 148 ++++++++++++++++++++++++++----------------------------
main.tf | 2 +-
2 files changed, 71 insertions(+), 79 deletions(-)
diff --git a/README.md b/README.md
index e8ac716..24e3693 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,8 @@
-
-# terraform-aws-elasticache-redis [](https://github.com/cloudposse/terraform-aws-elasticache-redis/releases/latest) [](https://slack.cloudposse.com)
+# terraform-aws-elasticache-redis
+
-[![README Header][readme_header_img]][readme_header_link]
-
-[![Cloud Posse][logo]](https://cpco.io/homepage)
-
- [logo]: https://cloudposse.com/logo-300x69.svg
- [docs]: https://cpco.io/docs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=docs
- [website]: https://cpco.io/homepage?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=website
- [github]: https://cpco.io/github?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=github
- [jobs]: https://cpco.io/jobs?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=jobs
- [hire]: https://cpco.io/hire?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=hire
- [slack]: https://cpco.io/slack?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=slack
- [twitter]: https://cpco.io/twitter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=twitter
- [office_hours]: https://cloudposse.com/office-hours?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=office_hours
- [newsletter]: https://cpco.io/newsletter?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=newsletter
- [email]: https://cpco.io/email?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=email
- [commercial_support]: https://cpco.io/commercial-support?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=commercial_support
- [we_love_open_source]: https://cpco.io/we-love-open-source?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=we_love_open_source
- [terraform_modules]: https://cpco.io/terraform-modules?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=terraform_modules
- [readme_header_img]: https://cloudposse.com/readme/header/img
- [readme_header_link]: https://cloudposse.com/readme/header/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=readme_header_link
- [readme_footer_img]: https://cloudposse.com/readme/footer/img
- [readme_footer_link]: https://cloudposse.com/readme/footer/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=readme_footer_link
- [readme_commercial_support_img]: https://cloudposse.com/readme/commercial-support/img
- [readme_commercial_support_link]: https://cloudposse.com/readme/commercial-support/link?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=readme_commercial_support_link
- [beacon]: https://ga-beacon.cloudposse.com/UA-76589703-4/cloudposse/terraform-aws-elasticache-redis?pixel&cs=github&cm=readme&an=terraform-aws-elasticache-redis
-
+Copyright © 2017-2024 [Cloud Posse, LLC](https://cpco.io/copyright)
+
+
+
+
+
diff --git a/main.tf b/main.tf
index 77d1fbd..c003993 100644
--- a/main.tf
+++ b/main.tf
@@ -154,7 +154,7 @@ resource "aws_elasticache_replication_group" "default" {
notification_topic_arn = var.notification_topic_arn
engine_version = var.engine_version
at_rest_encryption_enabled = var.at_rest_encryption_enabled
- transit_encryption_enabled = var.transit_encryption_enabled || var.auth_token != null
+ transit_encryption_enabled = var.transit_encryption_enabled
kms_key_id = var.at_rest_encryption_enabled ? var.kms_key_id : null
snapshot_name = var.snapshot_name
snapshot_arns = var.snapshot_arns
From 7aa5ed00e94797f970058d993d62279250cc8639 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sat, 2 Mar 2024 18:29:09 +0100
Subject: [PATCH 16/74] chore(deps): update terraform
cloudposse/dynamic-subnets/aws to v2.4.1 (#216)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
examples/complete/main.tf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/complete/main.tf b/examples/complete/main.tf
index 5f453a4..9c1304d 100644
--- a/examples/complete/main.tf
+++ b/examples/complete/main.tf
@@ -13,7 +13,7 @@ module "vpc" {
module "subnets" {
source = "cloudposse/dynamic-subnets/aws"
- version = "2.3.0"
+ version = "2.4.1"
availability_zones = var.availability_zones
vpc_id = module.vpc.vpc_id
From 747b47cc2ebb1a8c69a944657a9d7f4fd301435d Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sat, 2 Mar 2024 19:43:38 +0000
Subject: [PATCH 17/74] chore(deps): update terraform
cloudposse/route53-cluster-hostname/aws to v0.13.0 (#219)
* chore(deps): update terraform cloudposse/route53-cluster-hostname/aws to v0.13.0
* Auto-update README.md
---------
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot]
---
README.md | 2 +-
docs/terraform.md | 2 +-
main.tf | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 24e3693..c1429d3 100644
--- a/README.md
+++ b/README.md
@@ -196,7 +196,7 @@ Available targets:
| Name | Source | Version |
|------|--------|---------|
| [aws\_security\_group](#module\_aws\_security\_group) | cloudposse/security-group/aws | 2.2.0 |
-| [dns](#module\_dns) | cloudposse/route53-cluster-hostname/aws | 0.12.2 |
+| [dns](#module\_dns) | cloudposse/route53-cluster-hostname/aws | 0.13.0 |
| [this](#module\_this) | cloudposse/label/null | 0.25.0 |
## Resources
diff --git a/docs/terraform.md b/docs/terraform.md
index 2bdf23e..452e4fe 100644
--- a/docs/terraform.md
+++ b/docs/terraform.md
@@ -17,7 +17,7 @@
| Name | Source | Version |
|------|--------|---------|
| [aws\_security\_group](#module\_aws\_security\_group) | cloudposse/security-group/aws | 2.2.0 |
-| [dns](#module\_dns) | cloudposse/route53-cluster-hostname/aws | 0.12.2 |
+| [dns](#module\_dns) | cloudposse/route53-cluster-hostname/aws | 0.13.0 |
| [this](#module\_this) | cloudposse/label/null | 0.25.0 |
## Resources
diff --git a/main.tf b/main.tf
index c003993..d3c532d 100644
--- a/main.tf
+++ b/main.tf
@@ -249,7 +249,7 @@ resource "aws_cloudwatch_metric_alarm" "cache_memory" {
module "dns" {
source = "cloudposse/route53-cluster-hostname/aws"
- version = "0.12.2"
+ version = "0.13.0"
enabled = local.enabled && length(var.zone_id) > 0 ? true : false
dns_name = var.dns_subdomain != "" ? var.dns_subdomain : module.this.id
From f3c13e7277a3438f882f0792f4d05bf208b07436 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sat, 2 Mar 2024 12:08:35 -0800
Subject: [PATCH 18/74] chore(deps): update terraform cloudposse/vpc/aws to
v2.1.1 (#215)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
examples/complete/main.tf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/complete/main.tf b/examples/complete/main.tf
index 9c1304d..68ef8e3 100644
--- a/examples/complete/main.tf
+++ b/examples/complete/main.tf
@@ -4,7 +4,7 @@ provider "aws" {
module "vpc" {
source = "cloudposse/vpc/aws"
- version = "2.1.0"
+ version = "2.1.1"
ipv4_primary_cidr_block = "172.16.0.0/16"
From 5005fd042a2af6ebdb9f844ce18bff6c7fb68ac7 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sat, 2 Mar 2024 15:31:07 -0800
Subject: [PATCH 19/74] chore(deps): update terraform
cloudposse/cloudwatch-logs/aws to v0.6.8 (#214)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
examples/complete/main.tf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/complete/main.tf b/examples/complete/main.tf
index 68ef8e3..8ff1965 100644
--- a/examples/complete/main.tf
+++ b/examples/complete/main.tf
@@ -36,7 +36,7 @@ resource "aws_route53_zone" "private" {
module "cloudwatch_logs" {
source = "cloudposse/cloudwatch-logs/aws"
- version = "0.6.5"
+ version = "0.6.8"
context = module.this.context
}
From be3c74a39e042fb2d3af2d69ca438c9fe92c83bd Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 4 Mar 2024 11:35:15 -0800
Subject: [PATCH 20/74] chore(deps): update terraform cloudposse/vpc/aws to
v2.2.0 (#220)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
examples/complete/main.tf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/complete/main.tf b/examples/complete/main.tf
index 8ff1965..c2d8f4b 100644
--- a/examples/complete/main.tf
+++ b/examples/complete/main.tf
@@ -4,7 +4,7 @@ provider "aws" {
module "vpc" {
source = "cloudposse/vpc/aws"
- version = "2.1.1"
+ version = "2.2.0"
ipv4_primary_cidr_block = "172.16.0.0/16"
From 80f713407da21edad31e83786d1a49965a37c64c Mon Sep 17 00:00:00 2001
From: "Erik Osterman (CEO @ Cloud Posse)"
Date: Fri, 8 Mar 2024 22:15:06 -0600
Subject: [PATCH 21/74] chore: Update Scaffolding (#223)
---
.github/mergify.yml | 77 +------------------------
README.md | 135 ++++++++++++++++++++++----------------------
README.yaml | 32 ++++-------
3 files changed, 78 insertions(+), 166 deletions(-)
diff --git a/.github/mergify.yml b/.github/mergify.yml
index 148d85c..526045d 100644
--- a/.github/mergify.yml
+++ b/.github/mergify.yml
@@ -1,76 +1 @@
-# https://docs.mergify.io/conditions.html
-# https://docs.mergify.io/actions.html
-pull_request_rules:
-- name: "approve automated PRs that have passed checks"
- conditions:
- - "author~=^(cloudpossebot|renovate\\[bot\\])$"
- - "-closed"
- - "head~=^(auto-update|renovate)/.*"
- - "check-success=test/bats"
- - "check-success=test/readme"
- - "check-success=test/terratest"
- - "check-success=validate-codeowners"
- - or:
- - "base=master"
- - "base=main"
- - "base~=^release/v\\d{1,2}$"
-
- actions:
- review:
- type: "APPROVE"
- bot_account: "cloudposse-mergebot"
- message: "We've automatically approved this PR because the checks from the automated Pull Request have passed."
-
-- name: "merge automated PRs when approved and tests pass"
- conditions:
- - "author~=^(cloudpossebot|renovate\\[bot\\])$"
- - "-closed"
- - "head~=^(auto-update|renovate)/.*"
- - "check-success=test/bats"
- - "check-success=test/readme"
- - "check-success=test/terratest"
- - "check-success=validate-codeowners"
- - "#approved-reviews-by>=1"
- - "#changes-requested-reviews-by=0"
- - "#commented-reviews-by=0"
- - or:
- - "base=master"
- - "base=main"
- - "base~=^release/v\\d{1,2}$"
-
- actions:
- merge:
- method: "squash"
-
-- name: "delete the head branch after merge"
- conditions:
- - "merged"
- actions:
- delete_head_branch: {}
-
-- name: "ask to resolve conflict"
- conditions:
- - "conflict"
- - "-closed"
- actions:
- comment:
- message: "This pull request is now in conflict. Could you fix it @{{author}}? 🙏"
-
-- name: "remove outdated reviews"
- conditions:
- - or:
- - "base=master"
- - "base=main"
- - "base~=^release/v\\d{1,2}$"
- actions:
- dismiss_reviews:
- changes_requested: true
- approved: true
- message: "This Pull Request has been updated, so we're dismissing all reviews."
-
-- name: "close Pull Requests without files changed"
- conditions:
- - "#files=0"
- actions:
- close:
- message: "This pull request has been automatically closed by Mergify because there are no longer any changes."
+extends: .github
diff --git a/README.md b/README.md
index c1429d3..5660f97 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
+
+
# terraform-aws-elasticache-redis
-
+

## Makefile Targets
```text
@@ -319,23 +311,60 @@ Check out these related projects.
- [terraform-aws-security-group](https://github.com/cloudposse/terraform-aws-security-group) - Terraform module to provision an AWS Security Group.
- [terraform-null-label](https://github.com/cloudposse/terraform-null-label) - Terraform module designed to generate consistent names and tags for resources. Use terraform-null-label to implement a strict naming convention.
+
+> [!TIP]
+> #### Use Terraform Reference Architectures for AWS
+>
+> Use Cloud Posse's ready-to-go [terraform architecture blueprints](https://cloudposse.com/reference-architecture/) for AWS to get up and running quickly.
+>
+> ✅ We build it with you.
+> ✅ You own everything.
+> ✅ Your team wins.
+>
+>
+> 📚 Learn More
+>
+>
+>
+> Cloud Posse is the leading [**DevOps Accelerator**](https://cpco.io/commercial-support?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=commercial_support) for funded startups and enterprises.
+>
+> *Your team can operate like a pro today.*
+>
+> Ensure that your team succeeds by using Cloud Posse's proven process and turnkey blueprints. Plus, we stick around until you succeed.
+> #### Day-0: Your Foundation for Success
+> - **Reference Architecture.** You'll get everything you need from the ground up built using 100% infrastructure as code.
+> - **Deployment Strategy.** Adopt a proven deployment strategy with GitHub Actions, enabling automated, repeatable, and reliable software releases.
+> - **Site Reliability Engineering.** Gain total visibility into your applications and services with Datadog, ensuring high availability and performance.
+> - **Security Baseline.** Establish a secure environment from the start, with built-in governance, accountability, and comprehensive audit logs, safeguarding your operations.
+> - **GitOps.** Empower your team to manage infrastructure changes confidently and efficiently through Pull Requests, leveraging the full power of GitHub Actions.
+>
+>
+>
+> #### Day-2: Your Operational Mastery
+> - **Training.** Equip your team with the knowledge and skills to confidently manage the infrastructure, ensuring long-term success and self-sufficiency.
+> - **Support.** Benefit from a seamless communication over Slack with our experts, ensuring you have the support you need, whenever you need it.
+> - **Troubleshooting.** Access expert assistance to quickly resolve any operational challenges, minimizing downtime and maintaining business continuity.
+> - **Code Reviews.** Enhance your team’s code quality with our expert feedback, fostering continuous improvement and collaboration.
+> - **Bug Fixes.** Rely on our team to troubleshoot and resolve any issues, ensuring your systems run smoothly.
+> - **Migration Assistance.** Accelerate your migration process with our dedicated support, minimizing disruption and speeding up time-to-value.
+> - **Customer Workshops.** Engage with our team in weekly workshops, gaining insights and strategies to continuously improve and innovate.
+>
+>
+>
+
## ✨ Contributing
This project is under active development, and we encourage contributions from our community.
+
+
+
Many thanks to our outstanding contributors:
-### 🐛 Bug Reports & Feature Requests
-
-Please use the [issue tracker](https://github.com/cloudposse/terraform-aws-elasticache-redis/issues) to report any bugs or file feature requests.
-
-### 💻 Developing
-
-If you are interested in being a contributor and want to get involved in developing this project or help out with Cloud Posse's other projects, we would love to hear from you!
-Hit us up in [Slack](https://cpco.io/slack?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=slack), in the `#cloudposse` channel.
+For 🐛 bug reports & feature requests, please use the [issue tracker](https://github.com/cloudposse/terraform-aws-elasticache-redis/issues).
In general, PRs are welcome. We follow the typical "fork-and-pull" Git workflow.
1. Review our [Code of Conduct](https://github.com/cloudposse/terraform-aws-elasticache-redis/?tab=coc-ov-file#code-of-conduct) and [Contributor Guidelines](https://github.com/cloudposse/.github/blob/main/CONTRIBUTING.md).
@@ -360,38 +389,6 @@ Dropped straight into your Inbox every week — and usually a 5-minute read.
[Join us every Wednesday via Zoom](https://cloudposse.com/office-hours?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=office_hours) for your weekly dose of insider DevOps trends, AWS news and Terraform insights, all sourced from our SweetOps community, plus a _live Q&A_ that you can’t find anywhere else.
It's **FREE** for everyone!
-
-## About
-
-This project is maintained by Cloud Posse, LLC.
-
-
-We are a [**DevOps Accelerator**](https://cpco.io/commercial-support?utm_source=github&utm_medium=readme&utm_campaign=cloudposse/terraform-aws-elasticache-redis&utm_content=commercial_support) for funded startups and enterprises.
-Use our ready-to-go terraform architecture blueprints for AWS to get up and running quickly.
-We build it with you. You own everything. Your team wins. Plus, we stick around until you succeed.
-
-
-
-*Your team can operate like a pro today.*
-
-Ensure that your team succeeds by using our proven process and turnkey blueprints. Plus, we stick around until you succeed.
-
-
- 📚 See What's Included
-
-- **Reference Architecture.** You'll get everything you need from the ground up built using 100% infrastructure as code.
-- **Deployment Strategy.** You'll have a battle-tested deployment strategy using GitHub Actions that's automated and repeatable.
-- **Site Reliability Engineering.** You'll have total visibility into your apps and microservices.
-- **Security Baseline.** You'll have built-in governance with accountability and audit logs for all changes.
-- **GitOps.** You'll be able to operate your infrastructure via Pull Requests.
-- **Training.** You'll receive hands-on training so your team can operate what we build.
-- **Questions.** You'll have a direct line of communication between our teams via a Shared Slack channel.
-- **Troubleshooting.** You'll get help to triage when things aren't working.
-- **Code Reviews.** You'll receive constructive feedback on Pull Requests.
-- **Bug Fixes.** We'll rapidly work with you to fix any bugs in our projects.
-
-
-
## License
@@ -426,6 +423,8 @@ under the License.
## Trademarks
All other trademarks referenced herein are the property of their respective owners.
+
+
---
Copyright © 2017-2024 [Cloud Posse, LLC](https://cpco.io/copyright)
diff --git a/README.yaml b/README.yaml
index 9004b13..0a3b40d 100644
--- a/README.yaml
+++ b/README.yaml
@@ -1,4 +1,3 @@
----
#
# This is the canonical configuration for the `README.md`
# Run `make readme` to rebuild the `README.md`
@@ -31,12 +30,15 @@ github_repo: cloudposse/terraform-aws-elasticache-redis
# Badges to display
badges:
- - name: "Latest Release"
- image: "https://img.shields.io/github/release/cloudposse/terraform-aws-elasticache-redis.svg"
- url: "https://github.com/cloudposse/terraform-aws-elasticache-redis/releases/latest"
- - name: "Slack Community"
- image: "https://slack.cloudposse.com/badge.svg"
- url: "https://slack.cloudposse.com"
+ - name: Latest Release
+ image: https://img.shields.io/github/release/cloudposse/terraform-aws-elasticache-redis.svg?style=for-the-badge
+ url: https://github.com/cloudposse/terraform-aws-elasticache-redis/releases/latest
+ - name: Last Updated
+ image: https://img.shields.io/github/last-commit/cloudposse/terraform-aws-elasticache-redis.svg?style=for-the-badge
+ url: https://github.com/cloudposse/terraform-aws-elasticache-redis/commits
+ - name: Slack Community
+ image: https://slack.cloudposse.com/for-the-badge.svg
+ url: https://slack.cloudposse.com
# List any related terraform modules that this module may be used with or that this module depends on.
related:
@@ -159,18 +161,4 @@ include:
- "docs/terraform.md"
# Contributors to this project
-contributors:
- - name: "Erik Osterman"
- github: "osterman"
- - name: "Igor Rodionov"
- github: "goruha"
- - name: "Andriy Knysh"
- github: "aknysh"
- - name: "Daren Desjardins"
- github: "darend"
- - name: "Max Moon"
- github: "MoonMoon1919"
- - name: "Christopher Riley"
- github: "christopherriley"
- - name: "RB"
- github: "nitrocode"
+contributors: []
From be39ceb0f748d43e91731fa36644361d52cf7fac Mon Sep 17 00:00:00 2001
From: "Cloud Posse Bot (CI/CD)"
Date: Fri, 8 Mar 2024 20:17:02 -0800
Subject: [PATCH 22/74] Update README.md and docs (#222)
Co-authored-by: max-lobur
From 9bda18c185530fe60e0d588fbebda43af7f53487 Mon Sep 17 00:00:00 2001
From: "Erik Osterman (CEO @ Cloud Posse)"
Date: Thu, 14 Mar 2024 22:31:49 -0500
Subject: [PATCH 23/74] chore: Add GitHub Settings (#224)
---
.github/settings.yml | 7 +++++++
1 file changed, 7 insertions(+)
create mode 100644 .github/settings.yml
diff --git a/.github/settings.yml b/.github/settings.yml
new file mode 100644
index 0000000..fb87c08
--- /dev/null
+++ b/.github/settings.yml
@@ -0,0 +1,7 @@
+# Upstream changes from _extends are only recognized when modifications are made to this file in the default branch.
+_extends: .github
+repository:
+ name: terraform-aws-elasticache-redis
+ description: Terraform module to provision an ElastiCache Redis Cluster
+ homepage: https://cloudposse.com/accelerate
+ topics: terraform, terraform-module, elasticache, aws, cache, elasticache-redis
From decaf032e7a71d6e9be439920d6ef2387abeec64 Mon Sep 17 00:00:00 2001
From: "Erik Osterman (CEO @ Cloud Posse)"
Date: Wed, 10 Apr 2024 18:15:21 -0500
Subject: [PATCH 24/74] chore: Use GitHub Action Workflows from
`cloudposse/.github` Repo (#226)
---
.github/workflows/release-branch.yml | 10 +++-------
.github/workflows/release-published.yml | 5 ++---
2 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/.github/workflows/release-branch.yml b/.github/workflows/release-branch.yml
index b30901e..3593cea 100644
--- a/.github/workflows/release-branch.yml
+++ b/.github/workflows/release-branch.yml
@@ -4,20 +4,16 @@ on:
push:
branches:
- main
- - release/**
+ - release/v*
paths-ignore:
- '.github/**'
- 'docs/**'
- 'examples/**'
- 'test/**'
- - 'README.*'
-permissions:
- contents: write
- id-token: write
+permissions: {}
jobs:
terraform-module:
uses: cloudposse/github-actions-workflows-terraform-module/.github/workflows/release-branch.yml@main
- secrets:
- github_access_token: ${{ secrets.REPO_ACCESS_TOKEN }}
+ secrets: inherit
diff --git a/.github/workflows/release-published.yml b/.github/workflows/release-published.yml
index b31232b..1b0aaca 100644
--- a/.github/workflows/release-published.yml
+++ b/.github/workflows/release-published.yml
@@ -5,10 +5,9 @@ on:
types:
- published
-permissions:
- contents: write
- id-token: write
+permissions: {}
jobs:
terraform-module:
uses: cloudposse/github-actions-workflows-terraform-module/.github/workflows/release-published.yml@main
+ secrets: inherit
From 2488b89eaa5f4f0a48b6e29af3dc42e0b027d9c4 Mon Sep 17 00:00:00 2001
From: "Erik Osterman (CEO @ Cloud Posse)"
Date: Fri, 3 May 2024 09:33:20 -0500
Subject: [PATCH 25/74] chore: Update GitHub workflows (#228)
---
.github/workflows/feature-branch.yml | 3 +--
.github/workflows/release-branch.yml | 1 +
.github/workflows/scheduled.yml | 3 +--
3 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/feature-branch.yml b/.github/workflows/feature-branch.yml
index 8faa955..4567939 100644
--- a/.github/workflows/feature-branch.yml
+++ b/.github/workflows/feature-branch.yml
@@ -15,5 +15,4 @@ permissions:
jobs:
terraform-module:
uses: cloudposse/github-actions-workflows-terraform-module/.github/workflows/feature-branch.yml@main
- secrets:
- github_access_token: ${{ secrets.REPO_ACCESS_TOKEN }}
+ secrets: inherit
diff --git a/.github/workflows/release-branch.yml b/.github/workflows/release-branch.yml
index 3593cea..852d5e3 100644
--- a/.github/workflows/release-branch.yml
+++ b/.github/workflows/release-branch.yml
@@ -10,6 +10,7 @@ on:
- 'docs/**'
- 'examples/**'
- 'test/**'
+ - 'README.md'
permissions: {}
diff --git a/.github/workflows/scheduled.yml b/.github/workflows/scheduled.yml
index 163be0b..7bc09ab 100644
--- a/.github/workflows/scheduled.yml
+++ b/.github/workflows/scheduled.yml
@@ -13,5 +13,4 @@ permissions:
jobs:
scheduled:
uses: cloudposse/github-actions-workflows-terraform-module/.github/workflows/scheduled.yml@main
- secrets:
- github_access_token: ${{ secrets.REPO_ACCESS_TOKEN }}
+ secrets: inherit
From bf5b27ba9a87cdfbebc1983e0f9f74f2edf2c747 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?readme-action=20=F0=9F=93=96?=
Date: Mon, 6 May 2024 03:04:11 +0000
Subject: [PATCH 26/74] chore: update README.md
---
.github/banner.png | Bin 0 -> 1009593 bytes
README.md | 5 +++--
2 files changed, 3 insertions(+), 2 deletions(-)
create mode 100644 .github/banner.png
diff --git a/.github/banner.png b/.github/banner.png
new file mode 100644
index 0000000000000000000000000000000000000000..729b1160f0b8e979e4ebfec4d352e81cdb672ff2
GIT binary patch
literal 1009593
zcmXt*$cNN~I|4gdC@GNMc6V95x-~m?ge%owg(60wROi;wmkW~>HeL4B|m?K?4?on?!I?;_in4Ca;f}G#m}U7MdhcO
z1D_21jri;AJkA^=^QCC^LaZ@TRLaZ~zgmr7KQwLyTT$!P|qC$;Zx?jpNOhAx@8?+ARqcK2sT1~;cW7~ws=)V>?nx$ixF
zqg&f++0i(p8$M=VaU9`6bjdXJ2Q`t3^OCx)bHBt^bg@Tj$N7!P_N!oDLMveg1tR_e
zdi!}xpHcuFm&Q;n#crZQ4N9{ZK%$!7MUQ%7wsR@8E$)g<>hi>Ntyy4c*X}32FDA~H
z1zm)Dnf+W^t-Y-IATgiqRff>>t@UOfUl#J&l>Ma^+S!(FWd^40m9qLLwo9Upcz$VW
znu;xT4(-+EN2adAWVW;Gzg06m>LA#PcCl!`*JrS3v@kAK2G{kBPaO0Chh56_!1mWB
zT^{pNhlar*Wi0dMKbaK!T#1YB95Pd?w#a^6b4J_aFRnef%D@XTVx2}=7>LRKCCORc
zb05^&bDq9&qF-tT`9m&-u_TXNU1T$o1;S-iqS`EeYv3J9Am+*@=`A`Pae$YR0Fe;p
zt=qe>?kRi^tTHZm;r%nuXhihlu@e**@wp7z3j~)&=2LdEz~Z@9M<3M
zcmX^O-j0av6Kvw#SHgH5@_!vvkQEyEuYm{4&FccKY2X}@Rv
z!#w-5fmT#L&Li({>>VA5kLTcZ@oigqq8hiqHMNSiKN8%M+d}rTeY*;?9G^08)?h}&
zD=ti2k9qc_Qw`K~=FZx_0$)PSf_~_!B8;*cnR`z>K&W;_?^-BmQBQK+Myq4kZ3h(A
z7Zd)_-o@AZO&L5VB>)P!i@TY#(fL{#4fT?*v4fnCmfuk+HgLv3FCG}P7KjJ;u1*{z
z<_oX=hJLnaj7V{8r#E5^i3=+P+Qv5e$>;5YEldcqpv-Y5p#Cp6>PXok@@2Z)7+bXJNq
zaliE`O-0QmipQ9hFI&PhE)i?D*YPZp(c>xN#@0_8;Q1mV+_g$z`)jE*&ZjM^rI5QR$0P`=xL*@#S*+W
zM+MsQe8m0L6394YNR6>`BmVvixxxdkATf8Z;xag7k#ea_6|#-q0$O3yq?=L)b&+w
z{GTWijtA!yXm#ND`LO0=&{It)Ia5p6rf3_J3I?CdPz0+T
z0~GR!&xDw$*zpipYX=44Zd|qy;pU6Lf
zD%MA07Lvn5mK-<*%<7Jh!Oh0Q)1%RBZb|CzStw$s`AWa_Y(5>@X0MNbWd6r&48BOY
z<|N+Ny3N{!@#xOiTxS3
z!xk5T)%1#t^(H)YD|92KXTL5in6tOcI}k}`Y!W666ARJRe={%&OzT6?T~S>N+a#5!
z?d#6u73QE87}Rp!aY2nY@#wSax)b)Hq~yrKz;^!A;HB=#!1ZO2I*)Z3)V6j>f43kM
zX%%Z_PI1&t#JWBrE5Q6wPPDZ&m9zjFKNpO}OQbD#&k&y@FCZ3p%72vTBLzY0oN;QE
z8L@K^6wT{!IFmzvs@jINj_?O1v&vsG;0>~FdJoqn_KPda;^1rtB8_Yqh{N7TKW%&&Nj@zz*&+r7?jzQB_hr^A3^eIG+EM
zG@zy{KBi~6bs>Yq5W7!o6K@^7Z8D@si(9g+LoT;0bQ4i~CO)PU4^tw$c=_3cJ)5qU
zXf5!XjPApqU$dv7)=+4K<$x;Jkj2en=#0DfnXhQkvZy*I_4~d!YaDbTSuaTSoB6
z1)H&lBR#(W_M;q-!TO*loOBBiDw
zwylitF+;qIbsMAf|NnYk@?O>ukK=6^zgly*#5Wcy>6@V>Zh5z?7sgS_h(!AJG!I>h
ze%qPn)n5q7T}F;UUlz7%_zrj4g`wK>oww#tUuy|wiZypOUO8Lq26yK4Z;7D9?mtD`
zVeNs)dhiBMIKEP6;@#b2Sj@wP_&365zfwK#tlM8p+5
zg@12vIv)GP)uQ!ELdp42;iJLN4KAMub-u97s^z^DIY^E~V;uaUBAEA6g>^-=+TdHV
z;oy6Xgc-VP5cP-)cw#+I;+3WJnOf45RoVZ}<>5m@0C?nw!gV5P^xeLuU|E{hRon^X
z`?Q5m65`*e9)z84&U$79RR>g^mW38Owj?zBWm_!`lbwIw?pUi?ZxPva*JZg~>o>XH
zLxxcvs=MUc955Urs!@qT&Ifl^XDFlP+0X#W|bt?RO#fRN$-K?^A8W%%sa$-#h
zL+?vScHzj}EUng6PA%62bQojt^NGG+aDRhK!M)rHb?{-Lk~mCvzqoS&`z(i{^*S*v
zh}+Z@ye9C<+L_zlm=g2Y@|%O^yJJqBhE+MfrmyyG--`)FrCgS%J-FKtV~XCOjeIKX
zXX)`zjE=d?1a32t>~$L7qfUk!5N{FuYU=$;I1e{MCPws_IhEHxk%UEo8--+s*0WR<
zron5F^1Nv(W;gpb`ZTwfQF;n@J#Oveoi;y7&>vXoa^^f}Aj-upk!f>8pN{Hr?IUgw
z`^^NsXPvvVy7PPCFbR4&`%EEq9c7QycS-u?kWqP-*B@nAaC0njpfJOG1Kn^2ao31h
zIPn-4nMiL90OA9kAga}h%SO@$1wlBBhKM!O#9V6wUq6DsOw+!(;ViNG2jhWl+WN}`
zmA`oWm|~3r=0u!t%_a!@BhHt9_g;=x5;J%rA$p`6;F#F|ofSODlOjp-m
z4y!;bXz`&~}LnwgfXR2-AJ}E(2j+PFxN|i3FZ8rV|tv~{ejxW88eVe3}ANnYELpog$leDdo
zzSWOQnB#eVLptP6_KOgNE$fZKQ|rPu?5lcFr{Q??rs{dEb-$li{%vZYC}mB(5Tq<@
z3l(l^3-DOuph7FkC`K)e3|y_{)Aj%IC`K#@gOnf*j{9IQdIb(az;xm31TFsYq{d0&
z5N64uweI0~lSq5jdhPg(d=fnE#_fV8B(BG>0(r9~=(dg86jo{Mne>qDNw(uc)<_Sl
znQ8qI_Pp>Cae!Or@)&33{a?~(27Cc|yb{;7wq2<`bL>Fmb^UOba$DvD@^-cXoXpLd
z>Z!xL!Mw0(72f945fWWr2syRzl?0LSt~ID5Mww}W_Pj5*5Owxoo?sW@8Wz}AY}8OE
z(Bcmr!QR{9+Wg#j_p#0t!`+kW*8fE!=#FAl;oE5PQxxg8*q`{K9V|TuxFa!P{As8l
z1^clxCCZeu(RZxqIqKfsfXJ}Vn5?>~Vh(N=+A7qug)#@kTgAs$=-ek{J|8MUA6bGf
zJMfOz?Nc4uq!nW|d3@@}-fZ-dDs)6=zcAVmL
zt|}4N>}6Nqh@Tt?F3ycGI>uDB{WDV?GrEKY$ezMhigtb77Z%ySuOoJ1KAgvo_DQ=>
zGj<(DoRZbiqezhFN_5-xZHG5GEJoqJcdML)?;^Zc>Vm9r{|b)u*Tpf%VPDpU9z9Nq
z3O*8x_)o8y%x((O!zgL>Rz^QqJ|52xD4h)$YWs?0Kz^#deZ63-d@)!2ZjT(5xFNoN
zS2r3x{kUh-w&nMimVcPU28SkG5`TC&d!^t6C(7gu?j%i;ee`AV)nGpJ6lGv`_2*b@
z)G4uv-@)ZXke2T#ym(g)scsHHs+*GE&8ZZ(FHI7so@JIUe4-VYy#`c8Z$%yOREk_C
zT-%Vh6SP1|(BCOpoa)WI9x(pL3>vEE7tRpWcIX*yO5s~EzOT1&RLdXG%4#UO{DtB{D|F&Ws3
z_hc>RcMxRqq#niP#VAX{$lc=8t6Cy67G|5yY;gY?x`(%X&eU%r0UbB%^9~ocXEUg)
zQ?#u}95whmTx7#cEQOtV^W6A>M4qNcJQ4H?WMv)H@U77KmalcX5tnM>Mt-I{($s8d$(+b67JY){$#g8u>0x#P7#Wq8xe>JTvL
zNoiB>JnAjQxTa^J2OZa|WC@CW5r9ccea)PaP^XQ*+|JgO(1RCyXIX-EL!4y+DHPD&c@Pg_-zWQ41
zsRH<*r~?Ygfm1BRPY0>#*n*g=Vx77?q#?V_!yDMfMS#aJV*bj1g^P(2sjuLR_`F22
zB+y9jEU#N-Fw{bBtN<};d>d&P#9x4tF9m?vZ1n_!rR7xDpfzCpKo`WK{we9HI^a1|
zMS$W6*Xe{Zuzo~gtiVVvm7989i|L
z1>K@=!}PSy)-PjK6_XbFw>B9!yI2b@Ka+nOc`3y5_w{F<7i6cytUG_F*FX4o0@36d
zgW&?=FLPb}(4B|pQ)!F=q33~FIAb-n>lk;AT+I`M%w$Fq!PLl~X7_$5yiRf^y~w3MwC}^6Q#$Zc;}?=OJ^b6d8|&8SlXKFuTfW`u-{d8XGR@8(NLeUULOL>ujkGHtWA~(dBx03C?5F#5Lm5RfABUPrGM995@AG0>4~8
zr&-zxI-brE5TtEi^Qw^YCg2>{@O_%s?VB#G#8&IB{Lt`cEmzzmOYHYJXCaxF5F|*6
z$R4XPN6W=NED?Opx__h>nBD_FzlpoyjXfqrlh$35cknp4L~xRB;PN2&O1x4D4?uej
zlzFA#b++41Y}eN$M}YsD(vs4iAWzfeC#-~Lb{777yLn`19@#0c
z8zFRvzbOQ9_J`0;5SO`tzxM@wB4(CsSG8%WxO%}U_h#un6Ams$NSC-L8GADHNQ#Zc
zK&l3lZC4IaK$1`i&Qf*vhaTMR=EFY*`#UkOK)25yd0>N|6900oQvWK}T6t#5n;#);
z(U`i^pcIL|CWM~T1#PA&@c=A5V|=&PZ+Lb?;*LT#s6`tY$O6hDU>$v29oLCNCbDg8
z@|aq-ab#=6^;5Gs~~lPoBgo%I*ki$6CUi%-w<*#6Rp8c_
zw>vDU?;ReTt&}K
zYiZL|565zhc?9yHOlJ5O&QTZd+)X1hZj`{fAfYHFeB$ZT!W^>&-Q_yuD=}-IXPx<%
zTUb-xsUe#cb&g$`I8oz39~+V1veSB?(z1YqzEkr)Vp}48gBH+hL!KpZC3;)5LjBkL
zal+lLS`a@YNuoo;n*!5`uL5uWIg;Hj_C?H+qeWBAj3)h{q{OE5xRvO!Z8I|X%z+%&
z$x}M(XLf4!*Swhgk9RZCRUZP&o?hJNja9`xS!9UV$jjpD&u8-*xzEtS3+IK7`S3Qv
zhDGBv=qlOIxXW?Sl2Y@6s9dN^Rlo?*LTMX9h1U1!%n1xC>BbUl4`xiP?puu>=z*%C
zXV&ewgROVdncLxr2LGBA%V1v+rB+xu^Vb&g3&~pi`?4mUzZn282De}-gI@iXKF!Z1
z9s>98^M3VCCL%wfVrymsn(-TEMzZnbO{W$8>B34~C9o)7g
z+oQ#4y}p~{u{*IG{8CDZT;VT1Wj9&gk}2xTh1k60hRPJx%zqhH+xe@l0%^+c5W6DJ
zKqk4bEH~s0TlU;R5c<4#h9
z(CvL<|AYOq3=;LPUkHQ^r!}AIj|u7@!K_wGB@l^Px9hoSHR&hFx3%+)`%DO`A1r@xr|2uy6^Vs1Rl^w`eAESqVtPhq
z1Eh9#izM;Nf7;}b`a~+Q~8Mae4W{CM7Ju<
zZ})}{kO=Cw4F~*Qrrp?}>!vi4)2ONe&Vg4lo5uyYsHlzC>KuEmt1eFH(1*IpHr)Fx
zx5mE{;GNXGlAf}{EunG1g+pP+#sk8G@xBeGp!;7Ss4>
zG_UPkXwxC44q~?kWS(hbHbhod>LMphx5o^QYjKZE_dPIg$;SjP(T(N{jR}o}7r>;y
z$-?Uru2*b|u)hjZX7}@vo&IQeT;aNIR{e^2dSg0HywjosbAOM&ST}uKuHSlLMa!bN
z-1@xuQ(zpG5vNVvkAhChF9e^I1r`toP@8E7yY5zW1?f(sTr`O$aW^G)_4c)^-xJs0
z2@(jCJi-fG(4x~PY)RcNHGXVDvgOob2HAI&9{Wg~Ht_BO+G`b(PMNcKt}?;yQu?Sg
zb<{)PL?Y6!-GrOtr()Z%RFM^xofiNYE7`L<-)TmsQ-2|{Is4RtmQ~33N|Aj!@zZ#q
zC6)wZ9CvPvena6Mh|$GVbnKsVx^%-?W=AO7Ib|37o?D1I_VD0{@eJ?*@tA%kt_ED|
zaL|HZqGZ23+9^h%7n$;x^15e4S=ROQm|w80H(MIMHou!YSyIVa`7}Piw0>@8F1ASF
zj*~}s;pnKVuzS$S<2^S@jm602z5-WrE7P><6;{{5>%-3i%vs)Jm__Ehd
z1&1NgeUgXZT%DUCwfeYH`miLO)i*V#?F8Vg^OZ8hGl~$JWF#sCB3UI)ljHJH}84y-Zy_6NRd`Tx%Yx;~}QvoL2S!j0WL*vlX`hK$_B&
z2!^Hi%v|lAw-b%cz!*Gf%aH1%Z)0h6m}mw-UQ7~uj|R63j=xxiOUSYnfDG%k)H+23
z?IQ-W{3}1@W>u75rV4flHYsJ5jt`2&!~t)P8}M9t`VAc@V|0E)rV+4ZQdaB7TD<$r|`6XUqk|
z_0#1wH9eWMh}1BS8vVzh8+)tB)I=}3MlJ51--Y6$YLh?ROpjL35Axzs%2zpazk2lg
z-;*T@$wiRv6ikK5=QA5s%eoKVn!EBAa|7nC96I9YGvEw2VOh-l=+AJD-rl(KM)a__
zk=Afcm4NwWbaA?DHjti8u3H2D1fDl7
z{us>??VQeWGbp!!S$!F;3HcLY5g37pX@yU!WK|-6&;YZJ+ab^H{$P43U*)Ev?}#J1
zW-uynMGL(zW2p|{DA{&mg}JlWyQViTo+%oW4>OMoJ~iW=YYDRSETdA~t0;HIzR~a2
znz0WDvWssiOTSP+o=GbM&OQq_lYi*2JMV)ktZ8zz4_o<)MPiabpB{!_>?9M*!uIp6
z>G43LFmFxXp9YgsRNj4YqTpm2(`A3FS>KXt$>oE^ttlQY;ff|7zeub(mhi8aOv>L;
zsg@dFcPVLD6r#&CsBr}!*R@i}kHOz~pPfucwD`X^tydBJ8Fg7OJhJ!Ltj9%a@5DGM
zTr0Z-XO`X(3Nt@yqeiXWc*J}AyOfh)wM1!P5Q46+btW#oOh{hLE}dW%^j?{CL$H
zfMa9AoZ+u8y()d|@vggU>SuV_=6MS23gidQgYXQsg{;`R+=^bDE|{gvJ*UBctCa>U
zcVZL7*p(~D9h}5ZYKT(C(R)6)@)AfPofLcZo){5l#M2d|(ruC@iI&>SCTF9|#l8&Z
zd&U+a?pn&pItf$<;Ff2&vadD(&%X?e1j{
zJuQiYk9b%-GB-Mrdv##XfU$c`F23YGin|`;_piU@`#fuI
zL7PvEfyk>Rz606KfsLla)|C+2=v*pyaix+Z8a1CGU86q0IxJ1a?#Z?!UYy=Vy5!9(
zLFcf7W>Q1U6IS(US8|oUpFC-eP=v0yP;mU5#isU6bi6DJ+Nm
zfeah>VOqm4Y(Kl+hy*)G{sVWj!a76|Sok}xL%sgXDZl3jwBc<*LEvHVL3-akNKEGe
z{6WE&>Q(XyZP~Y^iy|Evk1AzJ)_Y_V$P+#$=-E*hwO2%$GUV4(c-GyuQH7t`)E}KE
z59jus@8!XIKOEcLMGTV7-2+<77&Zz}E$|N1Oq>UI;;x1G5SHCYUmIK07%7(Xs*>M)
z$uTQ_@IW>SU^W?%M1QAqDRzLLjjukR#lFL90VNMQzHxnXSmE9m`-de(7z>JC2eMA%
zj|aqqC9e1yYnQsGrsmr009Gmmn5{05@{RV6(yMldn50NPR>i{uH_xjz{jJSqIDh+V
z%p-qWzqGd@@At%Svh>vvZsxZqx!|92W;(0kwHjt;J(la__0`sa5(C8odh(e9$=huj
zU+-s)73y^S(Q71Wn8+4~#DB<#uVIdLH(jeEE;bolj>OT-);+F0Vq8MnPS!lqyWenN
zPrmF|_KOMfH78C+zQ6d`%+KL{fsB&TcLe;LYzLJ?L%za@;pjTB$^iJi)}kA
zUGhu^VULL#x6NlY)>jTn%Z%X)Bvk-n>;Mkc4v`!pwjw=xas9XT6pXMU1GBJ+;l8wB
zms`Tw%%wW9zX~A=oXZXxXmrm&hxJ5Jn9#6o;^z{ie-(xGXymOdQsuyc)HSc?=N&Y
zQA{J%EWL+yqX20AndUDhS-u{#p+7Pq4yO@q^q?~UZ2A*DDsOFv#>1Iw4cslSm$}&}
z)O(Cg!OvDcxW49B9an#6LA34acgch_wk{4!x^@Px@e(Z-a!~r>hjDR4Dev|grhm26
z_9e)0SLww&)xL3bM6tyXjMGD!vI0aU(wUYMOTLg7VYkHz(cb92U}M7T7y&m?utm@z
zw=#pgP3c)-FHB2(lG0dY(!Z{Q&y-N-!e0$9@4J^6gzEeBQj+d?$k&ZJbmYj-Z1&=p
z%X*X#F9WvT|8jV5_014#)Fkzc*~mgJitRD+pJACshp%#lclGc6!>Fe|qDZ$*2f>-|
zf*;z(hSQ7&?ra8`ak@ShhQ*+yu9=uu=-8s_>d4{Id<3GgPsP*UQtC}i{)YeO5QH4o
zBK*IT>D`f=6-&E)HR`|C)KXO@!~|@b|GvH*_hUV|FoZaFYc_xaW-J5={i&Fe3zuTTSBPke#7F}s4FOM
zP-WQLt*%0-f6%|Q?YwT*`K2pYDdk&k-IBlS+>pDaVQI_#;-^C|O*5*7xt}ma-+g%{
z;zD}8*^rnLu>W(_GSbUk2rubza9oP}VHe9Fo*@IeY}>L~xhwOUdXn>l#2}ZvCl2QxK~CLN$ct=fN*i8-A99{6aQXCkj#58r@f98u-kKLkZoS|#cU4cYCp+I&-?hO#
zwfmM3F7;gX(;(KmTvlhv=A()Zf6kI^Fp&lBKaHT|P6U68IV|?7+_(May}al)2P>M1
zZZ9Hg=)aGGXItFM?rbm{?8R+lZ?mv?roW+2_-
z-AniA3DXG{a=l+Y9f}#O{b3H2cbA5Hb;c-&Ekyq+<*zPs4>c~nJ3Cg9Xj(wq_Yq4P
zi7Ylc!9AjKa{?{DzGt1kXa}rH;o3|Cv|JSO=pN{a?uh|JX@CFkPKUv&i5{5}M`Z{=
zdA$u#N&E-Yc+wT3JOtqWPTjmOnfcf6cY$;KjYQ2NF(o@riF4LNYR*@gzNSZ+zUykW
z)x_89LDYW+-eoCw=EQ^SGW2yJdZAH+V?7YTM(e#6qa|Ca_mIyrh+^jN9azn%
zrwc$wDv;`-S1nvPonwAHKpJ6cqvBlC{AzF!nYn{|+7?m?-b8QQ{n29b31g`O8)vD9IDzGFhD)s}f3<9q
z?5$^3k&=P74G;sJ@Gr>UWD`qgqkj>i8P2}})gd1#1Cn~LWF;gaP#h1=SSO=jl(JgD
zWTcydnYcDr_|0ScGFo*t5}ZuG!m|yqNMn@|-5UNmW-K)hVL6!)6TZ&LRQZC
zf|S_%=wzh&zi+#~vR9=Z1LZF~tMOzVXqUYv8L>>Xv6GIj7O>uh3n;*h_Vw>>vgd+{)75r0r0sN@;%X{dG16TU
zHRtdrW&~3Za3uX=Bp-pbv)^tX;|tDz4yU$>lXy>Bybs~6Maj=8wQRve8{1EG+EC;W
zOnp*cy~;$gr=4mnSp&2b5_T0bd1%scv9Fsr%&tB*g3r7RhDmJ33d?0Iexiu@3NXL_
zL3+tz#>h7QWGU>ZlQ~*DRBKc{-4U{vc-wn;{q}sdZCN=r8@vOl&NSH01_)kU{8PxZ
znQ46}cLMDWaX^k%^K{|5ctzW`9ZL8`orRwv+xa=A<2$Wi08YGE&84nF0x=vBW*Iwj
z4-sXh{A9xn~inum=q&fIh=1OIE5+GLFsL$3XeuLR1^Vo|VT~&$YVuPUP$RbQF
z+DkHs%Q^YB=SuYj6}^S@%!3rbe|DEDUdaJY?9fdFzLf9Z*=n#P;M#$Mw~0|bY4!u+
zHvYvC>R-sKN@+}-Gr?y*$cX*t_~84TlJg5m*mjj2lqsS1H8}EZciUqRicpC)z*pev
z^Y0lFu8)=1XrL5Cqpe6?i%U&<^@L{pz^!*zZQW_iWY`G#O%)i<(#6yb=Xf8p8kUx?
z@EZ%$Mo;V9D@-9>?Meij&_(B12jHRep&BbV<3WSBF_WhI?st`ad7NiEM}M1P*{AVEl0nm+c6>=w?#M*EcU4U%zvw{0kd0{`UKfQdbE#fSTJ4;keujZxxtj=NXpSKp+D7j6}V61
zI@Y^)s`2?JaGM4A1O9LhY6e(c_FqY%(wM)*EPWTnnOKP^7;GKf_LkTx9`q%8BWAK5
z%PL965-SEs7}FR{Feun0GD81|`WPp}sspe$D6(!spzg&GS4MHV{Z4RwI;D
ziVRyj1&Qb4v`)-Eb8A@6dZLefebH~uA0>QcQJ=>&j){$}UQlWmUIoK|Pak2z(f|=s
z-=dFHwKmCz#qE^J%C%S>p}g6RA-36OUhb0%ug!dnv$e2fs?t&Nba0v4*xGUjr&0}k
z)xHrf7488HulLC>2?5>@1wQzjeNf2-5<(IPx07xUSJhUq-s`q%ZRBSR`hCtVFU@r8
zCO?Cpi|$rc(W0tpe+=y7Qw)~3IZXQe!`=Z4+xo+|)i0ZMU08kHHSJZLvZn|gI2C)3
zq}W;)`CnMf!RnjO@_&lgLcLf20jU1;Hyh9tp@a7eB@~FUwQLcB5sfOOs4coo-AOHG
z)|7;bO-)7PoL~k8I+EuaN%*g;JLpOa-@D&ovM0|KN+2*1c&ArurY(AheA9#WGP!Vo
z#SN?EuHX@38eNyI?)EDGR-5Gk)~C1K4iWn(Udo~W5Gt$hd;i}Iw;l73;kTlSE%#ME
ze%gKI{=SCm`CGqkI9QzZEK3&h+_UoRz)44^!1Fq#S8r#@{diAd`2K=(f*6p#lzUf`
z6aR&Pr<{t#6vk3f=U1xpZHL9dL$Kc|7)R=zEZO&C!=LDNBE+`cc$Wqb4UK?Lr%M(p
zOqfaa(|_S_e_1r$@Mg!wIenJy02S|h*?A)8cZ%Mcq(}irqwk4g6n}9o_9?6>SS^q=
zSd8{$*NvO}F5w2Asd9WEZpyL(vrD<;l!!GXzK+%z(bJS&xo^l%!$8z>1CAyXzZ|M)
zF1g5DPtApg5?)RZR5bk3Zs_>3<`G?|iPnUHY_2niLZS2AgZXc3bvr$@nuQT=ekBbi
znpZ@M5VaPRix7&hd)rSn8NRhW+r`NvtIa1biM7%n=+ct6&brFIe-PWauiAOH1{v}e
zQhLIu9k>mtF1dxeTE6qG!hoi|CMa}cSx6Qz%c87{^s`I2W7%VY@UUq6yvflK#|C+g
zgPi?kE-oHiE$^Kti*_;AOK09#4)zR}y??W{nibx;o=qxpGx4ORPxf069yBgWr
zTi2O&RXJ3M_*dlK9?o?svcuTNoS^t;$vloT-Ld}{J0*l8mzEo2Z7e
z@u*r4ugDx>Ekw+b$(1MdEhUAP!TN=pbcsV-EKf>2CwhCA#)UQ*EqWE6l#CaX_(wQ*
zzhf^>f5|f50SYZZqrA&e3au861H7OzF{Peb#@b;qzm@_2Dv4Q(WdA1q(inWz&`$QW
z&0}^U3JyBr8a~DD2A*`1lvo~rR*YoQJei0O`iJn^CsbGMdZ2mUV*lH(zBMtn7l{*V
zX0jE5*fS%k(NzLDzGF$!LGOQ=7sgtj{_i50%6Gm9d3(o*1)thK$w^tgW!Wb1jr3Rt
zA|3OjJ(yEz_9%{f4WD3=c2^rAF0R0G-)A(uN1uW3fez!fR0AdQoX4x#rRXd05OE4D
zkzB=t=s`qN$1F#zy2zTC6h7;LO*7;8ZY`gG1|)VRL0}*S7|tp;&?osJ)n+>>tq;65
z@GKHl%K36O{f;iZ;h_VInp%6X|E+n6)5JO}4$+sUvl3NU&6-cIOAdP%!cjZQ)@39UMyU%|(@F<4-Q`iucz>xifRbR1DV-zs(6VvWw{>T`RFjl`Y0_5qog+Q*CN_cZRO7jS
zhS-6+N)uaom
zIi}mjg>x@g-T9U6&j=W_Ea=5TyN=hJ-T){3>`dA6g};a;GyG#SgwZa_(VM-cc&h@ZgWb7H-#Aap_L-Cyd%lCCE=PqI
zlpe6Bux-?!+Iq@ZFA+NEPh}KZF?Z!JkDBi7_&S}8oV-KaT2%8-8UHC2
zk*4<5&*7F;b1!c)y;GrIU4uwn^L?#E?_rZy^{cdx#u^4P1xE9JDK}a`%hvP9)5C+C
z_Wdwv62JG6Jb%9l>6?c;QRDnDxQLftHN4_-^&j&=epGmmAeSPrZumz&fHbXb~wCU9BLol79QjkExs%
z+5FuPyVGt=`JHL~kRx41w9n&grs4=^&Vv2wtWwgQL#Bld(I)UyyM37l3z1hI{Z0ZE
zTV`@Tj2!yg>4r7veSo(m{rW)kKk{5IAn}=?zAJnUyh9edTWxBHco}*6ocybQlMS47
zfuP|@+#Xl)^ElfU)TiKdZgJ2?Pa#N+pN~b#xm?3d-xU*9cAEFxHR3YI%o;p6VS47R
z|Jf+(iS%uc*DuhNt6K#?|I1=?&a4x>H@_0$D;x@!GM5eNpb1)3nFG<9)+S;vcQwcD
z2HdA@;nobY%sJER=n=dk6x^fbF6lUeE#-(f@;|+c>09sB0vV6gLU)KZ(w`nb8p0Ku
zi{un%8m-+lx#uZM#QL3tzCMmig*qc}Q(6HxjyEk^ZMrYzPq);9w
zgwT6z9_&NUd|RA&w07%P0%WlSQX$QrntO)}w~s>q_||;Ldz3>Z-|(JV)ZM&B$G7be
zzi-D_L^`glIFLcA3N4kwsIfEy>}^bEYPtmy?WQ0upS$;Au+*lL8JAT(F*_B9vHiyO
zhWyBjB5u|tTMJrMV^@4W(}>|Qr!e=a6Easz6YEgv&grd6fHCRNAUkF`ly|psVS$^h
zkSelyWRD`MEoTv^7z;u+pgoj3N&guae*9C{UHXkW4GOV^l);rnYS##{TGTn6ZA&_~
zm3}Dij?(+TUXESXByOgNeLPHZqsp?+8dZPTx;Rt~n-E(}>U3Q>{c3;eZmoR3rufX!
zpnpkW#`LR>CSH->n`xJSb|LSoX2z#ixgAfY=fwxhu*`&B%%@=LVcDz*T_0DxR(Ndm
zM_Y$#fU)NiB9`}L48DapDhNJ+d2SpZpwHRGAEDJB*a)&^-k4!Dj&`#=CbZVpPL*BU
zM?rLvPNs*~)!d6zLuhDSJEZE0us-0yS^Kx+t=+1bMuWXw{i2gVNsmK(wzD+zKm%`l
z%=EA8zx>W>$+z&IYlk+}0m`eE_yDSKIN=)?Sz2Fk=$oueTO^21sy``R(2s+=t@Q(k*xFfX>|x@x>ML
zH`nK{qVCtn4yHs#VM}<_ZEvm6D!OZoN(CPx5MzpQ*Jz~aBDR+Nu@HU8D){VGTQvas
zE^DCSoE2DJq|)^hd1^&9h2lDMSP6WVH*>>{8tZ&k5-dZCb4+)M7g5TPNliW@ddt
z99eoL)ZO3<)TRtk*7>O6&b9xIL3ah=znRNd`DaZGzSq7f4Z3ivdW`uwbGT{=cz?=&
z;~7ttDfg`u7X#=Z*}|fzD5@vrK4rSEYn+NaCn}bry2g=reoz$Nj9xzaFP@BGyI#E(
z?5vQNwP5zuH&El3?{m99r6xX_gMn77)#ZcQ36upI}_0#zb^Q?`F?
z|758k?ks7)7X~Xmj9$|iEP44ho~nbUSj_JxP8K%saEpf)((Qko^bYEU_E5FFza7)0
zpZPa#4!9GYn3a9lI~>ff@j?u=LK=I%7m_q)ypqSh-T5RC*lx$~fmjdc&nW7dn0&Tu
zC0yjjy+|{ibc0~z;n(#2EH`?-99Lr5(@!#f72$oN%nsEokN$HA+n!t?Y!aq%AN=FS
zMH@IBDE}VTEZGHBK$oKWYQ$hAN#63nB}g&tzPB+1wXGsru}&zwyAzYyiFt&z^E>tR`(uGiOp(_&TJ|b=YG@6A
zLspular#w>_(VDH8`Ja;yR+E<>P3Hyyp7(*|L_}=t~Jjbr(5=sE$3Y~7dF!$?zYt?
zPT)5R^ilshgd^I(*C{JEE{1%@9}cof&j`-iZr1`m
z$ZKTQq(5Tmn@K}eGz`?DO^GKq#KP$+TCDK@a{-=3Z28Yi{~33H<-9qd%UjR4{5Wsx
z0o@frveH@o%dG!~Fb19<>b(+z@&7~9x&Jfy|9@OmLP#aasgi^oIy%jk)LW863JG%x
zNtqEghfT@(up&)4Oa~-~l|#swoaQ_wIU5_6<7{)-d0(F&zJI}WUAJAg>-O05d4Jqr
zcCR%Q@h>r2w&LXTKTCCM`~-ILAY+`WgDWUoocXX9Tt#c8)oy{Uy9tU>J
zk{~xXaF_Cc>CF{LEyyllsBjJ*)VKVq&RYuh0^u_~PafHe&i2sK<8#iEGncE|b3azea^)FG
zgo-vfHhe=J11S<*+h*ck&nCf5mGC1wn{ETV2LI5sv+xpe4$v`1s9W*Rp)Ihh7QR8&{u#d(^@aB0(;k7W79Ql3N
z$J##Zd;AL}rNl=g*KhuAJQYdoY}1|3XTiER)S&Y4RQQ+qEiYxO=NF6^bU(V^N7PxF
zcsgYIj>c9x`_3D?>&El&uI&)xS^fd>Tf%|kXRSXV$GYML6wWR|Q#?M3{Zw!Y87Wkt
z^lVi9@_G47uXHNXn;<45VkkdwRS70PFUMEu3}kMmSaxAE5Q-C@kuF5p`qpR&;exHl
zVSF4y(m2)nHEEdAX{3I91Xhzl4vr}#5-g2I$IvUrdHmhvt552Nn=YyTGvMx`07p-B
zzWU4Y2tcy9$Q7XafxM0PQEz{$t96lrADE1Hy$)?S^{0F0saI8TUHozV(#Q8APYO*4
z)_aP#gvzo@fCe6%rrNtp_UfmnZ#ENtnl^j+tk
z&}f3ZxtgJncjy2%*g1LasAtZ-TbN;jT6Fa^*UJyWy*78d2lAV@@8MTEvqC&?8x0lR
ztUIF9p?g{~jWA}~k4$KcX$H>`vc{txeFA=ndxyWs&{wOwKZqt0-VIq4D99v{b{XoD
zTRIZcABRIzNK{?(C*AEIom?9-{uCl#5nk5W(-Pst-=S3n&zUK+s}7
5u~
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