The goal is to retrieve secrets from the Azure Key Vault and use them as ENV variables used by Pods when they are launched. A very useful tool that allows this man-oeuvre is Azure Key Vault to Kubernetes (akv2k8s). Azure Key Vault to Kubernetes (akv2k8s) makes Azure Key Vault secrets, certificates and keys available in Kubernetes and/or your application - in a simple and secure way.

Summary diagram on how it works.

Installation

Apply Custom Resource Definition for AzureKeyVaultSecret

kubectl apply -f https://raw.githubusercontent.com/sparebankenvest/azure-key-vault-to-kubernetes/crd-1.1.0/crds/AzureKeyVaultSecret.yaml

*specify other versions if needed

Install akv2k8s components

Create separate namespace for these components

kubectl create ns akv2k8s

Install Components using helm charts

helm repo add spv-charts http://charts.spvapi.no

helm repo update
 
helm upgrade -i azure-key-vault-controller spv-charts/azure-key-vault-controller --namespace akv2k8s
 
helm upgrade -i azure-key-vault-env-injector spv-charts/azure-key-vault-env-injector --namespace akv2k8s

By default these components will use that subscription ID ,tenant ID and Kubernetes Service principal Accounts to access the Key Vault, since it is our case, no further setup to be done here

Use Components

Create namespace

We have to create a namespace with a specific label which will permit Get requests to the Key Vault, so that pods within this namespace can retrieve secrets.

apiVersion: v1
kind: Namespace
metadata:
  name: akv-test
  labels:
    azure-key-vault-env-injection: enabled

Definition for the Azure Key Vault secret

Create a reference to the secret that is stored in the Azure Key Vault and that will be injected into the pod.

kind: AzureKeyVaultSecret
metadata:
  name: secret-inject
  namespace: akv-test
spec:
  vault:
    name: min-ds-dev-kv # name of key vault
    object:
      name: testPassword # name of the akv object
      type: secret # akv object type

Deploy a test Micro-Service

Create a Test deployment that would use the secret

Create a Test deployment that would use the secret
kind: Deployment
metadata:
  name: akvs-secret-app
  namespace: akv-test
  labels:
    app: akvs-secret-app
spec:
  selector:
    matchLabels:
      app: akvs-secret-app
  template:
    metadata:
      labels:
        app: akvs-secret-app
    spec:
      containers:
      - name: akv2k8s-env-test
        image: spvest/akv2k8s-env-test:2.0.1
        args: ["TEST_SECRET"]
        env:
        - name: TEST_SECRET
          value: "secret-inject@azurekeyvault" # ref to akvs

Using this Syntax “secret-inject@azurekeyvault” will retrieve the reference secret-inject where the name of the secret is defined testPassword and retrieve it’s Value from the Vault

Test Secret and Secret Value retrieval

The test Micro-Service above prints the arguments it is given, so we gave it the Secret ENV variable name to see if the retrieval operation of the Secret and its value was successful.

kubectl logs -n akv-test logs deployment/akvs-secret-app

We indeed managed to retrieve the secret’s (testPassword) value (testPasswordValue) directly into the pod without specifying it’s content anywhere on the deployment chain. Also inject it as an ENV variable of that pod. Other Great thing is that only the entrypoint process can see the content of the secret.