Reputation: 2524
I'm having trouble rebooting my EC2 instance from a cfn-init
command. I have the following config key in my instance's CloudFormation::Init
metadata.
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
All the command is supposed to do is change the instance's hostname to the provided public DNS name. A reboot is required for this change to take effect, and since cfn-init
doesn't know this, I have to include the actual call to reboot
in the last line. Unfortunately, the build fails with the following log message (from /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
Clearly, the actual hostname change is not failing, just the call to reboot
. I get the same error message if I try to use shutdown -r
instead of reboot
, and if I try to use an absolute path (sbin/reboot
), then it just hangs and stack creation times out. How are these very basic commands not found? Am I missing something simple here? Any help is appreciated!
EDIT: According to this post, when common commands are not available, it may be due to a screwed up PATH
. And indeed, the CloudFormation::Init docs say that using the env
property will overwrite the current environment, potentially including PATH
. However, I added a line to my template to echo $PATH
inside the command, and that yielded: "usr/local/bin:/bin:/usr/bin
". So my PATH
still includes the path to the bash
executable, and I am still confused...
Upvotes: 0
Views: 1923
Reputation: 2524
Well, it looks like the env
property was the issue. Even though I thought that my PATH
still had the necessary paths to find the bash
executable and thereby run the reboot
command, it wasn't until I removed the env
property from my template that everything was able to build successfully. I still had some trouble getting the reboot
command to behave as expected, as the command doesn't seem to run as soon as you call it. For instance, the following code will output numbers 1-10 before rebooting.
echo 1
echo 2
echo 3
echo 4
echo 5
reboot
echo 6
echo 7
echo 8
echo 9
echo 10
So the instance would apparently try to reboot while in the middle of running other commands from later CloudFormation::Init
configs, causeing cfn-init
to fail. My solution to this was just to run configs with commands
blocks that manually called reboot
after all other configs. Long story short, here is the working template snippet:
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
Upvotes: 1