Run a script during shutdown/termination of an aws instance - shell

I need to execute a script during shutdown/termination of an AWS instance(debian).
I added my script to the /etc/init.d/myscript and a symlink to /etc/rc0.d/K01myscript however I noticed that when I terminate the instance I don't see that my script is executed.
Any idea?

I would not expect Amazon to terminate an instance gracefully. During an normal O/S shutdown, sure you can run a kill script. But not a terminate. If you're interested in being notified that it was terminated then take look at attaching EC2 CloudWatch events to the instance. According to the docs you can get:
This example of an EC2 Instance State-change Notification event shows
the instance in the pending state. The other possible values for state
include running, shutting-down, stopped, stopping, and terminated.
with a JSON package like:
{
"id":"7bf73129-1428-4cd3-a780-95db273d1602",
"detail-type":"EC2 Instance State-change Notification",
"source":"aws.ec2",
"account":"123456789012",
"time":"2015-11-11T21:29:54Z",
"region":"us-east-1",
"resources":[
"arn:aws:ec2:us-east-1:123456789012:instance/i-abcd1111"
],
"detail":{
"instance-id":"i-abcd1111",
"state":"pending"
}
}
If you really need to handle this then you'll have to shutdown the O/S first which will run your script and then terminate the stopped instance.

Related

How to use cloud-init to setup a bash script to be triggered by systemd whenever finishes bootup and about to shutdown?

I'm targeting ubuntu 22.04
I know how to use cloud-init to do simple stuff like runcmd and add user using users in the yaml.
I have two scripts that I like to be triggered via systemd
before-shutdown-script.sh : this script is to be triggered before the server is shutdown or before the server goes into reboot. The script's job is to call a webhook so network must at least be working before the script is activated. The webhook is simply to tell a centralized place, hey this server is powering down.
upon-bootup-script.sh : this script is to be triggered when the server is booted up. The script's job is to call a webhook so network must at least be working before the script is activated. The webhook is simply to tell a centralized place, hey this server has just booted up.
I am not confident of how to use systemd and how to use cloud-init to configure this. How should I script the cloud-init yaml?

leave AWS EC2 instance properly

I am new to AWS EC2 instance. I use ssh to connect to the instance and just want to know how to leave the instance properly. Sometimes I just close the terminal but I couldn't connect to it next time. Then I use
shutdown -h now
It works, but this way I need to restart the instance next time. Is any proper way to leave the instance?
Type
exit
if you just want to leave it and keep it running
The EC2 instance runs independently of you connecting to it. Each time you SSH in to the instance you start a new interactive shell. exit or Control-D will close the shell that you have logged in to, and leave the instance running.
If your instance is on-demand, you can shut it down to save costs, but that is an entirely separate operation from logging in and out.

Allow ec2:TerminateInstance only on self?

I have a worker machine running on a spot instance with a dedicated role. I'd like to grant it the permission to run ec2-terminate-instances when it finishes but want it to be able to terminate only itself.
Couldn't find any variable of instance-id or something similar. How do I define that kind of permission?
I've also tried using shutdown -h now but the behaviour with spot instances was a bit weird - it killed the machine (terminated) but kept the spot request as fulfilled (rather than terminated-by-user)
Thanks!

EC2: Waiting until a new instance is in running state

I would like to create a new instance based on my stored AMI.
I achieve this by the following code:
RunInstancesRequest rir = new RunInstancesRequest(imageId,1, 1);
// Code for configuring the settings of the new instance
...
RunInstancesResult runResult = ec2.runInstances(rir);
However, I cannot find a wait to "block"/wait until the instance is up and running apart from Thread.currentThread().sleep(xxxx) command.
On the other hand, StartInstancesResult and TerminateInstancesResult gives you a way to have access on the state of the instances and be able to monitor any changes. But, what about the state of a completely new instance?
boto3 has:
instance.wait_until_running()
From the boto3 docs:
Waits until this Instance is running. This method calls EC2.Waiter.instance_running.wait() which polls EC2.Client.describe_instances() every 15 seconds until a successful state is reached. An error is returned after 40 failed checks.
From the AWS CLI changelog for v1.6.0:
Add a wait subcommand that allows for a command to block until an AWS
resource reaches a given state (issue 992, issue 985)
I don't see this mentioned in the documentation, but the following worked for me:
aws ec2 start-instances --instance-ids "i-XXXXXXXX"
aws ec2 wait instance-running --instance-ids "i-XXXXXXXX"
The wait instance-running line did not finish until the EC2 instance was running.
I don't use Python/boto/botocore but assume it has something similar. Check out waiter.py on Github.
Waiting for the EC2 instance to get ready is a common pattern. In the Python library boto you also solve this with sleep calls:
reservation = conn.run_instances([Instance configuration here])
instance = reservation.instances[0]
while instance.state != 'running':
print '...instance is %s' % instance.state
time.sleep(10)
instance.update()
With this mechanism you will be able to poll when your new instance will come up.
Depending on what you are trying to do (and how many servers you plan on starting), instead of polling for the instance start events, you could install on the AMI a simple program/script that runs once when the instance starts and sends out a notification to that effect, i.e. to an AWS SNS Topic.
The process that needs to know about new servers starting could then subscribe to this SNS topic, and would receive a push notifications each time a server starts.
Solves the same problem from a different angle; your mileage may vary.
Go use Boto3's wait_until_running method:
http://boto3.readthedocs.io/en/latest/reference/services/ec2.html#EC2.Instance.wait_until_running
You can use boto3 waiters,
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#waiters
for this ex: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Waiter.InstanceRunning
Or in Java https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/
I am sure there are waiters implemented in all the AWS sdks.

AWS seems to start another EC2 instance with same AMI automatically after termination

I have 6 ec2 instances and I want to terminate about 3 of them. I've tried terminating them from the command line using ec2-terminate-instances and also using the AWS mananagement console ( Right click on instance and click on terminate).
The instance stops and goes into terminated state. However after some time another instance is automatically started with the same image of the terminated instance. I can't figure out why this is happening.
When I tried to stop instances and then terminate them separately it seemed to workw fine

Resources