You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Terraform生成SSH密钥并自动添加至ssh-agent失败问题

问题:Terraform执行ssh-add后密钥未加入ssh-agent

我用Terraform的tls_private_key资源生成ED25519格式的SSH密钥:

resource "tls_private_key" "cluster_key_private" {
  algorithm = "ED25519"
}

接着通过null_resource的local-exec执行本地命令,尝试将密钥自动添加到ssh-agent密钥链:

resource "null_resource" "sshkey_add" {
  triggers = {
    always_run = "${timestamp()}"
  }
  provisioner "local-exec" {
    command = <<-EOT
      eval "$(ssh-agent -s)"
      echo '${tls_private_key.cluster_key_private.private_key_openssh}' | tr -d '\r' | ssh-add -
    EOT
  }
}

但执行完成后,我在终端用ssh-add -L检查密钥列表,输出显示:

❯ ssh-add -L
The agent has no identities.

为什么密钥没有成功添加到ssh-agent中?


原因分析与解决方案

核心原因

  • 进程隔离导致作用域失效:local-exec会启动一个独立的子shell进程,你在这个子shell里启动的ssh-agent和执行的ssh-add操作,仅在该子shell的生命周期内有效。当local-exec执行完毕,这个子shell就会退出,对应的ssh-agent进程要么被终止,要么当前终端的shell无法获取它的通信环境变量,自然看不到添加的密钥。
  • 环境变量无法跨进程传递:ssh-agent启动后会输出SSH_AUTH_SOCK和SSH_AGENT_PID两个关键环境变量,只有后续进程继承这些变量才能和该agent通信。但local-exec子shell的环境变量不会回传至你的终端shell,所以即使agent未立即终止,终端也无法连接到它。

可行解决方案

方案1:复用终端已有的ssh-agent

如果你的终端已经启动了ssh-agent(可以通过echo $SSH_AUTH_SOCK验证,有输出则说明已启动),直接去掉启动agent的命令,让ssh-add自动复用终端当前的agent:

resource "null_resource" "sshkey_add" {
  triggers = {
    always_run = "${timestamp()}"
  }
  provisioner "local-exec" {
    command = <<-EOT
      echo '${tls_private_key.cluster_key_private.private_key_openssh}' | tr -d '\r' | ssh-add -
    EOT
  }
}

这样密钥会被添加到你终端正在使用的agent中,后续执行ssh-add -L就能看到。

方案2:写入本地文件后添加(更稳定)

将生成的私钥写入本地文件(注意设置正确的权限,SSH要求私钥权限必须为0600),再通过文件路径添加密钥,同时保留密钥文件方便后续使用:

resource "local_file" "ssh_private_key" {
  content        = tls_private_key.cluster_key_private.private_key_openssh
  filename       = "${path.module}/cluster_key"
  file_permission = "0600"
}

resource "null_resource" "sshkey_add" {
  triggers = {
    key_content = local_file.ssh_private_key.content
  }
  provisioner "local-exec" {
    command = "ssh-add ${local_file.ssh_private_key.filename}"
  }
  depends_on = [local_file.ssh_private_key]
}

这种方式不依赖环境变量传递,直接指定文件路径添加,可靠性更高,同时私钥文件会被保存在当前Terraform模块目录下。


内容的提问来源于stack exchange,提问作者Joost Dübken

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 08:30:50