使用Terraform Provisioner向GCP VM传输文件失败求助
解决Terraform File Provisioner SSH私钥读取失败问题
问题现象
使用Terraform的file provisioner向GCP Compute Instance传输文件时失败,报错如下:
Error: file provisioner error │ │ with google_compute_instance.controller, │ on Creation_VM_GCP.tf line 158, in resource "google_compute_instance" "controller": │ 158: provisioner "file" { │ │ Failed to read ssh private key: no key found
对应的实例配置代码:
resource "google_compute_address" "ip_address" { name = "ipv4-address" } resource "google_compute_instance" "controller" { name = "controller" machine_type = "n1-standard-2" zone = "us-central1-a" boot_disk { initialize_params { image = "ubuntu-os-cloud/ubuntu-2204-lts" } } # Pour attribuer une adresse IP dans la plage CIDR : 100.100.20.0/24 network_interface { subnetwork = google_compute_subnetwork.subnet.name network_ip = "10.100.20.3" access_config { nat_ip = google_compute_address.ip_address.address } } metadata_startup_script = "./'${file("${path.module}/Config_Ansible.sh")}'" connection { type = "ssh" user = "MSI" # Remplacez par votre nom d'utilisateur SSH private_key = file("./key") # Remplacez par le chemin de votre clé privée SSH host = google_compute_address.ip_address.address } provisioner "file" { source = "../Ansible_playbooks/Inventory_create.sh" destination = "/home/ubuntu/Inventory_create.sh" } tags = ["ansible"] }
排查方向
报错核心是Terraform无法读取指定的SSH私钥,可能的原因包括:
- 私钥文件路径错误或文件不存在
- 私钥文件权限不符合SSH要求
- 私钥格式不被Terraform的SSH客户端支持
- 连接配置中的用户与目标实例实际用户不匹配
- 实例未完全就绪导致SSH连接失败
解决方案
1. 验证私钥文件的存在与权限
- 确认
./key文件存在于Terraform执行目录(即运行terraform apply的目录),执行ls ./key检查文件是否存在 - 设置正确的私钥权限:SSH私钥必须限制为仅所有者可读,执行
chmod 600 ./key
2. 检查并修正私钥格式
- 打开
./key文件,确认开头为-----BEGIN RSA PRIVATE KEY-----或-----BEGIN OPENSSH PRIVATE KEY-----,且文件内容完整无截断 - 如果格式不兼容,使用
ssh-keygen转换为PEM格式:ssh-keygen -p -m PEM -f ./key
3. 修正连接用户与目标路径的一致性
- Ubuntu 22.04镜像的默认用户是
ubuntu,而非配置中的MSI,修改connection配置:connection { type = "ssh" user = "ubuntu" private_key = file("./key") host = google_compute_address.ip_address.address } - 确保
destination路径对应用户有写入权限,/home/ubuntu/属于ubuntu用户,配置无需修改
4. 修复元数据启动脚本的写法
- 当前
metadata_startup_script的写法错误,file()函数直接返回文件内容,无需额外包裹路径,修正为:metadata_startup_script = file("${path.module}/Config_Ansible.sh") - 错误写法会导致启动脚本无法执行,可能影响SSH服务启动,间接导致连接失败
5. 等待实例完全就绪
- 在
connection配置中添加超时和等待参数,确保实例SSH服务就绪后再执行provisioner:connection { type = "ssh" user = "ubuntu" private_key = file("./key") host = google_compute_address.ip_address.address timeout = "5m" sleep = "30s" }
内容的提问来源于stack exchange,提问作者Younes FARISS
相关产品推荐
相关产品推荐

