Skip to content

Vault Kubernetes Deployment Using Traefik Ingress

You can use Kubernetes ingress rules to connect to your HashiCorp Vault API and UI instead of load balancing its Kubernetes services. Also, if your Kubernetes cluster is using an Ingress Controller to forward traffic to other services depending on the url path, you may want to configure your ingress rule to use a /vault path to connect to Vault.

In this article we will describe the required configuration to use Traefik Kubernetes Ingress with HashiCorp Vault:

Traefik Proxy Configuration

We need to configure Traefik Proxy CRDs in order to deploy a middleware object that will be defined in the ingress rule:

  • Configure Traefik deployment arguments for Kubernetes CRD provider
  • Deploy a middleware CRD with a StripPrefix spec for your /vault path

You need to be sure that Traefik is running with the following arguments:

--providers.kubernetesingress=true
--providers.kubernetescrd=true

This can be done by deploying Traefik with its Helm Chart and use the following values in a traefik_values.yaml file:

# Content of traefik_values.yaml
providers:
  kubernetesCRD:
    enabled: true

  kubernetesIngress:
    enabled: true

Then you can deploy with Helm:

helm repo add traefik https://helm.traefik.io/traefik
helm repo update
helm install traefik \
  -n traefik \
  -f traefik_values.yaml \
  traefik/traefik \
  --create-namespace

Traefik Middleware

Because we want to use /vault path to forward traffic to our Vault active service, we need to deploy the following CRD (we are deploying with kubectl and describing the CRD in the same shell command):

kubectl deploy -n vault -f - << EOF
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: vaultstrip
  namespace: vault
spec:
  stripPrefix:
    prefixes:
    - /vault
EOF

Note

We are assumig that Vault will be deployed in vault namespace in Kubernetes and that it is already created. If it is not already created we need to create the namespace with:

kubectl create ns vault

Deploying HashiCorp Vault with Ingress

Now we are ready to deploy Vault with Helm using an easy ingress definition. We define a very simple vault_values.yaml with the required annotations:

# Content of vault_values.yaml
server:
  ingress:
    enabled: true
    # 'vaultstrip' middleware in 'vault' namespace needs to be deployed
    annotations: |
      kubernetes.io/ingress.class: traefik
      traefik.ingress.kubernetes.io/router.middlewares: vault-vaultstrip@kubernetescrd
    hosts:
    - host: ""
      paths:
      - /vault

And deploy with helm:

helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update
helm install vault \
  -f vault_values.yaml \
  -n vault \
  hashicorp/vault

Checking access to Vault

Now you can check access to Vault by requesting API health endpoint using your new forwarded path:

LBHOST="$(kubectl get svc -n traefik traefik-ingress-service -o go-template="{{ range .status.loadBalancer.ingress }}{{ .ip}}{{ end }}")"
LBPORT="$(kubectl get svc -n traefik traefik-ingress-service -o go-template="{{ range .spec.ports }}{{ if eq .name \"web\" }}{{ .port}}{{end}}{{ end }}")"
curl http://${LBHOST}:${LBPORT}/vault/v1/sys/health

You should get a response like the following:

{"initialized":true,"sealed":false,"standby":false,"performance_standby":false,"replication_performance_mode":"disabled","replication_dr_mode":"disabled","server_time_utc":1644793033,"version":"1.9.2","cluster_name":"vault-cluster-8bdfe08b","cluster_id":"37e02307-db1f-b805-8bde-8a7bb0251d79"}