通过Go代码执行Terraform文件时遇SSH认证失败问题求助
排查Go调用Terraform时SSH认证失败问题
问题场景
通过Go代码调用Terraform执行部署时出现SSH认证失败错误:
timeout - last error: SSH authentication failed (ec2-user@3.142.149.63:22): ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain Error: file provisioner error
但直接在Terraform工作目录手动执行terraform apply无任何报错,且确认密钥文件路径正确。
关联代码与配置
Go调用代码:
package main import ( "context" "fmt" "log" "github.com/hashicorp/go-version" "github.com/hashicorp/hc-install/product" "github.com/hashicorp/hc-install/releases" "github.com/hashicorp/terraform-exec/tfexec" ) func main() { installer := &releases.ExactVersion{ Product: product.Terraform, Version: version.Must(version.NewVersion("1.0.6")), Timeout: 1000000000000000, } execPath, err := installer.Install(context.Background()) if err != nil { log.Fatalf("error installing Terraform: %s", err) } workingDir := "C:/Users/XYZ/Learnings/Terraform JMeter/terraform-aws-jmeter-distributed-load-test-infra" tf, err := tfexec.NewTerraform(workingDir, execPath) if err != nil { log.Fatalf("error running NewTerraform: %s", err) } err = tf.Init(context.Background(), tfexec.Upgrade(true)) if err != nil { log.Fatalf("error running Init: %s", err) } err = tf.Apply(context.Background()) if err != nil { log.Fatalf("error running Apply: %s", err) } state, err := tf.Show(context.Background()) if err != nil { log.Fatalf("error running Show: %s", err) } fmt.Println(state.FormatVersion) // "0.1" }
Terraform连接与provisioner配置:
connection { type = "ssh" user = "ec2-user" private_key = file("C:/Users/XYZ/Learnings/GO/go-terraform.pem") host = self.public_ip } provisioner "file" { source = "Data98UserName.csv" destination = "/home/ec2-user/Data98UserName.csv" }
排查步骤
1. 验证Go进程对密钥文件的访问权限
手动执行时使用当前用户权限,Go程序运行时可能因权限限制无法读取密钥文件。在Go代码中添加读取测试:
import "os" // 在初始化Terraform实例后添加 content, err := os.ReadFile("C:/Users/XYZ/Learnings/GO/go-terraform.pem") if err != nil { log.Fatalf("Failed to read key file: %v", err) } log.Printf("Key file content length: %d", len(content))
如果读取失败,需调整密钥文件权限或Go程序的运行身份。
2. 对齐Terraform执行环境变量
手动执行时的环境变量(如HOME、SSH代理相关变量)可能与Go程序运行环境不一致。可以:
- 在Go代码中打印当前环境变量,对比手动执行时的环境:
for _, env := range os.Environ() { log.Println(env) } - 显式为Terraform设置必要环境变量:
tf.SetEnv(map[string]string{ "HOME": os.Getenv("HOME"), // 若使用SSH代理,添加对应的环境变量 })
3. 修复密钥文件换行格式
Windows下密钥文件默认使用\r\n换行,而SSH要求\n,可能导致密钥无效。修改Terraform配置替换换行符:
private_key = replace(file("C:/Users/XYZ/Learnings/GO/go-terraform.pem"), "\r\n", "\n")
4. 确认Terraform版本一致性
检查手动执行的Terraform版本与Go代码中安装的1.0.6是否一致:
# 手动执行环境运行 terraform version
若版本不一致,调整Go代码中的Version参数匹配手动版本。
5. 开启Terraform调试日志
在Go代码中开启调试日志,查看SSH认证的详细过程:
tf.SetLog(tfexec.LogLevelDebug)
从日志中可以确认密钥是否正确加载、认证请求的具体细节,定位问题根源。
内容的提问来源于stack exchange,提问作者Shady
相关产品推荐
相关产品推荐

