<p>I am trying to sync secrets between azure keyvault and my pod. Here is my setup.</p>
<ol>
<li><p>In container I have application.properties that refers to an environment secret TESTTOKEN</p>
</li>
<li><p>Have added TESTTOKEN (value without keyvault) to my deployment yml (env) and I am able to successfully run the microservice</p>
</li>
<li><p>Have set up CSI following Azure steps <a href="https://learn.microsoft.com/en-us/azure/aks/csi-secrets-store-driver" rel="nofollow noreferrer">here</a></p>
</li>
<li><p>Create a SecretProviderClass as below</p>
</li>
</ol>
<pre><code>apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: azure-kvname-user-msi
  namespace: myspace
spec:
  provider: azure
  parameters:
    usePodIdentity: &quot;false&quot;
    useVMManagedIdentity: &quot;true&quot;         
    userAssignedIdentityID: &quot;abcd-123&quot;   
    keyvaultName: &quot;my-kv-app&quot;        
    cloudName: &quot;&quot;                         
    objects:  |
      array:
        - |
          objectName: TESTTOKEN
          objectType: secret              
          objectVersion: &quot;&quot;               
    tenantId: &quot;12345_tenant_id&quot;   
</code></pre>
<ol start="5">
<li>In my deployment yaml I am trying to mount the volume and use the synced secret</li>
</ol>
<pre><code>kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    app: test-microservice
  name: testmsr
  namespace: myspace
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test-microservice
  template:
    metadata:
      labels:
        app: test-microservice
    spec:
      containers:
        - name: test-microservice
          image: cntrregistry-location/testmsr:v2.0.0
          imagePullPolicy: Always
          ports:
            - containerPort: 8183
          env:
            - name: TESTTOKEN    #Incorrect, but I do not know how to map
              valueFrom:
                secretKeyRef:
                  name: TESTTOKEN
                  key: TESTTOKEN
      volumeMounts:
      - name: secrets-store01-inline
        mountPath: &quot;/mnt/secrets-store&quot;
        readOnly: true
  volumes:
    - name: secrets-store01-inline
      csi:
        driver: secrets-store.csi.k8s.io
        readOnly: true
        volumeAttributes:
          secretProviderClass: &quot;azure-kvname-user-msi&quot;  
</code></pre>
<p>Applying the yaml the pod shows ContainerCreation error. I have tried modifying the env in deployment yml but without a clear understanding it just is failing.</p>
<p>I am not able to get the sequence of events, ie the deployment time only secrets will be mounted so how will it be available for env, when are the k8s secreyts created (are they necessary?) or from vault is possible without k8s secret.</p>
<p>Any pointer would help.</p>
<p>Thanks</p>

user14013917
<p>In your SecretProviderClass <code>cloudName</code> is generally not necessary unless you're using an Azure national cloud.</p>
<p>The way you've set up <code>volumeMounts</code> is correct.</p>
<p>The <code>ENV</code> part is where you seem to be a problem in your yaml. The environment variable (TESTTOKEN) should point to the path where the secret is mounted. For example:</p>
<pre class="lang-yaml prettyprint-override"><code>env:
  - name: TESTTOKEN
    value: /mnt/secrets-store/TESTTOKEN
</code></pre>
<p>Your application should be coded to read the secret from a file /mnt/secrets-store/TESTTOKEN instead of an environment variable directly.</p>
<p>Also</p>
<p>To synchronize the Azure Key Vault secrets with native Kubernetes secrets, you'd need to:</p>
<ul>
<li><p>Update SecretProviderClass with <code>secretObjects</code>:</p>
<p>You need to add the <code>secretObjects</code> section in the <code>SecretProviderClass</code> definition. This will instruct the Secret Store CSI driver to sync the mounted secrets with Kubernetes native secrets.</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
   name: azure-kvname-user-msi
   namespace: myspace
spec:
   provider: azure
   parameters:
    usePodIdentity: &quot;false&quot;
    useVMManagedIdentity: &quot;true&quot;         
    userAssignedIdentityID: &quot;abcd-123&quot;   
    keyvaultName: &quot;my-kv-app&quot;      
   secretObjects:
     - secretName: testtoken-k8s-secret
       type: Opaque
       data:
         - objectName: TESTTOKEN
           key: TESTTOKEN
</code></pre>
<ul>
<li><code>secretName</code>: Name of the Kubernetes native secret that will be created or updated.</li>
<li><code>type</code>: The type of Kubernetes secret to create. Usually, it's <code>Opaque</code> for general secrets.</li>
<li><code>data</code>:
<ul>
<li><code>objectName</code>: This should match the <code>objectName</code> from the <code>objects</code> section (name of the secret in Azure Key Vault).</li>
<li><code>key</code>: The key under which the secret will be stored in the Kubernetes secret.</li>
</ul>
</li>
</ul>
</li>
<li><p>Update Deployment to Use the Kubernetes Secret:</p>
</li>
</ul>
<p>Modify the deployment so that it reads the secret from the Kubernetes native secret.</p>
<pre class="lang-yaml prettyprint-override"><code>kind: Deployment
...
spec:
  ...
  containers:
    ...
    env:
      - name: TESTTOKEN
        valueFrom:
          secretKeyRef:
            name: testtoken-k8s-secret
            key: TESTTOKEN
</code></pre>
<p>Now the CSI driver will sync the secret from Azure Key Vault to a Kubernetes native secret named <code>testtoken-k8s-secret</code> in the <code>myspace</code> namespace. Your deployment will then read the value of <code>TESTTOKEN</code> from this Kubernetes secret and set it as an environment variable for the container.</p>
