Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make cloud-init startup scripts run every time my EC2 instance boots?

I have an EC2 instance running an AMI based on the Amazon Linux AMI. Like all such AMIs, it supports the cloud-init system for running startup scripts based on the User Data passed into every instance. In this particular case, my User Data input happens to be an Include file that sources several other startup scripts:

#include http://s3.amazonaws.com/path/to/script/1 http://s3.amazonaws.com/path/to/script/2 

The first time I boot my instance, the cloud-init startup script runs correctly. However, if I do a soft reboot of the instance (by running sudo shutdown -r now, for instance), the instance comes back up without running the startup script the second time around. If I go into the system logs, I can see:

Running cloud-init user-scripts user-scripts already ran once-per-instance [  OK  ] 

This is not what I want -- I can see the utility of having startup scripts that only run once per instance lifetime, but in my case these should run every time the instance starts up, like normal startup scripts.

I realize that one possible solution is to manually have my scripts insert themselves into rc.local after running the first time. This seems burdensome, however, since the cloud-init and rc.d environments are subtly different and I would now have to debug scripts on first launch and all subsequent launches separately.

Does anyone know how I can tell cloud-init to always run my scripts? This certainly sounds like something the designers of cloud-init would have considered.

like image 913
Adrian Petrescu Avatar asked Jun 25 '11 02:06

Adrian Petrescu


People also ask

Does cloud-init run every boot?

By default, user data scripts and cloud-init directives run only during the boot cycle when you first launch an instance. You can update your configuration to ensure that your user data scripts and cloud-init directives run every time you restart your instance.

Does cloud-init only run once?

There is no mechanism provided for running it only one time. It is provided with the instance ID in the environment variable INSTANCE_ID. Use this variable to provide a once-per-instance set of boothook data.


2 Answers

In 11.10, 12.04 and later, you can achieve this by making the 'scripts-user' run 'always'. In /etc/cloud/cloud.cfg you'll see something like:

cloud_final_modules:  - rightscale_userdata  - scripts-per-once  - scripts-per-boot  - scripts-per-instance  - scripts-user  - keys-to-console  - phone-home  - final-message 

This can be modified after boot, or cloud-config data overriding this stanza can be inserted via user-data. Ie, in user-data you can provide:

#cloud-config cloud_final_modules:  - rightscale_userdata  - scripts-per-once  - scripts-per-boot  - scripts-per-instance  - [scripts-user, always]  - keys-to-console  - phone-home  - final-message 

That can also be '#included' as you've done in your description. Unfortunately, right now, you cannot modify the 'cloud_final_modules', but only override it. I hope to add the ability to modify config sections at some point.

There is a bit more information on this in the cloud-config doc at https://github.com/canonical/cloud-init/tree/master/doc/examples

Alternatively, you can put files in /var/lib/cloud/scripts/per-boot , and they'll be run by the 'scripts-per-boot' path.

like image 74
smoser Avatar answered Sep 19 '22 00:09

smoser


In /etc/init.d/cloud-init-user-scripts, edit this line:

/usr/bin/cloud-init-run-module once-per-instance user-scripts execute run-parts ${SCRIPT_DIR} >/dev/null && success || failure 

to

 /usr/bin/cloud-init-run-module always user-scripts execute run-parts ${SCRIPT_DIR} >/dev/null && success || failure 

Good luck !

like image 21
EvanG Avatar answered Sep 23 '22 00:09

EvanG