Almacena datos en un administrador de secretos externo

Almacena datos en un administrador de secretos externo

En esta guía, se explica cómo almacenar y administrar los siguientes tipos de información en el servicio de almacenamiento de secretos externo, Hashicorp Vault, en lugar de hacerlo en el archivo overrides.yaml.

  • Sal de hash de AX
  • Contraseña de Redis
  • Claves de encriptación

Para almacenar otros tipos de información en Vault, consulta lo siguiente:

Requisitos previos

Procedimiento

  1. Crea políticas, secrets y roles de Vault
    1. Usa la IU o las APIs de Vault para crear Secrets y otorgar permisos a las cuentas de servicio de Apigee de Kubernetes para leer esos Secrets como se describe aquí. Los secretos deben constar de una clave y uno o más valores, como se muestra en la siguiente tabla:
      Clave de secreto Datos de los secretos
      secret/data/apigee/axhashsalt
      {
        "ax-hash-salt": "AX_HASH_SALT_VALUE"
      }
      secret/data/apigee/redis
      {
        "redis-password": "REDIS_PASSWORD_VALUE"
      }
      secret/data/apigee/orgencryptionkeys
      {
        "kmsEncryptionKey": "KMS_ENCRYPTION_KEY_VALUE"
        "kvmEncryptionKey": "KVM_ENCRYPTION_KEY_VALUE"
        "contractEncryptionKey": "CONTRACT_ENCRYPTION_KEY_VALUE"
      }
      secret/data/apigee/envencryptionkeys
      {
        "cacheEncryptionKey": "CACHE_ENCRYPTION_KEY_VALUE"
        "kvmEncryptionKey": "KVM_ENCRYPTION_KEY_VALUE"
        "envKvmEncryptionKey": "ENV_KVM_ENCRYPTION_KEY_VALUE"
        "kmsEncryptionKey": "KMS_ENCRYPTION_KEY_VALUE"
      }
    2. En Vault, crea políticas que otorguen acceso a los secretos:
      cat axhashsalt-auth-policy.txt
      path "secret/data/apigee/axhashsalt" {
        capabilities = ["read"]
      }
      cat redis-auth-policy.txt
      path "secret/data/apigee/redis" {
        capabilities = ["read"]
      }
      cat orgencryptionkeys-auth-policy.txt
      path "secret/data/apigee/orgencryptionkeys" {
        capabilities = ["read"]
      }
      cat envencryptionkeys-auth-policy.txt
      path "secret/data/apigee/envencryptionkeys" {
        capabilities = ["read"]
      }
      
      vault policy write apigee-axhashsalt-auth axhashsalt-auth-policy.txt
      vault policy write apigee-redis-auth redis-auth-policy.txt
      vault policy write apigee-orgencryptionkeys-auth orgencryptionkeys-auth-policy.txt
      vault policy write apigee-envencryptionkeys-auth envencryptionkeys-auth-policy.txt
      
    3. Crea una secuencia de comandos generate-encoded-sas.sh con el siguiente contenido:
      # generate-encoded-sas.sh
      
      ORG=$APIGEE_ORG            # Apigee organization name
      ENVS=$APIGEE_ENV_LIST      # comma separated env names, for example: dev,prod
      
      ORG_SHORT_NAME=$(echo $ORG | head -c 15)
      ENCODE=$(echo -n $ORG | shasum -a 256 | head -c 7)
      ORG_ENCODE=$(echo "$ORG_SHORT_NAME-$ENCODE")
      NAMES="apigee-manager,apigee-redis-default,apigee-redis-envoy-default,apigee-mart-${ORG_ENCODE},apigee-mint-task-scheduler-${ORG_ENCODE}"
      
      for ENV in ${ENVS//,/ }
      do
        ENV_SHORT_NAME=$(echo $ENV | head -c 15)
        ENCODE=$(echo -n $ORG:$ENV | shasum -a 256 | head -c 7)
        ENV_ENCODE=$(echo "$ORG_SHORT_NAME-$ENV_SHORT_NAME-$ENCODE")
        NAMES+=,apigee-runtime-${ENV_ENCODE},apigee-synchronizer-${ENV_ENCODE}
      done
      
      echo $NAMES
      
    4. Ejecuta la secuencia de comandos para generar la lista de nombres de cuentas de servicio a la que se vincularán las políticas:
      chmod +x ./generate-encoded-sas.sh
      ./generate-encoded-sas.sh
      

      El resultado debe mostrar una lista de los nombres de las cuentas de servicio codificadas.

    5. Mediante las políticas, crea funciones de Vault que vinculen las cuentas de servicio de Apigee necesarias.
      vault write auth/kubernetes/role/apigee-axhashsalt \
      	bound_service_account_names=BOUND_SA_NAMES \
      	bound_service_account_namespaces=APIGEE_NAMESPACE \
      	policies=apigee-axhashsalt-auth \
      	ttl=1m
      
      vault write auth/kubernetes/role/apigee-redis \
      	bound_service_account_names=BOUND_SA_NAMES \
      	bound_service_account_namespaces=APIGEE_NAMESPACE \
      	policies=apigee-redis-auth \
      	ttl=1m
      
      vault write auth/kubernetes/role/apigee-orgencryptionkeys \
      	bound_service_account_names=BOUND_SA_NAMES \
      	bound_service_account_namespaces=APIGEE_NAMESPACE \
      	policies=apigee-orgencryptionkeys-auth \
      	ttl=1m
      
      vault write auth/kubernetes/role/apigee-envencryptionkeys \
      	bound_service_account_names=BOUND_SA_NAMES \
      	bound_service_account_namespaces=APIGEE_NAMESPACE \
      	policies=apigee-envencryptionkeys-auth \
      	ttl=1m
      
      
  2. Crea objetos SecretProviderClass.
    1. Agrega los siguientes secretos a través de los recursos SecretProviderClass. Estos recursos le indican al controlador de CSI con qué proveedor se debe comunicar cuando solicita secretos. En la siguiente tabla, se muestran los nombres de archivos (objectNames) que espera Apigee Hybrid:
      Secreto Nombres de archivos de secrets esperados
      Sal de hash de AX
      • ax-hash-salt
      Redis
      • redis-password
      Claves de encriptación de la organización
      • kmsEncryptionKey
      • kvmEncryptionKey
      • contractEncryptionKey
      Claves de encriptación de entorno
      • kmsEncryptionKey
      • kvmEncryptionKey
      • envKvmEncryptionKey
      • cacheEncryptionKey
    2. Usa las siguientes plantillas de SecretProviderClass para configurar estos recursos:
      # axhashsalt-spc.yaml
      
      apiVersion: secrets-store.csi.x-k8s.io/v1
      kind: SecretProviderClass
      metadata:
        name: apigee-axhashsalt-spc
      spec:
        provider: vault
        parameters:
          roleName: apigee-axhashsalt
          vaultAddress: VAULT_ADDRESS
          # "objectName" is an alias used within the SecretProviderClass to reference
          # that specific secret. This will also be the filename containing the secret.
          # Apigee Hybrid expects these exact values so they must not be changed.
          # "secretPath" is the path in Vault where the secret should be retrieved.
          # "secretKey" is the key within the Vault secret response to extract a value from.
          objects: |
            - objectName: "ax-hash-salt"
              secretPath: ""
              secretKey: ""
      
      # redis-spc.yaml
      
      apiVersion: secrets-store.csi.x-k8s.io/v1
      kind: SecretProviderClass
      metadata:
        name: apigee-redis-spc
      spec:
        provider: vault
        parameters:
          roleName: apigee-redis
          vaultAddress: VAULT_ADDRESS
          # "objectName" is an alias used within the SecretProviderClass to reference
          # that specific secret. This will also be the filename containing the secret.
          # Apigee Hybrid expects these exact values so they must not be changed.
          # "secretPath" is the path in Vault where the secret should be retrieved.
          # "secretKey" is the key within the Vault secret response to extract a value from.
          objects: |
            - objectName: "redis-password"
              secretPath: ""
              secretKey: ""
      
      # orgencryptionkeys-spc.yaml
      
      apiVersion: secrets-store.csi.x-k8s.io/v1
      kind: SecretProviderClass
      metadata:
        name: apigee-orgencryptionkeys-spc
      spec:
        provider: vault
        parameters:
          roleName: apigee-orgencryptionkeys
          vaultAddress: VAULT_ADDRESS
          # "objectName" is an alias used within the SecretProviderClass to reference
          # that specific secret. This will also be the filename containing the secret.
          # Apigee Hybrid expects these exact values so they must not be changed.
          # "secretPath" is the path in Vault where the secret should be retrieved.
          # "secretKey" is the key within the Vault secret response to extract a value from.
          objects: |
            - objectName: "kmsEncryptionKey"
              secretPath: ""
              secretKey: ""
            - objectName: "kvmEncryptionKey"
              secretPath: ""
              secretKey: ""
            - objectName: "contractEncryptionKey"
              secretPath: ""
              secretKey: ""
      
      # envencryptionkeys-spc.yaml
      
      apiVersion: secrets-store.csi.x-k8s.io/v1
      kind: SecretProviderClass
      metadata:
        name: apigee-envencryptionkeys-spc
      spec:
        provider: vault
        parameters:
          roleName: apigee-envencryptionkeys
          vaultAddress: VAULT_ADDRESS
          # "objectName" is an alias used within the SecretProviderClass to reference
          # that specific secret. This will also be the filename containing the secret.
          # Apigee Hybrid expects these exact values so they must not be changed.
          # "secretPath" is the path in Vault where the secret should be retrieved.
          # "secretKey" is the key within the Vault secret response to extract a value from.
          objects: |
            - objectName: "cacheEncryptionKey"
              secretPath: ""
              secretKey: ""
            - objectName: "kvmEncryptionKey"
              secretPath: ""
              secretKey: ""
            - objectName: "envKvmEncryptionKey"
              secretPath: ""
              secretKey: ""
            - objectName: "kmsEncryptionKey"
              secretPath: ""
              secretKey: ""
      

      VAULT_ADDRESS es el extremo en el que se ejecuta tu servidor de Vault. Si Vault se ejecuta en el mismo clúster y espacio de nombres que Apigee, el formato suele ser http://vault.APIGEE_NAMESPACE.svc.cluster.local:VAULT_SERVICE_PORT.

    3. Aplica el SecretProviderClasses anterior al espacio de nombres APIGEE_NAMESPACE:
      kubectl -n APIGEE_NAMESPACE apply -f axhashsalt-spc.yaml
      kubectl -n APIGEE_NAMESPACE apply -f redis-spc.yaml
      kubectl -n APIGEE_NAMESPACE apply -f orgencryptionkeys-spc.yaml
      kubectl -n APIGEE_NAMESPACE apply -f envencryptionkeys-spc.yaml
      
  3. Habilita el secreto externo para la sal de hash de AX.
    1. En tu archivo overrides.yaml, agrega la siguiente configuración para habilitar el uso de secretos externos para la sal de hash de AX:
      axHashSaltSecretProviderClass: apigee-axhashsalt-spc
    2. Para aplicar el cambio, actualiza el gráfico de Helm org:
      helm upgrade org apigee-org/ \
        --namespace APIGEE_NAMESPACE \
        -f overrides.yaml
  4. Habilita el secreto externo para la contraseña de Redis.
    1. Dentro de tu archivo overrides.yaml, agrega la siguiente configuración a fin de habilitar el uso de secrets externos para la contraseña de Redis:
      redis:
        auth:
          secretProviderClass: apigee-redis-spc
    2. Luego, aplica los cambios actualizando los gráficos operator y redis en el siguiente orden:
      helm upgrade operator apigee-operator/ \
        --namespace APIGEE_NAMESPACE \
        -f overrides.yaml
      helm upgrade redis apigee-redis/ \
        --namespace APIGEE_NAMESPACE \
        -f overrides.yaml
      
  5. Habilita el secreto externo para las claves de encriptación.
    1. En tu archivo overrides.yaml, agrega la siguiente configuración para habilitar el uso de secretos externos para las claves de encriptación a nivel de la organización:
      encryptionKeySecretProviderClass: apigee-orgencryptionkeys-spc
    2. Para aplicar el cambio, actualiza el gráfico de Helm org:
      helm upgrade org apigee-org/ \
        --namespace APIGEE_NAMESPACE \
        -f overrides.yaml
    3. En el archivo overrides.yaml de cada entorno, agrega la siguiente configuración para las claves de encriptación específicas del entorno:
      envs:
      - name: ENV_NAME
        encryptionKeySecretProviderClass: apigee-envencryptionkeys-spc
    4. Para aplicar el cambio, actualiza el gráfico de Helm env una vez para cada entorno:
      helm upgrade ENV_NAME apigee-env/ \
        --namespace APIGEE_NAMESPACE \
        --set env=ENV_NAME \
        -f overrides.yaml
      

Revertir

Sal de AX de Hash

  1. En tu archivo overrides.yaml, quita la configuración que habilitó el uso de secretos externos para la sal de hash de AX:
    # Comment out or delete the following line:
    # axHashSaltSecretProviderClass: apigee-axhashsalt-spc
  2. Para aplicar el cambio, actualiza el gráfico de Helm org:
    helm upgrade org apigee-org/ \
      --namespace APIGEE_NAMESPACE \
      -f overrides.yaml

Contraseña de Redis

  1. Dentro de tu archivo overrides.yaml, quita la configuración que habilitó el uso de Secrets externos para la contraseña de Redis:
    redis:
      auth:
      # Comment out or delete the following line:
      # secretProviderClass: apigee-redis-spc
  2. Luego, aplica los cambios actualizando los gráficos redis y operator en el siguiente orden:
    helm upgrade redis apigee-redis/ \
      --namespace APIGEE_NAMESPACE \
      -f overrides.yaml
    helm upgrade operator apigee-operator/ \
      --namespace APIGEE_NAMESPACE \
      -f overrides.yaml
    

Claves de encriptación

  1. Dentro de tu archivo overrides.yaml, quita la configuración que habilitó el uso de un secreto externo para las claves de encriptación del entorno:
    envs:
      - name: ENV_NAME
      # Comment out or delete the following line:
      # encryptionKeySecretProviderClass: apigee-envencryptionkeys-spc
  2. Para aplicar el cambio, actualiza el gráfico de Helm env una vez para cada entorno:
    helm upgrade ENV_NAME apigee-env/ \
      --namespace APIGEE_NAMESPACE \
      --set env=ENV_NAME \
      -f overrides.yaml
    
  3. En tu archivo overrides.yaml, quita la configuración que habilitó el uso de secrets externos para las claves de encriptación de la organización:
    # Comment out or delete the following line:
    # encryptionKeySecretProviderClass: apigee-orgencryptionkeys-spc
    
  4. Luego, actualiza el gráfico de Helm org:
    helm upgrade org apigee-org/ \
      --namespace APIGEE_NAMESPACE \
      -f overrides.yaml