Self-Terminating AWS EC2 Instance?
Asked Answered
H

5

101

Is there a way that Amazon Web Services EC2 instances can be self terminating? Does Amazon have anything that allows an instance to terminate itself ("Hara-Kiri") after running for more than say an hour? I could change the scripts on the running instance to do this itself, but that might fail and I don't want to edit the image, so I would like Amazon to kill the instance.

Heading answered 10/5, 2012 at 20:8 Comment(1)
Just to clarify, I need an emergency shutoff switch if the instance lasts more than X amount of hours. My use case is that I use Amazon's EC2 to quickly spin an instance, run some process on Ubuntu (that takes about 5 minutes) and then shut itself down. This is being controlled by a windows desktop app. Most of the time it works like a charm, however, sometimes a user closes their laptop and goes on vacation for a week and guess what, I have AWS charges for a 168 hours that I didn't need. If anyone wants more details, I can tell you all about it. SteveHeading
L
122

To have an instance terminate itself do both of these steps:

  1. Start the instance with --instance-initiated-shutdown-behavior terminate or the equivalent on the AWS console or API call.
  2. Run shutdown -h now as root. On Ubuntu, you could set this up to happen in 55 minutes using:

    echo "sudo halt" | at now + 55 minutes
    

I wrote an article a while back on other options to accomplish this same "terminate in an hour" goal:

Automatic Termination of Temporary Instances on Amazon EC2
http://alestic.com/2010/09/ec2-instance-termination

The article was originally written before instance-initiated-shutdown-behavior was available, but you'll find updates and other gems in the comments.

Lindeman answered 10/5, 2012 at 21:32 Comment(5)
Eric, thank you, but I don't see where I can do #1 on the AWS console. I see a "Shutdown Behavior" setting in "Request Instances Wizard", but the only options are "Terminate" and "Stop". This doesn't actually schedule the instance to stop in an hour. I'm going to check in the AWS .NET API that I am using to launch the instance to see if I can do something like that.Heading
You set "shutdown behavior" to "terminate" and then execute "halt" or "shutdown -h now" on the instance when you want it to terminate. Schedule in advance using "at". (1) and (2) are required steps in a single process, not alternative approaches.Lindeman
Any reason for doing "shutdown -h now" as opposed to "shutdown -P now" ?Jerroldjerroll
@EricHammond The reason I ask is that my instances fail to shutdown about 5% of the time (they get stuck into a wedged state where they are running but won't terminate and can't be ssh'd into). Was just wondering if that might be the cause.Jerroldjerroll
@DustinBoswell it can be that you are using "halt" or "shutdown -h" which isn't the same as poweroff, depending on the system settings. Try "sudo poweroff" (or "sudo shutdown -P now", but I like "poweroff" for it's verbosity) instead.Humanize
P
26

You can do this

ec2-terminate-instances $(curl -s http://169.254.169.254/latest/meta-data/instance-id)

The ec2 will get its current instance id and terminate itself.

Pines answered 7/4, 2014 at 13:18 Comment(3)
I like this method... but it requires that you have credentials set up on the instance to run terminate-instances. That won't always be the case, and you'll get a "Client.UnauthorizedOperation" error.Cutlerr
You can set up an instance profile, which would remove the need for setting up credentials.Erythrism
@Cutlerr if you want an instance to terminate itself, it needs permission to terminate itself. Its an implicit condition.Kerstinkerwin
A
14

Hopefully this will work

instanceId=$(curl http://169.254.169.254/latest/meta-data/instance-id/)
region=$(curl http://169.254.169.254/latest/dynamic/instance-identity/document | grep region | awk '{print $3}' | sed  's/"//g'|sed 's/,//g')

/usr/bin/aws ec2 terminate-instances --instance-ids $instanceId --region $region

Hope this help you !!!

Aoristic answered 3/2, 2016 at 11:9 Comment(1)
Thanks! I modified it slightly, I don't know if you use jq, but figured I'd share either way. region=$(curl -s 169.254.169.254/latest/dynamic/instance-identity/document | jq -r .region)Percutaneous
S
8

Here is my script for Self-Terminating

$ EC2_INSTANCE_ID="`wget -q -O - http://instance-data/latest/meta-data/instance-id || die \"wget instance-id has failed: $?\"`"
$ echo "ec2-terminate-instances $EC2_INSTANCE_ID" | at now + 55 min || die 'cannot obtain instance-id'

If you want to assign it as Self-Stopping on Self-Terminating, you can do it one time only.

In your EC2 Console go to Instance Settings, change Shutdown Behavior to Stop.
Configure /etc/cloud/cloud.cfg, you may refer to how to run a boot script using cloud-init.
Follow answer from Eric Hammond, put the command in a file and locate it in scripts-per-boot path:

$ echo '#!/bin/sh' > per-boot.sh
$ echo 'echo "halt" | at now + 55 min' >> per-boot.sh
$ echo 'echo per-boot: `date` >> /tmp/per-boot.txt' >> per-boot.sh
$ chmod +x per-boot.sh
$ sudo chown -R root per-boot.sh
$ sudo mv -viu per-boot.sh /var/lib/cloud/scripts/per-boot

Reboot your instance, check if the script is executed:

$ cat /tmp/per-boot.txt 
per-boot: Mon Jul 4 15:35:42 UTC 2016

If so, just in case you forgot to stop your instance, it will assure you that the instance will do itself termination as stopping when it has run for 55 minutes or whatever time you set in the script.

Broadcast message from root@ip-10-0-0-32
        (unknown) at 16:30 ...

The system is going down for halt NOW!

PS: For everyone want to use the Self-Stopping, one thing you should note that not all EC2 types are self recovery on restarting. I recommend to use EC2-VPC/EBS with On/Off Schedule.

Septimal answered 4/7, 2016 at 14:11 Comment(0)
V
0

I had a similar need, where I had web applications firing up EC2 instances. I could not trust the web application to stop/terminate the instances, so I created a script to run in a separate process, called the "feeder". The feeder owns the responsibility of stopping/terminating the instance. The web application must periodically request that the feeder "feed" the instance. If an instance "starves" (is not fed within a timeout period), the feeder will stop/terminate it. Two feeders can be run simultaneously on different machines to protect against issues with one feeder process. In other words, the instance runs on a pressure switch. When pressure is released, the instance is stopped/terminated. This also allows me to share an instance among multiple users.

To the original question, the feeder, which could be running in the EC2 instance itself, eliminates the need to know a priori how long the task will be running, but it places a burden on the application to provide periodic feedings. If the laptop is closed, the instance will go down.

The feeder lives here: https://github.com/alessandrocomodi/fpga-webserver and has a permissive open-source license.

Voyeur answered 4/8, 2019 at 13:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.