如何通过本地SSH密钥传输Zip至EC2?Terraform报错及工具选择咨询
使用Terraform通过SSH传输压缩包到EC2的问题解决
咱们一步步来解决你的问题:
1. 解决SSH密钥读取失败的核心问题
你遇到的Error: Failed to read ssh private key: no key found错误,根源是你使用的是Putty专属的.ppk格式密钥,而Terraform的SSH连接模块只支持标准OpenSSH格式的私钥。解决步骤很简单:
- 打开Puttygen工具,加载你的
id_rsa.ppk文件 - 点击顶部菜单的
Conversions→Export OpenSSH key,将密钥保存为id_rsa(不要加任何后缀)到你的.ssh目录 - 修改Terraform代码中的
private_key配置,指向转换后的OpenSSH密钥:private_key = file("C:/Users/myuser/.ssh/id_rsa")
2. 修正远程文件路径的错误
你当前的destination路径存在逻辑问题:"/home/${var.ec2_user}/${data.archive_file.scripts.output_path}"会把本地的完整文件路径(比如C:/xxx/files/app.zip)直接拼到远程路径中,导致远程出现/home/ec2-user/C:/xxx/files/app.zip这种无效路径。你需要直接指定远程的文件名:
destination = "/home/${var.ec2_user}/app.zip"
3. 修正后的完整可运行代码
data "archive_file" "scripts" { type = "zip" source_dir = "${path.module}/files/app" output_path = "${path.module}/files/app.zip" } resource "null_resource" "upload" { provisioner "file" { source = data.archive_file.scripts.output_path destination = "/home/${var.ec2_user}/app.zip" connection { type = "ssh" user = var.ec2_user private_key = file("C:/Users/myuser/.ssh/id_rsa") # 替换为转换后的OpenSSH密钥 host = var.hostname } } # 触发条件:当源目录文件变化时,重新生成压缩包并上传 triggers = { archive_hash = data.archive_file.scripts.output_base64sha256 } }
我额外添加了triggers配置,这样当files/app目录下的文件发生变化时,Terraform会自动重新生成压缩包并执行上传,避免出现缓存导致的文件不更新问题。
4. 关于是否应该使用Provisioner的问题
因为你的文件体积很小,使用file provisioner是完全合适的——这种方式简单直接,不需要依赖额外的云服务(比如S3)就能完成传输。当然,如果后续需要处理大文件或者更复杂的分发场景,你可以考虑先上传到S3再在EC2上下载,但对于当前的小文件场景,provisioner是最优选择之一。
内容的提问来源于stack exchange,提问作者Connor Gervin
相关产品推荐
相关产品推荐

