nixos/virtualization/ec2: Adds IPv6 IMDS fetch capability

Updates the EC2 IMDS metadata fetcher script to support IPv6 endpoints. If you start an instance in an IPv6 subnet, if the EC2 instance gets an IPv6 address before the IPv4 address (extremely common), systemd will trigger the IMDS fetcher script and fail to fetch your NixOS configuration, leaving you with a useless unconfigured EC2 instance. This at least allows the NixOS configuration to be fetched and applied.
This commit is contained in:
Jared Dunbar
2026-03-24 15:37:36 -07:00
committed by Philip Taron
parent 22c2bff7e7
commit 2ef00e2d52
@@ -3,7 +3,12 @@ mkdir -p "$metaDir"
chmod 0755 "$metaDir"
rm -f "$metaDir/*"
IMDS_ENDPOINTS="http://169.254.169.254 http://[fd00:ec2::254]"
IMDS_BASE_URL="http://169.254.169.254"
IMDS_TOKEN=""
get_imds_token() {
endpoint=$1
# retry-delay of 1 selected to give the system a second to get going,
# but not add a lot to the bootup time
curl \
@@ -15,10 +20,11 @@ get_imds_token() {
-X PUT \
--connect-timeout 1 \
-H "X-aws-ec2-metadata-token-ttl-seconds: 600" \
http://169.254.169.254/latest/api/token
"$endpoint/latest/api/token"
}
preflight_imds_token() {
endpoint=$1
# retry-delay of 1 selected to give the system a second to get going,
# but not add a lot to the bootup time
curl \
@@ -30,13 +36,18 @@ preflight_imds_token() {
--connect-timeout 1 \
-H "X-aws-ec2-metadata-token: $IMDS_TOKEN" \
-o /dev/null \
http://169.254.169.254/1.0/meta-data/instance-id
"$endpoint/1.0/meta-data/instance-id"
}
try=1
while [ $try -le 3 ]; do
echo "(attempt $try/3) getting an EC2 instance metadata service v2 token..."
IMDS_TOKEN=$(get_imds_token) && break
for endpoint in $IMDS_ENDPOINTS; do
IMDS_TOKEN=$(get_imds_token "$endpoint") && IMDS_BASE_URL=$endpoint && break
done
if [ -n "$IMDS_TOKEN" ]; then
break
fi
try=$((try + 1))
sleep 1
done
@@ -48,7 +59,17 @@ fi
try=1
while [ $try -le 10 ]; do
echo "(attempt $try/10) validating the EC2 instance metadata service v2 token..."
preflight_imds_token && break
preflight_ok=""
for endpoint in $IMDS_ENDPOINTS; do
if preflight_imds_token "$endpoint"; then
IMDS_BASE_URL=$endpoint
preflight_ok=1
break
fi
done
if [ -n "$preflight_ok" ]; then
break
fi
try=$((try + 1))
sleep 1
done
@@ -85,7 +106,7 @@ try_decompress() {
fi
}
get_imds -o "$metaDir/ami-manifest-path" http://169.254.169.254/1.0/meta-data/ami-manifest-path
(umask 077 && get_imds -o "$metaDir/user-data" http://169.254.169.254/1.0/user-data && try_decompress "$metaDir/user-data")
get_imds -o "$metaDir/hostname" http://169.254.169.254/1.0/meta-data/hostname
get_imds -o "$metaDir/public-keys-0-openssh-key" http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key
get_imds -o "$metaDir/ami-manifest-path" "$IMDS_BASE_URL/1.0/meta-data/ami-manifest-path"
(umask 077 && get_imds -o "$metaDir/user-data" "$IMDS_BASE_URL/1.0/user-data" && try_decompress "$metaDir/user-data")
get_imds -o "$metaDir/hostname" "$IMDS_BASE_URL/1.0/meta-data/hostname"
get_imds -o "$metaDir/public-keys-0-openssh-key" "$IMDS_BASE_URL/1.0/meta-data/public-keys/0/openssh-key"