DEV Community

Kapildev Neupane
Kapildev Neupane

Posted on • Edited on

How to auto shutdown when you are not using the Cloud Virtual Machines?

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

Enter fullscreen mode Exit fullscreen mode
  1. Save this script in a file named: ~/bin/shutdown-if-inactive.sh

  2. Don't forget to make the file executable:

chmod +x ~/bin/shutdown-if-inactive.sh
Enter fullscreen mode Exit fullscreen mode

Add the script to a cron job to run it every 10 minutes

  1. Open up the crontab config file for the root user:
sudo crontab  -u root -e
Enter fullscreen mode Exit fullscreen mode

Note: we need to run this cronjob as a root because shutting down requires elevated privileges.

  1. 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
Enter fullscreen mode Exit fullscreen mode

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.

  1. 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.

Top comments (2)

Collapse
 
sisco profile image
Jorge Sisco

Thanks for this post, I had to do something about two instances that are being use as dev stations, sometimes we would forget to stop them, this is a money saver approach!

Collapse
 
kpldvnpne profile image
Kapildev Neupane

Glad I was able to help!