【问题标题】:Environment variables apparently not being passed to a systemd service invocation环境变量显然没有被传递给 systemd 服务调用
【发布时间】:2021-12-15 19:15:08
【问题描述】:

情况如下:

我正在编写一个go 程序。

有时,程序会通过os.Exec() 调用terragrunt cli。

程序在具有systemd 版本232 的机器上运行。

到目前为止,我一直在调用 terragrunt 并暴露了一些环境变量(terragrunt 需要,我们将在下面看到)

这些环境变量由/etc/profile.d/terragruntvars 传递给登录进程

export TF_VAR_remote_state_bucket=my-bucket-name

因此,当我在终端中运行时说 terragrunt plan 并通过在我的 tf / hcl 文件中进行适当的插值,我得到类似(这是 debug 级别的输出,显示实际的 terraform调用terragrunt 最终执行)

terraform init -backend-config=my-bucket-name ...(more flags following)

我的go 程序(通过os.Exec() 调用terragrunt cli)通过go run main.go 完美运行

我决定将其设为systemd 服务

[Service]
ExecStart=/bin/sh -c myprogram
EnvironmentFile=/etc/myprogram/config
User=someuser
Group=somegroup

[Install]
WantedBy=multi-user.target

程序开始惨遭失败。通过搜索根案例,我发现TF_VAR_* 变量在运行时从未传递给服务,因此terraform 命令最终就像

terraform init -backend-config=(this is empty, nothing here)

我认为通过bash 显式调用服务,即通过ExecStart=/bin/sh -c myprogram 这将解决问题。

奇怪的部分来了。

将这些变量添加到EnvironmentFile=/etc/myprogram/config terragrunt 执行中没有任何效果。当我说没有效果时,我的意思是变量确实对服务可用,但是命令仍然被破坏,即

terraform init -backend-config=(this is empty, nothing here)

但是,TF_VAR_* 变量那里。我在我的程序中添加了一个os.Exec("env"),它确实打印了它们。

这让我发疯了,所以任何关于可能导致这种情况的提示都将不胜感激。

【问题讨论】:

    标签: go terraform systemd systemctl terragrunt


    【解决方案1】:

    就像 shell 不会将它的进程 ENV VAR's 传递给子进程:

    $ X=abc
    $ bash -c 'echo $X'   # prints nothing
    

    除非你导出环境变量:

    $ export X
    $ bash -c 'echo $X'   # abc
    

    systemd 类似,在使用EnvironmentFile 时,要导出环境变量,请使用PassEnvironment 例如

    PassEnvironment=VAR1 VAR2 VAR3
    

    来自docs

    通行证环境= 将系统服务管理器设置的环境变量传递给执行的进程。 采用空格分隔的变量名列表...

    【讨论】:

    • 感谢您的建议;但是,正如我在最初的问题中提到的,当我运行 os.Exec("env") 时,变量似乎可用。
    猜你喜欢
    • 2018-01-04
    • 2019-10-13
    • 2016-01-10
    • 1970-01-01
    • 2013-12-29
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    • 2017-06-21
    相关资源
    最近更新 更多