Vault
Standalone server with TLS
Important Note: This chart is not compatible with Helm 2. Please use Helm 3.6+ with this chart.
This example can be used to set up a single server Vault cluster using TLS.
- Create key & certificate using Kubernetes CA
- Store key & cert into Kubernetes secrets store
- Configure helm chart to use Kubernetes secret from step 2
1. create key & certificate using kubernetes CA
There are four variables that will be used in this example.
# SERVICE is the name of the Vault service in kubernetes.
# It does not have to match the actual running service, though it may help for consistency.
export SERVICE=vault-server-tls
# NAMESPACE where the Vault service is running.
export NAMESPACE=vault-namespace
# SECRET_NAME to create in the kubernetes secrets store.
export SECRET_NAME=vault-server-tls
# TMPDIR is a temporary working directory.
export TMPDIR=/tmp
# CSR_NAME will be the name of our certificate signing request as seen by kubernetes.
export CSR_NAME=vault-csr
- Create a key for Kubernetes to sign. - $ openssl genrsa -out ${TMPDIR}/vault.key 2048 Generating RSA private key, 2048 bit long modulus ...................................................................................................+++ ...............+++ e is 65537 (0x10001)
- Create a Certificate Signing Request (CSR). - Create a file - ${TMPDIR}/csr.confwith the following contents:- cat <<EOF >${TMPDIR}/csr.conf [req] req_extensions = v3_req distinguished_name = req_distinguished_name [req_distinguished_name] [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = *.${SERVICE} DNS.2 = *.${SERVICE}.${NAMESPACE} DNS.3 = *.${SERVICE}.${NAMESPACE}.svc DNS.4 = *.${SERVICE}.${NAMESPACE}.svc.cluster.local IP.1 = 127.0.0.1 EOF
- Create a CSR. - openssl req -new \ -key ${TMPDIR}/vault.key \ -subj "/CN=system:node:${SERVICE}.${NAMESPACE}.svc;/O=system:nodes" \ -out ${TMPDIR}/server.csr \ -config ${TMPDIR}/csr.conf
 
- Create the certificate - Important Note: If you are using EKS, certificate signing requirements have changed. As per the AWS certificate signing documentation, EKS version - 1.22and later now requires the- signerNameto be- beta.eks.amazonaws.com/app-serving, otherwise, the CSR will be approved but the certificate will not be issued.- Create a file - ${TMPDIR}/csr.yamlwith the following contents:- cat <<EOF >${TMPDIR}/csr.yaml apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: name: ${CSR_NAME} spec: signerName: kubernetes.io/kubelet-serving groups: - system:authenticated request: $(base64 ${TMPDIR}/server.csr | tr -d '\n') signerName: kubernetes.io/kubelet-serving usages: - digital signature - key encipherment - server auth EOF
- Send the CSR to Kubernetes. - $ kubectl create -f ${TMPDIR}/csr.yaml certificatesigningrequest.certificates.k8s.io/vault-csr created- If this process is automated, you may need to wait to ensure the CSR has been received and stored: - kubectl get csr ${CSR_NAME}
- Approve the CSR in Kubernetes. - $ kubectl certificate approve ${CSR_NAME} certificatesigningrequest.certificates.k8s.io/vault-csr approved
- Verify that the certificate was approved and issued. - $ kubectl get csr ${CSR_NAME} NAME AGE SIGNERNAME REQUESTOR CONDITION vault-csr 1m13s kubernetes.io/kubelet-serving kubernetes-admin Approved,Issued
 
2. store key, cert, and kubernetes CA into kubernetes secrets store
- Retrieve the certificate. - $ serverCert=$(kubectl get csr ${CSR_NAME} -o jsonpath='{.status.certificate}')- If this process is automated, you may need to wait to ensure the certificate has been created. If it hasn't, this will return an empty string. 
- Write the certificate out to a file. - $ echo "${serverCert}" | openssl base64 -d -A -out ${TMPDIR}/vault.crt
- Retrieve Kubernetes CA. - kubectl get secret \ -o jsonpath="{.items[?(@.type==\"kubernetes.io/service-account-token\")].data['ca\.crt']}" \ | base64 --decode > ${TMPDIR}/vault.ca
- Create the namespace. - $ kubectl create namespace ${NAMESPACE} namespace/vault-namespace created
- Store the key, cert, and Kubernetes CA into Kubernetes secrets. - $ kubectl create secret generic ${SECRET_NAME} \ --namespace ${NAMESPACE} \ --from-file=vault.key=${TMPDIR}/vault.key \ --from-file=vault.crt=${TMPDIR}/vault.crt \ --from-file=vault.ca=${TMPDIR}/vault.ca # secret/vault-server-tls created
3. helm configuration
The below custom-values.yaml can be used to set up a single server Vault cluster using TLS.
This assumes that a Kubernetes secret exists with the server certificate, key and
certificate authority:
global:
  enabled: true
  tlsDisable: false
server:
  extraEnvironmentVars:
    VAULT_CACERT: /vault/userconfig/vault-server-tls/vault.ca
  volumes:
    - name: userconfig-vault-server-tls
      secret:
        defaultMode: 420
        secretName: vault-server-tls # Matches the ${SECRET_NAME} from above
  volumeMounts:
    - mountPath: /vault/userconfig/vault-server-tls
      name: userconfig-vault-server-tls
      readOnly: true
  standalone:
    enabled: true
    config: |
      listener "tcp" {
        address = "[::]:8200"
        cluster_address = "[::]:8201"
        tls_cert_file = "/vault/userconfig/vault-server-tls/vault.crt"
        tls_key_file  = "/vault/userconfig/vault-server-tls/vault.key"
        tls_client_ca_file = "/vault/userconfig/vault-server-tls/vault.ca"
      }
      storage "file" {
        path = "/vault/data"
      }