diff options
author | Jake Buchholz <tomalok@gmail.com> | 2019-02-03 14:53:40 -0800 |
---|---|---|
committer | Mike Crute <crutem@amazon.com> | 2019-02-04 13:08:11 -0800 |
commit | 0b15db8bb555cf128b7660170e4afdd7a0a5d2d0 (patch) | |
tree | 5375a9a564af46578ba02dd83180b62f8f46398a | |
parent | 4680ecd85e672540fa9b5e1f3366094306d540ee (diff) | |
download | alpine-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-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | README.md | 58 | ||||
-rw-r--r-- | alpine-ami.yaml | 23 | ||||
-rwxr-xr-x | make_ami.sh | 57 | ||||
-rw-r--r-- | variables.yaml-default | 22 |
6 files changed, 90 insertions, 74 deletions
@@ -1,3 +1,5 @@ | |||
1 | **/*~ | ||
2 | **/*.swp | ||
1 | /build/ | 3 | /build/ |
2 | /.py3/ | 4 | /.py3/ |
3 | /variables.yaml | 5 | /variables.yaml |
@@ -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 | ||
6 | edge: convert | 6 | edge: 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 | ||
10 | convert: build/convert | 10 | convert: build/convert |
@@ -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 |
4 | built and supported.** | 4 | community built and supported.** |
5 | 5 | ||
6 | This repository contains a packer file and a script to create an EC2 AMI | 6 | This repository contains a packer file and a script to create an EC2 AMI |
7 | containing Alpine Linux. The AMI is designed to work with most EC2 features | 7 | containing Alpine Linux. The AMI is designed to work with most EC2 features |
8 | such as Elastic Network Adapters and NVME EBS volumes by default. If anything | 8 | such as Elastic Network Adapters and NVME EBS volumes by default. If anything |
9 | is missing please report a bug. | 9 | is missing please report a bug. |
10 | 10 | ||
11 | This image can be launched on any modern instance type, including T3, M5, C5, | 11 | This image can be launched on any modern x86_64 instance type, including T3, |
12 | I3, R5, P3, X1, X1e, D2, Z1d. Other instances may also work but have not been | 12 | M5, C5, I3, R5, P3, X1, X1e, D2, Z1d. Other instances may also work but have |
13 | tested. If you find an issue with instance support for any current generation | 13 | not been tested. If you find an issue with instance support for any current |
14 | instance please file a bug against this project. | 14 | generation instance please file a bug against this project. |
15 | 15 | ||
16 | To get started use one of the AMIs below. The default user is `alpine` and will | 16 | To get started use one of the AMIs below. The default user is `alpine` and |
17 | be configured to use whatever SSH keys you chose when you launched the image. | 17 | will be configured to use whatever SSH keys you chose when you launched the |
18 | If user data is specified it must be a shell script that begins with `#!`. If a | 18 | image. If user data is specified it must be a shell script that begins with |
19 | script 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 |
20 | configured. | ||
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 |
22 | AWS adds regions. This file and | 23 | working on providing a set of updated 3.9 AMIs for all current AWS regions, and |
24 | hope 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) |
24 | will be updated as new regions are made available. | 26 | in 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. | |||
45 | This image is being used in production but it's still somewhat early stage in | 47 | This image is being used in production but it's still somewhat early stage in |
46 | its development and thus there are some sharp edges. | 48 | its 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 | ||
10 | builders: | 12 | builders: |
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 | ||
4 | set -eu | 4 | set -eu |
5 | 5 | ||
6 | : ${MIN_RELEASE:="3.8"} | 6 | MIN_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"} | 7 | MIN_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 | ||
14 | die() { | 17 | die() { |
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 |
83 | http://dl-cdn.alpinelinux.org/alpine/edge/main | 86 | http://dl-cdn.alpinelinux.org/alpine/edge/main |
84 | http://dl-cdn.alpinelinux.org/alpine/edge/community | 87 | http://dl-cdn.alpinelinux.org/alpine/edge/community |
@@ -86,16 +89,10 @@ http://dl-cdn.alpinelinux.org/alpine/edge/testing | |||
86 | EOF | 89 | EOF |
87 | else | 90 | else |
88 | cat > "$target"/etc/apk/repositories <<EOF | 91 | cat > "$target"/etc/apk/repositories <<EOF |
89 | http://dl-cdn.alpinelinux.org/alpine/v$ALPINE_RELEASE/main | 92 | http://dl-cdn.alpinelinux.org/alpine/v$VERSION/main |
90 | http://dl-cdn.alpinelinux.org/alpine/v$ALPINE_RELEASE/community | 93 | http://dl-cdn.alpinelinux.org/alpine/v$VERSION/community |
91 | EOF | 94 | EOF |
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 | ||
98 | EOF | ||
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 | ||
109 | install_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 | |||
112 | setup_chroot() { | 121 | setup_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 | ||
304 | main() { | 313 | main() { |
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. |
8 | subnet: | 8 | subnet: |
9 | 9 | ||
10 | # Optional security group to apply to the builder instance. | 10 | # Optional security group to apply to the builder instance |
11 | security_group: | 11 | security_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; |
22 | ami_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 |
25 | ami_name_prefix: "Alpine-" | 26 | ami_name_prefix: "alpine-ami-" |
26 | ami_name_suffix: "-EC2" | 27 | ami_name_suffix: "" |
27 | 28 | ||
28 | # AMI description prefix and suffix | 29 | # AMI description prefix and suffix |
29 | ami_desc_prefix: "Alpine Linux " | 30 | ami_desc_prefix: "Alpine Linux " |
30 | ami_desc_suffix: " Release with EC2 Optimizations" | 31 | ami_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. | ||
34 | add_repos: | 34 | add_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. |
37 | add_pkgs: | 38 | add_pkgs: |
39 | # - package-name | ||
38 | 40 | ||
39 | # Additional services to start at the specified level. | 41 | # Additional services to start at the specified level |
40 | add_svcs: | 42 | add_svcs: |
41 | # boot: | 43 | # boot: |
42 | # - service1 | 44 | # - service1 |
@@ -54,7 +56,7 @@ encrypt_ami: "false" | |||
54 | ami_access: | 56 | ami_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 |
58 | deploy_regions: | 60 | deploy_regions: |
59 | - "us-east-1" | 61 | - "us-east-1" |
60 | - "us-east-2" | 62 | - "us-east-2" |