> For the complete documentation index, see [llms.txt](https://docs.enclaive.cloud/virtual-hsm/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.enclaive.cloud/virtual-hsm/tutorials/passing-vhsm-secrets-using-configmaps.md).

# Passing vHSM secrets using ConfigMaps

vHSM stores secrets securely, but Kubernetes applications need a way to access them. One method is using [ConfigMaps.](https://kubernetes.io/docs/concepts/configuration/configmap/) This section provides instructions to inject vHSM secrets using ConfigMaps to an application running in Kubernetes.

#### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* [Install vHSM CLI](/virtual-hsm/documentation/setup.md)
* Install [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl)
* Install a Kubernetes cluster

To pass vault secrets using ConfigMaps:

1. [Deploy a sample application in your Kubernetes cluster](#deploy-a-sample-application)
2. [Enable vHSM secrets engine and store the secret](#enable-vault-secrets-engine-and-store-the-secret)
3. [Create a ConfigMap from vHSM secrets](#create-a-configmap-from-vault-secrets)

#### Deploy a sample application <a href="#deploy-a-sample-application" id="deploy-a-sample-application"></a>

1. Create a deployment YAML file, named `app-deployment.yaml`.

   ```
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: my-app
   spec:
     replicas: 2
     selector:
       matchLabels:
         app: my-app
     template:
       metadata:
         labels:
           app: my-app
       spec:
         containers:
         - name: my-app
           image: nginx
           ports:
           - containerPort: 80
   ```
2. Change to the directory that contains the `app-deployment.yaml` and apply the deployment.

   ```
   kubectl apply -f app-deployment.yaml
   ```

   The output is similar to:

   ```
   deployment.apps/my-app created
   ```
3. Verify that the application is deployed.

   ```
   kubectl get pods
   ```

   It might takes a couple of minutes for Pods to be in a `Running` status. The output is similar to:

   ```
   NAME                      READY   STATUS   RESTARTS   AGE
   my-app-86d5bc587d-g85bz   1/1     Running   0          7s
   my-app-86d5bc587d-j4x4p   1/1     Running   0          7s
   ```
4. Create a service to expose the application.

   ```
   kubectl expose deployment my-app --type=NodePort --port=80
   ```
5. Find the port on which the application is running.

   ```
   kubectl get svc my-app
   ```

   The output is similar to:

   ```
   NAME     TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
   my-app   NodePort   10.96.114.36   <none>        80:32696/TCP   8s
   ```
6. Port forward the application to access the application in your browser.

   ```
   kubectl port-forward svc/my-app 8080:80
   ```
7. Access the application that you deployed in your browser at: `http://localhost:8080`.

#### Enable vHSM secrets engine and store the secret <a href="#enable-vault-secrets-engine-and-store-the-secret" id="enable-vault-secrets-engine-and-store-the-secret"></a>

1. Ensure that vHSM is running and the status is unsealed. For more information about using vHSM CLI, see the vHSM CLI documentation.

   ```
   vhsm status
   ```

   The output is similar to:

   ```
   Key             Value
   ---             -----
   Seal Type       shamir
   Initialized     true
   Sealed          false
   Total Shares    1
   Threshold       1
   Version         1.3.7-0
   Build Date      2025-01-29T15:11:42Z
   Storage Type    inmem
   Cluster Name    vault-cluster-64dcd906
   Cluster ID      d36a3be0-d5ae-380d-58ae-ad2a18b01c6c
   HA Enabled      false

   ```
2. Enable KV Secrets Engine, a key-value store that contains secrets in vHSM's physical storage:

   ```
   vhsm secrets enable -path=secret kv-v2
   ```

   The output is similar to:

   ```
   Success! Enabled the kv-v2 secrets engine at: secret/
   ```
3. Store a secret in vHSM:

   ```
   vhsm kv put secret/myapp DB_PASSWORD="super-secret-password"
   ```

   The output is similar to:

   ```
   ===== Secret Path =====
   secret/data/myapp

   ======= Metadata =======
   Key                Value
   ---                -----
   created_time       2025-02-02T06:40:35.316916Z
   custom_metadata    <nil>
   deletion_time      n/a
   destroyed          false
   version            1
   ```

#### Create a ConfigMap from vHSM secrets <a href="#create-a-configmap-from-vault-secrets" id="create-a-configmap-from-vault-secrets"></a>

1. Retrive the password that you stored in the vHSM server.

   ```
   DB_PASSWORD=$(vault kv get -field=DB_PASSWORD secret/myapp)
   ```
2. Create a ConfigMap that would inject the secret from the vHSM.

   ```
   kubectl create configmap app-config --from-literal=DB_PASSWORD=$DB_PASSWORD
   ```

   The output is similar to:

   ```
   configmap/app-config created
   ```
3. Create a new deployment YAML file, named `app-with-configmap.yaml`.

   ```
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: my-app-with-configmap
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: my-app
     template:
       metadata:
         labels:
           app: my-app
       spec:
         containers:
         - name: my-app
           image: nginx
           env:
           - name: DB_PASSWORD
             valueFrom:
               configMapKeyRef:
                 name: app-config
                 key: DB_PASSWORD
   ```
4. Change to the directory that contains the `app-with-configmap.yaml` and apply the deployment.

   ```
   kubectl apply -f app-with-configmap.yaml
   ```

   The output is similar to:

   ```
   deployment.apps/my-app-with-configmap created
   ```
5. Verify that the application is deployed.

   ```
   kubectl get pods
   ```

   The output is similar to:

   ```
   NAME                                     READY   STATUS    RESTARTS   AGE
   my-app-86d5bc587d-g85bz                  1/1     Running   0          8m57s
   my-app-86d5bc587d-j4x4p                  1/1     Running   0          8m57s
   my-app-with-configmap-6946f8b754-hfhcn   1/1     Running   0          20s
   ```
6. Verify that secrets are passed to the newly deployed application using the command: `kubectl exec -it <pod> -- printenv | grep DB_PASSWORD` In this case the Pod that is running with the application with ConfigMap is `my-app-with-configmap-6946f8b754-hfhcn`.

   ```
   kubectl exec -it my-app-with-configmap-6946f8b754-hfhcn -- printenv | grep DB_PASSWORD
   ```

   The output is:

   ```
   DB_PASSWORD=super-secret-password
   ```

   This confirms that the secret for the application is injected to the application using ConfigMaps.
