Minimalistic init script that is designed for any Linux with
OpenRC/systemd/runit to automatically bootstrap EC2 instances in the way similar
to cloud-init but without Python dependency (and a lot of other modules pulled
by cloud-init).
The script has a minimal set of modules but can effectively initialize EC2 instances: allow remote access over SSH and run custom bootstrap scripts.
This shell script depends on:
- coreutils
- curl
Some Linux distributions could have these dependencies not installed, for
example, Void Linux requires manual installation of curl.
This shell script supports these init systems:
- OpenRC
- systemd
- runit
Ensure that coreutils and curl are installed. Not all distros have them
installed by default. For example, coreutils could be not installed if busybox
is installed. For example, curl is not installed by default on Void Linux.
# install ec2-init/service file
curl -s https://raw.githubusercontent.com/sormy/ec2-init/master/ec2-init.openrc -o /etc/init.d/ec2-init
chmod +x /etc/init.d/ec2-init
# run ec2-init automatically
rc-update add ec2-init boot# install ec2-init helper script
curl -s https://raw.githubusercontent.com/sormy/ec2-init/master/ec2-init.script -o /usr/sbin/ec2-init
chmod +x /usr/sbin/ec2-init
# install service file
curl -s https://raw.githubusercontent.com/sormy/ec2-init/master/ec2-init.service -o /etc/systemd/system/ec2-init.service
# run ec2-init automatically
systemctl enable ec2-init# install ec2-init helper script
curl -s https://raw.githubusercontent.com/sormy/ec2-init/master/ec2-init.script -o /usr/sbin/ec2-init
chmod +x /usr/sbin/ec2-init
# install service file
mkdir -m 755 -pv /etc/sv/ec2-init
curl -s https://raw.githubusercontent.com/sormy/ec2-init/master/ec2-init.runit -o /etc/sv/ec2-init/run
chmod 755 -v /etc/sv/ec2-init/run
ln -sfv /run/runit/supervise.ec2-init /etc/sv/ec2-init/supervise
# run ec2-init automatically
ln -sfv /etc/sv/ec2-init /etc/runit/runsvdir/default/ec2-init script runs on every boot, however, it doesn't reinitialize the
instance on every reboot. It initializes the instance only if instance ID from
last run doesn't match with current instance ID. So, if you take an image from
existing instance and then spawn a new instance using the same image, then
ec2-init will detect change in instance ID and will run init again.
The location of lock file can be change using EC2_INIT_LOCK option.
By default ec2-init runs with 3 modules hostname, ssh and exec but the
list of modules to execute can be changed using EC2_INIT_MODULES option.
The script uses curl to access EC2 instance metadata. It is not recommended to
change curl options, but, if needed, it can be done using CURL option.
The log for init process is logged to /var/log/ec2-init.log. The location of
log file can be changed using EC2_INIT_LOG option.
Module hostname sets local hostname based on EC2 metadata.
In most cases needed just to differentiate hosts by shell prompt after login into EC2 instance.
Module ssh imports ssh public keys into /root/.ssh/authorized_keys during
boot (with default configuration).
Needed to login into EC2 instance using SSH keys provided in AWS console.
The location of target directory for .ssh/authorized_keys file can be changed
using SSH_USER_HOME option or using SSH_USER_NAME option.
Module exec runs shell script (if exists) from instance user data. It
downloads instance user data, decodes it from base64, then executes it if there
is a shebang #! localed on first line of user data.
Instance user data by default is downloaded and decoded to
/var/lib/ec2-init.user-data but the location can be changed using
EC2_INIT_USER_DATA option.
The output of executed shell script is also logged to /var/log/ec2-init.log.
Needed to programmatically initialize EC2 instance using customizable instance provisioning shell script.
Currently script assumes that IMDSv1 is used (IMDSv2 is not supported at this time).
Read more about EC2 instance user data: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-add-user-data.html
While ec2-init script has sane defaults, you still have an option to change
some of them.
Create file /etc/conf.d/ec2-init and override any variables you want.
For example:
echo 'EC2_INIT_MODULES="ssh"' > /etc/conf.d/ec2-initEdit service unit file /etc/systemd/system/ec2-init.service.
Add environment variables in [Service] section, for example:
[Unit]
Description=EC2 Init
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/ec2-init
Environment="EC2_INIT_MODULES=ssh"
[Install]
WantedBy=multi-user.targetAnd then reload systemd: systemctl daemon-reload.
Edit service unit file /etc/sv/ec2-init/run.
Export any changed variables before invoking /usr/sbin/ec2-init:
#!/bin/sh
export EC2_INIT_MODULES=ssh
if /usr/sbin/ec2-init; then
sv down ec2-init
fiBelow is the list of all variables you can set.
| Name | Default | Description |
|---|---|---|
| EC2_INIT_LOCK | /var/lib/ec2-init.lock | Init lock file path. |
| EC2_INIT_LOG | /var/log/ec2-init.log | Init log file path. |
| EC2_INIT_USER_DATA | /var/lib/ec2-init.user-data | Init user data. |
| EC2_INIT_MODULES | hostname ssh exec | Modules to execute on init. |
| SSH_USER_NAME | $(whoami) | User name for ssh init. |
| SSH_USER_HOME | autodetect using /etc/passwd | User home directory (ssh). |
| CURL | curl $CURL_OPTS | CURL and options. |
Default CURL_OPTS:
curl --silent --max-time 1 --retry-delay 1 --retry 10 --retry-all-errors --fail
Would like to cleanup created by ec2-init files?
rm /var/log/ec2-init.* /var/lib/ec2-init.*MIT