aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Crute <mike@crute.us>2017-12-24 03:46:11 +0000
committerMike Crute <mike@crute.us>2017-12-24 03:49:52 +0000
commit20513b6595ff1ae1bf0be4d899bfc83806b5f5d4 (patch)
treeb81a4ee6effbab11ff37b828b85b89322f1aee19
downloadtiny-ec2-bootstrap-release-1.0.0.tar.bz2
tiny-ec2-bootstrap-release-1.0.0.tar.xz
tiny-ec2-bootstrap-release-1.0.0.zip
Initial commitrelease-1.0.0
-rw-r--r--LICENSE.txt19
-rw-r--r--Makefile5
-rw-r--r--README.md56
-rw-r--r--tiny-ec2-bootstrap66
4 files changed, 146 insertions, 0 deletions
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..736d3fe
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,19 @@
1Copyright (c) 2017 Michael Crute
2
3Permission is hereby granted, free of charge, to any person obtaining a copy of
4this software and associated documentation files (the "Software"), to deal in
5the Software without restriction, including without limitation the rights to
6use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7of the Software, and to permit persons to whom the Software is furnished to do
8so, subject to the following conditions:
9
10The above copyright notice and this permission notice shall be included in all
11copies or substantial portions of the Software.
12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19SOFTWARE.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..394004e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,5 @@
1PREFIX?=/
2
3.PHONY: install
4install:
5 install -Dm 755 tiny-ec2-bootstrap $(PREFIX)/etc/init.d/tiny-ec2-bootstrap
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..86ebfc5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,56 @@
1# Tiny EC2 Bootstrapper
2
3This is designed to do the minimal amount of work required to bootstrap an EC2
4instance based on the local settings assigned at boot time as well as the
5user's configured settings. This is in-concept similar to
6[cloud-init](https://cloudinit.readthedocs.io/en/latest/) but trades features
7and cloud platform support for small size and limited external dependencies.
8
9## Requirements
10
11The most important feature of this bootstrapper is the very limited set of
12dependencies. In-fact this works with just busybox provided the wget applet is
13built-in. The only required dependencies are:
14
15- bash-like shell (e.g. bash, dash, ash)
16- wget
17
18## Supported Features and Environments
19
20cloud-init has support for many different cloud providers. This project only
21supports EC2, specifically the [EC2 metadata
22service](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)
23is a hard requirement of using this bootstrapper. All of the data for the
24supported features below is sourced from the EC2 instance metadata service
25which runs on every EC2 instance at IP 169.254.169.254.
26
27cloud-init also has a very rich feature set with support for adding users,
28installing packages, and many other things. This bootstrap does not support
29those things. Instead it supports:
30
31- setting system hostname
32- install user's configured SSH keys to the alpine user's authorized_keys file
33- run any script-like user data (must start with #!)
34
35These steps only run once. After the initial bootstrap the bootstrapper script
36is a no-op. To force the script to run again at boot time remove the file
37`/var/lib/cloud/.bootstrap-complete` and reboot the instance.
38
39## User Data
40
41User data is provided at instance boot time and can be any arbitrary string of
42data. The bootstrapper will consider any user data that begins with the ASCII
43characters '#!' to be a script. It will write the entire contents of the user
44data to `/var/lib/cloud/user-data.sh`, make the file executable, and execute
45the file piping any output to `/var/log/cloud-bootstrap.log`.
46
47The user data script can do anything it pleases with the instance. It will be
48run as root and networking will be up. No other grantees about system state are
49made at the point the script runs.
50
51## Assumptions
52
53- This was written for Alpine Linux and thus assumes that the login user is
54 called alpine. This could be configurable in the future but currently is not.
55
56- The script is run by OpenRC
diff --git a/tiny-ec2-bootstrap b/tiny-ec2-bootstrap
new file mode 100644
index 0000000..510f4f7
--- /dev/null
+++ b/tiny-ec2-bootstrap
@@ -0,0 +1,66 @@
1#!/sbin/openrc-run
2# vim:set ft=bash:
3
4description="Provides EC2 cloud bootstrap"
5
6depend() {
7 need net
8 provide cloud-final
9}
10
11_get_metadata() {
12 local uri="$1"
13 wget -qO - "http://169.254.169.254/latest/$uri" 2>/dev/null
14}
15
16_update_hostname() {
17 local ec2_fqdn="$(_get_metadata meta-data/hostname)"
18 local short_hostname="${ec2_fqdn%%\.*}"
19 echo "$short_hostname" > /etc/hostname
20 hostname -F /etc/hostname
21 echo -e "127.0.1.1\t$ec2_fqdn $short_hostname" >> /etc/hosts
22}
23
24_set_ssh_keys() {
25 local user="$1"
26 local group="$(getent passwd $user | cut -d: -f4)"
27 local ssh_dir="$(getent passwd $user | cut -d: -f6)/.ssh"
28 local keys_file="$ssh_dir/authorized_keys"
29
30 if [ ! -d "$ssh_dir" ]; then
31 mkdir -p "$ssh_dir"
32 chmod 755 "$ssh_dir"
33 fi
34
35 [ -f "$keys_file" ] && rm "$keys_file"
36
37 touch "$keys_file"
38 chmod 600 "$keys_file"
39 chown -R $user:$group "$ssh_dir"
40
41 for key in "$(_get_metadata meta-data/public-keys/)"; do
42 echo $(_get_metadata "meta-data/public-keys/${key%=*}/openssh-key/") >> "$keys_file"
43 done
44}
45
46_run_userdata() {
47 user_data=$(_get_metadata user-data)
48 if echo $user_data | grep '^#!/' 2>&1 >/dev/null; then
49 echo "$user_data" > /var/lib/cloud/user-data.sh
50 chmod +x /var/lib/cloud/user-data.sh
51 /var/lib/cloud/user-data.sh > /var/log/cloud-bootstrap.log 2>&1
52 fi
53}
54
55start() {
56 # Don't bootstrap if the host has already been bootstrapped
57 [ -f "/var/lib/cloud/.bootstrap-complete" ] && return 0
58
59 [ -d "/var/lib/cloud" ] || mkdir -p /var/lib/cloud
60
61 ebegin "Setting ec2 hostname"; _update_hostname; eend $?
62 ebegin "Setting ec2 user ssh keys"; _set_ssh_keys "alpine"; eend $?
63 ebegin "Running ec2 user data script"; _run_userdata; eend $?
64
65 touch "/var/lib/cloud/.bootstrap-complete"
66}