Packer CI/CD流水线中如何避免配置ssh_private_key_file本地路径
回答
两个需求都完全可行,不需要将任何SSH密钥文件提交到GitHub仓库,适配GitHub Actions的具体配置方法如下:
1. 环境变量传入SSH私钥(无需本地文件)
你已经定义了从SSH_PVT_KEY环境变量读取私钥内容的pvt_key变量,只需要调整source块的SSH配置即可,有两种可选方案:
- 方案一(无临时文件,最简洁):Packer的SSH通信器原生支持直接传入私钥内容,不需要读取本地文件,直接将变量传给
ssh_private_key参数,删除原有ssh_private_key_file配置即可:
source "digitalocean" "example" { # 保留原有api_token、image、region、size等配置 ssh_private_key = var.pvt_key # 删除 ssh_private_key_file = path/to/my/file 这行 }
- 方案二(兼容旧版本Packer):如果使用的Packer版本较低不支持
ssh_private_key参数,可以在GitHub Actions的作业步骤里将环境变量中的私钥临时写入runner的临时文件,设置600权限后传入路径。GitHub Actions的runner是每次作业全新创建的临时环境,作业结束后会直接销毁,临时文件不会留存,没有泄露风险:
# GitHub Actions 工作流步骤 - name: 生成临时SSH私钥文件 run: | install -m 600 /dev/null ~/.ssh/ci_packer_key echo "$SSH_PVT_KEY" > ~/.ssh/ci_packer_key env: SSH_PVT_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
对应Packer配置修改为:
ssh_private_key_file = pathexpand("~/.ssh/ci_packer_key")
另外你当前配置里的ssh_key_id = id存在配置错误,CI场景下不需要提前在DigitalOcean控制台上传公钥,直接将公钥内容传入ssh_key参数即可,构建时Packer会自动将公钥注入临时Droplet,构建完成后随Droplet销毁,不会留存在你的DO账户中。
2. 环境变量传入SSH公钥(替代file provisioner)
不需要依赖本地公钥文件,完全可以通过环境变量传入公钥内容,替换原有file provisioner:
首先新增公钥变量,从环境变量读取:
variable "ssh_pub_key" { type = string default = env("SSH_PUB_KEY") }
然后删除原有file provisioner,换成shell provisioner直接将公钥内容写入目标路径:
build { sources = ["source.digitalocean.example"] # 替换原有的file provisioner provisioner "shell" { inline = [ "echo '${var.ssh_pub_key}' > /tmp/publickey.pub", "chmod 644 /tmp/publickey.pub" ] } # 保留原有的ansible-local provisioner配置不变 provisioner "ansible-local" { playbook_file = "../ansible/playbook.yml" extra_arguments= [ "-vvv", "--extra-vars", "'ansible_python_interpreter=/usr/bin/python3'" ] } }
同时在source块补充公钥注入配置:
source "digitalocean" "example" { # 其他配置不变 ssh_key = var.ssh_pub_key # 删除原有的ssh_key_id = id配置 }
GitHub Actions 环境变量配置
将DigitalOcean PAT、SSH私钥、SSH公钥全部存入GitHub仓库的Secrets,在Packer构建步骤中将Secrets注入为对应环境变量即可,不需要提交任何敏感文件到仓库:
- name: Packer 构建镜像 run: | packer init . packer build . env: DO_PAT: ${{ secrets.DIGITALOCEAN_PAT }} SSH_PVT_KEY: ${{ secrets.SSH_PRIVATE_KEY }} SSH_PUB_KEY: ${{ secrets.SSH_PUBLIC_KEY }}
注意事项
- 所有敏感信息统一存放在GitHub Secrets中,不要硬编码在配置文件或工作流文件里,Secrets内容只会在作业运行时解密注入,不会明文打印到日志。
- SSH公钥为单行格式,直接通过echo写入不会存在shell转义问题。
- 如果使用临时私钥文件方案,不需要额外手动清理,runner销毁时会自动清除所有数据。
内容的提问来源于stack exchange,提问作者user19413311
相关产品推荐
相关产品推荐

