aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJake Buchholz <tomalok@gmail.com>2019-02-03 14:53:40 -0800
committerMike Crute <crutem@amazon.com>2019-02-04 13:08:11 -0800
commit0b15db8bb555cf128b7660170e4afdd7a0a5d2d0 (patch)
tree5375a9a564af46578ba02dd83180b62f8f46398a
parent4680ecd85e672540fa9b5e1f3366094306d540ee (diff)
downloadalpine-ec2-ami-0b15db8bb555cf128b7660170e4afdd7a0a5d2d0.tar.bz2
alpine-ec2-ami-0b15db8bb555cf128b7660170e4afdd7a0a5d2d0.tar.xz
alpine-ec2-ami-0b15db8bb555cf128b7660170e4afdd7a0a5d2d0.zip
* Re-baseline to the newly-released Alpine 3.9
* Match meanings of 'version' and 'release' to how Alpine uses them * Use optional 'revision' to denote any same-release AMI rebuild * Include CPU 'arch' in naming/description (may also offer 'aarch64' AMIs someday) * Upgrade build instance to use Amazon Linux 2 AMIs * Use env vars to pass details to 'make_ami.sh' instead of via CLI parameters * make_ami.sh + minimum version/release shouldn't be overrideable + update APK tools & Alpine keys + check build's release vs. installed /etc/alpine-release
-rw-r--r--.gitignore2
-rw-r--r--Makefile2
-rw-r--r--README.md58
-rw-r--r--alpine-ami.yaml23
-rwxr-xr-xmake_ami.sh57
-rw-r--r--variables.yaml-default22
6 files changed, 90 insertions, 74 deletions
diff --git a/.gitignore b/.gitignore
index 0bf92c9..efc91a3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
1**/*~
2**/*.swp
1/build/ 3/build/
2/.py3/ 4/.py3/
3/variables.yaml 5/variables.yaml
diff --git a/Makefile b/Makefile
index 6a76c0a..bd8d329 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ ami: convert
4 packer build -var-file=build/variables.json build/alpine-ami.json 4 packer build -var-file=build/variables.json build/alpine-ami.json
5 5
6edge: convert 6edge: convert
7 @echo '{ "alpine_release": "edge", "ami_release": "'`date +%Y%m%d%H%M%S`'" }' > build/edge.json 7 @echo '{ "version": "edge", "release": "edge", "revision": "'-`date +%Y%m%d%H%M%S`'" }' > build/edge.json
8 packer build -var-file=build/variables.json -var-file=build/edge.json build/alpine-ami.json 8 packer build -var-file=build/variables.json -var-file=build/edge.json build/alpine-ami.json
9 9
10convert: build/convert 10convert: build/convert
diff --git a/README.md b/README.md
index 893075a..10862f1 100644
--- a/README.md
+++ b/README.md
@@ -1,27 +1,29 @@
1# Alpine Linux EC2 AMI Build 1# Alpine Linux EC2 AMI Build
2 2
3**NOTE: This is not an official Amazon or AWS provided image. This is community 3**NOTE: This is not an official Amazon or AWS provided image. This is
4built and supported.** 4community built and supported.**
5 5
6This repository contains a packer file and a script to create an EC2 AMI 6This repository contains a packer file and a script to create an EC2 AMI
7containing Alpine Linux. The AMI is designed to work with most EC2 features 7containing Alpine Linux. The AMI is designed to work with most EC2 features
8such as Elastic Network Adapters and NVME EBS volumes by default. If anything 8such as Elastic Network Adapters and NVME EBS volumes by default. If anything
9is missing please report a bug. 9is missing please report a bug.
10 10
11This image can be launched on any modern instance type, including T3, M5, C5, 11This image can be launched on any modern x86_64 instance type, including T3,
12I3, R5, P3, X1, X1e, D2, Z1d. Other instances may also work but have not been 12M5, C5, I3, R5, P3, X1, X1e, D2, Z1d. Other instances may also work but have
13tested. If you find an issue with instance support for any current generation 13not been tested. If you find an issue with instance support for any current
14instance please file a bug against this project. 14generation instance please file a bug against this project.
15 15
16To get started use one of the AMIs below. The default user is `alpine` and will 16To get started use one of the AMIs below. The default user is `alpine` and
17be configured to use whatever SSH keys you chose when you launched the image. 17will be configured to use whatever SSH keys you chose when you launched the
18If user data is specified it must be a shell script that begins with `#!`. If a 18image. If user data is specified it must be a shell script that begins with
19script is provided it will be executed as root after the network is configured. 19`#!`. If a script is provided it will be executed as root after the network is
20configured.
20 21
21**Note:** This image will be updated as Alpine Linux changes over time and as 22**NOTE:** *The images listed below are currently very much out of date. We are
22AWS adds regions. This file and 23working on providing a set of updated 3.9 AMIs for all current AWS regions, and
24hope to automate AMI builds and updates to this file and
23[release.yaml](https://github.com/mcrute/alpine-ec2-ami/blob/master/release.yaml) 25[release.yaml](https://github.com/mcrute/alpine-ec2-ami/blob/master/release.yaml)
24will be updated as new regions are made available. 26in the not-too-distant future.*
25 27
26| Alpine Version | Region Code | AMI ID | 28| Alpine Version | Region Code | AMI ID |
27| -------------- | ----------- | ------ | 29| -------------- | ----------- | ------ |
@@ -45,28 +47,22 @@ will be updated as new regions are made available.
45This image is being used in production but it's still somewhat early stage in 47This image is being used in production but it's still somewhat early stage in
46its development and thus there are some sharp edges. 48its development and thus there are some sharp edges.
47 49
48- Only EBS-backed HVM instances are supported. While paravirtualized instances 50- Only EBS-backed HVM instances are supported. While paravirtualized instances
49 are still available from AWS they are not supported on any of the newer 51 are still available from AWS they are not supported on any of the newer
50 hardware so it seems unlikely that they will be supported going forward. Thus 52 hardware so it seems unlikely that they will be supported going forward.
51 this project does not support them. 53 Thus this project does not support them.
52 54
53- [cloud-init](https://cloudinit.readthedocs.io/en/latest/) is not currently 55- [cloud-init](https://cloudinit.readthedocs.io/en/latest/) is not currently
54 supported on Alpine Linux. Instead this image uses 56 supported on Alpine Linux. Instead this image uses
55 [tiny-ec2-bootstrap](https://github.com/mcrute/tiny-ec2-bootstrap). Hostname 57 [tiny-ec2-bootstrap](https://github.com/mcrute/tiny-ec2-bootstrap). Hostname
56 setting will work as will setting the ssh keys for the Alpine user based on 58 setting will work, as will setting the ssh keys for the Alpine user based on
57 what was configured during instance launch. User data is supported as long 59 what was configured during instance launch. User data is supported as long
58 as it's a shell script (starts with #!). See the tiny-ec2-bootstrap README 60 as it's a shell script (starts with #!). See the tiny-ec2-bootstrap README
59 for more details. You can still install cloud-init (from the edge/3.9 testing 61 for more details. You can still install cloud-init (from the edge testing
60 repositories), but we haven't tested whether it will not work correctly for 62 repositories), but we haven't tested whether it will not work correctly for
61 this AMI. If full cloud-init support is important to you please file a bug 63 this AMI. If full cloud-init support is important to you please file a bug
62 against this project. 64 against this project.
63 65
64- Because several key packages in Alpine 3.8 are missing or lacking features, 66- CloudFormation support is still forthcoming. This requires patches and
65 we currently need to install some packages from edge. We expect that these
66 will be included in Alpine 3.9.
67 - linux-virt @edge-main (includes necessary ENA drivers)
68 - tiny-ec2-bootstrap @edge-main (updated to v1.2.0)
69
70- CloudFormation support is still forthcoming. This requires patches and
71 packaging for the upstream cfn tools that have not yet been accepted. 67 packaging for the upstream cfn tools that have not yet been accepted.
72 Eventually full CloudFormation support will be available. 68 Eventually full CloudFormation support will be available.
diff --git a/alpine-ami.yaml b/alpine-ami.yaml
index a4ba2c0..71f26fc 100644
--- a/alpine-ami.yaml
+++ b/alpine-ami.yaml
@@ -3,9 +3,11 @@ variables:
3 # NOTE: Configuration is done with a 'variables.yaml' file. If it doesn't 3 # NOTE: Configuration is done with a 'variables.yaml' file. If it doesn't
4 # exist, default configuration is copied from 'variables.yaml-default'. 4 # exist, default configuration is copied from 'variables.yaml-default'.
5 5
6 # NOTE: Changing alpine_release may require modifying 'make_ami.sh'. 6 # NOTE: Changing arch/version/release may require modifying 'make_ami.sh'.
7 alpine_release: "3.8" 7 arch: x86_64
8 8 version: "3.9"
9 release: "3.9.0"
10 revision: ""
9 11
10builders: 12builders:
11 - type: "amazon-ebssurrogate" 13 - type: "amazon-ebssurrogate"
@@ -29,15 +31,15 @@ builders:
29 virtualization-type: "hvm" 31 virtualization-type: "hvm"
30 root-device-type: "ebs" 32 root-device-type: "ebs"
31 architecture: "x86_64" 33 architecture: "x86_64"
32 name: "amzn-ami-hvm-*-x86_64-gp2" 34 name: "amzn2-ami-hvm-2.0.*-gp2"
33 owners: 35 owners:
34 - "137112412989" 36 - "137112412989"
35 most_recent: "true" 37 most_recent: "true"
36 38
37 ### AMI Build Details 39 ### AMI Build Details
38 40
39 ami_name: "{{user `ami_name_prefix`}}{{user `alpine_release`}}-r{{user `ami_release`}}{{user `ami_name_suffix`}}" 41 ami_name: "{{user `ami_name_prefix`}}{{user `release`}}{{user `revision`}}-{{user `arch`}}{{user `ami_name_suffix`}}"
40 ami_description: "{{user `ami_desc_prefix`}}{{user `alpine_release`}}-r{{user `ami_release`}}{{user `ami_desc_suffix`}}" 42 ami_description: "{{user `ami_desc_prefix`}}{{user `release`}}{{user `revision`}} {{user `arch`}}{{user `ami_desc_suffix`}}"
41 ami_virtualization_type: "hvm" 43 ami_virtualization_type: "hvm"
42 ami_root_device: 44 ami_root_device:
43 source_device_name: "/dev/xvdf" 45 source_device_name: "/dev/xvdf"
@@ -59,5 +61,10 @@ provisioners:
59 - type: "shell" 61 - type: "shell"
60 script: "make_ami.sh" 62 script: "make_ami.sh"
61 environment_vars: 63 environment_vars:
62 - "ALPINE_RELEASE={{user `alpine_release`}}" 64 - "VERSION={{user `version`}}"
63 execute_command: 'sudo sh -c "{{ .Vars }} {{ .Path }} ''{{user `add_repos`}}'' ''{{user `add_pkgs`}}'' ''{{user `add_svcs`}}''"' 65 - "RELEASE={{user `release`}}"
66 - "REVISION={{user `revision`}}"
67 - "ADD_REPOS='{{user `add_repos`}}'"
68 - "ADD_PKGS='{{user `add_pkgs`}}'"
69 - "ADD_SVCS='{{user `add_svcs`}}'"
70 execute_command: 'sudo sh -c "{{ .Vars }} {{ .Path }}"'
diff --git a/make_ami.sh b/make_ami.sh
index c8dde78..8c00a6c 100755
--- a/make_ami.sh
+++ b/make_ami.sh
@@ -3,13 +3,16 @@
3 3
4set -eu 4set -eu
5 5
6: ${MIN_RELEASE:="3.8"} 6MIN_VERSION="3.9"
7: ${APK_TOOLS_URI:="https://github.com/alpinelinux/apk-tools/releases/download/v2.10.0/apk-tools-2.10.0-x86_64-linux.tar.gz"} 7MIN_RELEASE="3.9.0"
8: ${APK_TOOLS_SHA256:="77f2d256fcd5d6fdafadf43bb6a9c85c3da7bb471ee842dcd729175235cb9fed"}
9: ${ALPINE_KEYS:="http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/alpine-keys-2.1-r1.apk"}
10: ${ALPINE_KEYS_SHA256:="f7832b848cedca482b145011cf516e82392f02a10713875cb09f39c7221c6f17"}
11 8
12: ${ALPINE_RELEASE:="${MIN_RELEASE}"} # unless otherwise specified 9: ${VERSION:="${MIN_VERSION}"} # unless otherwise specified
10: ${RELEASE:="${MIN_RELEASE}"} # unless otherwise specified
11
12: ${APK_TOOLS_URI:="https://github.com/alpinelinux/apk-tools/releases/download/v2.10.3/apk-tools-2.10.3-x86_64-linux.tar.gz"}
13: ${APK_TOOLS_SHA256:="4d0b2cda606720624589e6171c374ec6d138867e03576d9f518dddde85c33839"}
14: ${ALPINE_KEYS:="http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/alpine-keys-2.1-r1.apk"}
15: ${ALPINE_KEYS_SHA256:="9c7bc5d2e24c36982da7aa49b3cfcb8d13b20f7a03720f25625fa821225f5fbc"}
13 16
14die() { 17die() {
15 printf '\033[1;31mERROR:\033[0m %s\n' "$@" >&2 # bold red 18 printf '\033[1;31mERROR:\033[0m %s\n' "$@" >&2 # bold red
@@ -78,7 +81,7 @@ setup_repositories() {
78 81
79 mkdir -p "$target"/etc/apk/keys 82 mkdir -p "$target"/etc/apk/keys
80 83
81 if [ "$ALPINE_RELEASE" = 'edge' ]; then 84 if [ "$VERSION" = 'edge' ]; then
82 cat > "$target"/etc/apk/repositories <<EOF 85 cat > "$target"/etc/apk/repositories <<EOF
83http://dl-cdn.alpinelinux.org/alpine/edge/main 86http://dl-cdn.alpinelinux.org/alpine/edge/main
84http://dl-cdn.alpinelinux.org/alpine/edge/community 87http://dl-cdn.alpinelinux.org/alpine/edge/community
@@ -86,16 +89,10 @@ http://dl-cdn.alpinelinux.org/alpine/edge/testing
86EOF 89EOF
87 else 90 else
88 cat > "$target"/etc/apk/repositories <<EOF 91 cat > "$target"/etc/apk/repositories <<EOF
89http://dl-cdn.alpinelinux.org/alpine/v$ALPINE_RELEASE/main 92http://dl-cdn.alpinelinux.org/alpine/v$VERSION/main
90http://dl-cdn.alpinelinux.org/alpine/v$ALPINE_RELEASE/community 93http://dl-cdn.alpinelinux.org/alpine/v$VERSION/community
91EOF 94EOF
92 fi 95 fi
93 # NOTE: until several key packages graduate from edge...
94 cat >> "$target"/etc/apk/repositories <<EOF
95@edge-main http://dl-cdn.alpinelinux.org/alpine/edge/main
96@edge-community http://dl-cdn.alpinelinux.org/alpine/edge/community
97@edge-testing http://dl-cdn.alpinelinux.org/alpine/edge/testing
98EOF
99 96
100 echo "$add_repos" | tr , "\012" >> "$target"/etc/apk/repositories 97 echo "$add_repos" | tr , "\012" >> "$target"/etc/apk/repositories
101} 98}
@@ -109,6 +106,18 @@ fetch_keys() {
109 rm -rf "$tmp" 106 rm -rf "$tmp"
110} 107}
111 108
109install_base() {
110 local target="$1"
111
112 $apk add --root "$target" --no-cache --initdb alpine-base
113 # verify release matches
114 if [ "$VERSION" != "edge" ]; then
115 ALPINE_RELEASE=$(cat "$target/etc/alpine-release")
116 [ "$RELEASE" = "$ALPINE_RELEASE" ] || \
117 die "Current Alpine $VERSION release ($ALPINE_RELEASE) does not match build ($RELEASE)"
118 fi
119}
120
112setup_chroot() { 121setup_chroot() {
113 local target="$1" 122 local target="$1"
114 123
@@ -131,13 +140,13 @@ install_core_packages() {
131 # tiny-ec2-bootstrap - to bootstrap system from EC2 metadata 140 # tiny-ec2-bootstrap - to bootstrap system from EC2 metadata
132 # 141 #
133 chroot "$target" apk --no-cache add \ 142 chroot "$target" apk --no-cache add \
134 linux-virt@edge-main \ 143 linux-virt \
135 alpine-mirrors \ 144 alpine-mirrors \
136 nvme-cli \ 145 nvme-cli \
137 chrony \ 146 chrony \
138 openssh \ 147 openssh \
139 sudo \ 148 sudo \
140 tiny-ec2-bootstrap@edge-main \ 149 tiny-ec2-bootstrap \
141 tzdata \ 150 tzdata \
142 $(echo "$add_pkgs" | tr , ' ') 151 $(echo "$add_pkgs" | tr , ' ')
143 152
@@ -302,14 +311,14 @@ version_sorted() {
302} 311}
303 312
304main() { 313main() {
305 [ "$#" -ne 3 ] && die "Expecting three parameters\nUsage: $0 '[<repo>[,...]]' '[<pkg>[,...]]' '[<lvl>=<svc>[,...][:...]]'" 314 [ "$VERSION" != 'edge' ] && {
306 [ "$ALPINE_RELEASE" != 'edge' ] && { 315 version_sorted $MIN_VERSION $VERSION || die "Minimum Alpine version is '$MIN_RELEASE'"
307 version_sorted $MIN_RELEASE $ALPINE_RELEASE || die "Minimum alpine_release is '$MIN_RELEASE'" 316 version_sorted $MIN_RELEASE $RELEASE || die "Minimum Alpine release is '$MIN_RELEASE'"
308 } 317 }
309 318
310 local add_repos="$1" 319 local add_repos="$ADD_REPOS"
311 local add_pkgs="$2" 320 local add_pkgs="$ADD_PKGS"
312 local add_svcs="$3" 321 local add_svcs="$ADD_SVCS"
313 322
314 local device="/dev/xvdf" 323 local device="/dev/xvdf"
315 local target="/mnt/target" 324 local target="/mnt/target"
@@ -331,7 +340,7 @@ main() {
331 fetch_keys "$target" 340 fetch_keys "$target"
332 341
333 einfo "Installing base system" 342 einfo "Installing base system"
334 $apk add --root "$target" --no-cache --initdb alpine-base 343 install_base "$target"
335 344
336 setup_chroot "$target" 345 setup_chroot "$target"
337 346
diff --git a/variables.yaml-default b/variables.yaml-default
index d9dff95..10a10a6 100644
--- a/variables.yaml-default
+++ b/variables.yaml-default
@@ -7,7 +7,7 @@ region:
7# automatically determined. 7# automatically determined.
8subnet: 8subnet:
9 9
10# Optional security group to apply to the builder instance. 10# Optional security group to apply to the builder instance
11security_group: 11security_group:
12 12
13# By default, public IPs are assigned (or not) per the subnet's configuration. 13# By default, public IPs are assigned (or not) per the subnet's configuration.
@@ -18,25 +18,27 @@ public_ip: ""
18 18
19### Build Options ### 19### Build Options ###
20 20
21# Treat similar to a ABUILD pkgrel variable and increment with every release. 21# Uncomment/increment every for every rebuild of an Alpine release;
22ami_release: "2" 22# re-comment/zero for every new Alpine release
23#revision: "-0"
23 24
24# AMI name prefix and suffix 25# AMI name prefix and suffix
25ami_name_prefix: "Alpine-" 26ami_name_prefix: "alpine-ami-"
26ami_name_suffix: "-EC2" 27ami_name_suffix: ""
27 28
28# AMI description prefix and suffix 29# AMI description prefix and suffix
29ami_desc_prefix: "Alpine Linux " 30ami_desc_prefix: "Alpine Linux "
30ami_desc_suffix: " Release with EC2 Optimizations" 31ami_desc_suffix: ""
31 32
32# List of custom lines to add to /etc/apk/repositories. Note that @edge-main, 33# List of custom lines to add to /etc/apk/repositories
33# @edge-community, and @edge-testing repos have been predefined.
34add_repos: 34add_repos:
35# - "@my-repo http://my-repo.tld/path"
35 36
36# List of additional packages to add to the AMI. 37# List of additional packages to add to the AMI.
37add_pkgs: 38add_pkgs:
39# - package-name
38 40
39# Additional services to start at the specified level. 41# Additional services to start at the specified level
40add_svcs: 42add_svcs:
41# boot: 43# boot:
42# - service1 44# - service1
@@ -54,7 +56,7 @@ encrypt_ami: "false"
54ami_access: 56ami_access:
55 - "all" 57 - "all"
56 58
57# List of regions to where the AMI should be copied. 59# List of regions to where the AMI should be copied
58deploy_regions: 60deploy_regions:
59 - "us-east-1" 61 - "us-east-1"
60 - "us-east-2" 62 - "us-east-2"