如何使用Terraform提供的功能开始远程服务?

17
我希望我的Terraform配置可以通过调用命令来提供服务器并在最后启动服务,并保持其运行。我尝试使用nohup和screen以及remote-exec: nohup:
provisioner "remote-exec" {
 inline = "nohup sudo command &"
}

屏幕:

provisioner "remote-exec" {
 inline = "screen -d -m sudo command"
}

我通过手动登录来检查命令是否正在运行。但它们不能保持进程运行。如果我手动尝试并使用ssh调用它们,这些命令确实可以工作。

我如何使用Terraform进行配置以启动一个命令并使其在返回控制流的同时保持运行?


1
你尝试过使用用户数据(user-data)而不是远程执行(remote-exec)吗?不确定为什么远程执行无法工作,但用户数据可能提供另一种途径。 - Liam
2个回答

36

尝试在nohup后添加一个sleep。这对我有用。我怀疑在将最后一个远程执行程序放入后台让Terraform在没有nohup的情况下关闭连接,这样子进程就有机会启动了,但是这个方法可能并不可靠。

provisioner "remote-exec" {
    inline = [
        "nohup sudo command &",
        "sleep 1"
    ]
}

5
这应该是被接受的答案。对我来说它运行得很好。 - Rafael Colucci
1
我尝试了许多使用nohup和disown的解决方案,但都没有奏效。但是这个解决方案对我有效。 - Abdul Jabbar

2
更加健壮的解决方案是启动一个服务来运行您的进程。
这意味着 init 系统可以控制该进程,如果必要,可以重新启动它。它还获得现代 init 系统的其他好处,例如处理依赖关系排序(确保其他服务在该服务启动之前运行)和日志等。
如果您将服务设置为在启动时启动,则可以避免通过 SSH 连接到服务器,并且可以使服务器在不需要重新配置的情况下容忍重新启动。
使用 Systemd,这意味着创建一个 unit 文件,可以简单地如下所示:
[Unit]
Description=foo

[Service]
ExecStart=command
Restart=always

[Install]
WantedBy=multi-user.target

运行以下命令将确保command在启动时自动运行,并且任何进程故障都会导致它自动重新启动:
systemctl enable foo.service
systemctl start foo.service

当使用像 AWS自动扩展组这样的机制来配置您的实例时,这变得更加重要。通过 aws_autoscaling_group资源创建自动扩展组时,您无法轻松连接到在那时创建的实例,并且无法控制连接到实例时组扩展或替换实例。此时,重要的是实例能够完全自行配置,可以仅使用基本镜像(可以使用诸如 Packer之类的工具创建)或通过用户数据脚本,在第一次启动时自动运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接