--- title: Secret management weight: 25 aliases: /rhoso-gitops/secret-management/ --- :toc: :_content-type: ASSEMBLY include::modules/comm-attributes.adoc[] :imagesdir: /images [id="rhoso-gitops-secret-management"] = Secret management for the {rhoso-gitops-pattern} The {rhoso-gitops-pattern} requires secrets for OpenStack service passwords, SSH key pairs, bare-metal controller credentials, and container registry authentication. You can provide these secrets in two ways depending on whether a secure storage backend is available. The two approaches can also be combined: for example, store shared credentials (registry, subscription) in the backend while injecting service-specific passwords as `bootstrap_secrets`, or use `onMissingValue: generate` to let the backend generate passwords at deployment time. For the canonical list of required secrets, see link:https://docs.redhat.com/en/documentation/red_hat_openstack_services_on_openshift/latest/html/deploying_red_hat_openstack_services_on_openshift/assembly_preparing-rhocp-for-rhoso#proc_providing-secure-access-to-the-RHOSO-services_preparing[Providing secure access to the {rh-rhoso-short} services] in the {rh-rhoso} documentation. [id="rhoso-secrets-approaches"] == Choosing a secrets approach Review the following approaches before you deploy the pattern. [id="rhoso-secrets-vault-eso"] === Secure storage backend and {eso-op} image::rhoso-gitops/rhoso-gitops-secrets-vault-eso.png[Secure storage backend and {eso-op} secrets flow] This is the recommended approach for production deployments. You store secrets in a secure storage backend (for example {hashicorp-vault}, AWS Secrets Manager, or any link:https://external-secrets.io/latest/provider/aws-secrets-manager/[provider supported by the {eso-op}]). `ExternalSecret` resources project these secrets into the `openstack` namespace through a `SecretStore`. The framework does not install the storage backend or the {eso-op} automatically. You must include the {eso-op} through the `operator-dependencies` Argo CD application by using a Kustomize component from the upstream link:https://github.com/openstack-k8s-operators/gitops/tree/main/components/secrets[secrets components]. The `openstack-secrets` Argo CD application deploys the `SecretStore` and `ExternalSecret` resources that pull secrets from the backend. This approach uses the following configuration: * The bootstrap secret (for example `vault-approle-secret-id`) is defined as a `bootstrap_secret`. The framework injects it into the `openstack` namespace during `make install` so that the {eso-op} `SecretStore` can authenticate against the backend. * All other secrets are defined under the `secrets:` section of the `values-secret.yaml` file. The framework loads them into the backend during `make load-secrets`. * `ExternalSecret` resources, deployed by the `openstack-secrets` Argo CD application, fetch secrets from the backend and create the corresponding Kubernetes `Secret` objects. [id="rhoso-secrets-direct-injection"] === Direct injection without an external store image::rhoso-gitops/rhoso-gitops-secrets-direct.png[Direct injection secrets flow] Use this approach when you do not have a secure storage backend. All secrets are defined as `bootstrap_secrets` in the `values-secret.yaml` file. The framework injects them as Kubernetes `Secret` objects during `make install`. No storage backend or {eso-op} is installed. When you use this approach, configure the following: * Set `global.secretStore.backend` to `"none"` in `values-global.yaml`. * Define every required secret under the `bootstrap_secrets:` section. * Leave the `secrets:` section empty. [id="rhoso-required-secrets"] == Required secrets The {rhoso-gitops-pattern} requires the following secrets in the `openstack` namespace. The `values-secret.yaml.template` file in the pattern repository contains placeholder entries for each secret. [cols="2,3,3",options="header"] |=== | Secret name | Key fields | Purpose | `vault-approle-secret-id` | `id` | Authentication credential for the {eso-op} `SecretStore` to connect to the secure storage backend. Required only with the backend + {eso-op} approach. | `osp-secret` | Multiple service and database password fields | OpenStack service passwords (for example `AdminPassword`, `KeystoneDatabasePassword`, `NeutronPassword`). See the link:https://docs.redhat.com/en/documentation/red_hat_openstack_services_on_openshift/latest/html/deploying_red_hat_openstack_services_on_openshift/assembly_preparing-rhocp-for-rhoso#proc_providing-secure-access-to-the-RHOSO-services_preparing[{rh-rhoso} documentation] for the complete list. | `baremetalset-password-secret` | `NodeRootPassword` | Root password for bare-metal data plane nodes. | `dataplane-ansible-ssh-private-key-secret` | `ssh-privatekey`, `ssh-publickey`, `authorized_keys` | SSH key pair for Ansible provisioning of data plane nodes. | `libvirt-secret` | `LibvirtPassword` | Libvirt authentication password. | `nova-migration-ssh-key` | `ssh-privatekey`, `ssh-publickey` | SSH key pair for Nova live migration. | `redfish-bmc-secret-auth` | `username`, `password` | Redfish BMC credentials for bare-metal node management. | `redhat-registry` | `edpm_container_registry_logins` | Container registry credentials for EDPM nodes (JSON format). | `subscription-manager` | `username`, `password`, `rhc_auth` | {redhat} Subscription Manager credentials for EDPM nodes. |=== [id="rhoso-configuring-vault-eso"] == Configuring secrets with a secure storage backend .Prerequisites * You have forked and cloned the link:https://github.com/validatedpatterns-sandbox/rhoso-gitops[rhoso-gitops] repository. * You have deployed a secure storage backend and have an authentication credential (for example an AppRole secret ID) available. * You have a Git repository with Kustomize overlays that define the `SecretStore` and `ExternalSecret` resources for the `openstack` namespace. * You have the OpenStack service passwords, SSH key pairs, BMC credentials, and registry credentials listed in the link:https://docs.redhat.com/en/documentation/red_hat_openstack_services_on_openshift/latest/html/deploying_red_hat_openstack_services_on_openshift/assembly_preparing-rhocp-for-rhoso#proc_providing-secure-access-to-the-RHOSO-services_preparing[{rh-rhoso} documentation]. .Procedure . Include the {eso-op} in the `operator-dependencies` application by adding a Kustomize component in `overrides/values-rhoso-gitops.yaml`. The following example uses the {redhat} build of the {eso-op}: + [source,yaml,subs="+quotes"] ---- applications: operator-dependencies: kustomize: components: - "https://github.com/openstack-k8s-operators/gitops/components/secrets/external-secrets-operator/redhat?ref=____" ---- + For other {eso-op} variants, see the upstream link:https://github.com/openstack-k8s-operators/gitops/tree/main/components/secrets[components/secrets] README. . Enable the `openstack-secrets` application in the same overrides file. This application deploys the `SecretStore` and `ExternalSecret` resources that pull secrets from the backend: + [source,yaml,subs="+quotes"] ---- openstack-secrets: enabled: true repoURL: "https://github.com/____/____.git" path: "____" targetRevision: "____" ---- . Extract the authentication credential from your secure storage backend (for example an AppRole secret ID) and save it to a file: + [source,terminal,subs="+quotes"] ---- $ echo -n "____" > ~/vault-approle-secret-id ---- . Create a `values-secret.yaml` file based on the template. Include the bootstrap secret for the backend credential and define all other secrets under the `secrets:` section for backend injection: + [source,yaml,subs="+quotes"] ---- version: "2.0" bootstrap_secrets: - name: vault-approle-secret-id targetNamespaces: - openstack fields: - name: id path: ~/vault-approle-secret-id onMissingValue: error secrets: - name: osp-secret fields: - name: AdminPassword value: "____" # ... remaining service password fields # ... remaining secrets ---- . Install the pattern: + [source,terminal] ---- $ ./pattern.sh make install ---- . Verify that the `ExternalSecret` resources are synchronized: + [source,terminal] ---- $ oc get externalsecrets -n openstack ---- + Each `ExternalSecret` shows a `SecretSynced` status when the {eso-op} has created the corresponding Kubernetes `Secret`. [id="rhoso-configuring-direct-injection"] == Configuring secrets with direct injection .Prerequisites * You have forked and cloned the link:https://github.com/validatedpatterns-sandbox/rhoso-gitops[rhoso-gitops] repository. * You have the OpenStack service passwords, SSH key pairs, BMC credentials, and registry credentials listed in the link:https://docs.redhat.com/en/documentation/red_hat_openstack_services_on_openshift/latest/html/deploying_red_hat_openstack_services_on_openshift/assembly_preparing-rhocp-for-rhoso#proc_providing-secure-access-to-the-RHOSO-services_preparing[{rh-rhoso} documentation]. .Procedure . Set the secret store backend to `none` in `values-global.yaml`: + [source,yaml] ---- global: secretStore: backend: "none" ---- . Copy the secrets template and edit it: + [source,terminal,subs="+quotes"] ---- $ cp values-secret.yaml.template ~/values-secret-rhoso-gitops.yaml ---- + Replace every `CHANGEME_*` placeholder with the actual value. For SSH key pairs, set the `path:` field to point at your local key files. Secret values must be in plain text, not base64-encoded. . Install the pattern: + [source,terminal] ---- $ ./pattern.sh make install ---- . Verify that the secrets exist in the `openstack` namespace: + [source,terminal] ---- $ oc get secrets -n openstack ----