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

Terraform中如何将AWS EC2实例SSH签名存入AWS Secrets Manager?

解决Terraform中堡垒机SSH known_hosts存入AWS Secrets Manager的问题

问题场景

使用Terraform 1.4创建EC2堡垒机实例,需生成该实例的SSH known_hosts条目并存入AWS Secrets Manager,供后续CI/CD通过堡垒机隧道执行kubectl(避免K8s API服务器暴露)。因无法使用sshclient Provider,采用local-exec调用ssh-keyscan工具,但将结果存入本地文件后,Terraform计划阶段会提前加载该文件(此时local-exec尚未执行),导致执行中断。

最优解决方案:直接在Provisioner中完成扫描与Secret写入

跳过本地文件存储步骤,直接在terraform_data的local-exec中完成ssh-keyscan扫描,并通过AWS CLI将结果打包为JSON后写入Secrets Manager,彻底避免计划阶段的文件加载冲突。

完整代码示例

resource "aws_instance" "bastion" {
  key_name               = "key_name"
  instance_type          = "t2.micro"
  ami                    = "ami-..."
  subnet_id              = "subnet-..."
  vpc_security_group_ids = ["sg-..."] # 必须放行22端口,确保ssh-keyscan可连接
}

resource "aws_secretsmanager_secret" "bastion" {
  name = "bastion"
}

resource "terraform_data" "ssh_keyscan_store_secret" {
  input = [aws_instance.bastion.id, aws_secretsmanager_secret.bastion.arn]

  provisioner "local-exec" {
    interpreter = ["bash", "-c"]
    command = <<EOF
# 重试获取known_hosts,避免实例刚启动SSHD未就绪
KNOWN_HOSTS=""
for i in {1..10}; do
  KNOWN_HOSTS=$(ssh-keyscan -t rsa ${aws_instance.bastion.public_dns} 2>/dev/null)
  if [ -n "$KNOWN_HOSTS" ]; then
    break
  fi
  sleep 5
done

if [ -z "$KNOWN_HOSTS" ]; then
  echo "Failed to retrieve SSH known_hosts after 10 attempts" >&2
  exit 1
fi

# 构造JSON格式的Secret内容
SECRET_JSON=$(jq -n \
  --arg public_dns "${aws_instance.bastion.public_dns}" \
  --arg ssh_known_hosts "$KNOWN_HOSTS" \
  '{public_dns: $public_dns, ssh_known_hosts: $ssh_known_hosts}')

# 写入AWS Secrets Manager
aws secretsmanager put-secret-value \
  --secret-id ${aws_secretsmanager_secret.bastion.arn} \
  --secret-string "$SECRET_JSON"
EOF
  }
}

关键说明

  1. 避免本地文件依赖:直接在local-exec中完成扫描和Secret写入,跳过中间文件,彻底解决计划阶段加载文件的问题。
  2. 重试机制:添加10次循环重试,每次间隔5秒,确保实例的SSHD服务完全启动后再执行扫描,避免因实例未就绪导致的扫描失败。
  3. 环境依赖:执行Terraform的环境需安装jq(用于构造JSON)和AWS CLI,且AWS CLI需具备secretsmanager:PutSecretValue权限。
  4. 权限与网络:确保堡垒机安全组放行22端口,且执行环境可访问堡垒机的公网DNS。

内容的提问来源于stack exchange,提问作者Oliver

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 00:15:03