From 0b15db8bb555cf128b7660170e4afdd7a0a5d2d0 Mon Sep 17 00:00:00 2001 From: Jake Buchholz Date: Sun, 3 Feb 2019 14:53:40 -0800 Subject: [PATCH] * 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 --- .gitignore | 2 ++ Makefile | 2 +- README.md | 58 ++++++++++++++++++++---------------------- alpine-ami.yaml | 23 +++++++++++------ make_ami.sh | 57 ++++++++++++++++++++++++----------------- variables.yaml-default | 22 ++++++++-------- 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 @@ +**/*~ +**/*.swp /build/ /.py3/ /variables.yaml diff --git a/Makefile b/Makefile index 6a76c0a..bd8d329 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ ami: convert packer build -var-file=build/variables.json build/alpine-ami.json edge: convert - @echo '{ "alpine_release": "edge", "ami_release": "'`date +%Y%m%d%H%M%S`'" }' > build/edge.json + @echo '{ "version": "edge", "release": "edge", "revision": "'-`date +%Y%m%d%H%M%S`'" }' > build/edge.json packer build -var-file=build/variables.json -var-file=build/edge.json build/alpine-ami.json convert: build/convert diff --git a/README.md b/README.md index 893075a..10862f1 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,29 @@ # Alpine Linux EC2 AMI Build -**NOTE: This is not an official Amazon or AWS provided image. This is community -built and supported.** +**NOTE: This is not an official Amazon or AWS provided image. This is +community built and supported.** This repository contains a packer file and a script to create an EC2 AMI -containing Alpine Linux. The AMI is designed to work with most EC2 features -such as Elastic Network Adapters and NVME EBS volumes by default. If anything +containing Alpine Linux. The AMI is designed to work with most EC2 features +such as Elastic Network Adapters and NVME EBS volumes by default. If anything is missing please report a bug. -This image can be launched on any modern instance type, including T3, M5, C5, -I3, R5, P3, X1, X1e, D2, Z1d. Other instances may also work but have not been -tested. If you find an issue with instance support for any current generation -instance please file a bug against this project. +This image can be launched on any modern x86_64 instance type, including T3, +M5, C5, I3, R5, P3, X1, X1e, D2, Z1d. Other instances may also work but have +not been tested. If you find an issue with instance support for any current +generation instance please file a bug against this project. -To get started use one of the AMIs below. The default user is `alpine` and will -be configured to use whatever SSH keys you chose when you launched the image. -If user data is specified it must be a shell script that begins with `#!`. If a -script is provided it will be executed as root after the network is configured. +To get started use one of the AMIs below. The default user is `alpine` and +will be configured to use whatever SSH keys you chose when you launched the +image. If user data is specified it must be a shell script that begins with +`#!`. If a script is provided it will be executed as root after the network is +configured. -**Note:** This image will be updated as Alpine Linux changes over time and as -AWS adds regions. This file and +**NOTE:** *The images listed below are currently very much out of date. We are +working on providing a set of updated 3.9 AMIs for all current AWS regions, and +hope to automate AMI builds and updates to this file and [release.yaml](https://github.com/mcrute/alpine-ec2-ami/blob/master/release.yaml) -will be updated as new regions are made available. +in the not-too-distant future.* | Alpine Version | Region Code | AMI ID | | -------------- | ----------- | ------ | @@ -45,28 +47,22 @@ will be updated as new regions are made available. This image is being used in production but it's still somewhat early stage in its development and thus there are some sharp edges. -- Only EBS-backed HVM instances are supported. While paravirtualized instances +- Only EBS-backed HVM instances are supported. While paravirtualized instances are still available from AWS they are not supported on any of the newer - hardware so it seems unlikely that they will be supported going forward. Thus - this project does not support them. + hardware so it seems unlikely that they will be supported going forward. + Thus this project does not support them. - [cloud-init](https://cloudinit.readthedocs.io/en/latest/) is not currently - supported on Alpine Linux. Instead this image uses - [tiny-ec2-bootstrap](https://github.com/mcrute/tiny-ec2-bootstrap). Hostname - setting will work as will setting the ssh keys for the Alpine user based on - what was configured during instance launch. User data is supported as long - as it's a shell script (starts with #!). See the tiny-ec2-bootstrap README - for more details. You can still install cloud-init (from the edge/3.9 testing + supported on Alpine Linux. Instead this image uses + [tiny-ec2-bootstrap](https://github.com/mcrute/tiny-ec2-bootstrap). Hostname + setting will work, as will setting the ssh keys for the Alpine user based on + what was configured during instance launch. User data is supported as long + as it's a shell script (starts with #!). See the tiny-ec2-bootstrap README + for more details. You can still install cloud-init (from the edge testing repositories), but we haven't tested whether it will not work correctly for this AMI. If full cloud-init support is important to you please file a bug against this project. -- Because several key packages in Alpine 3.8 are missing or lacking features, - we currently need to install some packages from edge. We expect that these - will be included in Alpine 3.9. - - linux-virt @edge-main (includes necessary ENA drivers) - - tiny-ec2-bootstrap @edge-main (updated to v1.2.0) - -- CloudFormation support is still forthcoming. This requires patches and +- CloudFormation support is still forthcoming. This requires patches and packaging for the upstream cfn tools that have not yet been accepted. 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: # NOTE: Configuration is done with a 'variables.yaml' file. If it doesn't # exist, default configuration is copied from 'variables.yaml-default'. - # NOTE: Changing alpine_release may require modifying 'make_ami.sh'. - alpine_release: "3.8" - + # NOTE: Changing arch/version/release may require modifying 'make_ami.sh'. + arch: x86_64 + version: "3.9" + release: "3.9.0" + revision: "" builders: - type: "amazon-ebssurrogate" @@ -29,15 +31,15 @@ builders: virtualization-type: "hvm" root-device-type: "ebs" architecture: "x86_64" - name: "amzn-ami-hvm-*-x86_64-gp2" + name: "amzn2-ami-hvm-2.0.*-gp2" owners: - "137112412989" most_recent: "true" ### AMI Build Details - ami_name: "{{user `ami_name_prefix`}}{{user `alpine_release`}}-r{{user `ami_release`}}{{user `ami_name_suffix`}}" - ami_description: "{{user `ami_desc_prefix`}}{{user `alpine_release`}}-r{{user `ami_release`}}{{user `ami_desc_suffix`}}" + ami_name: "{{user `ami_name_prefix`}}{{user `release`}}{{user `revision`}}-{{user `arch`}}{{user `ami_name_suffix`}}" + ami_description: "{{user `ami_desc_prefix`}}{{user `release`}}{{user `revision`}} {{user `arch`}}{{user `ami_desc_suffix`}}" ami_virtualization_type: "hvm" ami_root_device: source_device_name: "/dev/xvdf" @@ -59,5 +61,10 @@ provisioners: - type: "shell" script: "make_ami.sh" environment_vars: - - "ALPINE_RELEASE={{user `alpine_release`}}" - execute_command: 'sudo sh -c "{{ .Vars }} {{ .Path }} ''{{user `add_repos`}}'' ''{{user `add_pkgs`}}'' ''{{user `add_svcs`}}''"' + - "VERSION={{user `version`}}" + - "RELEASE={{user `release`}}" + - "REVISION={{user `revision`}}" + - "ADD_REPOS='{{user `add_repos`}}'" + - "ADD_PKGS='{{user `add_pkgs`}}'" + - "ADD_SVCS='{{user `add_svcs`}}'" + 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 @@ set -eu -: ${MIN_RELEASE:="3.8"} -: ${APK_TOOLS_URI:="https://github.com/alpinelinux/apk-tools/releases/download/v2.10.0/apk-tools-2.10.0-x86_64-linux.tar.gz"} -: ${APK_TOOLS_SHA256:="77f2d256fcd5d6fdafadf43bb6a9c85c3da7bb471ee842dcd729175235cb9fed"} -: ${ALPINE_KEYS:="http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/alpine-keys-2.1-r1.apk"} -: ${ALPINE_KEYS_SHA256:="f7832b848cedca482b145011cf516e82392f02a10713875cb09f39c7221c6f17"} +MIN_VERSION="3.9" +MIN_RELEASE="3.9.0" -: ${ALPINE_RELEASE:="${MIN_RELEASE}"} # unless otherwise specified +: ${VERSION:="${MIN_VERSION}"} # unless otherwise specified +: ${RELEASE:="${MIN_RELEASE}"} # unless otherwise specified + +: ${APK_TOOLS_URI:="https://github.com/alpinelinux/apk-tools/releases/download/v2.10.3/apk-tools-2.10.3-x86_64-linux.tar.gz"} +: ${APK_TOOLS_SHA256:="4d0b2cda606720624589e6171c374ec6d138867e03576d9f518dddde85c33839"} +: ${ALPINE_KEYS:="http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/alpine-keys-2.1-r1.apk"} +: ${ALPINE_KEYS_SHA256:="9c7bc5d2e24c36982da7aa49b3cfcb8d13b20f7a03720f25625fa821225f5fbc"} die() { printf '\033[1;31mERROR:\033[0m %s\n' "$@" >&2 # bold red @@ -78,7 +81,7 @@ setup_repositories() { mkdir -p "$target"/etc/apk/keys - if [ "$ALPINE_RELEASE" = 'edge' ]; then + if [ "$VERSION" = 'edge' ]; then cat > "$target"/etc/apk/repositories < "$target"/etc/apk/repositories <> "$target"/etc/apk/repositories <> "$target"/etc/apk/repositories } @@ -109,6 +106,18 @@ fetch_keys() { rm -rf "$tmp" } +install_base() { + local target="$1" + + $apk add --root "$target" --no-cache --initdb alpine-base + # verify release matches + if [ "$VERSION" != "edge" ]; then + ALPINE_RELEASE=$(cat "$target/etc/alpine-release") + [ "$RELEASE" = "$ALPINE_RELEASE" ] || \ + die "Current Alpine $VERSION release ($ALPINE_RELEASE) does not match build ($RELEASE)" + fi +} + setup_chroot() { local target="$1" @@ -131,13 +140,13 @@ install_core_packages() { # tiny-ec2-bootstrap - to bootstrap system from EC2 metadata # chroot "$target" apk --no-cache add \ - linux-virt@edge-main \ + linux-virt \ alpine-mirrors \ nvme-cli \ chrony \ openssh \ sudo \ - tiny-ec2-bootstrap@edge-main \ + tiny-ec2-bootstrap \ tzdata \ $(echo "$add_pkgs" | tr , ' ') @@ -302,14 +311,14 @@ version_sorted() { } main() { - [ "$#" -ne 3 ] && die "Expecting three parameters\nUsage: $0 '[[,...]]' '[[,...]]' '[=[,...][:...]]'" - [ "$ALPINE_RELEASE" != 'edge' ] && { - version_sorted $MIN_RELEASE $ALPINE_RELEASE || die "Minimum alpine_release is '$MIN_RELEASE'" + [ "$VERSION" != 'edge' ] && { + version_sorted $MIN_VERSION $VERSION || die "Minimum Alpine version is '$MIN_RELEASE'" + version_sorted $MIN_RELEASE $RELEASE || die "Minimum Alpine release is '$MIN_RELEASE'" } - local add_repos="$1" - local add_pkgs="$2" - local add_svcs="$3" + local add_repos="$ADD_REPOS" + local add_pkgs="$ADD_PKGS" + local add_svcs="$ADD_SVCS" local device="/dev/xvdf" local target="/mnt/target" @@ -331,7 +340,7 @@ main() { fetch_keys "$target" einfo "Installing base system" - $apk add --root "$target" --no-cache --initdb alpine-base + install_base "$target" setup_chroot "$target" 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: # automatically determined. subnet: -# Optional security group to apply to the builder instance. +# Optional security group to apply to the builder instance security_group: # By default, public IPs are assigned (or not) per the subnet's configuration. @@ -18,25 +18,27 @@ public_ip: "" ### Build Options ### -# Treat similar to a ABUILD pkgrel variable and increment with every release. -ami_release: "2" +# Uncomment/increment every for every rebuild of an Alpine release; +# re-comment/zero for every new Alpine release +#revision: "-0" # AMI name prefix and suffix -ami_name_prefix: "Alpine-" -ami_name_suffix: "-EC2" +ami_name_prefix: "alpine-ami-" +ami_name_suffix: "" # AMI description prefix and suffix ami_desc_prefix: "Alpine Linux " -ami_desc_suffix: " Release with EC2 Optimizations" +ami_desc_suffix: "" -# List of custom lines to add to /etc/apk/repositories. Note that @edge-main, -# @edge-community, and @edge-testing repos have been predefined. +# List of custom lines to add to /etc/apk/repositories add_repos: +# - "@my-repo http://my-repo.tld/path" # List of additional packages to add to the AMI. add_pkgs: +# - package-name -# Additional services to start at the specified level. +# Additional services to start at the specified level add_svcs: # boot: # - service1 @@ -54,7 +56,7 @@ encrypt_ami: "false" ami_access: - "all" -# List of regions to where the AMI should be copied. +# List of regions to where the AMI should be copied deploy_regions: - "us-east-1" - "us-east-2"