Skip to content
7 min read·Lesson 8 of 8

Vault Integrations: Kubernetes, AWS, and CI/CD

Connect Vault to the rest of your stack — Vault Agent, the Kubernetes Vault Secrets Operator, External Secrets Operator, AWS, and CI/CD pipelines.

A Vault deployment is only valuable if applications use it. This lesson covers the patterns and tools that bridge Vault to the rest of your stack.

Vault Agent

Vault Agent is a sidecar/companion process that handles Vault auth and secret retrieval on behalf of an application. Three responsibilities:

  1. Auto-auth: Logs in using the configured method, manages the token, renews it before expiry
  2. Templating: Renders secrets into files/env vars the app reads
  3. Caching: Caches lease responses so the app doesn't re-fetch on every call

A typical agent config

vault {
  address = "https://vault.acme:8200"
}

auto_auth {
  method "kubernetes" {
    config = {
      role = "web-api"
    }
  }
  sink "file" {
    config = {
      path = "/vault/token"
    }
  }
}

template {
  source      = "/etc/vault/templates/db.env.tpl"
  destination = "/etc/secrets/db.env"
  command     = "kill -HUP $(pidof app)"   # reload the app on rotation
}
# db.env.tpl
{{ with secret "database/creds/web-api" -}}
DB_USER={{ .Data.username }}
DB_PASS={{ .Data.password }}
{{- end }}

The agent re-renders db.env when the lease is renewed (or when the secret rotates). The app, blissfully unaware of Vault, just reads the file.

Kubernetes: Three Patterns

Pattern 1: Vault Agent Injector (sidecar)

Install the HashiCorp Helm chart; annotate your pods:

metadata:
  annotations:
    vault.hashicorp.com/agent-inject: 'true'
    vault.hashicorp.com/role: 'web-api'
    vault.hashicorp.com/agent-inject-secret-db.env: 'database/creds/web-api'
    vault.hashicorp.com/agent-inject-template-db.env: |
      {{ with secret "database/creds/web-api" -}}
      DB_USER={{ .Data.username }}
      DB_PASS={{ .Data.password }}
      {{- end }}

A mutating webhook injects Vault Agent as a sidecar; the secret appears in /vault/secrets/db.env inside your pod.

Pattern 2: Vault Secrets Operator (VSO)

Vault Secrets Operator is HashiCorp's newer, CRD-based approach. It runs in the cluster and syncs Vault secrets into native Kubernetes Secret objects:

apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
  name: app-config
  namespace: production
spec:
  vaultAuthRef: vault-auth
  mount: kv
  type: kv-v2
  path: production/app-config
  destination:
    name: app-config-secret
    create: true
  refreshAfter: 30s

Apps consume the native Secret as usual (mounted volume or env). The operator polls Vault and keeps the Secret in sync. Compared to the injector: no sidecar, simpler RBAC, native K8s semantics.

Pattern 3: External Secrets Operator (ESO)

ESO is a vendor-neutral operator (Apache-licensed, broad community) that supports Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, and others through a common ExternalSecret CRD. Choose it if you need to support multiple vault providers in the same cluster.

AWS Integration

Two flavours:

  • Vault auth method: AWS workloads authenticate to Vault using their IAM identity (covered in lesson 3)
  • AWS secrets engine: Vault generates short-lived AWS credentials for non-AWS workloads that need them (covered in lesson 5)

The two patterns can compose: a Kubernetes pod auths to Vault via the Kubernetes method, then asks Vault for an AWS credential via the AWS secrets engine. No AWS access keys are stored anywhere.

CI/CD Integration

Pipeline runs need credentials — deploy keys, cloud credentials, container-registry tokens, signing keys. Two clean patterns:

JWT/OIDC auth from the pipeline

GitHub Actions, GitLab CI, CircleCI, Buildkite, and Tekton all issue OIDC tokens to their pipeline runs. Vault's JWT auth method verifies these tokens and returns a Vault token bound to a role. The role's policy determines what the pipeline can read.

# GitHub Actions
- uses: hashicorp/vault-action@v3
  with:
    url: https://vault.acme:8200
    method: jwt
    role: github-actions-deploy
    secrets: |
      kv/data/aws-deploy AWS_ACCESS_KEY_ID ;
      kv/data/aws-deploy AWS_SECRET_ACCESS_KEY

The action exchanges the GitHub OIDC token for a Vault token, fetches the secrets, and exports them as env vars for the job.

AppRole with response wrapping

For CI systems that don't have OIDC: store the AppRole RoleID in the pipeline config, and have a trusted bootstrap process deliver a wrapped SecretID. The pipeline unwraps it, authenticates, fetches secrets, then exits.

Application Library Integration

For apps that want direct Vault API access, official client libraries exist for Go, Java, Python, Node.js, .NET, Ruby. Use them when:

  • You need to call dynamic secrets engines with arguments only the app knows
  • You use Transit (encrypt/decrypt at runtime)
  • You need fine-grained lease lifecycle (renew when "still in use")

For everything else — static secrets, dynamic DB credentials — prefer Vault Agent or VSO to keep Vault out of the app code.

Consul-Template Standalone

Before Vault Agent existed, consul-template was the standard tool for rendering secrets to files. It still works and is sometimes simpler for non-K8s VMs. Vault Agent is essentially Consul-Template plus auto-auth.

Observability of Integrations

Track these per integration:

  • Auth success/failure rate (per role)
  • Token TTL distribution (alerting on anomalously short or long TTLs)
  • Lease counts per role (catches a runaway service)
  • Per-app secret fetch rate (catch loops)

Putting It All Together

A mature deployment looks like:

  • K8s workloads auth via Kubernetes method; Vault Secrets Operator syncs the secrets they need
  • EC2/ECS workloads auth via AWS IAM; consume dynamic DB and AWS creds
  • CI/CD auths via OIDC/JWT; fetches short-lived deploy credentials per run
  • Humans auth via OIDC SSO; access scoped to the policies attached to their entity group
  • Apps doing app-level crypto use Transit via SDK
  • Operations use a separate auth path with audit logs feeding the SIEM

What to Build First

If you're starting a Vault rollout, sequence it like this:

  1. Set up the cluster (3 nodes, Raft, auto-unseal)
  2. Enable a KV v2 mount and migrate one application's static secrets — prove the operational pattern
  3. Stand up the Vault Secrets Operator (or Agent Injector) for your dominant runtime
  4. Onboard new services to dynamic DB credentials
  5. Add OIDC for humans
  6. Add Transit for at-rest crypto in apps that need it

You've now reached the end of the course. You understand why secrets management matters, how Vault is built, how identities and policies combine to enforce access, the difference between static and dynamic secrets, how Transit provides encryption-as-a-service, and how to operate and integrate Vault. The next step is the Vault Associate (003) certification — and, more importantly, a real deployment that proves these concepts in your environment.

Key Takeaways

  • Vault Agent automatically handles auth, token renewal, and templating secrets to files for apps.
  • The Vault Secrets Operator (VSO) syncs Vault secrets into native Kubernetes Secrets.
  • External Secrets Operator (ESO) is a vendor-neutral alternative supporting Vault and cloud providers.
  • CI/CD pipelines authenticate via OIDC/JWT and fetch short-lived credentials per pipeline run.
  • AWS/Azure/GCP integrations let cloud workloads auth as themselves — no shared secrets to manage.
🎉

Course Complete!

You've finished HashiCorp Vault & Secrets Management. Now put your knowledge to the test with real exam-style practice questions.