Skip to content

Commit

Permalink
BFD-3696: Standardize MGMT Base Config Module (#2472)
Browse files Browse the repository at this point in the history
Co-authored-by: aschey-forpeople <[email protected]>
  • Loading branch information
malessi and aschey-forpeople authored Nov 4, 2024
1 parent cdf42be commit 1874391
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 199 deletions.
57 changes: 6 additions & 51 deletions ops/terraform/env/mgmt/base_config/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,8 @@ locals {
}
)

yaml = data.external.yaml.result
common_sensitive = {
for key, value in local.yaml
: key => value if contains(split("/", key), "common") && value != "UNDEFINED"
}
cpm_sensitive = {
for key, value in local.yaml
: key => value if contains(split("/", key), "cpm") && value != "UNDEFINED"
}
jenkins_sensitive = {
for key, value in local.yaml
: key => value if contains(split("/", key), "jenkins") && value != "UNDEFINED"
}
quicksight_sensitive = {
for key, value in local.yaml
: key => value if contains(split("/", key), "quicksight") && value != "UNDEFINED"
}
yaml = data.external.yaml.result
defined_ssm_parameters = { for key, value in local.yaml : key => value if value != "UNDEFINED" }
}

resource "aws_kms_key" "primary_config" {
Expand Down Expand Up @@ -100,42 +85,12 @@ resource "aws_kms_alias" "secondary_config" {
}
##

resource "aws_ssm_parameter" "common_sensitive" {
for_each = local.common_sensitive

key_id = local.kms_key_id
name = each.key
overwrite = true
type = "SecureString"
value = each.value
}

resource "aws_ssm_parameter" "cpm_sensitive" {
for_each = local.cpm_sensitive

key_id = local.kms_key_id
name = each.key
overwrite = true
type = "SecureString"
value = each.value
}

resource "aws_ssm_parameter" "jenkins_sensitive" {
for_each = local.jenkins_sensitive

key_id = local.kms_key_id
name = each.key
overwrite = true
type = "SecureString"
value = each.value
}

resource "aws_ssm_parameter" "quicksight_sensitive" {
for_each = local.quicksight_sensitive
resource "aws_ssm_parameter" "ssm" {
for_each = local.defined_ssm_parameters

key_id = local.kms_key_id
key_id = strcontains(each.key, "/sensitive/") ? local.kms_key_id : null
name = each.key
overwrite = true
type = "SecureString"
type = strcontains(each.key, "/sensitive/") ? "SecureString" : "String"
value = each.value
}
100 changes: 4 additions & 96 deletions ops/terraform/env/mgmt/base_config/scripts/read-and-decrypt-yaml.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,109 +42,17 @@ readonly CMK_LOOKUP
CMK_ARN="${CMK_ARN_OVERRIDE:-"$CMK_LOOKUP"}"
readonly CMK_ARN

if test -f "${YAML_FILE}"; then
# Returns an object like
# {
# "/bfd/...": {
# "sensitive": <"sensitive"/"nonsensitive">
# },
# ...
# }
# if the configuration parameter's value includes a <<CIPHER>> token, indicating that the value is
# sensitive and should be encrypted. Note that some keys may be sensitive themselves, and so will
# be encrypted, so the JSON string returned will need to be decrypted by cipher to restore the
# actual keys
encrypted_params_sensitivity="$(
yq eval -o=j <"$YAML_FILE" |
jq 'tostream
| select(length==2)
| .[0] |= (
map(strings)
| join("/")
)
| {
(.[0]): {
"sensitivity": (
if (.[1] | tostring | contains("<<CIPHER>>")) == true then
"sensitive"
else
"nonsensitive"
end
)
}
}' |
jq -s 'add'
)"
# This will decrypt any encrypted keys allowing this script to merge the sensitivity of all keys
# with their decrypted values, even if the key is encrypted
decrypted_params_sensitivity="$(
kotlin "$REPO_ROOT/apps/utils/cipher/cipher.main.kts" \
--key "$CMK_ARN" cat <(echo "$encrypted_params_sensitivity")
)"
sensitivity_with_value="$(
kotlin "$REPO_ROOT/apps/utils/cipher/cipher.main.kts" \
--key "$CMK_ARN" cat "${YAML_FILE}" |
yq eval -o=j |
# Merges the resulting decrypted YAML configuration (now JSON) into an object like
# {
# "/bfd/...": {
# "value": "...",
# "sensitivity": <"sensitive"/"nonsensitive">
# },
# ...
# }
jq 'tostream
| select(length==2)
| .[0] |= (
map(strings)
| join("/")
)
| {
(.[0]): {
"value": (.[1] | tostring)
}
}' |
jq -s --argjson sensitivity "$decrypted_params_sensitivity" 'add * $sensitivity'
)"

# FUTURE: This is awful, but done so that compatability can be had with existing Terraform state
# and so that these changes are not as significant for services that consume configuration from
# SSM. Clean this up in the future when parameters are standardized.
# Given an object like:
# {
# "/bfd/...": {
# "value": "...",
# "sensitivity": <"sensitive"/"nonsensitive">
# },
# ...
# }
# Returns an object like:
# {
# "/bfd/.../.../<sensitive OR nonsensitive>/...": "...",
# "/bfd/...": "...",
# ...
# }
untemplated_json="$(jq 'with_entries(
.value as $value
| .key |= (
split("/")
| (
if .[2] == "pipeline" and (.[3] == "shared" or .[3] == "rda" or .[3] == "ccw") then
(["/" + .[0], .[1], .[2], .[3], $value.sensitivity] + .[4:length]) | join("/")
else
(["/" + .[0], .[1], .[2], $value.sensitivity] + .[3:length]) | join("/")
end
)
)
| .value |= .value
)' <<<"$sensitivity_with_value")"
if test -f "$YAML_FILE"; then
untemplated_json="$(kotlin "${REPO_ROOT}/apps/utils/cipher/cipher.main.kts" \
--key "$CMK_ARN" cat "$YAML_FILE" | yq 'map_values(tostring)' --output-format=json)"

# Using eval we can exploit heredoc to template any values (like ${env}) within the final JSON,
# provided that the templated variable is defined within the environment or within this script.
# This enables ephemeral configuration support.
eval "cat <<EOF
$untemplated_json
EOF" 2>/dev/null

else
echo '{}'
fi
Loading

0 comments on commit 1874391

Please sign in to comment.