diff --git a/modules/eso-external-secret/README.md b/modules/eso-external-secret/README.md index 19a9b5fa..82ddc532 100644 --- a/modules/eso-external-secret/README.md +++ b/modules/eso-external-secret/README.md @@ -38,7 +38,7 @@ No modules. |------|-------------|------|---------|:--------:| | [es\_container\_registry](#input\_es\_container\_registry) | The registry URL to be used in dockerconfigjson | `string` | `"us.icr.io"` | no | | [es\_container\_registry\_email](#input\_es\_container\_registry\_email) | Optional - Email to be used in dockerconfigjson | `string` | `null` | no | -| [es\_container\_registry\_secrets\_chain](#input\_es\_container\_registry\_secrets\_chain) | Structure to generate a chain of secrets into a single dockerjsonconfig secret for multiple registries authentication. |
list(object({
es_container_registry = string
sm_secret_id = string # id of the secret storing the apikey that will be used for the secrets chain
es_container_registry_email = optional(string, null)
}))
| `[]` | no | +| [es\_container\_registry\_secrets\_chain](#input\_es\_container\_registry\_secrets\_chain) | Structure to generate a chain of secrets into a single dockerjsonconfig secret for multiple registries authentication. |
list(object({
es_container_registry = string
sm_secret_id = string # id of the secret storing the apikey that will be used for the secrets chain
es_container_registry_email = optional(string, null)
trusted_profile = optional(string, null)
}))
| `[]` | no | | [es\_helm\_rls\_name](#input\_es\_helm\_rls\_name) | Name to use for the helm release for externalsecrets resource. Must be unique in the namespace | `string` | n/a | yes | | [es\_helm\_rls\_namespace](#input\_es\_helm\_rls\_namespace) | Namespace to deploy the helm release for the externalsecret. Default if null is the externalsecret namespace | `string` | `null` | no | | [es\_kubernetes\_namespace](#input\_es\_kubernetes\_namespace) | Namespace to use to generate the externalsecret | `string` | n/a | yes | @@ -54,7 +54,7 @@ No modules. | [sm\_kv\_keyid](#input\_sm\_kv\_keyid) | Secrets-Manager key value (kv) keyid | `string` | `null` | no | | [sm\_kv\_keypath](#input\_sm\_kv\_keypath) | Secrets-Manager key value (kv) keypath | `string` | `null` | no | | [sm\_secret\_id](#input\_sm\_secret\_id) | Secrets-Manager secret ID where source data will be synchronized with Kubernetes secret. It can be null only in the case of a dockerjsonconfig secrets chain | `string` | n/a | yes | -| [sm\_secret\_type](#input\_sm\_secret\_type) | Secrets-manager secret type to be used as source data by ESO. Valid input types are 'arbitrary', 'username\_password' and 'iam\_credentials' | `string` | n/a | yes | +| [sm\_secret\_type](#input\_sm\_secret\_type) | Secrets-manager secret type to be used as source data by ESO. Valid input types are 'iam\_credentials', 'username\_password', 'trusted\_profile', 'arbitrary', 'imported\_cert', 'public\_cert', 'private\_cert', 'kv' | `string` | n/a | yes | ### Outputs diff --git a/modules/eso-external-secret/main.tf b/modules/eso-external-secret/main.tf index 5a3cf511..fdac30e3 100644 --- a/modules/eso-external-secret/main.tf +++ b/modules/eso-external-secret/main.tf @@ -17,9 +17,9 @@ locals { # dockerjsonconfig secrets chain flag is_dockerjsonconfig_chain = length(var.es_container_registry_secrets_chain) > 0 ? true : false - # validation for dockerjsonconfig secrets chain -> if it is a chain the kube secret type must be dockerconfigjson and sm secret type iam_credentials - validate_condition_chain = local.is_dockerjsonconfig_chain == true && (var.es_kubernetes_secret_type != "dockerconfigjson" || var.sm_secret_type != "iam_credentials") # checkov:skip=CKV_SECRET_6: does not require high entropy string as is static value - validate_msg_chain = "If the externalsecret is expected to generate a dockerjsonconfig secrets chain the only supported value for es_kubernetes_secret_type is dockerconfigjson and for sm_secret_type is iam_credentials" + # validation for dockerjsonconfig secrets chain -> if it is a chain the kube secret type must be dockerconfigjson and sm secret types iam_credentials or trusted_profile + validate_condition_chain = local.is_dockerjsonconfig_chain == true && (var.es_kubernetes_secret_type != "dockerconfigjson" || (var.sm_secret_type != "iam_credentials" && var.sm_secret_type != "trusted_profile")) # checkov:skip=CKV_SECRET_6: does not require high entropy string as is static value + validate_msg_chain = "If the externalsecret is expected to generate a dockerjsonconfig secrets chain the only supported value for es_kubernetes_secret_type is dockerconfigjson and for sm_secret_type is iam_credentials or trusted_profile" # tflint-ignore: terraform_unused_declarations validate_check_chain = regex("^${local.validate_msg_chain}$", (!local.validate_condition_chain ? local.validate_msg_chain : "")) @@ -85,6 +85,10 @@ locals { "username" : "iamapikey", "password" : "{{ .secretid_${index} }}", "email" : (element.es_container_registry_email) } : + (element.trusted_profile != null && element.trusted_profile != "") ? + { + "username" : element.trusted_profile, "password" : "{{ .secretid_${index} }}" + } : { "username" : "iamapikey", "password" : "{{ .secretid_${index} }}" } @@ -129,7 +133,7 @@ locals { ### Define kubernetes secret to be installed in cluster for sm_secret_type iam_credentials or arbitrary resource "helm_release" "kubernetes_secret" { - count = (var.sm_secret_type == "iam_credentials" || var.sm_secret_type == "arbitrary") && local.is_dockerjsonconfig_chain == false ? 1 : 0 + count = (var.sm_secret_type == "iam_credentials" || var.sm_secret_type == "arbitrary" || var.sm_secret_type == "trusted_profile") && local.is_dockerjsonconfig_chain == false ? 1 : 0 name = local.helm_secret_name namespace = local.es_helm_rls_namespace chart = "${path.module}/../../chart/${local.helm_raw_chart_name}" @@ -201,12 +205,13 @@ resource "helm_release" "kubernetes_secret_chain_list" { %{for index, element in var.es_container_registry_secrets_chain~} - secretKey: secretid_${index} remoteRef: - key: "${var.sm_secret_type}/${element.sm_secret_id}" + key: "${var.sm_secret_type == "trusted_profile" ? "iam_credentials/${element.sm_secret_id}" : "${var.sm_secret_type}/${element.sm_secret_id}"}" %{endfor~} EOF ] } + ### Define kubernetes secret to be installed in cluster for opaque secret type based on SM user credential secret type resource "helm_release" "kubernetes_secret_user_pw" { count = var.sm_secret_type == "username_password" ? 1 : 0 diff --git a/modules/eso-external-secret/variables.tf b/modules/eso-external-secret/variables.tf index 3dbb168f..dae5da24 100644 --- a/modules/eso-external-secret/variables.tf +++ b/modules/eso-external-secret/variables.tf @@ -50,12 +50,12 @@ variable "es_kubernetes_secret_data_key" { } variable "sm_secret_type" { - description = "Secrets-manager secret type to be used as source data by ESO. Valid input types are 'arbitrary', 'username_password' and 'iam_credentials'" + description = "Secrets-manager secret type to be used as source data by ESO. Valid input types are 'iam_credentials', 'username_password', 'trusted_profile', 'arbitrary', 'imported_cert', 'public_cert', 'private_cert', 'kv'" type = string validation { - condition = can(regex("^iam_credentials$|^username_password$|^arbitrary$|^imported_cert$|^public_cert$|^private_cert|^kv$|$^$", var.sm_secret_type)) + condition = can(regex("^iam_credentials$|^username_password$|^trusted_profile$|^arbitrary$|^imported_cert$|^public_cert$|^private_cert|^kv$|$^$", var.sm_secret_type)) # If it is empty, no secret will be created - error_message = "The sm_secret_type value must be one of the following: iam_credentials, username_password, arbitrary, imported_cert, public_cert, private_cert, kv or leave it empty." + error_message = "The sm_secret_type value must be one of the following: iam_credentials, username_password, trusted_profile, arbitrary, imported_cert, public_cert, private_cert, kv or leave it empty." } } @@ -82,6 +82,7 @@ variable "es_container_registry_secrets_chain" { es_container_registry = string sm_secret_id = string # id of the secret storing the apikey that will be used for the secrets chain es_container_registry_email = optional(string, null) + trusted_profile = optional(string, null) })) default = [] nullable = false