Terraform File Provisioner问题:无法将文件复制到GCP VM
1. 目标父目录未自动创建
你的service_account_destination设置为/tmp/gcp/credentials.json,但Terraform的file provisioner不会自动创建目标路径的父目录。如果VM内/tmp/gcp目录不存在,文件复制操作会失败,部分场景下Terraform可能不会抛出明确错误,仅显示执行成功。
2. SSH连接用户不存在或配置错误
你指定的连接用户是terraform,但默认Ubuntu 20.04镜像中没有这个用户。如果startup-script.sh未创建terraform用户,Terraform的SSH连接实际会失败,部分情况下可能通过 fallback 机制(比如使用默认ubuntu用户)完成连接,但文件会被复制到其他用户的目录(如/home/ubuntu/tmp/gcp/...),而非你指定的路径。
3. Provisioner未触发执行
Terraform的provisioner默认仅在资源首次创建时执行。如果VM是之前已创建的资源,后续修改provisioner配置后,Terraform不会自动重新执行该步骤。需要手动标记资源为tainted(terraform taint google_compute_instance.vm_instance)或销毁重建VM,才能触发provisioner重新运行。
4. 本地私钥文件权限问题
SSH要求私钥文件权限必须严格限制(如600),如果你的private_key.pem权限过宽(如644),SSH客户端会拒绝使用该密钥连接。这种情况下,Terraform可能通过其他方式(如GCP OS Login或临时密钥)完成连接,但文件复制步骤可能未正确执行。
5. 目标路径权限限制
虽然/tmp目录默认全局可写,但如果startup-script.sh修改了/tmp的权限或ACL,可能导致连接用户无法在/tmp下创建目录或写入文件,进而导致复制失败。
排查步骤建议
- 查看VM系统日志:在GCP控制台的VM实例详情页,查看串行端口输出,搜索SSH连接和文件复制相关的报错信息。
- 验证连接用户:登录VM后,查看
/var/log/auth.log,确认Terraform实际使用哪个用户进行SSH连接。 - 手动测试复制:用本地生成的私钥,手动执行
scp命令复制文件到目标路径,验证是否能成功:scp -i ../../../../credentials/private_key.pem ../../../../credentials/credentials.json terraform@<VM_IP>:/tmp/gcp/credentials.json - 查看provisioner详细日志:重新运行
terraform apply时添加-debug参数,查看provisioner执行的完整日志,确认文件复制是否真正执行。
内容的提问来源于stack exchange,提问作者Umamaheswararao Meka

