Answers: <p>Method #1 from the original post works - the key point I was missing was <em>how</em> I was getting the cert/key into Azure KeyVault. As mentioned in the post, I was copy/pasting the text from the files into the web portal secret creation UI. Something was getting lost in translation doing it this way. The right way to do it is to use the Azure CLI, like so:</p>
  <pre><code>az keyvault secret set --vault-name &lt;vault name&gt; --name my-private-key --file &lt;path to key file&gt;
  
  az keyvault secret set --vault-name &lt;vault name&gt; --name my-certificate --file &lt;path to cert file&gt;
  </code></pre>
  
Answers: CC BY-SA 4.0
Answers: 2023-02-14T20:52:53.567Z
Answers: 2023-02-14T20:52:53.567Z
Answers: az2tonez
Body: <p>I have a certificate file and a private key file that I am using to implement tls encrypted traffic for several different k8s pods running under an NGINX ingress load balancer. This works fine (i.e. the web apps are visible and show as secure in a browser) if I create the kubernetes.io/tls secret in either of these ways:</p>
  <ol>
  <li>Use kubectl: <code>kubectl create secret my-tls-secret --key &lt;path to key file&gt; --cert &lt;path to cert file&gt;</code>.</li>
  <li>Reference those files locally in terraform:</li>
  </ol>
  <pre class="lang-terraform prettyprint-override"><code>resource &quot;kubernetes_secret&quot; &quot;my_tls_secret&quot; {
    metadata {
      name = &quot;my-tls-secret&quot;
    }
  
    type = &quot;kubernetes.io/tls&quot;
  
    data = {
      &quot;tls.crt&quot; = file(&quot;${path.module}/certfile.cer&quot;),
      &quot;tls.key&quot; = file(&quot;${path.module}/keyfile.key&quot;)
    }
  }
  </code></pre>
  <p>However, neither of these methods are ideal because for #1, it turns my <code>terraform plan/apply</code> steps into 2-step processes and for #2, I don't want to commit the key file to source control for security reasons.</p>
  <p>So, my question is: is there a way to do this by using some combination of Azure Key Vault data resources (i.e. keys, secrets or certificates)?</p>
  <p>I have tried the following:</p>
  <ol>
  <li>Copy/pasting the cert and key into key vault secrets (have also tried this with base64 encoding the values before pasting them into the key vault and using base64decode() around the tls.crt and tls.key values in the Terraform):</li>
  </ol>
  <pre class="lang-terraform prettyprint-override"><code>data &quot;azurerm_key_vault_secret&quot; &quot;my_private_key&quot; {
    name         = &quot;my-private-key&quot;
    key_vault_id = data.azurerm_key_vault.mykv.id
  }
  
  data &quot;azurerm_key_vault_secret&quot; &quot;my_certificate&quot; {
    name         = &quot;my-certificate&quot;
    key_vault_id = data.azurerm_key_vault.mykv.id
  }
  
  resource &quot;kubernetes_secret&quot; &quot;my_tls_secret&quot; {
    metadata {
      name = &quot;my-tls-secret&quot;
    }
  
    type = &quot;kubernetes.io/tls&quot;
  
    data = {
      &quot;tls.crt&quot; = data.azurerm_key_vault_secret.my_certificate.value,
      &quot;tls.key&quot; = data.azurerm_key_vault_secret.my_private_key.value
    }
  }
  </code></pre>
  <ol start="2">
  <li>Tried importing the cert as an Azure key vault certificate and accessing its attributes like so:</li>
  </ol>
  <pre class="lang-terraform prettyprint-override"><code>data &quot;azurerm_key_vault_certificate_data&quot; &quot;my_certificate_data&quot; {
    name         = &quot;my-certificate&quot;
    key_vault_id = data.azurerm_key_vault.mykv.id
  }
  
  resource &quot;kubernetes_secret&quot; &quot;my_tls_secret&quot; {
    metadata {
      name = &quot;my-tls-secret&quot;
    }
  
    type = &quot;kubernetes.io/tls&quot;
  
    data = {
      &quot;tls.crt&quot; = data.azurerm_key_vault_certificate_data.my_certificate_data.pem,
      &quot;tls.key&quot; = data.azurerm_key_vault_certificate_data.my_certificate_data.key
    }
  }
  </code></pre>
  <p>which results in an error in the NGINX ingress log of:
  <code>[lua] certificate.lua:253: call(): failed to convert private key from PEM to DER: PEM_read_bio_PrivateKey() failed, context: ssl_certificate_by_lua*, client: xx.xx.xx.xx, server: 0.0.0.0:443</code></p>
  <p>Both of these attempts resulted in failure and the sites ended up using the default/fake/acme kubernetes certificate and so are shown as insecure in a browser.</p>
  <p>I could potentially store the files in a storage container and wrap my <code>terraform</code> commands in a script that pulls the cert/key from the storage container first and then use working method #2 from above, but I'm hoping there's a way I can avoid that that I am just missing. Any help would be greatly appreciated!</p>
  
