Auto-terminate EC2 instance when image is created

amazon ec2

I want to get an automated process for AMI creation going, and one piece remaining is automatically cleaning up the instance after image creation.

The instance is booted with a user-data script that does the necessary setup, then kicks off image creation from self using AWS CLI. Then it shuts down. I could go with --no-reboot option and wait there until the image is ready, then terminate, but the docs state that "file system integrity on the created image can't be guaranteed", so I want to avoid using it.

What's the best way to kill the instance from itself after image creation is completed?

Best Answer

There are a couple approaches to consider for how to terminate an instance from itself:

  1. Start the EC2 instance with the instance-initiated-shutdown-behavior set to "terminate", then "sudo halt" or equivalent from inside the instance.

  2. Start the EC2 instance with an IAM role that allows it to terminate itself, then invoke the ec2 terminate-instances API from the instance (e.g., using the aws-cli). Get the instance id from the instance metadata.

The first method is quite a bit easier and has less risk of the instance being able to terminate other instances, but you're already calling AWS API from the instance so you're half way to rm /etc/rc2.d/S90halt-after-create-image the second method as well.

Now for the question of how to trigger the termination after the create-image reboot.

You could simply drop the desired halt/terminate command into a startup script like /etc/rc.local and it would get run when the system comes back up. As @AlexB points out in the comments, you need to make sure this doesn't cause new instances with the image to halt, so perhaps test the instance_id.

There's no need to wait for the new AMI creation to complete. It will finish just fine even though your instance is no longer running.

Here's a quick hack that has lots of room for improvement:

# This would be dangerous in a non-EC2 environment or on an instance that
# does not fit the criteria in the original question.
original_instance_id=$(curl -s http://instance-data/latest/meta-data/instance-id)
cat >/etc/rc2.d/S90halt-after-create-image <<EOF
#!/bin/sh
rm \$0
instance_id=\$(curl -s http://instance-data/latest/meta-data/instance-id)
test "\$instance_id" = "$original_instance_id" && sudo halt
EOF
chmod +x /etc/rc2.d/S90halt-after-create-image

This code creates a startup script that removes itself and halts the system if certain conditions are true. Could cause general havok if things go wrong. Tested on Ubuntu 12.04. May not work elsewhere.