Copies Secrets from Azure Key Vault to Kubernetes Secrets
  • Python 97.1%
  • Dockerfile 2.9%
Find a file
Chris Pressland db0cd48ae2
All checks were successful
lint / linting (push) Successful in 9s
publish / pypi (push) Successful in 1m16s
publish / container (push) Successful in 2m55s
chore: use pip instead of uv for container build
2026-04-22 10:14:05 +01:00
.forgejo/workflows fix: add missing needs arg 2026-04-21 16:45:23 +01:00
deploy chore: migrate project to uv 2026-04-21 16:09:49 +01:00
kv_to_kube chore: migrate project to uv 2026-04-21 16:09:49 +01:00
.gitignore Initial Commit 2023-11-04 20:39:56 +00:00
.python-version chore: migrate project to uv 2026-04-21 16:09:49 +01:00
Containerfile chore: use pip instead of uv for container build 2026-04-22 10:14:05 +01:00
kustomization.yaml Initial Commit 2023-11-04 20:39:56 +00:00
LICENSE Initial Commit 2023-11-04 20:39:56 +00:00
pyproject.toml fix: build failure 2026-04-21 16:50:28 +01:00
README.md Initial Commit 2023-11-04 20:39:56 +00:00
renovate.json Add renovate.json 2025-06-05 16:18:58 +01:00
uv.lock chore: migrate to forgejo 2026-04-21 16:41:48 +01:00

kv-to-kube

Syncs Azure Key Vault Secrets with a kube_secret_name label to Kubernetes Secrets.

Installation

Via Kustomize/Flux for Kubernetes

Installation via Kustomize/Flux 2.0 is the recommended installation approach for kv-to-kube, note this requires Azure Workload Identity to be setup and working along with the respective OIDC Federated Credentials.

Create a kustomize.yaml file with the following content, being sure to replace keyvault-name, excluded-namespaces, and azure.workload.identity/client-id with your desired values:

resources:
  - github.com/cpressland/kv-to-kube/deploy

patches:
  - target:
      kind: CronJob
    patch: |
      - op: replace
        path: /spec/jobTemplate/spec/template/spec/containers/0/command
        value:
        - kv-to-kube
        - --keyvault-name=my-keyvault
        - --excluded-namespaces=kube-system
  - target:
      kind: ServiceAccount
    patch: |
      - op: replace
        path: /metadata/annotations/azure.workload.identity~1client-id
        value: 5d4017fa-3f60-4fcb-a15c-2ffbd8081807

Apply this to your cluster with kubectl apply -k . or using Flux 2.0.

Via Pipx

Pipx is the recommended installation method for running locally, outside of Kubernetes, note this requires azure-cli to be installed and working.

pipx install kv-to-kube

Usage

Once the application is installed either locally or in your cluster, simply create or update secrets within your Key Vault to match the following spec:

{
    "postgres_user": "lunalux",
    "postgres_pass": "asmr",
    "postgres_host": "katherina.postgres.database.azure.com"
}

with a tag of: {"kube_secret_name": "azure-postgres"}

This will create a Kubernetes Secret in all namespaces, as follows:

{
    "apiVersion": "v1",
    "kind": "Secret",
    "metadata": {
        "name": "azure-postgres",
        "namespace": "default",
    },
    "data": {
        "postgres_host": "a2F0aGVyaW5hLnBvc3RncmVzLmRhdGFiYXNlLmF6dXJlLmNvbQ==",
        "postgres_pass": "YXNtcg==",
        "postgres_user": "bHVuYWx1eA=="
    },
    "type": "Opaque"
}

FAQs

Q: What would I use this for? A: I use it with Terraform. During the creation of something like a Postgres Server we store the connection details in Azure Key Vault, AKS then uses kv-to-kube to syncronise those secrets so they can be used in a Pods environment variables.

Q: Why does this delete and re-create secrets instead of updating them? A: I couldn't find an elegant way to perform this operation with the kr8s library. I've opened an issue here, should that get a satifactory resolution I'll change this to update and provide an annotation on the secret for the last updated time. Because of this, I wouldn't recommend using this for secrets that require mounting as a volume. But if thats your use case, you should probably be using a Secrets Store CSI Driver