Vault Agent Injector Examples

The following are different configuration examples to support a variety of deployment models.

Before Using the Vault Agent Injector

Before applying Vault Agent injection annotations to pods, the following requirements should be satisfied:

  • the master Kubernetes nodes can receive traffic from worker nodes on port 8080,
  • Kubernetes auth method should be configured and enabled in Vault,
  • Pod should have a service account,
  • desired secrets exist within Vault,
  • the service account should be bound to a Vault role with a policy enabling access to desired secrets.

For more information on configuring the Vault Kubernetes auth method, see the official documentation.

Debugging

If an error occurs with a mutation request, Kubernetes will attach the error to the owner of the pod. Check the following for errors:

  • If the pod was created by a deployment or statefulset, check for errors in the replicaset that owns the pod.
  • If the pod was created by a job, check the job for errors.

Patching Existing Pods

To patch existing pods, a Kubernetes patch can be applied to add the required annoations to pods. When applying a patch, the pods will be rescheduled.

First, create the patch:

cat <<EOF >> ./patch.yaml
spec:
  template:
    metadata:
      annotations:
        vault.hashicorp.com/agent-inject: "true"
        vault.hashicorp.com/agent-inject-status: "update"
        vault.hashicorp.com/agent-inject-secret-db-creds: "database/creds/db-app"
        vault.hashicorp.com/agent-inject-template-db-creds: |
          {{- with secret "database/creds/db-app" -}}
          postgres://{{ .Data.username }}:{{ .Data.password }}@postgres:5432/appdb?sslmode=disable
          {{- end }}
        vault.hashicorp.com/role: "db-app"
        vault.hashicorp.com/ca-cert: "/vault/tls/ca.crt"
        vault.hashicorp.com/client-cert: "/vault/tls/client.crt"
        vault.hashicorp.com/client-key: "/vault/tls/client.key"
        vault.hashicorp.com/tls-secret: "vault-tls-client"
EOF

Next, apply the patch:

kubectl patch deployment <MY DEPLOYMENT> --patch "$(cat patch.yaml)"

The pod should now be rescheduled with additional containers. The pod can be inspected using the kubectl describe command:

kubectl describe pod <name of pod>

Deployments, StatefulSets, etc.

The annotations for configuring Vault Agent injection must be on the pod specification. Since higher level resources such as Deployments wrap pod specification templates, Vault Agent Injector can be used with all of these higher level constructs, too.

An example Deployment below shows how to enable Vault Agent injection:

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: app-example
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-example-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-example
  template:
    metadata:
      labels:
        app: app-example
      annotations:
        vault.hashicorp.com/agent-inject: "true"
        vault.hashicorp.com/agent-inject-secret-db-creds: "database/creds/db-app"
        vault.hashicorp.com/agent-inject-template-db-creds: |
          {{- with secret "database/creds/db-app" -}}
          postgres://{{ .Data.username }}:{{ .Data.password }}@postgres:5432/appdb?sslmode=disable
          {{- end }}
        vault.hashicorp.com/role: "db-app"
        vault.hashicorp.com/ca-cert: "/vault/tls/ca.crt"
        vault.hashicorp.com/client-cert: "/vault/tls/client.crt"
        vault.hashicorp.com/client-key: "/vault/tls/client.key"
        vault.hashicorp.com/tls-secret: "vault-tls-client"
    spec:
      containers:
        - name:app
          image: "app:1.0.0"
      serviceAccountName: app-example

ConfigMap Example

The following example creates a deployment that mounts a Kubernetes ConfigMap containing Vault Agent configuration files. For a complete list of the Vault Agent configuration settings, see the Agent documentation.

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: app-example
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-example-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app-example
  template:
    metadata:
      labels:
        app: app-example
      annotations:
        vault.hashicorp.com/agent-inject: "true"
        vault.hashicorp.com/agent-configmap: "my-configmap"
        vault.hashicorp.com/tls-secret: "vault-tls-client"
    spec:
      containers:
        - name:app
          image: "app:1.0.0"
      serviceAccountName: app-example
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-configmap
agent-config
    app: app-example
data:
  config.hcl: |
    "auto_auth" = {
      "method" = {
        "config" = {
          "role" = "db-app"
        }
        "type" = "kubernetes"
      }

      "sink" = {
        "config" = {
          "path" = "/home/vault/.token"
        }

        "type" = "file"
      }
    }

    "exit_after_auth" = false
    "pid_file" = "/home/vault/.pid"

    "template" = {
      "contents" = "{{- with secret "database/creds/db-app" -}}postgres://{{ .Data.username }}:{{ .Data.password }}@postgres:5432/mydb?sslmode=disable{{- end }}"
      "destination" = "/vault/secrets/db-creds"
    }

    "vault" = {
      "address" = "https://vault.demo.svc.cluster.local:8200"
      "ca_cert" = "/vault/tls/ca.crt"
      "client_cert" = "/vault/tls/client.crt"
      "client_key" = "/vault/tls/client.key"
    }
  config-init.hcl: |
    "auto_auth" = {
      "method" = {
        "config" = {
          "role" = "db-app"
        }
        "type" = "kubernetes"
      }

      "sink" = {
        "config" = {
          "path" = "/home/vault/.token"
        }

        "type" = "file"
      }
    }

    "exit_after_auth" = true
    "pid_file" = "/home/vault/.pid"

    "template" = {
      "contents" = "{{- with secret "database/creds/db-app" -}}postgres://{{ .Data.username }}:{{ .Data.password }}@postgres:5432/mydb?sslmode=disable{{- end }}"
      "destination" = "/vault/secrets/db-creds"
    }

    "vault" = {
      "address" = "https://vault.demo.svc.cluster.local:8200"
      "ca_cert" = "/vault/tls/ca.crt"
      "client_cert" = "/vault/tls/client.crt"
      "client_key" = "/vault/tls/client.key"
    }