<p>The private key is stored in the terraform state. Typically you would show the resources with the <code>terraform state</code> command, but sensitive values are not shared on the screen. If you use the -json option, this restriction is removed, dumping the entire state in json format.</p>
<p>Then you can use <code>jq</code> to parse the output to find the value. This value will have quotes around it and escaped newlines that you'll need to clean up in order to get a properly formatted PEM key. The <code>-r</code> option to jq will handle that well by dumping the value in raw format.</p>
<pre><code>terraform show -json | \
jq -r '.values.root_module.resources[].values | select(.private_key_pem) |.private_key_pem' \
&gt; ~/.ssh/terraform_private_key.pem

</code></pre>
<p>In the above <code>jq</code> command, three are three sections. The first filters down to the values of each resource. The second selects only value sets with a <code>privatey_key_pem</code> key in them. The third prints the value of those specific key(s). The select prevents the printing of a null line for each value set without a <code>private_key_pem</code> key/value pair to show.</p>

CC BY-SA 4.0
2023-02-08T15:31:50.263Z
For the record, @Martin-atkins answer is better, but this will work in a pinch with code changes.
Josiah
CC BY-SA 4.0
2021-08-11T18:27:48.637Z
2021-08-24T17:37:22.260Z
2021-08-24T17:37:22.260Z
Josiah
<h1>Using <code>private_key_openssh</code></h1>
<p>Another option is to use</p>
<pre class="lang-shell prettyprint-override"><code>terraform show -json |
  jq -r '.values.root_module.resources[] | select(.address==&quot;tls_private_key.ssh&quot;).values.private_key_openssh'
</code></pre>
<p>This command also uses <code>root_module.resources</code> specifically, because that's where the key is created. This address corresponds to this in a <code>main.tf</code>,</p>
<pre><code>resource &quot;tls_private_key&quot; &quot;ssh&quot; {
  algorithm   = &quot;ECDSA&quot;
  ecdsa_curve = &quot;P384&quot;
}
</code></pre>
<p>In your case the key may have a different name and resource. By any means, I'd rather not write it explicitly, you can find out what resource it's in with,</p>
<pre><code>terraform show -json | jq -r | less
</code></pre>
<p>I choose not to use PEM because OpenSSH has its own key format which is different in some cases. For example, as of now OpenSSH can not read ed25519 keys in PKCS#9 (PEM).</p>

CC BY-SA 4.0
2023-02-07T01:13:48.663Z
2023-02-07T01:13:48.663Z
Evan Carroll
<p>If you need to use a value like this private key for later steps, the common answer is to return it as a root module output value. Since the private key is sensitive, you can mark it as such to prevent Terraform from showing it on the screen by default:</p>
<pre><code>output &quot;private_key&quot; {
  value     = tls_private_key.example.private_key_pem
  sensitive = true
}
</code></pre>
<p>When you run <code>terraform apply</code>, Terraform will redact the value because it's sensitive. However, you can still access it from scripts by running <code>terraform output -raw private_key</code>, because the value is still stored in the state and the sensitive option only prevents it from showing in human-oriented output. (The <code>-raw</code> option is intended for use in scripts.)</p>

CC BY-SA 4.0
2021-08-16T21:31:17.000Z
2021-08-16T21:31:17.000Z
Martin Atkins
<p>I used the terraform resource tls_private_key to generate a key and push that into AWS, but it didn't give me the private key to use to access the related resources. How can I recover that key?</p>

<terraform><tls>
Get private key from terraform state?
Josiah
# Get private key from terraform state?

(Asked by: username_0 on 2021-08-11)

I used the terraform resource tls\_private\_key to generate a key and push that into AWS, but it didn't give me the private key to use to access the related resources. How can I recover that key?

**Tags:** terraform, tls


---

## 3 answers

### Answer by username_2 on 2021-08-16. Score: 10 | Accepted answer

If you need to use a value like this private key for later steps, the common answer is to return it as a root module output value. Since the private key is sensitive, you can mark it as such to prevent Terraform from showing it on the screen by default:
output "private_key" {
  value     = tls_private_key.example.private_key_pem
  sensitive = true
}

When you run terraform apply, Terraform will redact the value because it's sensitive. However, you can still access it from scripts by running terraform output -raw private_key, because the value is still stored in the state and the sensitive option only prevents it from showing in human-oriented output. (The -raw option is intended for use in scripts.)


---

### Answer by username_0 on 2021-08-11. Score: 4

The private key is stored in the terraform state. Typically you would show the resources with the terraform state command, but sensitive values are not shared on the screen. If you use the -json option, this restriction is removed, dumping the entire state in json format.
Then you can use jq to parse the output to find the value. This value will have quotes around it and escaped newlines that you'll need to clean up in order to get a properly formatted PEM key. The -r option to jq will handle that well by dumping the value in raw format.
terraform show -json | \
jq -r '.values.root_module.resources[].values | select(.private_key_pem) |.private_key_pem' \
> ~/.ssh/terraform_private_key.pem


In the above jq command, three are three sections. The first filters down to the values of each resource. The second selects only value sets with a privatey_key_pem key in them. The third prints the value of those specific key(s). The select prevents the printing of a null line for each value set without a private_key_pem key/value pair to show.

> **Comments:**
> **username_0**: For the record, @Martin-atkins answer is better, but this will work in a pinch with code changes.  

---

### Answer by username_1 on 2023-02-07. Score: 1

Using private_key_openssh
Another option is to use
terraform show -json |
  jq -r '.values.root_module.resources[] | select(.address=="tls_private_key.ssh").values.private_key_openssh'

This command also uses root_module.resources specifically, because that's where the key is created. This address corresponds to this in a main.tf,
resource "tls_private_key" "ssh" {
  algorithm   = "ECDSA"
  ecdsa_curve = "P384"
}

In your case the key may have a different name and resource. By any means, I'd rather not write it explicitly, you can find out what resource it's in with,
terraform show -json | jq -r | less

I choose not to use PEM because OpenSSH has its own key format which is different in some cases. For example, as of now OpenSSH can not read ed25519 keys in PKCS#9 (PEM).


---

