|
1 | | -# Terraform IBM External Secrets Operator |
| 1 | +# Cloud automation for External Secrets Operator (Fully configurable) |
2 | 2 |
|
3 | | -This architecture allows to deploy [External Secrets Operator](https://external-secrets.io/latest/) (also known as ESO) on an existing IBM Cloud OpenShift Cluster |
4 | | - |
5 | | -External Secrets Operator synchronizes secrets in the Kubernetes cluster with secrets that are mapped in [Secrets Manager](https://cloud.ibm.com/docs/secrets-manager). |
6 | | - |
7 | | -The architecture provides the following features: |
8 | | -- Install and configure External Secrets Operator (ESO). |
9 | | -- Customise External Secret Operator deployment on specific cluster workers by configuration approriate NodeSelector and Tolerations in the ESO helm release [More details below](#customise-eso-deployment-on-specific-cluster-nodes) |
10 | | -- Deploy and configure [ClusterSecretStore](https://external-secrets.io/latest/api/clustersecretstore/) resources for cluster scope secrets store |
11 | | -- Deploy and configure [SecretStore](https://external-secrets.io/latest/api/secretstore/) resources for namespace scope secrets store |
12 | | -- Leverage on two authentication methods to be configured on the single stores instances: |
13 | | - - IAM apikey standard authentication |
14 | | - - IAM Trusted profile |
15 | | - |
16 | | -The current version of the architecture supports multitenants configuration by setting up "ESO as a service" (ref. https://cloud.redhat.com/blog/how-to-setup-external-secrets-operator-eso-as-a-service) for both authentication methods<br/> |
17 | | -[More details](https://github.com/terraform-ibm-modules/terraform-ibm-external-secrets-operator#example-of-multitenancy-configuration-example-in-namespaced-externalsecrets-stores) |
18 | | - |
19 | | -### Pod Reloader |
20 | | - |
21 | | -The architecture allows also to deploy optionally Stakater Reloader](https://github.com/stakater/Reloader): when secrets are updated, depending on you configuration pods may need to be restarted to pick up the new secrets. To do this you can use it. |
22 | | -By default, the module deploys this to watch for changes in secrets and configmaps and trigger a rolling update of the related pods. |
23 | | -To have Reloader watch a secret or configMap add the annotation `reloader.stakater.com/auto: "true"` to the secret or configMap, the same annotation can be added to deployments to have them restarted when the secret or configMap changes. |
24 | | - |
25 | | -This can be further configured as needed, for more details see https://github.com/stakater/Reloader By default it watches all namespaces. |
26 | | -If you do not need it please set `reloader_deployed = false` in the input variable value. |
27 | | - |
28 | | -### Output content and Secrets configuration |
29 | | - |
30 | | -This architecture doesn't provide support for configuring the Secrets and the ESO external-secrets structures needed to synchronize the secret with Secrets Manager. |
31 | | -However its output provides, for each Cluster Secrets Store and Secrets Store configured in input, the IDs for the ServiceIDs, for the Account and Service Secrets Groups and so on: these output structures can be easily used in a terraform template to configure and deploy the secrets on the cluster. |
32 | | -The code below is an example of generating a username/password secret on Secrets Manager to deploy a dockerjson cluster secret for each Cluster Secrets Store: |
33 | | - |
34 | | -``` |
35 | | -################################################################## |
36 | | -# creation of generic username/password secret |
37 | | -# (for example to store artifactory username and API key) |
38 | | -################################################################## |
39 | | -
|
40 | | -locals { |
41 | | - # secret value for sm_userpass_secret |
42 | | - userpass_apikey = sensitive("password-payload-example") |
43 | | -} |
44 | | -
|
45 | | -# Create username_password secret and store in secret manager |
46 | | -module "sm_userpass_secret" { |
47 | | - for_each = local.cluster_secrets_stores_account_secrets_groups |
48 | | - source = "terraform-ibm-modules/secrets-manager-secret/ibm" |
49 | | - version = "1.7.0" |
50 | | - region = local.sm_region |
51 | | - secrets_manager_guid = local.sm_guid |
52 | | - secret_group_id = each.value.secrets_group.secret_group_id |
53 | | - #tfsec:ignore:general-secrets-no-plaintext-exposure |
54 | | - secret_name = "${each.key}-usernamepassword-secret" # checkov:skip=CKV_SECRET_6 |
55 | | - secret_description = "example secret for ${each.value.name}" #tfsec:ignore:general-secrets-no-plaintext-exposure # checkov:skip=CKV_SECRET_6 |
56 | | - secret_payload_password = local.userpass_apikey # pragma: allowlist secret |
57 | | - secret_type = "username_password" #checkov:skip=CKV_SECRET_6 |
58 | | - #tfsec:ignore:general-secrets-no-plaintext-exposure |
59 | | - secret_username = "artifactory-user" # checkov:skip=CKV_SECRET_6: does not require high entropy string as is static value |
60 | | - secret_auto_rotation = false |
61 | | - secret_auto_rotation_interval = 0 |
62 | | - secret_auto_rotation_unit = null |
63 | | - providers = { |
64 | | - ibm = ibm.ibm-sm |
65 | | - } |
66 | | -} |
67 | | -
|
68 | | -################################################################## |
69 | | -# ESO externalsecrets with cluster scope and apikey authentication |
70 | | -################################################################## |
71 | | -
|
72 | | -# ESO externalsecret with cluster scope creating a dockerconfigjson type secret |
73 | | -module "external_secret_usr_pass" { |
74 | | - for_each = local.cluster_secrets_store_account_serviceid_apikey_secrets |
75 | | - depends_on = [module.eso_clustersecretsstore] |
76 | | - source = "../../modules/eso-external-secret" |
77 | | - es_kubernetes_secret_type = "dockerconfigjson" #checkov:skip=CKV_SECRET_6 |
78 | | - sm_secret_type = "username_password" #checkov:skip=CKV_SECRET_6 |
79 | | - sm_secret_id = each.value.secrets_manager_secret.secret_id |
80 | | - es_kubernetes_namespace = var.eso_secretsstores_configuration.cluster_secrets_stores[each.key].namespace |
81 | | - eso_store_name = each.key |
82 | | - es_container_registry = "example-registry-local.artifactory.com" |
83 | | - es_kubernetes_secret_name = "dockerconfigjson-uc" #checkov:skip=CKV_SECRET_6 |
84 | | - es_helm_rls_name = "es-docker-uc" |
85 | | -} |
86 | | -
|
87 | | -output "sm_userpass_secret" { |
88 | | - value = module.sm_userpass_secret |
89 | | -} |
90 | | -``` |
| 3 | +:exclamation: **Important:** This solution is not intended to be called by other modules because it contains a provider configuration and is not compatible with the `for_each`, `count`, and `depends_on` arguments. For more information, see [Providers Within Modules](https://developer.hashicorp.com/terraform/language/modules/develop/providers). |
0 commit comments