Kapildev Neupane
Posted on October 31, 2021
Background
I always forget to turn off my virtual machines on Cloud when I am not using the computer. Because of this, I always end up paying tons for forgetting to turn it off. The cost of these instances/machines are usually $1 per hour. Hence, if I forget to turn it off for a whole day, I would incur $24.
This feels like something the machine should do itself and not burden me for remembering. Hence, I have gathered information from all over the web to make this short, simple and easy to follow guide.
A script that checks if there is a user connecting through SSH
First, we need a script that checks if there is a user connecting through SSH and turn off the EC2 instance if there are none for a set interval of time. The following script does exactly that:
#!/bin/bash
#
# Reference: https://serverfault.com/a/1061792
# Shuts down the host on inactivity.
#
# Designed to be executed as root from a cron job.
# It will power off on the 2nd consecutive run without an active ssh session.
# That prevents an undesirable shutdown when the machine was just started, or on a brief disconnect.
#
# To enable, add this entry to /etc/crontab:
# */5 * * * * root /home/<name_of_user>/dotfiles/bin/shutdown-if-inactive
#
set -o nounset -o errexit -o pipefail
MARKER_FILE="/tmp/ssh-inactivity-flag"
STATUS=$(netstat | grep ssh | grep ESTABLISHED &>/dev/null && echo active || echo inactive)
if [ "$STATUS" == "inactive" ]; then
if [ -f "$MARKER_FILE" ]; then
echo "Powering off due to ssh inactivity."
rm "$MARKER_FILE"
/sbin/shutdown -h now
else
# Create a marker file so that it will shut down if still inactive on the next time this script runs.
touch "$MARKER_FILE"
fi
else
# Delete marker file if it exists
rm --force "$MARKER_FILE"
fi
Save this script in a file named:
~/bin/shutdown-if-inactive.sh
Don't forget to make the file executable:
chmod +x ~/bin/shutdown-if-inactive.sh
Add the script to a cron job to run it every 10 minutes
- Open up the crontab config file for the root user:
sudo crontab -u root -e
Note: we need to run this cronjob as a root because shutting down requires elevated privileges.
- Add the following line to the end of the file so that the script from above is invoked every 10 minutes:
*/10 * * * * /home/<name_of_user>/bin/shutdown-if-inactive.sh >> /home/<name_of_user>/bin/shutdown-if-inactive-logs 2>&1
Here,
a. */10 * * * *
means run the script every 10 minutes at any hour, at any day, at any month and at any day of the month respectively.
b. /home/<name_of_user>/bin/shutdown-if-inactive.sh
is the file where we put the bash script from above.
c. /home/<name_of_user>/bin/shutdown-if-inactive-logs
is the file where we put the output and errors from the script.
d. 2>&1
means redirect stderr
to stdout
. Basically, it means, we are redirecting error stream the output stream. Combine it with >> file_here
; and we get errors appended to the file.
e. Here, we are storing logs to be able to debug why the above script is not working properly.
- I would recommend changing the above line to have
*/1
instead of*/10
. This way, you can check if this whole thing works in 2 minutes instead of having to wait for the whole 20 minutes.
Please let me know in the comments if this worked for you. Thank you for reading my first post in DEV.to.
Posted on October 31, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.