Skip to content

Vault Installation

Vault is a Centralised Secret Management


Vault will be installed on 🟢 Management Kubernetes Cluster

  • 📥Ingress Service provided as Kubernetes Ingress Class (IngressClass)
  • 🛡️TLS Certificate for Vault provided as Kubernetes Secret
    • Vault will be exposed as HTTPS with Kubernetes Ingress.
  • 💿Persistence Storage as Kubernetes Storage Class (StorageClass)

Vault depends on multiple dependencies to be up and running but only the following will be provisioned and/or managed by you.

  • 📦S3 API-compatible Object Storage ;i.e SeaweedFS
    • 🪣S3 Bucket: A Unit of Logical Storage with 🌏Region specified.
      • Vault uses 1 bucket.
        • For Unseal Key and Root Token Storage after initialised, Auto-Unseal Process.
    • 🔑Credentials to Access S3 Bucket: Access Key, Secret Key.
      • Create/Gather a Dedicated Access Key/Secret Key for Vault to access to its buckets.

Ensure you have defined and loaded your Global Shell Variables as described in Shell Variables.

  1. Connect to 🟢 Management Kubernetes Cluster ; i.e w/ Kubeconfig File

    Ensure you have defined and loaded your Global Shell Variables as described in Shell Variables.

    Terminal window
    source $HOME/opstella-installation/shell-values/kubernetes/management_cluster.vars.sh
    source $HOME/opstella-installation/shell-values/tools/vault.vars.sh
    Terminal window
    export KUBECONFIG="$HOME/opstella-installation/kubeconfigs/management_cluster.yaml"
  2. Export Required Shell Variables

    Ensure VAULT_DOMAIN is defined as per the Shell Variables guide.

    Ensure K8S_INTERNAL_DOMAIN, K8S_INGRESSCLASS_NAME, K8S_STORAGECLASS_NAME, K8S_INGRESS_TLS_CERTIFICATE_SECRET_NAME are defined as per the Shell Variables guide. Additionally, export the following variables:

    Terminal window
    # Infrastructure Configuration
    export VAULT_S3_DOMAIN="seaweedfs-api.${BASE_DOMAIN}"
    export VAULT_S3_BUCKET_NAME="vault"
    export VAULT_S3_BUCKET_REGION="us-east-1"
    export VAULT_S3_ACCESS_KEY="vault"
    export VAULT_S3_ACCESS_SECRET="${SEAWEEDFS_HA_S3_VAULT_PASSWORD}"
  3. Create Kubernetes Secret for 🛡️ TLS Certificate for Vault in Namespace devsecops-system.

    Create one using from .crt and .key file.

    Terminal window
    kubectl create secret tls $K8S_INGRESS_TLS_CERTIFICATE_SECRET_NAME \
    --cert=/path/to/cert/file --key=/path/to/key/file \
    --namespace devsecops-system

    💡 Should return secret/wildcard-...-tls created message.

Set S3 API-compatible Object Storage Information for Vault.

Prepare Vault Auto-Unsealing Configurations

