Skip to content

Commit

Permalink
feat: add ability to set service discovery name for redis kvstore (#15)
Browse files Browse the repository at this point in the history
## Description
<!--- Describe your changes in detail -->

## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->

## Breaking Changes
<!-- Does this break backwards compatibility with the current major
version? -->
<!-- If so, please provide an explanation why it is necessary. -->

## How Has This Been Tested?
- [ ] I have updated at least one of the `examples/*` to demonstrate and
validate my change(s)
- [ ] I have tested and validated these changes using one or more of the
provided `examples/*` projects
<!--- Users should start with an existing example as its written, deploy
it, then check their changes against it -->
<!--- This will highlight breaking/disruptive changes. Once you have
checked, deploy your changes to verify -->
<!--- Please describe how you tested your changes -->
- [ ] I have executed `pre-commit run -a` on my pull request
<!--- Please see
https://github.com/antonbabenko/pre-commit-terraform#how-to-install for
how to install -->
  • Loading branch information
applike-ss authored Jan 20, 2023
1 parent 1d0731e commit 18edb49
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 55 deletions.
19 changes: 9 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@ Terraform module which creates a kvstore backed by dynamodb and redis

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.6 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.45.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.30.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.45.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.30.0 |

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_container_definition"></a> [container\_definition](#module\_container\_definition) | cloudposse/ecs-container-definition/aws | 0.58.1 |
| <a name="module_ddb"></a> [ddb](#module\_ddb) | github.com/justtrackio/terraform-aws-dynamodb-table | v1.0.1 |
| <a name="module_ddb"></a> [ddb](#module\_ddb) | justtrackio/dynamodb-table/aws | 1.0.2 |
| <a name="module_ddb_label"></a> [ddb\_label](#module\_ddb\_label) | cloudposse/label/null | 0.25.0 |
| <a name="module_exec_label"></a> [exec\_label](#module\_exec\_label) | cloudposse/label/null | 0.25.0 |
| <a name="module_redis"></a> [redis](#module\_redis) | cloudposse/ecs-alb-service-task/aws | 0.66.4 |
Expand Down Expand Up @@ -50,15 +50,14 @@ Terraform module which creates a kvstore backed by dynamodb and redis
| <a name="input_ddb_autoscale_read_schedule"></a> [ddb\_autoscale\_read\_schedule](#input\_ddb\_autoscale\_read\_schedule) | Provides an DynamoDB autoscaling scheduled action resource | <pre>list(object({<br> schedule = string<br> min_capacity = number<br> max_capacity = number<br> }))</pre> | `[]` | no |
| <a name="input_ddb_autoscale_write_schedule"></a> [ddb\_autoscale\_write\_schedule](#input\_ddb\_autoscale\_write\_schedule) | Provides an DynamoDB autoscaling scheduled action resource | <pre>list(object({<br> schedule = string<br> min_capacity = number<br> max_capacity = number<br> }))</pre> | `[]` | no |
| <a name="input_ddb_billing_mode"></a> [ddb\_billing\_mode](#input\_ddb\_billing\_mode) | The billing mode for the DDB table | `string` | `"PROVISIONED"` | no |
| <a name="input_ddb_label_order"></a> [ddb\_label\_order](#input\_ddb\_label\_order) | The order in which the labels (ID elements) appear in the `id`.<br>Defaults to ["namespace", "environment", "stage", "name", "attributes"].<br>You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no |
| <a name="input_delimiter"></a> [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.<br>Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no |
| <a name="input_descriptor_formats"></a> [descriptor\_formats](#input\_descriptor\_formats) | Describe additional descriptors to be output in the `descriptors` output map.<br>Map of maps. Keys are names of descriptors. Values are maps of the form<br>`{<br> format = string<br> labels = list(string)<br>}`<br>(Type is `any` so the map values can later be enhanced to provide additional options.)<br>`format` is a Terraform format string to be passed to the `format()` function.<br>`labels` is a list of labels, in order, to pass to `format()` function.<br>Label values will be normalized before being passed to `format()` so they will be<br>identical to how they appear in `id`.<br>Default is `{}` (`descriptors` output will be empty). | `any` | `{}` | no |
| <a name="input_enabled"></a> [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no |
| <a name="input_environment"></a> [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no |
| <a name="input_iam_label_order"></a> [iam\_label\_order](#input\_iam\_label\_order) | The order in which the labels (ID elements) appear in the `id`.<br>Defaults to ["namespace", "environment", "stage", "name", "attributes"].<br>You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no |
| <a name="input_id_length_limit"></a> [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).<br>Set to `0` for unlimited length.<br>Set to `null` for keep the existing setting, which defaults to `0`.<br>Does not affect `id_full`. | `number` | `null` | no |
| <a name="input_label_key_case"></a> [label\_key\_case](#input\_label\_key\_case) | Controls the letter case of the `tags` keys (label names) for tags generated by this module.<br>Does not affect keys of tags passed in via the `tags` input.<br>Possible values: `lower`, `title`, `upper`.<br>Default value: `title`. | `string` | `null` | no |
| <a name="input_label_order"></a> [label\_order](#input\_label\_order) | The order in which the labels (ID elements) appear in the `id`.<br>Defaults to ["namespace", "environment", "stage", "name", "attributes"].<br>You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no |
| <a name="input_label_orders"></a> [label\_orders](#input\_label\_orders) | Overrides the `labels_order` for the different labels to modify ID elements appear in the `id` | <pre>object({<br> iam = optional(list(string)),<br> ddb = optional(list(string)),<br> redis = optional(list(string)),<br> })</pre> | `{}` | no |
| <a name="input_label_value_case"></a> [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of ID elements (labels) as included in `id`,<br>set as tag values, and output by this module individually.<br>Does not affect values of tags passed in via the `tags` input.<br>Possible values: `lower`, `title`, `upper` and `none` (no transformation).<br>Set this to `title` and set `delimiter` to `""` to yield Pascal Case IDs.<br>Default value: `lower`. | `string` | `null` | no |
| <a name="input_labels_as_tags"></a> [labels\_as\_tags](#input\_labels\_as\_tags) | Set of labels (ID elements) to include as tags in the `tags` output.<br>Default is to include all labels.<br>Tags with empty values will not be included in the `tags` output.<br>Set to `[]` to suppress all generated tags.<br>**Notes:**<br> The value of the `name` tag, if included, will be the `id`, not the `name`.<br> Unlike other `null-label` inputs, the initial setting of `labels_as_tags` cannot be<br> changed in later chained modules. Attempts to change it will be silently ignored. | `set(string)` | <pre>[<br> "default"<br>]</pre> | no |
| <a name="input_name"></a> [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.<br>This is the only ID element not also included as a `tag`.<br>The "name" tag is set to the full `id` string. There is no tag with the value of the `name` input. | `string` | `null` | no |
Expand All @@ -67,20 +66,20 @@ Terraform module which creates a kvstore backed by dynamodb and redis
| <a name="input_redis_deployment_maximum_percent"></a> [redis\_deployment\_maximum\_percent](#input\_redis\_deployment\_maximum\_percent) | The upper limit of the number of tasks (as a percentage of `desired_count`) that can be running in a service during a deployment | `number` | `100` | no |
| <a name="input_redis_deployment_minimum_healthy_percent"></a> [redis\_deployment\_minimum\_healthy\_percent](#input\_redis\_deployment\_minimum\_healthy\_percent) | The lower limit (as a percentage of `desired_count`) of the number of tasks that must remain running and healthy in a service during a deployment | `number` | `0` | no |
| <a name="input_redis_desired_count"></a> [redis\_desired\_count](#input\_redis\_desired\_count) | The desired count for the redis service. When using github.com/justtrackio/gosoline kvstore implementation it is currently suggested to use the default '1' | `number` | `1` | no |
| <a name="input_redis_ecs_cluster_arn"></a> [redis\_ecs\_cluster\_arn](#input\_redis\_ecs\_cluster\_arn) | The arn of the ecs cluster to spawn the redis instance in | `string` | n/a | yes |
| <a name="input_redis_ecs_cluster_arn"></a> [redis\_ecs\_cluster\_arn](#input\_redis\_ecs\_cluster\_arn) | The arn of the ecs cluster to spawn the redis instance in | `string` | `null` | no |
| <a name="input_redis_enabled"></a> [redis\_enabled](#input\_redis\_enabled) | Defines if redis is to be used or not | `bool` | `true` | no |
| <a name="input_redis_image_repository"></a> [redis\_image\_repository](#input\_redis\_image\_repository) | Redis image repository to use when use\_redis is true | `string` | `"redis"` | no |
| <a name="input_redis_image_tag"></a> [redis\_image\_tag](#input\_redis\_image\_tag) | Redis image tag to use when use\_redis is true | `string` | `"7-alpine"` | no |
| <a name="input_redis_label_order"></a> [redis\_label\_order](#input\_redis\_label\_order) | The order in which the labels (ID elements) appear in the `id`.<br>Defaults to ["namespace", "environment", "stage", "name", "attributes"].<br>You can omit any of the 6 labels ("tenant" is the 6th), but at least one must be present. | `list(string)` | `null` | no |
| <a name="input_redis_launch_type"></a> [redis\_launch\_type](#input\_redis\_launch\_type) | The launch type on which to run your service. Valid values are `EC2` and `FARGATE` | `string` | `"EC2"` | no |
| <a name="input_redis_memory_size"></a> [redis\_memory\_size](#input\_redis\_memory\_size) | The memory size of the redis instance | `string` | `"25"` | no |
| <a name="input_redis_network_mode"></a> [redis\_network\_mode](#input\_redis\_network\_mode) | The networking mode used for task, can be null or awsvpc | `string` | `null` | no |
| <a name="input_redis_propagate_tags"></a> [redis\_propagate\_tags](#input\_redis\_propagate\_tags) | Specifies whether to propagate the tags from the task definition or the service to the tasks. The valid values are SERVICE and TASK\_DEFINITION | `string` | `"SERVICE"` | no |
| <a name="input_redis_service_discovery_dns_namespace_id"></a> [redis\_service\_discovery\_dns\_namespace\_id](#input\_redis\_service\_discovery\_dns\_namespace\_id) | ID of the aws service discovery dns namespace (generated by the terraform-aws-ocean-ecs module, visible in Cloud Map) | `string` | n/a | yes |
| <a name="input_redis_service_discovery_dns_namespace_id"></a> [redis\_service\_discovery\_dns\_namespace\_id](#input\_redis\_service\_discovery\_dns\_namespace\_id) | ID of the aws service discovery dns namespace (generated by the terraform-aws-ocean-ecs module, visible in Cloud Map) | `string` | `null` | no |
| <a name="input_redis_service_discovery_name"></a> [redis\_service\_discovery\_name](#input\_redis\_service\_discovery\_name) | Name for the service discovery entry in cloudmap | `string` | `null` | no |
| <a name="input_redis_service_memory_size"></a> [redis\_service\_memory\_size](#input\_redis\_service\_memory\_size) | The memory size of the ECS container | `number` | `50` | no |
| <a name="input_redis_service_placement_constraints"></a> [redis\_service\_placement\_constraints](#input\_redis\_service\_placement\_constraints) | service placement constraints for redis service, will set 'type = "memberOf"' and expression = "attribute:spotinst.io/container-instance-lifecycle==od" when environment == "prod" for stability when this var is unset | <pre>set(object({<br> type = string<br> expression = string<br> }))</pre> | `null` | no |
| <a name="input_redis_vpc_id"></a> [redis\_vpc\_id](#input\_redis\_vpc\_id) | ID of the aws vpc in which to spawn the redis service | `string` | `null` | no |
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.<br>Characters matching the regex will be removed from the ID elements.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `"/[^a-zA-Z0-9-_]/"` | no |
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.<br>Characters matching the regex will be removed from the ID elements.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| <a name="input_stage"></a> [stage](#input\_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).<br>Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no |
| <a name="input_tenant"></a> [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 |
Expand Down
21 changes: 12 additions & 9 deletions examples/all-labels/main.tf
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
module "example" {
source = "../.."

tenant = "t"
namespace = "ns"
environment = "env"
stage = "st"
name = "nm"
attributes = ["a1", "a2"]
ddb_label_order = ["environment", "name", "attributes"]
iam_label_order = ["environment", "name", "attributes"]
redis_label_order = ["name", "attributes"]
tenant = "t"
namespace = "ns"
environment = "env"
stage = "st"
name = "nm"
attributes = ["a1", "a2"]
label_orders = {
iam = ["environment", "name", "attributes"]
ddb = ["environment", "name", "attributes"]
redis = ["name", "attributes"]
}
label_value_case = "none" # only for keeping case
redis_ecs_cluster_arn = "arn:aws:ecs:eu-central-1:123456789123:cluster/my-cluster"
redis_service_discovery_dns_namespace_id = "ns-ab12c34defghij5k"
redis_service_discovery_name = "my_kvstore.st.redis"
}
1 change: 1 addition & 0 deletions examples/basic/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ module "example" {
attributes = ["myEntity"]
redis_ecs_cluster_arn = "arn:aws:ecs:eu-central-1:123456789123:cluster/my-cluster"
redis_service_discovery_dns_namespace_id = "ns-ab12c34defghij5k"
redis_service_discovery_name = "my_kvstore.service-name.redis"
}
13 changes: 7 additions & 6 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module "ddb_label" {
delimiter = module.this.delimiter
tags = module.this.tags
additional_tag_map = module.this.additional_tag_map
label_order = var.ddb_label_order
label_order = var.label_orders.ddb
regex_replace_chars = module.this.regex_replace_chars
id_length_limit = module.this.id_length_limit
label_key_case = var.label_key_case
Expand All @@ -33,11 +33,12 @@ module "redis_label" {

context = module.ddb_label.context
attributes = concat(["kvstore_${try(module.this.attributes[0], "")}"], local.has_additional_attributes ? slice(module.this.attributes, 1, length(module.this.attributes)) : [])
label_order = var.redis_label_order
label_order = var.label_orders.redis
}

module "ddb" {
source = "github.com/justtrackio/terraform-aws-dynamodb-table?ref=v1.0.1"
source = "justtrackio/dynamodb-table/aws"
version = "1.0.2"

context = module.ddb_label.context
attributes = concat(["kvstore-${try(module.this.attributes[0], "")}"], local.has_additional_attributes ? slice(module.this.attributes, 1, length(module.this.attributes)) : [])
Expand Down Expand Up @@ -65,7 +66,7 @@ module "task_label" {
source = "cloudposse/label/null"
version = "0.25.0"
attributes = ["task"]
label_order = var.iam_label_order
label_order = var.label_orders.iam

context = module.this.context
}
Expand Down Expand Up @@ -94,7 +95,7 @@ module "exec_label" {
source = "cloudposse/label/null"
version = "0.25.0"
attributes = ["exec"]
label_order = var.iam_label_order
label_order = var.label_orders.iam

context = module.this.context
}
Expand Down Expand Up @@ -207,7 +208,7 @@ module "redis" {

resource "aws_service_discovery_service" "this" {
count = var.redis_enabled ? 1 : 0
name = "kvstore_${try(module.this.attributes[0], "")}.${module.this.stage}-${module.this.name}.redis"
name = var.redis_service_discovery_name

dns_config {
namespace_id = var.redis_service_discovery_dns_namespace_id
Expand Down
42 changes: 14 additions & 28 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,14 @@ variable "ddb_billing_mode" {
description = "The billing mode for the DDB table"
}

variable "ddb_label_order" {
type = list(string)
default = null
description = <<-EOT
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.
EOT
}

variable "iam_label_order" {
type = list(string)
default = null
description = <<-EOT
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.
EOT
variable "label_orders" {
type = object({
iam = optional(list(string)),
ddb = optional(list(string)),
redis = optional(list(string)),
})
default = {}
description = "Overrides the `labels_order` for the different labels to modify ID elements appear in the `id`"
}

variable "redis_cpu_size" {
Expand Down Expand Up @@ -92,16 +82,6 @@ variable "redis_image_tag" {
default = "7-alpine"
}

variable "redis_label_order" {
type = list(string)
default = null
description = <<-EOT
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.
EOT
}

variable "redis_launch_type" {
type = string
description = "The launch type on which to run your service. Valid values are `EC2` and `FARGATE`"
Expand Down Expand Up @@ -152,3 +132,9 @@ variable "redis_vpc_id" {
default = null
description = "ID of the aws vpc in which to spawn the redis service"
}

variable "redis_service_discovery_name" {
type = string
default = null
description = "Name for the service discovery entry in cloudmap"
}
4 changes: 2 additions & 2 deletions versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.45.0"
version = ">= 4.30.0"
}
}
required_version = ">= 1.3.6"
required_version = ">= 1.3.0"
}

0 comments on commit 18edb49

Please sign in to comment.