systemd服务运行Go程序调用terragrunt时TF_VAR环境变量不生效问题
问题根因
- Go代码调用
os/exec包生成子进程时未主动继承当前进程的全量环境变量。默认情况下exec.Cmd未显式设置Env字段时会继承父进程环境,但如果代码中手动为Env字段赋值了自定义变量列表,未追加os.Environ()获取的当前进程现有变量,就会导致TF_VAR_*变量没有传递给terragrunt子进程,这是该问题最高概率的触发原因。 - systemd的EnvironmentFile配置格式错误。如果
/etc/myprogram/config直接复用了/etc/profile.d/terragruntvars的写法保留了export前缀,systemd会将export关键字识别为变量内容的一部分,导致变量名或值不符合terragrunt的读取规则。 - systemd 232版本中使用
/bin/sh -c包裹启动命令时,shell层可能过滤部分环境变量,导致变量传递中断。
解决方案
- 修复Go代码的子进程环境继承逻辑,调用terragrunt前明确将当前进程的环境变量传递给子进程,示例代码:
import "os" import "os/exec" // 调用terragrunt的逻辑 cmd := exec.Command("terragrunt", "plan", "your-args") // 先继承当前进程所有环境变量,再按需追加自定义变量 cmd.Env = append(os.Environ(), "YOUR_CUSTOM_VAR=custom_value") // 后续执行cmd的逻辑保持不变
- 修正EnvironmentFile格式,删除所有
export前缀,直接写纯键值对,/etc/myprogram/config示例:
TF_VAR_remote_state_bucket=my-bucket-name # 其余变量同理,不要加export关键字
- 优化systemd服务配置,删除不必要的
/bin/sh -c包裹,直接指定程序二进制路径启动,避免shell层过滤环境变量:
[Service] ExecStart=/绝对路径/到/你的/myprogram EnvironmentFile=/etc/myprogram/config User=someuser Group=somegroup [Install] WantedBy=multi-user.target
- 验证修复效果:修改完成后执行
systemctl daemon-reload重载systemd配置,再重启服务,可在terragrunt执行前打印子进程的Env列表,确认TF_VAR_*变量存在且格式正常。
内容的提问来源于stack exchange,提问作者pkaramol
相关产品推荐
相关产品推荐