Section titled “Prepare Vault Auto-Unsealing Configurations”
  1. Install Script Artifact as Kubernetes ConfigMap

    You will be creating Kubernetes ConfigMap named vault-init-script from Provision Assets

    Terminal window
    # Create Kubernetes ConfigMap
    kubectl create configmap vault-init-script -n devsecops-system \
    --from-file=$HOME/opstella-installation/assets/scripts/vault-init.sh

    💡 Should return configmap/vault-init-script created message.

  2. Create S3 Endpoint and Credentials as Kubernetes Secret

    S3 Endpoint here will need to specify protocol, will use HTTPS by default.

    Terminal window
    kubectl apply --namespace devsecops-system -f - <<EOF
    apiVersion: v1
    kind: Secret
    type: Opaque
    metadata:
    name: vault-s3-credentials
    stringData:
    VAULT_AUTO_UNSEAL_METHOD: MINIO
    VAULT_S3_URL: https://${VAULT_S3_DOMAIN}
    VAULT_S3_ACCESS_KEY: ${VAULT_S3_ACCESS_KEY}
    VAULT_S3_ACCESS_SECRET: ${VAULT_S3_ACCESS_SECRET}
    VAULT_S3_BUCKET_NAME: ${VAULT_S3_BUCKET_NAME}
    EOF
  3. Create Kubernetes Service to Point to the First Vault Pod

    By create Kubernetes Service with label/selector to pod name.

    Terminal window
    kubectl apply --namespace devsecops-system -f - <<EOF
    apiVersion: v1
    kind: Service
    metadata:
    name: vault-main-headless
    spec:
    clusterIP: None
    selector:
    statefulset.kubernetes.io/pod-name: vault-0
    ports:
    - name: http
    protocol: TCP
    port: 8200
    targetPort: 8200
    - name: https-internal
    protocol: TCP
    port: 8201
    targetPort: 8201
    EOF
  1. Create Helm Values Configurations

    Terminal window
    cat <<EOF > $HOME/opstella-installation/helm-values/vault-full-values.yaml
    # Application: Enabled Web Interface
    ui:
    enabled: true
    # Application: Disable Built-in Injector (use ESO+Reloader instead)
    injector:
    enabled: false
    server:
    # Kubernetes/Application: Enabled Persistence
    dataStorage:
    enabled: true
    storageClass: ${K8S_STORAGECLASS_NAME}
    # OPSTELLA_CUSTOMIZE/Kubernetes/Application: Auto Unsealing Script, Run after server started
    extraArgs: '| /vault/userconfig/scripts/vault-init.sh'
    # Application: Enabled High Availability (Odd Number of Pods)
    ha:
    enabled: true
    replicas: 3
    raft:
    enabled: true
    setNodeId: true
    config: |
    ui = true
    listener "tcp" {
    tls_disable = 1
    address = "[::]:8200"
    cluster_address = "[::]:8201"
    # Enable unauthenticated metrics access (necessary for Prometheus Operator)
    telemetry {
    unauthenticated_metrics_access = "true"
    }
    }
    storage "raft" {
    path = "/vault/data"
    }
    service_registration "kubernetes" {}
    # Kubernetes: Config Kubernetes Security Context
    statefulSet:
    securityContext:
    pod:
    fsGroup: 10000
    runAsGroup: 10000
    runAsUser: 10000
    runAsNonRoot: true
    seccompProfile:
    type: RuntimeDefault
    container:
    runAsGroup: 10000
    runAsUser: 10000
    runAsNonRoot: true
    seccompProfile:
    type: RuntimeDefault
    ### CONTAINER ONLY KEYS ###
    privileged: false
    allowPrivilegeEscalation: false
    capabilities:
    drop: ["ALL"]
    ### CONTAINER ONLY KEYS ###
    # Kubernetes: Expose through Ingress
    ingress:
    enabled: true
    ingressClassName: ${K8S_INGRESSCLASS_NAME}
    hosts:
    - host: ${VAULT_DOMAIN}
    paths: ["/"]
    tls:
    - secretName: ${K8S_INGRESS_TLS_CERTIFICATE_SECRET_NAME}
    hosts:
    - ${VAULT_DOMAIN}
    # Kubernetes: Velero VPC Backup Annotation
    configAnnotation: true
    annotations:
    backup.velero.io/backup-volumes: data
    # OPSTELLA_CUSTOMIZE/Kubernetes/Application: Auto Unsealing Script
    # Provide a S3(-compatible) Connection with Credentials
    extraSecretEnvironmentVars:
    - envName: VAULT_AUTO_UNSEAL_METHOD
    secretName: vault-s3-credentials
    secretKey: VAULT_AUTO_UNSEAL_METHOD
    - envName: VAULT_S3_URL
    secretName: vault-s3-credentials
    secretKey: VAULT_S3_URL
    - envName: VAULT_S3_ACCESS_KEY
    secretName: vault-s3-credentials
    secretKey: VAULT_S3_ACCESS_KEY
    - envName: VAULT_S3_ACCESS_SECRET
    secretName: vault-s3-credentials
    secretKey: VAULT_S3_ACCESS_SECRET
    - envName: VAULT_S3_BUCKET_NAME
    secretName: vault-s3-credentials
    secretKey: VAULT_S3_BUCKET_NAME
    # OPSTELLA_CUSTOMIZE/Kubernetes/Application: Auto Unsealing Script
    # Mount the script from Kubernetes ConfigMap
    volumes:
    - name: vault-scripts
    configMap:
    name: vault-init-script
    defaultMode: 0770
    volumeMounts:
    - mountPath: /vault/userconfig/scripts
    name: vault-scripts
    EOF
  1. Add Vault Helm Repository

    Terminal window
    helm repo add hashicorp https://helm.releases.hashicorp.com
    helm repo update
  2. Install Vault

    • Install a Helm Release with specific Helm Chart Version --version 0.30.1 (App Version: 1.20.0)

      Terminal window
      helm install vault hashicorp/vault --version 0.30.1 \
      --namespace devsecops-system \
      -f $HOME/opstella-installation/helm-values/vault-full-values.yaml

Gather Credentials from Auto-Unsealing Process

Section titled “Gather Credentials from Auto-Unsealing Process”

Credentials of Hashicorp Vault will be store on the provided S3-API Compatible Object Storage.

  • 🗝️ Vault Unseal Key
  • 🗝️ Vault Root Token
    • Initial Credentials for Access to Vault.
    • Also required for integrating with Opstella.

You can gather it by visiting the Console or Admin Panal of your provided S3-API Compatible Object Storage or Using mc CLI to get the file.

  • In case using SeaweedFS Admin Panal
  1. Go to https://seaweedfs-admin.${BASE_DOMAIN} and login with credentials

  2. Go to Bucket Name vault.

  3. You should see files.

    • rootToken.txt
    • unsealKey.txt
  4. Download all of the files.

  5. Copy the token from rootToken.txt to replace CHANGEME and run the command to set the variable.

    export VAULT_TOKEN="CHANGEME"

Next Steps: Setup Single Sign-On with Opstella

  1. Get Pod Status - Vault

    Terminal window
    kubectl get pods -n devsecops-system

    Vault should be Running

    NAME READY STATUS RESTARTS AGE
    ... (deducted)
    vault-0 1/1 Running 0 XdXh
    vault-1 1/1 Running 0 XdXh
    vault-2 1/1 Running 0 XdXh
  2. Visit https://${VAULT_DOMAIN}

    • It should be accessible.
    • TLS Certificate should be valid and coresponding to your TLS Certificate Installed

  3. Login with Root Token

    • Try to login with Root Token, if success then it works.

Finished?

Use the below navigation to proceed