Tags: <kubernetes><terraform><azure><ssl><secret-management>
Title: Is it possible to create a tls kubernetes secret using Azure Key Vault data resources in Terraform?
UserDisplayName: az2tonez
ThreadText: # Is it possible to create a tls kubernetes secret using Azure Key Vault data resources in Terraform?
  
  (Asked by: username_0 on 2023-01-03)
  
  I have a certificate file and a private key file that I am using to implement tls encrypted traffic for several different k8s pods running under an NGINX ingress load balancer. This works fine (i.e. the web apps are visible and show as secure in a browser) if I create the kubernetes.io/tls secret in either of these ways:
  
  1. Use kubectl: `kubectl create secret my-tls-secret --key <path to key file> --cert <path to cert file>`.
  2. Reference those files locally in terraform:
  
  ```terraform
  resource "kubernetes_secret" "my_tls_secret" {
    metadata {
      name = "my-tls-secret"
    }
  
    type = "kubernetes.io/tls"
  
    data = {
      "tls.crt" = file("${path.module}/certfile.cer"),
      "tls.key" = file("${path.module}/keyfile.key")
    }
  }
  
  ```
  
  However, neither of these methods are ideal because for #1, it turns my `terraform plan/apply` steps into 2-step processes and for #2, I don't want to commit the key file to source control for security reasons.
  
  So, my question is: is there a way to do this by using some combination of Azure Key Vault data resources (i.e. keys, secrets or certificates)?
  
  I have tried the following:
  
  1. Copy/pasting the cert and key into key vault secrets (have also tried this with base64 encoding the values before pasting them into the key vault and using base64decode() around the tls.crt and tls.key values in the Terraform):
  
  ```terraform
  data "azurerm_key_vault_secret" "my_private_key" {
    name         = "my-private-key"
    key_vault_id = data.azurerm_key_vault.mykv.id
  }
  
  data "azurerm_key_vault_secret" "my_certificate" {
    name         = "my-certificate"
    key_vault_id = data.azurerm_key_vault.mykv.id
  }
  
  resource "kubernetes_secret" "my_tls_secret" {
    metadata {
      name = "my-tls-secret"
    }
  
    type = "kubernetes.io/tls"
  
    data = {
      "tls.crt" = data.azurerm_key_vault_secret.my_certificate.value,
      "tls.key" = data.azurerm_key_vault_secret.my_private_key.value
    }
  }
  
  ```
  
  2. Tried importing the cert as an Azure key vault certificate and accessing its attributes like so:
  
  ```terraform
  data "azurerm_key_vault_certificate_data" "my_certificate_data" {
    name         = "my-certificate"
    key_vault_id = data.azurerm_key_vault.mykv.id
  }
  
  resource "kubernetes_secret" "my_tls_secret" {
    metadata {
      name = "my-tls-secret"
    }
  
    type = "kubernetes.io/tls"
  
    data = {
      "tls.crt" = data.azurerm_key_vault_certificate_data.my_certificate_data.pem,
      "tls.key" = data.azurerm_key_vault_certificate_data.my_certificate_data.key
    }
  }
  
  ```
  
  which results in an error in the NGINX ingress log of:
  `[lua] certificate.lua:253: call(): failed to convert private key from PEM to DER: PEM_read_bio_PrivateKey() failed, context: ssl_certificate_by_lua*, client: xx.xx.xx.xx, server: 0.0.0.0:443`
  
  Both of these attempts resulted in failure and the sites ended up using the default/fake/acme kubernetes certificate and so are shown as insecure in a browser.
  
  I could potentially store the files in a storage container and wrap my `terraform` commands in a script that pulls the cert/key from the storage container first and then use working method #2 from above, but I'm hoping there's a way I can avoid that that I am just missing. Any help would be greatly appreciated!
  
  **Tags:** kubernetes, terraform, azure, ssl, secret-management
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2023-02-14. Score: 1 | Accepted answer
  
  Method #1 from the original post works - the key point I was missing was *how* I was getting the cert/key into Azure KeyVault. As mentioned in the post, I was copy/pasting the text from the files into the web portal secret creation UI. Something was getting lost in translation doing it this way. The right way to do it is to use the Azure CLI, like so:
  
  ```
  az keyvault secret set --vault-name <vault name> --name my-private-key --file <path to key file>
  
  az keyvault secret set --vault-name <vault name> --name my-certificate --file <path to cert file>
  
  ```
  
  
  ---
  
  