147 lines
7.2 KiB
HCL
Executable File
147 lines
7.2 KiB
HCL
Executable File
locals {
|
|
|
|
defaults = {
|
|
label_order = ["namespace", "environment", "stage", "name", "attributes"]
|
|
regex_replace_chars = "/[^-a-zA-Z0-9]/"
|
|
delimiter = "-"
|
|
replacement = ""
|
|
id_length_limit = 0
|
|
id_hash_length = 5
|
|
label_key_case = "title"
|
|
label_value_case = "lower"
|
|
}
|
|
|
|
# So far, we have decided not to allow overriding replacement or id_hash_length
|
|
replacement = local.defaults.replacement
|
|
id_hash_length = local.defaults.id_hash_length
|
|
|
|
# The values provided by variables supersede the values inherited from the context object,
|
|
# except for tags and attributes which are merged.
|
|
input = {
|
|
# It would be nice to use coalesce here, but we cannot, because it
|
|
# is an error for all the arguments to coalesce to be empty.
|
|
enabled = var.enabled == null ? var.context.enabled : var.enabled
|
|
namespace = var.namespace == null ? var.context.namespace : var.namespace
|
|
environment = var.environment == null ? var.context.environment : var.environment
|
|
stage = var.stage == null ? var.context.stage : var.stage
|
|
name = var.name == null ? var.context.name : var.name
|
|
delimiter = var.delimiter == null ? var.context.delimiter : var.delimiter
|
|
# modules tack on attributes (passed by var) to the end of the list (passed by context)
|
|
attributes = compact(distinct(concat(coalesce(var.context.attributes, []), coalesce(var.attributes, []))))
|
|
tags = merge(var.context.tags, var.tags)
|
|
|
|
additional_tag_map = merge(var.context.additional_tag_map, var.additional_tag_map)
|
|
label_order = var.label_order == null ? var.context.label_order : var.label_order
|
|
regex_replace_chars = var.regex_replace_chars == null ? var.context.regex_replace_chars : var.regex_replace_chars
|
|
id_length_limit = var.id_length_limit == null ? var.context.id_length_limit : var.id_length_limit
|
|
label_key_case = var.label_key_case == null ? lookup(var.context, "label_key_case", null) : var.label_key_case
|
|
label_value_case = var.label_value_case == null ? lookup(var.context, "label_value_case", null) : var.label_value_case
|
|
}
|
|
|
|
|
|
enabled = local.input.enabled
|
|
regex_replace_chars = coalesce(local.input.regex_replace_chars, local.defaults.regex_replace_chars)
|
|
|
|
# string_label_names are names of inputs that are strings (not list of strings) used as labels
|
|
string_label_names = ["name", "namespace", "environment", "stage"]
|
|
normalized_labels = { for k in local.string_label_names : k =>
|
|
local.input[k] == null ? "" : replace(local.input[k], local.regex_replace_chars, local.replacement)
|
|
}
|
|
normalized_attributes = compact(distinct([for v in local.input.attributes : replace(v, local.regex_replace_chars, local.replacement)]))
|
|
|
|
formatted_labels = { for k in local.string_label_names : k => local.label_value_case == "none" ? local.normalized_labels[k] :
|
|
local.label_value_case == "title" ? title(lower(local.normalized_labels[k])) :
|
|
local.label_value_case == "upper" ? upper(local.normalized_labels[k]) : lower(local.normalized_labels[k])
|
|
}
|
|
|
|
attributes = compact(distinct([
|
|
for v in local.normalized_attributes : (local.label_value_case == "none" ? v :
|
|
local.label_value_case == "title" ? title(lower(v)) :
|
|
local.label_value_case == "upper" ? upper(v) : lower(v))
|
|
]))
|
|
|
|
name = local.formatted_labels["name"]
|
|
namespace = local.formatted_labels["namespace"]
|
|
environment = local.formatted_labels["environment"]
|
|
stage = local.formatted_labels["stage"]
|
|
|
|
delimiter = local.input.delimiter == null ? local.defaults.delimiter : local.input.delimiter
|
|
label_order = local.input.label_order == null ? local.defaults.label_order : coalescelist(local.input.label_order, local.defaults.label_order)
|
|
id_length_limit = local.input.id_length_limit == null ? local.defaults.id_length_limit : local.input.id_length_limit
|
|
label_key_case = local.input.label_key_case == null ? local.defaults.label_key_case : local.input.label_key_case
|
|
label_value_case = local.input.label_value_case == null ? local.defaults.label_value_case : local.input.label_value_case
|
|
|
|
additional_tag_map = merge(var.context.additional_tag_map, var.additional_tag_map)
|
|
|
|
tags = merge(local.generated_tags, local.input.tags)
|
|
|
|
tags_as_list_of_maps = flatten([
|
|
for key in keys(local.tags) : merge(
|
|
{
|
|
key = key
|
|
value = local.tags[key]
|
|
}, var.additional_tag_map)
|
|
])
|
|
|
|
tags_context = {
|
|
# For AWS we need `Name` to be disambiguated since it has a special meaning
|
|
name = local.id
|
|
namespace = local.namespace
|
|
environment = local.environment
|
|
stage = local.stage
|
|
attributes = local.id_context.attributes
|
|
}
|
|
|
|
generated_tags = {
|
|
for l in keys(local.tags_context) :
|
|
local.label_key_case == "upper" ? upper(l) : (
|
|
local.label_key_case == "lower" ? lower(l) : title(lower(l))
|
|
) => local.tags_context[l] if length(local.tags_context[l]) > 0
|
|
}
|
|
|
|
id_context = {
|
|
name = local.name
|
|
namespace = local.namespace
|
|
environment = local.environment
|
|
stage = local.stage
|
|
attributes = join(local.delimiter, local.attributes)
|
|
}
|
|
|
|
labels = [for l in local.label_order : local.id_context[l] if length(local.id_context[l]) > 0]
|
|
|
|
id_full = join(local.delimiter, local.labels)
|
|
# Create a truncated ID if needed
|
|
delimiter_length = length(local.delimiter)
|
|
# Calculate length of normal part of ID, leaving room for delimiter and hash
|
|
id_truncated_length_limit = local.id_length_limit - (local.id_hash_length + local.delimiter_length)
|
|
# Truncate the ID and ensure a single (not double) trailing delimiter
|
|
id_truncated = local.id_truncated_length_limit <= 0 ? "" : "${trimsuffix(substr(local.id_full, 0, local.id_truncated_length_limit), local.delimiter)}${local.delimiter}"
|
|
# Support usages that disallow numeric characters. Would prefer tr 0-9 q-z but Terraform does not support it.
|
|
id_hash_plus = "${md5(local.id_full)}qrstuvwxyz"
|
|
id_hash_case = local.label_value_case == "title" ? title(local.id_hash_plus) : local.label_value_case == "upper" ? upper(local.id_hash_plus) : local.label_value_case == "lower" ? lower(local.id_hash_plus) : local.id_hash_plus
|
|
id_hash = replace(local.id_hash_case, local.regex_replace_chars, local.replacement)
|
|
# Create the short ID by adding a hash to the end of the truncated ID
|
|
id_short = substr("${local.id_truncated}${local.id_hash}", 0, local.id_length_limit)
|
|
id = local.id_length_limit != 0 && length(local.id_full) > local.id_length_limit ? local.id_short : local.id_full
|
|
|
|
|
|
# Context of this label to pass to other label modules
|
|
output_context = {
|
|
enabled = local.enabled
|
|
name = local.name
|
|
namespace = local.namespace
|
|
environment = local.environment
|
|
stage = local.stage
|
|
delimiter = local.delimiter
|
|
attributes = local.attributes
|
|
tags = local.tags
|
|
additional_tag_map = local.additional_tag_map
|
|
label_order = local.label_order
|
|
regex_replace_chars = local.regex_replace_chars
|
|
id_length_limit = local.id_length_limit
|
|
label_key_case = local.label_key_case
|
|
label_value_case = local.label_value_case
|
|
}
|
|
|
|
}
|