diff options
author | Jake Buchholz <tomalok@gmail.com> | 2018-09-04 22:23:24 -0700 |
---|---|---|
committer | Mike Crute <crutem@amazon.com> | 2018-09-05 07:39:39 -0700 |
commit | 4065c4ebb316dab2e9f66b5e3f903e0548271266 (patch) | |
tree | 2e717aec70c0203c6c9c74771967b8db0313e3e5 | |
parent | 95b7837c9fc2b070bc9e44da1f6fdc0987eabf75 (diff) | |
download | alpine-ec2-ami-4065c4ebb316dab2e9f66b5e3f903e0548271266.tar.bz2 alpine-ec2-ami-4065c4ebb316dab2e9f66b5e3f903e0548271266.tar.xz alpine-ec2-ami-4065c4ebb316dab2e9f66b5e3f903e0548271266.zip |
Incorporate recent Alpine edge changes
* standardize on 'linux-virt' kernel
+ no longer need 'kernel_flavor' variable
+ always install 'aws-ena-driver' package
+ always enable ena_support
* switch to 'variables.yaml' for config
+ update build/convert script to stringify certain keys that may contain arrays
+ copy from 'variables.yaml-default' if it doesn't exist
* drop 'vpc' variable, using 'subnet' derives the proper VPC to use
* fix chrony.conf (all pool.ntp.org references are changed to 169.254.169.123)
* update README.md caveats
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 10 | ||||
-rw-r--r-- | README.md | 17 | ||||
-rw-r--r-- | alpine-ami.yaml | 12 | ||||
-rwxr-xr-x | make_ami.sh | 24 | ||||
-rw-r--r-- | variables.json-default | 20 | ||||
-rw-r--r-- | variables.json-example | 74 | ||||
-rw-r--r-- | variables.yaml-default | 64 |
8 files changed, 97 insertions, 126 deletions
@@ -1,5 +1,5 @@ | |||
1 | /build/ | 1 | /build/ |
2 | /.py3/ | 2 | /.py3/ |
3 | /variables.json | 3 | /variables.yaml |
4 | /scrub-old-amis.py | 4 | /scrub-old-amis.py |
5 | /gen-readme.py | 5 | /gen-readme.py |
@@ -1,7 +1,9 @@ | |||
1 | .PHONY: ami | 1 | .PHONY: ami |
2 | ami: build/convert | 2 | ami: build/convert |
3 | [ -f variables.yaml ] || cp variables.yaml-default variables.yaml | ||
4 | build/convert variables.yaml > build/variables.json | ||
3 | build/convert alpine-ami.yaml > build/alpine-ami.json | 5 | build/convert alpine-ami.yaml > build/alpine-ami.json |
4 | packer build -var-file=variables.json build/alpine-ami.json | 6 | packer build -var-file=build/variables.json build/alpine-ami.json |
5 | 7 | ||
6 | build/convert: | 8 | build/convert: |
7 | [ -d ".py3" ] || python3 -m venv .py3 | 9 | [ -d ".py3" ] || python3 -m venv .py3 |
@@ -14,7 +16,11 @@ build/convert: | |||
14 | # which only supports JSON | 16 | # which only supports JSON |
15 | @echo "#!`pwd`/.py3/bin/python" > build/convert | 17 | @echo "#!`pwd`/.py3/bin/python" > build/convert |
16 | @echo "import yaml, json, sys" >> build/convert | 18 | @echo "import yaml, json, sys" >> build/convert |
17 | @echo "json.dump(yaml.load(open(sys.argv[1])), sys.stdout, indent=4, separators=(',', ': '))" >> build/convert | 19 | @echo "y = yaml.load(open(sys.argv[1]))" >> build/convert |
20 | @echo "for k in ['ami_access','deploy_regions','add_repos','add_pkgs']:" >> build/convert | ||
21 | @echo " if k in y and isinstance(y[k], list):" >> build/convert | ||
22 | @echo " y[k] = ','.join(str(x) for x in y[k])" >> build/convert | ||
23 | @echo "json.dump(y, sys.stdout, indent=4, separators=(',', ': '))" >> build/convert | ||
18 | @chmod +x build/convert | 24 | @chmod +x build/convert |
19 | 25 | ||
20 | %.py: %.py.in | 26 | %.py: %.py.in |
@@ -50,16 +50,6 @@ its development and thus there are some sharp edges. | |||
50 | hardware so it seems unlikely that they will be supported going forward. Thus | 50 | hardware so it seems unlikely that they will be supported going forward. Thus |
51 | this project does not support them. | 51 | this project does not support them. |
52 | 52 | ||
53 | - The linux-vanilla kernel all the linux-firmware packages it installs is much | ||
54 | larger than is necessary for an AMI designed to run on EC2. Unfortunately, | ||
55 | the linux-virt kernel is currently missing NVMe support, which is required for | ||
56 | the newest generation of instance families. | ||
57 | |||
58 | - The aws-ena-driver-vanilla package is still in edge/testing, and requires the | ||
59 | matching linux-vanilla package from edge/main. When ENA is available in an | ||
60 | alpine version release (ideally with a 'virt' kernel flavor), edge/testing | ||
61 | and edge/main should no longer be necessary. | ||
62 | |||
63 | - [cloud-init](https://cloudinit.readthedocs.io/en/latest/) is not currently | 53 | - [cloud-init](https://cloudinit.readthedocs.io/en/latest/) is not currently |
64 | supported on Alpine Linux. Instead this image uses | 54 | supported on Alpine Linux. Instead this image uses |
65 | [tiny-ec2-bootstrap](https://github.com/mcrute/tiny-ec2-bootstrap). Hostname | 55 | [tiny-ec2-bootstrap](https://github.com/mcrute/tiny-ec2-bootstrap). Hostname |
@@ -71,6 +61,13 @@ its development and thus there are some sharp edges. | |||
71 | If full cloud-init support is important to you please file a bug against this | 61 | If full cloud-init support is important to you please file a bug against this |
72 | project. | 62 | project. |
73 | 63 | ||
64 | - Because several key packages in Alpine 3.8 are missing or lacking features, | ||
65 | we currently need to install some packages from edge. We expect that these | ||
66 | will be included in Alpine 3.9, or perhaps as a 3.8.x update. | ||
67 | - linux-virt @edge-main (includes necessary NVMe drivers) | ||
68 | - aws-ena-driver @edge-testing (installs 'virt' flavored subpackage) | ||
69 | - tiny-ec2-bootstrap @edge-main (updated to v1.2.0) | ||
70 | |||
74 | - CloudFormation support is still forthcoming. This requires patches and | 71 | - CloudFormation support is still forthcoming. This requires patches and |
75 | packaging for the upstream cfn tools that have not yet been accepted. | 72 | packaging for the upstream cfn tools that have not yet been accepted. |
76 | Eventually full CloudFormation support will be available. | 73 | Eventually full CloudFormation support will be available. |
diff --git a/alpine-ami.yaml b/alpine-ami.yaml index 09e0c4d..0ec2e21 100644 --- a/alpine-ami.yaml +++ b/alpine-ami.yaml | |||
@@ -1,8 +1,7 @@ | |||
1 | variables: | 1 | variables: |
2 | 2 | ||
3 | # NOTE: Configuration is done with a `variables.json` file. | 3 | # NOTE: Configuration is done with a `variables.yaml` file. If it doesn't |
4 | # To use default values, simply `cp variables.json-default variables.json`. | 4 | # exist, default configuration is copied from `variables.yaml-default`. |
5 | # See `variables.json-example` for full configuration variable descriptions. | ||
6 | 5 | ||
7 | # NOTE: Changing alpine_release requires modifying `make_ami.sh` -- don't | 6 | # NOTE: Changing alpine_release requires modifying `make_ami.sh` -- don't |
8 | # override this in `variables.json`! | 7 | # override this in `variables.json`! |
@@ -14,7 +13,6 @@ builders: | |||
14 | 13 | ||
15 | ### Builder Instance Details | 14 | ### Builder Instance Details |
16 | 15 | ||
17 | vpc_id: "{{user `vpc`}}" | ||
18 | subnet_id: "{{user `subnet`}}" | 16 | subnet_id: "{{user `subnet`}}" |
19 | security_group_id: "{{user `security_group`}}" | 17 | security_group_id: "{{user `security_group`}}" |
20 | instance_type: "t3.nano" | 18 | instance_type: "t3.nano" |
@@ -36,7 +34,7 @@ builders: | |||
36 | - "137112412989" | 34 | - "137112412989" |
37 | most_recent: "true" | 35 | most_recent: "true" |
38 | 36 | ||
39 | ### Built AMI Details | 37 | ### AMI Build Details |
40 | 38 | ||
41 | ami_name: "{{user `ami_name_prefix`}}{{user `alpine_release`}}-r{{user `ami_release`}}{{user `ami_name_suffix`}}" | 39 | ami_name: "{{user `ami_name_prefix`}}{{user `alpine_release`}}-r{{user `ami_release`}}{{user `ami_name_suffix`}}" |
42 | ami_description: "{{user `ami_desc_prefix`}}{{user `alpine_release`}}-r{{user `ami_release`}}{{user `ami_desc_suffix`}}" | 40 | ami_description: "{{user `ami_desc_prefix`}}{{user `alpine_release`}}-r{{user `ami_release`}}{{user `ami_desc_suffix`}}" |
@@ -48,7 +46,7 @@ builders: | |||
48 | volume_size: "{{user `volume_size`}}" | 46 | volume_size: "{{user `volume_size`}}" |
49 | volume_type: "gp2" | 47 | volume_type: "gp2" |
50 | encrypt_boot: "{{user `encrypt_ami`}}" | 48 | encrypt_boot: "{{user `encrypt_ami`}}" |
51 | ena_support: "{{user `ena_enable`}}" | 49 | ena_support: "true" |
52 | sriov_support: "true" | 50 | sriov_support: "true" |
53 | ami_groups: "{{user `ami_access`}}" | 51 | ami_groups: "{{user `ami_access`}}" |
54 | ami_regions: "{{user `deploy_regions`}}" | 52 | ami_regions: "{{user `deploy_regions`}}" |
@@ -57,4 +55,4 @@ builders: | |||
57 | provisioners: | 55 | provisioners: |
58 | - type: "shell" | 56 | - type: "shell" |
59 | script: "make_ami.sh" | 57 | script: "make_ami.sh" |
60 | execute_command: 'sudo sh -c "{{ .Vars }} {{ .Path }} {{user `kernel_flavor`}} ''{{user `add_repos`}}'' ''{{user `add_pkgs`}}''"' | 58 | execute_command: 'sudo sh -c "{{ .Vars }} {{ .Path }} ''{{user `add_repos`}}'' ''{{user `add_pkgs`}}''"' |
diff --git a/make_ami.sh b/make_ami.sh index 6218694..0d10058 100755 --- a/make_ami.sh +++ b/make_ami.sh | |||
@@ -108,8 +108,7 @@ setup_chroot() { | |||
108 | 108 | ||
109 | install_core_packages() { | 109 | install_core_packages() { |
110 | local target="$1" # target directory | 110 | local target="$1" # target directory |
111 | local flavor="$2" # kernel flavor | 111 | local add_pkgs="$2" # extra packages, space separated |
112 | local add_pkgs="$3" # extra packages, space separated | ||
113 | 112 | ||
114 | # Most from: https://git.alpinelinux.org/cgit/alpine-iso/tree/alpine-virt.packages | 113 | # Most from: https://git.alpinelinux.org/cgit/alpine-iso/tree/alpine-virt.packages |
115 | # | 114 | # |
@@ -117,15 +116,15 @@ install_core_packages() { | |||
117 | # tiny-ec2-bootstrap - to bootstrap system from EC2 metadata | 116 | # tiny-ec2-bootstrap - to bootstrap system from EC2 metadata |
118 | # | 117 | # |
119 | chroot "$target" apk --no-cache add \ | 118 | chroot "$target" apk --no-cache add \ |
120 | linux-"$flavor" \ | 119 | linux-virt@edge-main \ |
120 | aws-ena-driver@edge-testing \ | ||
121 | alpine-mirrors \ | 121 | alpine-mirrors \ |
122 | chrony \ | 122 | chrony \ |
123 | e2fsprogs \ | ||
124 | openssh \ | 123 | openssh \ |
125 | sudo \ | 124 | sudo \ |
126 | tiny-ec2-bootstrap \ | 125 | tiny-ec2-bootstrap@edge-main \ |
127 | tzdata \ | 126 | tzdata \ |
128 | $add_pkgs | 127 | $(echo "$add_pkgs" | tr , ' ') |
129 | 128 | ||
130 | chroot "$target" apk --no-cache add --no-scripts syslinux | 129 | chroot "$target" apk --no-cache add --no-scripts syslinux |
131 | 130 | ||
@@ -244,7 +243,9 @@ configure_ntp() { | |||
244 | # in EC2. | 243 | # in EC2. |
245 | # | 244 | # |
246 | # See: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/set-time.html | 245 | # See: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/set-time.html |
247 | sed -i 's/^pool .*/server 169.254.169.123 iburst/' "$target"/etc/chrony/chrony.conf | 246 | sed -e 's/^pool /server /' \ |
247 | -e 's/pool.ntp.org/169.254.169.123/g' \ | ||
248 | -i "$target"/etc/chrony/chrony.conf | ||
248 | } | 249 | } |
249 | 250 | ||
250 | cleanup() { | 251 | cleanup() { |
@@ -267,11 +268,10 @@ cleanup() { | |||
267 | } | 268 | } |
268 | 269 | ||
269 | main() { | 270 | main() { |
270 | [ "$#" -ne 3 ] && { echo "usage: $0 <kernel-flavor> '<repo>[,<repo>]' '<pkg>[ <pkg>]'"; exit 1; } | 271 | [ "$#" -ne 2 ] && { echo "usage: $0 '<repo>[,<repo>]' '<pkg>[,<pkg>]'"; exit 1; } |
271 | 272 | ||
272 | local flavor="$1" | 273 | local add_repos="$1" |
273 | local add_repos="$2" | 274 | local add_pkgs="$2" |
274 | local add_pkgs="$3" | ||
275 | 275 | ||
276 | local device="/dev/xvdf" | 276 | local device="/dev/xvdf" |
277 | local target="/mnt/target" | 277 | local target="/mnt/target" |
@@ -297,7 +297,7 @@ main() { | |||
297 | setup_chroot "$target" | 297 | setup_chroot "$target" |
298 | 298 | ||
299 | einfo "Installing core packages" | 299 | einfo "Installing core packages" |
300 | install_core_packages "$target" "$flavor" "$add_pkgs" | 300 | install_core_packages "$target" "$add_pkgs" |
301 | 301 | ||
302 | einfo "Configuring and enabling boot loader" | 302 | einfo "Configuring and enabling boot loader" |
303 | create_initfs "$target" | 303 | create_initfs "$target" |
diff --git a/variables.json-default b/variables.json-default deleted file mode 100644 index d45378f..0000000 --- a/variables.json-default +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | { | ||
2 | "ami_release": "1", | ||
3 | "ami_name_prefix": "Alpine-", | ||
4 | "ami_name_suffix": "-EC2", | ||
5 | "ami_desc_prefix": "Alpine Linux ", | ||
6 | "ami_desc_suffix": " Release with EC2 Optimizations", | ||
7 | "kernel_flavor": "vanilla@edge-main", | ||
8 | "add_repos": "", | ||
9 | "add_pkgs": "aws-ena-driver-vanilla@edge-testing", | ||
10 | "ena_enable": "true", | ||
11 | "volume_size": "1", | ||
12 | "encrypt_ami": "false", | ||
13 | "ami_access": "all", | ||
14 | "deploy_regions": "us-east-1,us-east-2,us-west-1,us-west-2,ca-central-1,eu-central-1,eu-west-1,eu-west-2,eu-west-3,ap-northeast-1,ap-northeast-2,ap-southeast-1,ap-southeast-2,ap-south-1,sa-east-1", | ||
15 | |||
16 | "vpc": "", | ||
17 | "subnet": "", | ||
18 | "security_group": "", | ||
19 | "public_ip": "false" | ||
20 | } | ||
diff --git a/variables.json-example b/variables.json-example deleted file mode 100644 index 0e10c9a..0000000 --- a/variables.json-example +++ /dev/null | |||
@@ -1,74 +0,0 @@ | |||
1 | # *** NOTE: This is file not valid JSON! *** | ||
2 | |||
3 | { | ||
4 | ### Build Options ### | ||
5 | |||
6 | # Treat similar to a ABUILD pkgrel variable and increment with every release. | ||
7 | "ami_release": "1", | ||
8 | |||
9 | # AMI name prefix and suffix | ||
10 | "ami_name_prefix": "Alpine-", | ||
11 | "ami_name_suffix": "-EC2", | ||
12 | |||
13 | # AMI description prefix and suffix | ||
14 | "ami_desc_prefix": "Alpine Linux ", | ||
15 | "ami_desc_suffix": " Release with EC2 Optimizations", | ||
16 | |||
17 | # Kernel "flavor" to install. | ||
18 | # | ||
19 | # 'virt' is the slim choice, but doesn't currently include NVMe support and | ||
20 | # there is no matching 'aws-ena-driver' package. When these features are | ||
21 | # available, this kernel flavor will be the default (if not hardcoded). | ||
22 | # | ||
23 | # 'vanilla' installs a lot of unneeded stuff (for an AMI), but does support | ||
24 | # NVMe; however, there is no matching ENA driver in the main repo. In order | ||
25 | # to support NVMe and ENA, we need to use 'vanilla@edge-main', which matches | ||
26 | # the 'aws-ena-driver@edge-testing' package. | ||
27 | # | ||
28 | "kernel_flavor": "vanilla@edge-main", | ||
29 | |||
30 | # Comma separated list of custom lines to add to /etc/apk/repositories. | ||
31 | # @edge-main, @edge-community, and @edge-testing repos have been predefined. | ||
32 | "add_repos": "", | ||
33 | |||
34 | # Space separated list of additional packages to add to the AMI. | ||
35 | # aws-ena-driver-vanilla - ENA driver (until we have a 'virt' flavor) | ||
36 | "add_pkgs": "aws-ena-driver-vanilla@edge-testing", | ||
37 | |||
38 | # Enable ENA support on the AMI. | ||
39 | # When ENA is available for the 'virt' kernel, this will always be on. | ||
40 | "ena_enable": "true", | ||
41 | |||
42 | # Size of the AMI image (in GiB). | ||
43 | "volume_size": "1", | ||
44 | |||
45 | # Encrypt the AMI? | ||
46 | "encrypt_ami": "false", | ||
47 | |||
48 | # Comma separated list of groups that should have access to the AMI. However, | ||
49 | # only two values are currently supported: 'all' for public, '' for private. | ||
50 | "ami_access": "all", | ||
51 | |||
52 | # Comma separated list of regions to where the AMI should be copied. | ||
53 | # NOTE: ap-northeast-3 skipped, as it is available by subscription-only. | ||
54 | "deploy_regions": "us-east-1,us-east-2,us-west-1,us-west-2,ca-central-1,eu-central-1,eu-west-1,eu-west-2,eu-west-3,ap-northeast-1,ap-northeast-2,ap-southeast-1,ap-southeast-2,ap-south-1,sa-east-1", | ||
55 | |||
56 | |||
57 | ### Builder-Instance Options ### | ||
58 | |||
59 | # VPC in which the builder instance is to be launched; you must also provide | ||
60 | # a subnet. | ||
61 | "vpc": "", | ||
62 | |||
63 | # Subnet in which the builder instance is to be launched. | ||
64 | "subnet": "", | ||
65 | |||
66 | # Security group to apply to the builder instance. | ||
67 | "security_group": "", | ||
68 | |||
69 | # Assign a public IP to the builder instance. Set to 'true' for if you need | ||
70 | # to initiate the build from somewhere that wouldn't normally be able to | ||
71 | # access the builder instance's private network. | ||
72 | "public_ip": "false" | ||
73 | |||
74 | } | ||
diff --git a/variables.yaml-default b/variables.yaml-default new file mode 100644 index 0000000..3ec54f4 --- /dev/null +++ b/variables.yaml-default | |||
@@ -0,0 +1,64 @@ | |||
1 | ### Builder-Instance Options ### | ||
2 | |||
3 | # Subnet ID in which the builder instance is to be launched. VPC will be | ||
4 | # automatically determined. | ||
5 | subnet: | ||
6 | |||
7 | # Optional security group to apply to the builder instance. | ||
8 | security_group: | ||
9 | |||
10 | # Assign a public IP to the builder instance. Set to "true" for if you need | ||
11 | # to initiate the build from somewhere that wouldn't normally be able to access | ||
12 | # the builder instance's private network and a private IP is not auto-assigned. | ||
13 | public_ip: "false" | ||
14 | |||
15 | |||
16 | ### Build Options ### | ||
17 | |||
18 | # Treat similar to a ABUILD pkgrel variable and increment with every release. | ||
19 | ami_release: "1" | ||
20 | |||
21 | # AMI name prefix and suffix | ||
22 | ami_name_prefix: "Alpine-" | ||
23 | ami_name_suffix: "-EC2" | ||
24 | |||
25 | # AMI description prefix and suffix | ||
26 | ami_desc_prefix: "Alpine Linux " | ||
27 | ami_desc_suffix: " Release with EC2 Optimizations" | ||
28 | |||
29 | # List of custom lines to add to /etc/apk/repositories. Note that @edge-main, | ||
30 | # @edge-community, and @edge-testing repos have been predefined. | ||
31 | add_repos: | ||
32 | |||
33 | # List of additional packages to add to the AMI. | ||
34 | add_pkgs: | ||
35 | |||
36 | # Size of the AMI image (in GiB). | ||
37 | volume_size: "1" | ||
38 | |||
39 | # Encrypt the AMI? | ||
40 | encrypt_ami: "false" | ||
41 | |||
42 | # List of groups that should have access to the AMI. However, only two | ||
43 | # values are currently supported: 'all' for public, '' or unset for private. | ||
44 | ami_access: | ||
45 | - "all" | ||
46 | |||
47 | # List of regions to where the AMI should be copied. | ||
48 | deploy_regions: | ||
49 | - "us-east-1" | ||
50 | - "us-east-2" | ||
51 | - "us-west-1" | ||
52 | - "us-west-2" | ||
53 | - "ca-central-1" | ||
54 | - "eu-central-1" | ||
55 | - "eu-west-1" | ||
56 | - "eu-west-2" | ||
57 | - "eu-west-3" | ||
58 | - "ap-northeast-1" | ||
59 | - "ap-northeast-2" | ||
60 | # - "ap-northeast-3" # skipped, available by subscription only | ||
61 | - "ap-southeast-1" | ||
62 | - "ap-southeast-2" | ||
63 | - "ap-south-1" | ||
64 | - "sa-east-1" | ||