我在通过 cfn-init
命令重新启动 EC2 实例时遇到问题。我的实例的 CloudFormation::Init
元数据中有以下配置键。
dns-hostname:
commands:
dns-hostname:
env: { publicDns: !Ref PublicDns }
command: |
old=$(hostname)
sed "s|HOSTNAME=localhost.localdomain|HOSTNAME=$publicDns|" --in-place /etc/sysconfig/network
echo HOSTNAME changed from \"$old\" to \"$publicDns\"
reboot
ignoreErrors: true
该命令要做的就是将实例的主机名更改为提供的公共(public) DNS 名称。此更改需要重新启动才能生效,并且由于 cfn-init
不知道这一点,因此我必须在最后一行中包含对 reboot
的实际调用。不幸的是,构建失败并显示以下日志消息(来自 /var/log/cfn-init.log
):
2017-04-16 12:16:00,301 [DEBUG] Running command dns-hostname
2017-04-16 12:16:00,301 [DEBUG] Running test for command dns-hostname
2017-04-16 12:16:00,309 [DEBUG] Test command output: HOSTNAME will be changed to "bastion.example.com"
2017-04-16 12:16:00,309 [DEBUG] Test for command dns-hostname passed
2017-04-16 12:16:00,321 [ERROR] Command dns-hostname (old=$(hostname)
sed "s|HOSTNAME=localhost.localdomain|HOSTNAME=$publicDns|" --in-place /etc/sysconfig/network
echo HOSTNAME changed from \"$old\" to \"$publicDns\"
reboot
) failed
2017-04-16 12:16:00,321 [DEBUG] Command dns-hostname output: HOSTNAME changed from "ip-10-0-128-4" to "bastion.example.com"
/bin/sh: line 3: reboot: command not found
2017-04-16 12:16:00,321 [INFO] ignoreErrors set to true, continuing build
显然,实际的主机名更改并未失败,只是调用了reboot
。如果我尝试使用 shutdown -r
而不是 reboot
,并且如果我尝试使用绝对路径 (sbin/reboot
),我会收到相同的错误消息code>),然后它就会挂起并且堆栈创建超时。怎么找不到这些非常基本的命令呢?我在这里缺少一些简单的东西吗?如有任何帮助,我们将不胜感激!
编辑:根据this post ,当常用命令不可用时,可能是由于 PATH
搞砸了。事实上,CloudFormation::Init docs假设使用 env
属性将覆盖当前环境,可能包括 PATH
。但是,我在模板中添加了一行以在命令内 echo $PATH
,结果是:“usr/local/bin:/bin:/usr/bin
” 。所以我的 PATH
仍然包含 bash
可执行文件的路径,我仍然很困惑......
最佳答案
嗯,看起来 env
属性是问题所在。尽管我认为我的 PATH
仍然有必要的路径来查找 bash
可执行文件,从而运行 reboot
命令,但直到我从模板中删除了 env 属性,一切都能够成功构建。我在让 reboot
命令按预期运行时仍然遇到一些问题,因为该命令似乎不会在您调用它后立即运行。例如,以下代码将在重新启动之前输出数字 1-10。
echo 1
echo 2
echo 3
echo 4
echo 5
reboot
echo 6
echo 7
echo 8
echo 9
echo 10
因此,该实例显然会在运行稍后的 CloudFormation::Init 配置中的其他命令时尝试重新启动,从而导致 cfn-init 失败。我的解决方案只是使用 commands
block 运行配置,这些命令 block 在所有其他配置之后手动调用 reboot
。长话短说,这是工作模板片段:
other-config:
...
# This config comes after the other b/c it manually calls 'reboot'
dns-hostname:
commands:
dns-hostname:
command: !Sub |
publicDns=${PublicDns}
old=$(hostname)
sed "s|HOSTNAME=localhost.localdomain|HOSTNAME=$publicDns|" --in-place /etc/sysconfig/network
echo HOSTNAME changed from \"$old\" to \"$publicDns\"
reboot
ignoreErrors: true
# Any other configs that call reboot can follow
关于linux - 从 CloudFormation::Init 命令重新启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43443155/