linux - 从 CloudFormation::Init 命令重新启动

标签 linux amazon-web-services amazon-ec2 aws-cloudformation

我在通过 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/

相关文章:

node.js - 此 Node 实例的 N-API 版本为 1。此模块支持 N-API 版本 3。此 Node 实例无法运行此模块

linux - 权限被拒绝(公钥)Git 和 AWS EC2

c - 使用 libata 从用户空间应用程序在 HDD 上执行 ATA 命令

ios - 为什么 mmap() 使用 MAP_FAILED 而不是 NULL?

linux - 为什么 kmalloc() 比 vmalloc() 更高效?

amazon-web-services - 使用 AWS Cognito 和 Serverless 实现基于角色的访问控制

apache - 使用命令行更改文档根目录

node.js - NodeJS - 如何让进程在出现问题时自动重启?

apache - 在 Elastic beanstalk 上设置 https 代理

amazon-web-services - 如何在 Amazon RDS 上设置具有系统管理员权限的用户