August 17th, 2024
The reference platform for both of the classes I teach (Advanced Programming in the UNIX Environment and System Administration) has been NetBSD for about two decades now. I provide students with instructions for how to install NetBSD in VirtualBox or UTM, but also want them to use Amazon EC2. Unfortunately, the NetBSD project does not provide up to date Amazon Machine Images (AMIs) for EC2, so I have been creating my own. This page describes how - primarily for myself, so I remember the steps next semester if I need to roll a new image.
Here are instructions to create an amd64 image from scratch.
Fetching the NetBSD image
In this example, I'm using NetBSD/evbarm. As of August 2024, the latest release for NetBSD is 10.0; you may want to update the steps below for different releases in the future.
$ ftp https://ftp.netbsd.org/pub/NetBSD/NetBSD-10.0/evbarm-aarch64/binary/gzimg/arm64.img.gz Trying [2001:470:a085:999::21]:443 ... Requesting https://ftp.netbsd.org/pub/NetBSD/NetBSD-10.0/evbarm-aarch64/binary/gzimg/arm64.img.gz 100% |*******************************************| 380 MiB 426.87 KiB/s 00:00 ETA $
Installing bsdec2-image-upload
The tool we use to build the image is bsdec2-image-upload.
You can install it from pkgsrc or via pkgin:
$ sudo pkgin -y install bsdec2-image-upload calculating dependencies...done. 1 package to install: bsdec2-image-upload-1.4.5nb1 0 to refresh, 0 to upgrade, 1 to install 0B to download, 63K to install installing bsdec2-image-upload-1.4.5nb1... pkg_install warnings: 0, errors: 0 reading local summary... processing local summary... marking bsdec2-image-upload-1.4.5nb1 as non auto-removable $
Alternatively, you can of course also install it from GitHub:
$ git clone https://github.com/cperciva/bsdec2-image-upload.git Cloning into 'bsdec2-image-upload'... [...] $ cd bsdec2-image-upload $ make [...] cc -o bsdec2-image-upload main.o sha256.o elasticarray.o asprintf.o entropy.o getopt.o hexify.o insecure_memzero.o warnp.o aws_readkeys.o aws_sign.o rfc3986.o sslreq.o -lcrypto -lssl $ ./bsdec2-image-upload/bsdec2-image-upload -h usage: bsdec2-image-upload [--public] [--publicamis] [--allregions] [--publicsnap] [--ssm-name <path>] [--sriov] [--ena] [--arm64] [--vhd] <disk image> <name> <description> <region> <bucket> <AWS keyfile> [<topicarn> <releaseversion> <imageversion>] $
Note that depending on your platform you may want
to specify an alternate location for OpenSSL. For
example, on macOS, I had to point to
/opt/homebrew by specifying:
$ make CFLAGS="-I/opt/homebrew/include" LDFLAGS="-L/opt/homebrew/lib -Wl,-rpath,/opt/homebrew/lib"
Create necessary AWS resources
You will need a file containing access credentials for an account with the right privileges (e.g., as described in the SETUP file). If you're lazy and you only have one set of access credentials configured for use with the AWS CLI, you can probably do the following:
$ umask 077
$ awk '/=/ { print toupper($1) "=" $3 }' ~/.aws/credentials |
sed -e 's/AWS_//' -e 's/SECRET_ACCESS_KEY/ACCESS_KEY_SECRET/' > keyfileNext, you'll want to create a new S3 bucket. Remember that amazingly the S3 bucket name must be globally unique:
$ export S3BUCKET=${USER}-netbsd-amis
$ aws s3 mb s3://${S3BUCKET}
make_bucket: jschauma-netbsd-amis
$ Making changes to the image
The default NetBSD image will already do the right thing
when running in EC2. That is, it will correctly
detect the fact that it's running in EC2 and install
the specified SSH key for the ec2-user
user. However, should you want to customize the
image, you can do so by first mounting the image using
vndconfig(8):
$ gzip -d arm64.img.gz $ su # vndconfig vnd0 arm64.img # dmesg | grep vnd0 [ 49.790348] vnd0: GPT GUID: 987939cb-c08e-4614-88c3-6749b5d3104f [ 49.790348] dk3 at vnd0: "EFI", 163840 blocks at 32768, type: msdos [ 49.790348] dk4 at vnd0: "netbsd-root", 2891776 blocks at 196608, type: ffs # mount /dev/dk4 /mnt # cd /mnt # ls .cshrc bin etc libexec proc sbin usr .profile boot lib mnt rescue stand var altroot dev libdata netbsd root tmp # [ make changes here ] # cd # umount /mnt # vndconfig -u vnd0 # exit $
Running bsdec2-image-upload
Running the bsdec2-image-upload
command will then upload the image to the S3 bucket,
create a snapshot, and finally create the AMI:
$ export AWS_REGION=$(awk '/^region =/ { print $3}' ~/.aws/config)
$ bsdec2-image-upload --sriov --ena --arm64 arm64.img \
"NetBSD 10.0 Arm" "NetBSD/evbarm 10.0 $(date +%Y-%m-%d)" \
${AWS_REGION} ${S3BUCKET} keyfile
[...]
Uploading volume manifest... done.
Importing volume: Progress: 40% done.
Creating snapshot....... done.
Registering AMI... done.
Created AMI in us-east-1 region: ami-01eeb2af939d69edd
$ (Note from experience, wasting at least 30 minutes
on chasing wrong ends: if you mistype the AWS region,
the command will fail with a misleading error message
(SSL handshake
failed).)
As mentioned above, the command uploads the image to
the S3 bucket. Those files are no longer needed once
the AMI has been created, but
bsdec2-image-upload does not remove them.
To avoid charges for storing unneeded files, you can
safely nuke the folder it created:
$ aws s3 ls s3://${S3BUCKET}
PRE 88d97df5b81413acc10503ba8c997fe8/
$ aws s3 ls s3://${S3BUCKET}/88d97df5b81413acc10503ba8c997fe8/
[...]
2024-08-16 15:42:46 10485760 part97
2024-08-16 15:42:51 10485760 part98
2024-08-16 15:42:58 10485760 part99
$ aws s3 rm --recursive s3://${S3BUCKET}/88d97df5b81413acc10503ba8c997fe8/
[...]
delete: s3://jschauma-netbsd-amis/88d97df5b81413acc10503ba8c997fe8/part97
delete: s3://jschauma-netbsd-amis/88d97df5b81413acc10503ba8c997fe8/part98
delete: s3://jschauma-netbsd-amis/88d97df5b81413acc10503ba8c997fe8/part99
$ You can also delete the entire bucket (aws s3 rb s3://${S3BUCKET}), but
keeping an empty bucket doesn't incur any charges.
You should now be able to launch the new instance. Since this is an Arm image, you want to use either an a1 or a t4g instance:
$ export AMI=ami-01eeb2af939d69edd
$ aws ec2 run-instances --image-id ${AMI} --instance-type t4g.nano
[...]
$ ssh ec2-user@ec2-3-85-77-28.compute-1.amazonaws.com
NetBSD 10.0 (GENERIC64) #0: Thu Mar 28 08:33:33 UTC 2024
Welcome to NetBSD!
ip-10-10-0-24$ uname -a
NetBSD ip-10-10-0-24.ec2.internal 10.0 NetBSD 10.0 (GENERIC64) #0: Thu Mar 28 08:33:33 UTC 2024 mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/evbarm/compile/GENERIC64 evbarm
ip-10-10-0-24$ ifconfig -a
ena0: flags=0x8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
capabilities=0x200<IP4CSUM_Tx>
enabled=0x200<IP4CSUM_Tx>
ec_capabilities=0x4<JUMBO_MTU>
ec_enabled=0
address: 0e:50:7e:03:4f:b3
media: Ethernet autoselect
status: active
inet6 fe80::cd2b:35fb:2408:cc4f%ena0/64 flags 0 scopeid 0x1
inet6 2600:1f18:400c:b800:5606:9173:aacc:ea32/128 flags 0
inet 10.10.0.24/26 broadcast 10.10.0.63 flags 0
lo0: flags=0x8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 33624
status: active
inet6 ::1/128 flags 0x20<NODAD>
inet6 fe80::1%lo0/64 flags 0 scopeid 0x2
inet 127.0.0.1/8 flags 0
ip-10-10-0-24$ If you're happy with the image, you can then mark it as public to allow other users to launch instances from it:
$ aws ec2 modify-image-attribute --image-id ${AMI} \
--launch-permission "Add=[{Group=all}]"
August 17th, 2024
Links:
- Creating a NetBSD AMI with bsdec2-image-upload (NetBSD Wiki)
- awsaliases -- aliases and functions I use with the AWS CLI tools
- NetBSD AWS EC2 AMIs -- AMIs I provide for my students
- Installing NetBSD on Linode
Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.