diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bed3c96..07b38d2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -12,3 +12,6 @@ # Cloud Posse must review any changes to GitHub actions .github/* @cloudposse/engineering + +# Cloud Posse must review any changes to standard context definition +**/context.tf @cloudposse/engineering diff --git a/README.md b/README.md index df28dd2..067095f 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ For automated tests of the complete example using [bats](https://github.com/bats } module "vpc" { - source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.8.1" + source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=master" namespace = var.namespace stage = var.stage name = var.name @@ -85,7 +85,7 @@ For automated tests of the complete example using [bats](https://github.com/bats } module "subnets" { - source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.18.1" + source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=master" availability_zones = var.availability_zones namespace = var.namespace stage = var.stage @@ -130,7 +130,7 @@ For automated tests of the complete example using [bats](https://github.com/bats ## Examples -Review the [complete example](examples/simple) to see how to use this module. +Review the [complete example](examples/complete) to see how to use this module. @@ -165,6 +165,7 @@ Available targets: | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| additional\_tag\_map | Additional tags for appending to tags\_as\_list\_of\_maps. Not added to `tags`. | `map(string)` | `{}` | no | | alarm\_actions | Alarm action list | `list(string)` | `[]` | no | | alarm\_cpu\_threshold\_percent | CPU threshold alarm level | `number` | `75` | no | | alarm\_memory\_threshold\_bytes | Ram threshold alarm level | `number` | `10000000` | no | @@ -172,36 +173,42 @@ Available targets: | allowed\_security\_groups | List of Security Group IDs that are allowed ingress to the cluster's Security Group created in the module | `list(string)` | `[]` | no | | apply\_immediately | Apply changes immediately | `bool` | `true` | no | | at\_rest\_encryption\_enabled | Enable encryption at rest | `bool` | `false` | no | -| attributes | Additional attributes (\_e.g.\_ "1") | `list(string)` | `[]` | no | +| attributes | Additional attributes (e.g. `1`) | `list(string)` | `[]` | no | | 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 | | automatic\_failover\_enabled | Automatic failover (Not available for T1/T2 instances) | `bool` | `false` | no | | availability\_zones | Availability zone IDs | `list(string)` | `[]` | no | +| cloudwatch\_metric\_alarms\_enabled | Boolean flag to enable/disable CloudWatch metrics alarms | `bool` | `false` | no | | cluster\_mode\_enabled | Flag to enable/disable creation of a native redis cluster. `automatic_failover_enabled` must be set to `true`. Only 1 `cluster_mode` block is allowed | `bool` | `false` | no | | cluster\_mode\_num\_node\_groups | Number of node groups (shards) for this Redis replication group. Changing this number will trigger an online resizing operation before other settings modifications | `number` | `0` | no | | 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 | Number of nodes in cluster. \*Ignored when `cluster_mode_enabled` == `true`\* | `number` | `1` | no | -| delimiter | Delimiter between `name`, `namespace`, `stage` and `attributes` | `string` | `"-"` | no | +| 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. |
object({
enabled = bool
namespace = string
environment = string
stage = string
name = string
delimiter = string
attributes = list(string)
tags = map(string)
additional_tag_map = map(string)
regex_replace_chars = string
label_order = list(string)
id_length_limit = number
})
|
{
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_order": [],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {}
}
| no | +| delimiter | Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | | dns\_subdomain | The subdomain to use for the CNAME record. If not provided then the CNAME record will use var.name. | `string` | `""` | no | | elasticache\_subnet\_group\_name | Subnet group name for the ElastiCache instance | `string` | `""` | no | -| enabled | Set to false to prevent the module from creating any resources | `bool` | `true` | no | +| enabled | Set to false to prevent the module from creating any resources | `bool` | `null` | no | | engine\_version | Redis engine version | `string` | `"4.0.10"` | no | +| environment | Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | | existing\_security\_groups | List of existing Security Group IDs to place the cluster into. Set `use_existing_security_groups` to `true` to enable using `existing_security_groups` as Security Groups for the cluster | `list(string)` | `[]` | no | | family | Redis family | `string` | `"redis4.0"` | no | +| id\_length\_limit | Limit `id` to this many characters.
Set to `0` for unlimited length.
Set to `null` for default, which is `0`.
Does not affect `id_full`. | `number` | `null` | no | | instance\_type | Elastic cache instance type | `string` | `"cache.t2.micro"` | no | | 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\_order | The naming order of the id output and Name tag.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 5 elements, but at least one must be present. | `list(string)` | `null` | no | | maintenance\_window | Maintenance window | `string` | `"wed:03:00-wed:04:00"` | no | -| name | Name of the application | `string` | n/a | yes | -| namespace | Namespace (e.g. `eg` or `cp`) | `string` | `""` | no | +| name | Solution name, e.g. 'app' or 'jenkins' | `string` | `null` | no | +| namespace | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | `string` | `null` | no | | notification\_topic\_arn | Notification topic arn | `string` | `""` | no | | 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 | 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 | | port | Redis port | `number` | `6379` | no | +| regex\_replace\_chars | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`.
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 | 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 | | snapshot\_retention\_limit | The number of days for which ElastiCache will retain automatic cache cluster snapshots before deleting them. | `number` | `0` | no | | snapshot\_window | The daily time range (in UTC) during which ElastiCache will begin taking a daily snapshot of your cache cluster. | `string` | `"06:30-07:30"` | no | -| stage | Stage (e.g. `prod`, `dev`, `staging`) | `string` | `""` | no | +| stage | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | | subnets | Subnet IDs | `list(string)` | `[]` | no | -| tags | Additional tags (\_e.g.\_ map("BusinessUnit","ABC") | `map(string)` | `{}` | no | +| tags | Additional tags (e.g. `map('BusinessUnit','XYZ')` | `map(string)` | `{}` | no | | transit\_encryption\_enabled | Enable TLS | `bool` | `true` | no | | use\_existing\_security\_groups | Flag to enable/disable creation of Security Group in the module. Set to `true` to disable Security Group creation and provide a list of existing security Group IDs in `existing_security_groups` to place the cluster into | `bool` | `false` | no | | vpc\_id | VPC ID | `string` | n/a | yes | diff --git a/README.yaml b/README.yaml index 7233583..74872e5 100644 --- a/README.yaml +++ b/README.yaml @@ -56,7 +56,7 @@ usage: |- } module "vpc" { - source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.8.1" + source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=master" namespace = var.namespace stage = var.stage name = var.name @@ -64,7 +64,7 @@ usage: |- } module "subnets" { - source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.18.1" + source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=master" availability_zones = var.availability_zones namespace = var.namespace stage = var.stage @@ -105,7 +105,7 @@ usage: |- ``` examples: |- - Review the [complete example](examples/simple) to see how to use this module. + Review the [complete example](examples/complete) to see how to use this module. include: - "docs/targets.md" diff --git a/context.tf b/context.tf new file mode 100644 index 0000000..bae0cf1 --- /dev/null +++ b/context.tf @@ -0,0 +1,167 @@ +# +# ONLY EDIT THIS FILE IN github.com/cloudposse/terraform-null-label +# All other instances of this file should be a copy of that one +# +# +# Copy this file from https://github.com/cloudposse/terraform-null-label/blob/master/exports/context.tf +# and then place it in your Terraform module to automatically get +# Cloud Posse's standard configuration inputs suitable for passing +# to Cloud Posse modules. +# +# Modules should access the whole context as `module.this.context` +# to get the input variables with nulls for defaults, +# for example `context = module.this.context`, +# and access individual variables as `module.this.`, +# with final values filled in. +# +# For example, when using defaults, `module.this.context.delimiter` +# will be null, and `module.this.delimiter` will be `-` (hyphen). +# + +module "this" { + source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.19.2" + + enabled = var.enabled + namespace = var.namespace + environment = var.environment + stage = var.stage + name = var.name + delimiter = var.delimiter + attributes = var.attributes + tags = var.tags + additional_tag_map = var.additional_tag_map + label_order = var.label_order + regex_replace_chars = var.regex_replace_chars + id_length_limit = var.id_length_limit + + context = var.context +} + +# Copy contents of cloudposse/terraform-null-label/variables.tf here + +variable "context" { + type = object({ + enabled = bool + namespace = string + environment = string + stage = string + name = string + delimiter = string + attributes = list(string) + tags = map(string) + additional_tag_map = map(string) + regex_replace_chars = string + label_order = list(string) + id_length_limit = number + }) + default = { + enabled = true + namespace = null + environment = null + stage = null + name = null + delimiter = null + attributes = [] + tags = {} + additional_tag_map = {} + regex_replace_chars = null + label_order = [] + id_length_limit = null + } + description = <<-EOT + 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. + EOT +} + +variable "enabled" { + type = bool + default = null + description = "Set to false to prevent the module from creating any resources" +} + +variable "namespace" { + type = string + default = null + description = "Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp'" +} + +variable "environment" { + type = string + default = null + description = "Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT'" +} + +variable "stage" { + type = string + default = null + description = "Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release'" +} + +variable "name" { + type = string + default = null + description = "Solution name, e.g. 'app' or 'jenkins'" +} + +variable "delimiter" { + type = string + default = null + description = <<-EOT + Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`. + Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. + EOT +} + +variable "attributes" { + type = list(string) + default = [] + description = "Additional attributes (e.g. `1`)" +} + +variable "tags" { + type = map(string) + default = {} + description = "Additional tags (e.g. `map('BusinessUnit','XYZ')`" +} + +variable "additional_tag_map" { + type = map(string) + default = {} + description = "Additional tags for appending to tags_as_list_of_maps. Not added to `tags`." +} + +variable "label_order" { + type = list(string) + default = null + description = <<-EOT + The naming order of the id output and Name tag. + Defaults to ["namespace", "environment", "stage", "name", "attributes"]. + You can omit any of the 5 elements, but at least one must be present. + EOT +} + +variable "regex_replace_chars" { + type = string + default = null + description = <<-EOT + Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`. + If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. + EOT +} + +variable "id_length_limit" { + type = number + default = null + description = <<-EOT + Limit `id` to this many characters. + Set to `0` for unlimited length. + Set to `null` for default, which is `0`. + Does not affect `id_full`. + EOT +} + +#### End of copy of cloudposse/terraform-null-label/variables.tf diff --git a/docs/terraform.md b/docs/terraform.md index f6e8e6e..94b87ae 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -17,6 +17,7 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| additional\_tag\_map | Additional tags for appending to tags\_as\_list\_of\_maps. Not added to `tags`. | `map(string)` | `{}` | no | | alarm\_actions | Alarm action list | `list(string)` | `[]` | no | | alarm\_cpu\_threshold\_percent | CPU threshold alarm level | `number` | `75` | no | | alarm\_memory\_threshold\_bytes | Ram threshold alarm level | `number` | `10000000` | no | @@ -24,36 +25,42 @@ | allowed\_security\_groups | List of Security Group IDs that are allowed ingress to the cluster's Security Group created in the module | `list(string)` | `[]` | no | | apply\_immediately | Apply changes immediately | `bool` | `true` | no | | at\_rest\_encryption\_enabled | Enable encryption at rest | `bool` | `false` | no | -| attributes | Additional attributes (\_e.g.\_ "1") | `list(string)` | `[]` | no | +| attributes | Additional attributes (e.g. `1`) | `list(string)` | `[]` | no | | 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 | | automatic\_failover\_enabled | Automatic failover (Not available for T1/T2 instances) | `bool` | `false` | no | | availability\_zones | Availability zone IDs | `list(string)` | `[]` | no | +| cloudwatch\_metric\_alarms\_enabled | Boolean flag to enable/disable CloudWatch metrics alarms | `bool` | `false` | no | | cluster\_mode\_enabled | Flag to enable/disable creation of a native redis cluster. `automatic_failover_enabled` must be set to `true`. Only 1 `cluster_mode` block is allowed | `bool` | `false` | no | | cluster\_mode\_num\_node\_groups | Number of node groups (shards) for this Redis replication group. Changing this number will trigger an online resizing operation before other settings modifications | `number` | `0` | no | | 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 | Number of nodes in cluster. \*Ignored when `cluster_mode_enabled` == `true`\* | `number` | `1` | no | -| delimiter | Delimiter between `name`, `namespace`, `stage` and `attributes` | `string` | `"-"` | no | +| 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. |
object({
enabled = bool
namespace = string
environment = string
stage = string
name = string
delimiter = string
attributes = list(string)
tags = map(string)
additional_tag_map = map(string)
regex_replace_chars = string
label_order = list(string)
id_length_limit = number
})
|
{
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_order": [],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {}
}
| no | +| delimiter | Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | | dns\_subdomain | The subdomain to use for the CNAME record. If not provided then the CNAME record will use var.name. | `string` | `""` | no | | elasticache\_subnet\_group\_name | Subnet group name for the ElastiCache instance | `string` | `""` | no | -| enabled | Set to false to prevent the module from creating any resources | `bool` | `true` | no | +| enabled | Set to false to prevent the module from creating any resources | `bool` | `null` | no | | engine\_version | Redis engine version | `string` | `"4.0.10"` | no | +| environment | Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | | existing\_security\_groups | List of existing Security Group IDs to place the cluster into. Set `use_existing_security_groups` to `true` to enable using `existing_security_groups` as Security Groups for the cluster | `list(string)` | `[]` | no | | family | Redis family | `string` | `"redis4.0"` | no | +| id\_length\_limit | Limit `id` to this many characters.
Set to `0` for unlimited length.
Set to `null` for default, which is `0`.
Does not affect `id_full`. | `number` | `null` | no | | instance\_type | Elastic cache instance type | `string` | `"cache.t2.micro"` | no | | 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\_order | The naming order of the id output and Name tag.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 5 elements, but at least one must be present. | `list(string)` | `null` | no | | maintenance\_window | Maintenance window | `string` | `"wed:03:00-wed:04:00"` | no | -| name | Name of the application | `string` | n/a | yes | -| namespace | Namespace (e.g. `eg` or `cp`) | `string` | `""` | no | +| name | Solution name, e.g. 'app' or 'jenkins' | `string` | `null` | no | +| namespace | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | `string` | `null` | no | | notification\_topic\_arn | Notification topic arn | `string` | `""` | no | | 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 | 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 | | port | Redis port | `number` | `6379` | no | +| regex\_replace\_chars | Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`.
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 | 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 | | snapshot\_retention\_limit | The number of days for which ElastiCache will retain automatic cache cluster snapshots before deleting them. | `number` | `0` | no | | snapshot\_window | The daily time range (in UTC) during which ElastiCache will begin taking a daily snapshot of your cache cluster. | `string` | `"06:30-07:30"` | no | -| stage | Stage (e.g. `prod`, `dev`, `staging`) | `string` | `""` | no | +| stage | Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no | | subnets | Subnet IDs | `list(string)` | `[]` | no | -| tags | Additional tags (\_e.g.\_ map("BusinessUnit","ABC") | `map(string)` | `{}` | no | +| tags | Additional tags (e.g. `map('BusinessUnit','XYZ')` | `map(string)` | `{}` | no | | transit\_encryption\_enabled | Enable TLS | `bool` | `true` | no | | use\_existing\_security\_groups | Flag to enable/disable creation of Security Group in the module. Set to `true` to disable Security Group creation and provide a list of existing security Group IDs in `existing_security_groups` to place the cluster into | `bool` | `false` | no | | vpc\_id | VPC ID | `string` | n/a | yes | diff --git a/examples/complete/context.tf b/examples/complete/context.tf new file mode 100644 index 0000000..bae0cf1 --- /dev/null +++ b/examples/complete/context.tf @@ -0,0 +1,167 @@ +# +# ONLY EDIT THIS FILE IN github.com/cloudposse/terraform-null-label +# All other instances of this file should be a copy of that one +# +# +# Copy this file from https://github.com/cloudposse/terraform-null-label/blob/master/exports/context.tf +# and then place it in your Terraform module to automatically get +# Cloud Posse's standard configuration inputs suitable for passing +# to Cloud Posse modules. +# +# Modules should access the whole context as `module.this.context` +# to get the input variables with nulls for defaults, +# for example `context = module.this.context`, +# and access individual variables as `module.this.`, +# with final values filled in. +# +# For example, when using defaults, `module.this.context.delimiter` +# will be null, and `module.this.delimiter` will be `-` (hyphen). +# + +module "this" { + source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.19.2" + + enabled = var.enabled + namespace = var.namespace + environment = var.environment + stage = var.stage + name = var.name + delimiter = var.delimiter + attributes = var.attributes + tags = var.tags + additional_tag_map = var.additional_tag_map + label_order = var.label_order + regex_replace_chars = var.regex_replace_chars + id_length_limit = var.id_length_limit + + context = var.context +} + +# Copy contents of cloudposse/terraform-null-label/variables.tf here + +variable "context" { + type = object({ + enabled = bool + namespace = string + environment = string + stage = string + name = string + delimiter = string + attributes = list(string) + tags = map(string) + additional_tag_map = map(string) + regex_replace_chars = string + label_order = list(string) + id_length_limit = number + }) + default = { + enabled = true + namespace = null + environment = null + stage = null + name = null + delimiter = null + attributes = [] + tags = {} + additional_tag_map = {} + regex_replace_chars = null + label_order = [] + id_length_limit = null + } + description = <<-EOT + 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. + EOT +} + +variable "enabled" { + type = bool + default = null + description = "Set to false to prevent the module from creating any resources" +} + +variable "namespace" { + type = string + default = null + description = "Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp'" +} + +variable "environment" { + type = string + default = null + description = "Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT'" +} + +variable "stage" { + type = string + default = null + description = "Stage, e.g. 'prod', 'staging', 'dev', OR 'source', 'build', 'test', 'deploy', 'release'" +} + +variable "name" { + type = string + default = null + description = "Solution name, e.g. 'app' or 'jenkins'" +} + +variable "delimiter" { + type = string + default = null + description = <<-EOT + Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`. + Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. + EOT +} + +variable "attributes" { + type = list(string) + default = [] + description = "Additional attributes (e.g. `1`)" +} + +variable "tags" { + type = map(string) + default = {} + description = "Additional tags (e.g. `map('BusinessUnit','XYZ')`" +} + +variable "additional_tag_map" { + type = map(string) + default = {} + description = "Additional tags for appending to tags_as_list_of_maps. Not added to `tags`." +} + +variable "label_order" { + type = list(string) + default = null + description = <<-EOT + The naming order of the id output and Name tag. + Defaults to ["namespace", "environment", "stage", "name", "attributes"]. + You can omit any of the 5 elements, but at least one must be present. + EOT +} + +variable "regex_replace_chars" { + type = string + default = null + description = <<-EOT + Regex to replace chars with empty string in `namespace`, `environment`, `stage` and `name`. + If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. + EOT +} + +variable "id_length_limit" { + type = number + default = null + description = <<-EOT + Limit `id` to this many characters. + Set to `0` for unlimited length. + Set to `null` for default, which is `0`. + Does not affect `id_full`. + EOT +} + +#### End of copy of cloudposse/terraform-null-label/variables.tf diff --git a/examples/complete/fixtures.us-east-2.tfvars b/examples/complete/fixtures.us-east-2.tfvars index 8cec532..94c7259 100644 --- a/examples/complete/fixtures.us-east-2.tfvars +++ b/examples/complete/fixtures.us-east-2.tfvars @@ -1,3 +1,5 @@ +enabled = true + region = "us-east-2" availability_zones = ["us-east-2a", "us-east-2b"] @@ -21,3 +23,5 @@ at_rest_encryption_enabled = false transit_encryption_enabled = true zone_id = "Z3SO0TKDDQ0RGG" + +cloudwatch_metric_alarms_enabled = false diff --git a/examples/complete/main.tf b/examples/complete/main.tf index be5a950..9ad33bb 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -3,44 +3,43 @@ provider "aws" { } module "vpc" { - source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.16.1" - namespace = var.namespace - stage = var.stage - name = var.name + source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.17.0" + cidr_block = "172.16.0.0/16" + + context = module.this.context } module "subnets" { - source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.26.0" + source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.30.0" + availability_zones = var.availability_zones - namespace = var.namespace - stage = var.stage - name = var.name vpc_id = module.vpc.vpc_id igw_id = module.vpc.igw_id cidr_block = module.vpc.vpc_cidr_block - nat_gateway_enabled = true + nat_gateway_enabled = false nat_instance_enabled = false + + context = module.this.context } module "redis" { - source = "../../" - availability_zones = var.availability_zones - namespace = var.namespace - stage = var.stage - name = var.name - zone_id = var.zone_id - vpc_id = module.vpc.vpc_id - allowed_security_groups = [module.vpc.vpc_default_security_group_id] - subnets = module.subnets.private_subnet_ids - cluster_size = var.cluster_size - instance_type = var.instance_type - apply_immediately = true - automatic_failover_enabled = false - engine_version = var.engine_version - family = var.family - at_rest_encryption_enabled = var.at_rest_encryption_enabled - transit_encryption_enabled = var.transit_encryption_enabled + source = "../../" + + availability_zones = var.availability_zones + zone_id = var.zone_id + vpc_id = module.vpc.vpc_id + allowed_security_groups = [module.vpc.vpc_default_security_group_id] + subnets = module.subnets.private_subnet_ids + cluster_size = var.cluster_size + instance_type = var.instance_type + apply_immediately = true + automatic_failover_enabled = false + engine_version = var.engine_version + family = var.family + at_rest_encryption_enabled = var.at_rest_encryption_enabled + transit_encryption_enabled = var.transit_encryption_enabled + cloudwatch_metric_alarms_enabled = var.cloudwatch_metric_alarms_enabled parameter = [ { @@ -48,4 +47,6 @@ module "redis" { value = "lK" } ] + + context = module.this.context } diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf index f7e56e3..5d1f762 100644 --- a/examples/complete/variables.tf +++ b/examples/complete/variables.tf @@ -8,21 +8,6 @@ variable "availability_zones" { description = "Availability zone IDs" } -variable "namespace" { - type = string - description = "Namespace (e.g. `eg` or `cp`)" -} - -variable "stage" { - type = string - description = "Stage (e.g. `prod`, `dev`, `staging`)" -} - -variable "name" { - type = string - description = "Name (e.g. `app` or `cluster`)" -} - variable "cluster_size" { type = number description = "Number of nodes in cluster" @@ -57,3 +42,8 @@ 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/examples/complete/versions.tf b/examples/complete/versions.tf new file mode 100644 index 0000000..723d6b1 --- /dev/null +++ b/examples/complete/versions.tf @@ -0,0 +1,8 @@ +terraform { + required_version = ">= 0.12.0" + + required_providers { + aws = ">= 2.0" + null = ">= 2.0" + } +} diff --git a/main.tf b/main.tf index 4225a26..962b429 100644 --- a/main.tf +++ b/main.tf @@ -1,26 +1,15 @@ -module "label" { - source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.17.0" - enabled = var.enabled - namespace = var.namespace - name = var.name - stage = var.stage - delimiter = var.delimiter - attributes = var.attributes - tags = var.tags -} - # # Security Group Resources # resource "aws_security_group" "default" { - count = var.enabled && var.use_existing_security_groups == false ? 1 : 0 + count = module.this.enabled && var.use_existing_security_groups == false ? 1 : 0 vpc_id = var.vpc_id - name = module.label.id - tags = module.label.tags + name = module.this.id + tags = module.this.tags } resource "aws_security_group_rule" "egress" { - count = var.enabled && var.use_existing_security_groups == false ? 1 : 0 + count = module.this.enabled && var.use_existing_security_groups == false ? 1 : 0 description = "Allow all egress traffic" from_port = 0 to_port = 0 @@ -31,7 +20,7 @@ resource "aws_security_group_rule" "egress" { } resource "aws_security_group_rule" "ingress_security_groups" { - count = var.enabled && var.use_existing_security_groups == false ? length(var.allowed_security_groups) : 0 + count = module.this.enabled && var.use_existing_security_groups == false ? length(var.allowed_security_groups) : 0 description = "Allow inbound traffic from existing Security Groups" from_port = var.port to_port = var.port @@ -42,7 +31,7 @@ resource "aws_security_group_rule" "ingress_security_groups" { } resource "aws_security_group_rule" "ingress_cidr_blocks" { - count = var.enabled && var.use_existing_security_groups == false && length(var.allowed_cidr_blocks) > 0 ? 1 : 0 + count = module.this.enabled && var.use_existing_security_groups == false && length(var.allowed_cidr_blocks) > 0 ? 1 : 0 description = "Allow inbound traffic from CIDR blocks" from_port = var.port to_port = var.port @@ -54,6 +43,7 @@ resource "aws_security_group_rule" "ingress_cidr_blocks" { locals { 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 member_clusters_count = (var.cluster_mode_enabled @@ -62,24 +52,23 @@ locals { : var.cluster_size ) - elasticache_member_clusters = var.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" { - count = var.enabled && var.elasticache_subnet_group_name == "" && length(var.subnets) > 0 ? 1 : 0 - name = module.label.id + count = module.this.enabled && var.elasticache_subnet_group_name == "" && length(var.subnets) > 0 ? 1 : 0 + name = module.this.id subnet_ids = var.subnets } resource "aws_elasticache_parameter_group" "default" { - count = var.enabled ? 1 : 0 - name = module.label.id + count = module.this.enabled ? 1 : 0 + name = module.this.id family = var.family - - dynamic "parameter" { - for_each = var.cluster_mode_enabled ? concat([{ "name" = "cluster-enabled", "value" = "yes" }], var.parameter) : var.parameter + for_each = var.cluster_mode_enabled ? concat([{ name = "cluster-enabled", value = "yes" }], var.parameter) : var.parameter content { name = parameter.value.name value = parameter.value.value @@ -88,11 +77,11 @@ resource "aws_elasticache_parameter_group" "default" { } resource "aws_elasticache_replication_group" "default" { - count = var.enabled ? 1 : 0 + count = module.this.enabled ? 1 : 0 auth_token = var.transit_encryption_enabled ? var.auth_token : null - replication_group_id = var.replication_group_id == "" ? module.label.id : var.replication_group_id - replication_group_description = module.label.id + replication_group_id = var.replication_group_id == "" ? module.this.id : var.replication_group_id + replication_group_description = module.this.id node_type = var.instance_type number_cache_clusters = var.cluster_mode_enabled ? null : var.cluster_size port = var.port @@ -111,7 +100,7 @@ resource "aws_elasticache_replication_group" "default" { snapshot_retention_limit = var.snapshot_retention_limit apply_immediately = var.apply_immediately - tags = module.label.tags + tags = module.this.tags dynamic "cluster_mode" { for_each = var.cluster_mode_enabled ? ["true"] : [] @@ -120,14 +109,13 @@ resource "aws_elasticache_replication_group" "default" { num_node_groups = var.cluster_mode_num_node_groups } } - } # # CloudWatch Resources # resource "aws_cloudwatch_metric_alarm" "cache_cpu" { - count = var.enabled ? local.member_clusters_count : 0 + count = module.this.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" @@ -149,7 +137,7 @@ resource "aws_cloudwatch_metric_alarm" "cache_cpu" { } resource "aws_cloudwatch_metric_alarm" "cache_memory" { - count = var.enabled ? local.member_clusters_count : 0 + count = module.this.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" @@ -171,10 +159,13 @@ resource "aws_cloudwatch_metric_alarm" "cache_memory" { } module "dns" { - source = "git::https://github.com/cloudposse/terraform-aws-route53-cluster-hostname.git?ref=tags/0.6.0" - enabled = var.enabled && var.zone_id != "" ? true : false - name = var.dns_subdomain != "" ? var.dns_subdomain : var.name - ttl = 60 - zone_id = 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)] + source = "git::https://github.com/cloudposse/terraform-aws-route53-cluster-hostname.git?ref=tags/0.7.0" + + enabled = module.this.enabled && var.zone_id != "" ? true : false + dns_name = var.dns_subdomain != "" ? var.dns_subdomain : module.this.id + ttl = 60 + zone_id = 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)] + + context = module.this.context } diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go index 5756cf5..b186275 100644 --- a/test/src/examples_complete_test.go +++ b/test/src/examples_complete_test.go @@ -1,7 +1,10 @@ package test import ( + "math/rand" + "strconv" "testing" + "time" "github.com/gruntwork-io/terratest/modules/terraform" "github.com/stretchr/testify/assert" @@ -11,12 +14,20 @@ import ( func TestExamplesComplete(t *testing.T) { t.Parallel() + rand.Seed(time.Now().UnixNano()) + + randId := strconv.Itoa(rand.Intn(100000)) + attributes := []string{randId} + terraformOptions := &terraform.Options{ // The path to where our Terraform code is located TerraformDir: "../../examples/complete", Upgrade: true, // Variables to pass to our Terraform code using -var-file options VarFiles: []string{"fixtures.us-east-2.tfvars"}, + Vars: map[string]interface{}{ + "attributes": attributes, + }, } // At the end of the test, run `terraform destroy` to clean up any resources that were created @@ -43,10 +54,10 @@ func TestExamplesComplete(t *testing.T) { // Run `terraform output` to get the value of an output variable clusterHost := terraform.Output(t, terraformOptions, "cluster_host") // Verify we're getting back the outputs we expect - assert.Equal(t, "redis-test.testing.cloudposse.co", clusterHost) + assert.Equal(t, "eg-test-redis-test-"+randId+".testing.cloudposse.co", clusterHost) // Run `terraform output` to get the value of an output variable clusterId := terraform.Output(t, terraformOptions, "cluster_id") // Verify we're getting back the outputs we expect - assert.Equal(t, "eg-test-redis-test", clusterId) + assert.Equal(t, "eg-test-redis-test-"+randId, clusterId) } diff --git a/test/src/go.mod b/test/src/go.mod index bddfc6d..bb9d38c 100644 --- a/test/src/go.mod +++ b/test/src/go.mod @@ -1,6 +1,6 @@ module github.com/cloudposse/terraform-aws-elasticache-redis -go 1.13 +go 1.14 require ( github.com/aws/aws-sdk-go v1.34.6 // indirect diff --git a/variables.tf b/variables.tf index 34da5a9..bd3ebd0 100644 --- a/variables.tf +++ b/variables.tf @@ -1,26 +1,3 @@ -variable "enabled" { - type = bool - description = "Set to false to prevent the module from creating any resources" - default = true -} - -variable "namespace" { - type = string - description = "Namespace (e.g. `eg` or `cp`)" - default = "" -} - -variable "stage" { - type = string - description = "Stage (e.g. `prod`, `dev`, `staging`)" - default = "" -} - -variable "name" { - type = string - description = "Name of the application" -} - variable "use_existing_security_groups" { type = bool 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" @@ -180,24 +157,6 @@ variable "dns_subdomain" { description = "The subdomain to use for the CNAME record. If not provided then the CNAME record will use var.name." } -variable "delimiter" { - type = string - default = "-" - description = "Delimiter between `name`, `namespace`, `stage` and `attributes`" -} - -variable "attributes" { - type = list(string) - description = "Additional attributes (_e.g._ \"1\")" - default = [] -} - -variable "tags" { - type = map(string) - description = "Additional tags (_e.g._ map(\"BusinessUnit\",\"ABC\")" - default = {} -} - variable "auth_token" { type = string description = "Auth token for password protecting redis, `transit_encryption_enabled` must be set to `true`. Password must be longer than 16 chars" @@ -245,3 +204,9 @@ variable "cluster_mode_num_node_groups" { description = "Number of node groups (shards) for this Redis replication group. Changing this number will trigger an online resizing operation before other settings modifications" default = 0 } + +variable "cloudwatch_metric_alarms_enabled" { + type = bool + description = "Boolean flag to enable/disable CloudWatch metrics alarms" + default = false +}