
Amazon Linux 2が2026年6月30日にEOLになるので、あの鳥を逃がしてみた
コンバンハ、千葉(幸)です。
Amazon Linux 2のサポート終了日は2026年6月30日に設定されています。
振り返ってみると歴史は長いもので、下記のようなイベントをたどってきました。
- 2017年11月:Amazon Linux 2の発表
- 2018年6月:5年間のLTS(Long Term Support)を含む正式リリース
- 2022年夏:サポート期限が2023年6月30日から2024年6月30日に延長
- 2022年12月:サポート期限が2024年6月30日から2025年6月30日に延長
- 2024年12月:サポート期限が2025年6月30日から2026年6月30日に延長
わたし自身は2020年前後によくお世話になりました。
Amazon Linux2と言えばSSHログインした際に下記のようなバナーが表示されるイメージを持つ人が多いのではないでしょうか。
__| __|_ )
_| ( / Amazon Linux 2 AMI
___|\___|___|

しかしある時から、以下のように鳥が出迎えてくれるようになっています。

, #_
~\_ ####_ Amazon Linux 2
~~ \_#####\
~~ \###| AL2 End of Life is 2025-06-30.
~~ \#/ ___
~~ V~' '->
~~~ / A newer version of Amazon Linux is available!
~~._. _/
_/ _/ Amazon Linux 2023, GA and supported until 2028-03-15.
_/m/' https://aws.amazon.com/linux/amazon-linux-2023/
これはAmazon Linux 2023のログインバナーでお馴染みの鳥ですね。わたしはこの形状の鳥を見ると染めたくなります。なぜなら、染め方を知っているからです。
ドリルを持っていれば穴を開けたくなるように、染め方を知っている故にこの鳥も染めてみたくなります。どのようなカラーに染め上げるのがいいかなと思案している中で、ふと 染めるのではなく逃がした方がいいのではないか? と考えるようになりました。
EOLを告げるため、終わりゆくこの場所にとどまり続けているこの鳥をあの空に還してやること。それこそが今の自分に与えられた役目なのではないかと思うようになったのです。それを思いついた時にわたしの脳天に稲妻が走り、世界の色が違って見えるようになりました。
今回はこの鳥を逃がしてみたいと思います。お前を囲む鳥籠など、もはや無い。 そう精一杯伝えてやりましょう。
先にまとめ
- Amazon Linux 2は2026年6月30日にEOLを迎え、以降はセキュリティアップデートが提供されなくなります
- Amazon Linux 2023などへの移行を検討しましょう
- この後の文章は特に読まなくても困りません
プロローグ:私は鳥を逃がしたい
鳥が僕らの町にやってきた日
古来より人類は鳥のことを何らかシンボリックな存在として捉えて生きてきました。ある時は幸福を象徴するもの、ある時は不幸を撒き散らすもの、そしてある時は季節の変わり目を告げるもの──といった具合です。
空翔けるすべを持たず、両の翼で天を往く彼らをただ地べたから見上げ続けてきた我々にとっては、それもまた当然のことかもしれません。いつしか自分たちが鋼鉄の塊に乗って彼らより高く、そして速く空を駆けることができるようになった後も、我々は鳥を見上げ続けています。「ここではないどこか」。いつも探し求めるその場所へ、何の隔たりもなく自由に移動できるIconとして彼らを捉え続けているのです。
いつからAmazon Linux 2に鳥が来たか知っていますか?
Amazon Linux 2のログインバナーにいつからか鳥が来るようになりました。正確な日付は分かりませんが、まぁ大体、2023年9月20日くらいです。
「鳥来たじゃん!!」と浮き足立っていた私は、当時のAMIからインスタンスを立ち上げて、鳥がいるかいないかを手元のメモに記録していました。
% aws ec2 describe-images \
--owners amazon \
--filters "Name=name,Values=amzn2-ami-kernel-5.10*x86_64-gp2" \
--query 'reverse(sort_by(Images, &CreationDate))[].[Name,ImageId]' \
--output text
amzn2-ami-kernel-5.10-hvm-2.0.20230926.0-x86_64-gp2 ami-0adac58024a7f03bb 鳥いる
amzn2-ami-kernel-5.10-hvm-2.0.20230912.0-x86_64-gp2 ami-03a1b4db103179555 鳥いない
amzn2-ami-kernel-5.10-hvm-2.0.20230906.0-x86_64-gp2 ami-0f89bdd365c3d966d
amzn2-ami-kernel-5.10-hvm-2.0.20230822.0-x86_64-gp2 ami-07d6bd9a28134d3b3
amzn2-ami-kernel-5.10-hvm-2.0.20230808.0-x86_64-gp2 ami-044dbe71ee2d3c59e
amzn2-ami-kernel-5.10-hvm-2.0.20230727.0-x86_64-gp2 ami-0e25eba2025eea319 鳥いない
amzn2-ami-kernel-5.10-hvm-2.0.20230719.0-x86_64-gp2 ami-09bad682e5ae72267
amzn2-ami-kernel-5.10-hvm-2.0.20230628.0-x86_64-gp2 ami-05ffd9ad4ddd0d6e2
amzn2-ami-kernel-5.10-hvm-2.0.20230612.0-x86_64-gp2 ami-0b51fe1c0254d8fc9
amzn2-ami-kernel-5.10-hvm-2.0.20230530.0-x86_64-gp2 ami-0d739893974bd27d0
amzn2-ami-kernel-5.10-hvm-2.0.20230515.0-x86_64-gp2 ami-07c2a88388bb80eb0
……
今はもう当時のAMIにはアクセスできないので自分のメモを信じるしかないですが、20230926のAMIには鳥いる、20230912のAMIには鳥いないと書かれています。
もちろん、AMIからのローンチ時にアップデートがかからないよう以下のユーザーデータを入れていたはずです。
#cloud-config
repo_upgrade: none
ということで、大体そのくらいにAmazon Linux 2に鳥が来たはずです。
僕が初めて鳥を染めた日
わたしは普段、クラスメソッド株式会社でソリューションアーキテクトとして働いています。2020年1月から今のキャリアをスタートし、AWSを中心としたお客様への技術支援、プリセールス活動、ブログ執筆や登壇などを行ってきました。
それと並行して、2023年8月からは鳥染士(とりぞめ-し)としての業も開始しました。鳥染士とは、Amazon Linux 2023にいる鳥に色をつける人のことです。たまに鳥を赤くしたり、「この鳥も染めたら面白そうだな」とニヤニヤする活動が主です。鳥染士ならではの苦労ポイントとしては、業務中にAmazon Linuxの鳥を見ると少し笑いそうになることです。
わたしがはじめて鳥染め(とりぞめ)に手を染めた時のエントリが以下です。
- echo コマンドでは色属性のエスケープシーケンスを記述することで文字色を変える
/etc/update-motd.d/配下にechoコマンドを含むbashスクリプトを配置し、ログイン時にmotdでバナー表示する
というアプローチを取りました。今から鳥染めに挑戦したい方は参考にしてください。
Amazon Linux2の鳥も染めてみたい、いや……
2023年9月22日のつぶやきです。
3年前の自分は、Amazon Linux 2の鳥に対しても鳥染士としての役割を果たそうとしていました。何なら実際に途中まで染めていました。ただ、途中で「あ、ちょっとAmazon Linux 2023とAmazon Linux 2で勝手が違うや」ということに気づいたり、「そもそもこれって面白いか……?」と思ったり、「鳥を染めるって何?」何のためにやってんの?などと正気に戻ったりして、道なかばで倒れていました。当時のブログの下書きの最終更新時刻は2年くらい止まっていました。
しかし、Amazon Linux 2がいよいよEOLを迎えるこのタイミングでふと気づきました。鳥は染めるもんじゃない、逃すもんだと。染めるのは二番煎じ感があるけど、逃すのならまた新鮮さがある。楽しそう。鳥も嬉しい。今なら生成AIもあって簡単に逃がせそう。
こうしてわたしは鳥逃士(とりのが-し)としての役割を果たすことに決めました。Amazon Linux2の鳥を、ただの鳥に。お前を囲む鳥籠など、もはや無い。
Amazon Linux2の鳥をどうやって逃すか
鳥が逃げていくアニメーションを動かすスクリプトを作ります。まぁそれはさっとできるでしょう。そのスクリプトを上手いところに配置して、SSHログイン時に表示させたいです。
Amazon Linux 2023 で鳥を染めたときのように、motd関連のあれこれを確認してみましょう。
まずは/etc/update-motd.d/から。
$ ls -la /etc/update-motd.d/
total 24
drwxr-xr-x 2 root root 86 Jun 8 2021 .
drwxr-xr-x 81 root root 8192 Oct 4 15:18 ..
-rwxr-xr-x 1 root root 553 Sep 4 21:56 30-banner
-rwxr-xr-x 1 root root 67 Sep 13 2021 50-amazon-linux-extras-news
-rwxr-xr-x 1 root root 454 Sep 4 21:56 70-available-updates
一番大事そうな/etc/update-motd.d/30-banner の中身。ここを置き換えるのが手っ取り早いでしょうか。
$ cat /etc/update-motd.d/30-banner
#!/bin/sh
test -e /etc/os-release && os_release='/etc/os-release' || os_release='/usr/lib/os-release'
. "${os_release}"
cat << EOF
, #_
~\_ ####_ ${PRETTY_NAME:-Amazon Linux 2}
~~ \_#####\\
~~ \###| AL2 End of Life is ${SUPPORT_END:-2025-06-30}.
~~ \#/ ___
~~ V~' '->
~~~ / A newer version of Amazon Linux is available!
~~._. _/
_/ _/ Amazon Linux 2023, GA and supported until 2028-03-15.
_/m/' https://aws.amazon.com/linux/amazon-linux-2023/
EOF
ついでに他においてあるファイルも確認します。
$ cat /etc/update-motd.d/50-amazon-linux-extras-news
#!/bin/bash
timeout 5s amazon-linux-extras system_motd 2>/dev/null
$ cat /etc/update-motd.d/70-available-updates
#!/bin/bash
# Possible summaries include:
# No packages needed for security; %d packages available
# %d package(s) needed[ (+%d related)] for security, out of %d available
# There are [[%d security update(s)[ out of ]%d total update(s)]] available
LANG=C timeout 30s /usr/bin/yum \
--debuglevel 2 \
--security check-update 2>/dev/null \
| grep -P '(?<! 0 packages) available$' \
&& echo 'Run "sudo yum update" to apply all updates.'
その他のパスもざっと確認します。Amazon Linux 2023では存在しているがAmazon Linux 2では存在しない、というものがちょこちょこあります。
# ls -l /usr/lib/motd
ls: cannot access /usr/lib/motd: No such file or directory
# ls -l /etc/motd
lrwxrwxrwx 1 root root 25 Oct 13 22:21 /etc/motd -> /var/lib/update-motd/motd
# cat /var/lib/update-motd/motd
, #_
~\_ ####_ Amazon Linux 2
~~ \_#####\
~~ \###| AL2 End of Life is 2025-06-30.
~~ \#/ ___
~~ V~' '->
~~~ / A newer version of Amazon Linux is available!
~~._. _/
_/ _/ Amazon Linux 2023, GA and supported until 2028-03-15.
_/m/' https://aws.amazon.com/linux/amazon-linux-2023/
11 package(s) needed for security, out of 11 available
Run "sudo yum update" to apply all updates.
# ls -l /etc/motd.d/
ls: cannot access /etc/motd.d/: No such file or directory
# ls -l /run/motd
ls: cannot access /run/motd: No such file or directory
# ls -l /run/motd.d/
ls: cannot access /run/motd.d/: No such file or directory
update-motdの確認。
$ systemctl status update-motd
● update-motd.service - Dynamically Generate Message Of The Day
Loaded: loaded (/usr/lib/systemd/system/update-motd.service; enabled; vendor preset: enabled)
Active: active (exited) since Wed 2023-10-04 15:19:05 UTC; 1min 31s ago
Process: 3126 ExecStart=/usr/sbin/update-motd (code=exited, status=0/SUCCESS)
Main PID: 3126 (code=exited, status=0/SUCCESS)
CGroup: /system.slice/update-motd.service
Oct 04 15:18:33 ip-172-31-38-67.ap-northeast-1.compute.internal systemd[1]: Starting Dynamically Generate Message Of The Day...
Oct 04 15:19:05 ip-172-31-38-67.ap-northeast-1.compute.internal systemd[1]: Started Dynamically Generate Message Of The Day.
大体わかりました。
スクリプトは/etc/update-motd.d/ではなく/etc/profile.d/に置く
先に結論から書くと、/etc/update-motd.d/配下にアニメーションスクリプトを格納しても想定通りの挙動を示しませんでした。
update-motd.serviceはブート時に1回だけ実行され、/etc/update-motd.d/配下のスクリプトを実行して結果を/var/lib/update-motd/motdに書き込み、以降のSSHログインではそのファイルを表示するだけ、という仕組みのようです。(あまりここで調査に時間をかけると「何やってるんだろう……」という気持ちが湧いてくるので、「ようです」程度の調査で早々に切り上げました。)
アニメーションを実現するには、TTYに直接出力できる場所でスクリプトを動かす必要があります。今回は/etc/profile.d/を選びました。
/etc/profile.d/のスクリプトはSSHログインシェル起動時に/etc/profileからsourceされます。TTYが使えるので、tputでカーソルを動かしたり色をつけたりといったインタラクティブな表示が可能です。
Amazon Linux 2の鳥を逃す構成
今回は下記の構成で逃がしてみます。

パブリックサブネットにAmazon Linux 2のEC2インスタンスを起動し、AWSマネジメントコンソールからEC2 Instance ConnectでSSH接続します。
SSH接続した際に鳥が逃げれば、鳥逃士としての役割は完了です。
ちなみに鳥はどこから逃げるんでしょうね?やはりInternet Gatewayを経由してインターネットに抜けていくんでしょうか。

いえ、今回はインターネット経由で接続して逃してみるものの、インターネットへのアウトバウンドができない構成で検証しても鳥は逃げられるはずです。そうなると、こうですね。

「上」に鳥は逃げていきます。鳥はパケットじゃないので、ルートテーブルを読めません。Internet Gatewayは通らないでしょうね。何言ってるんでしょうね。
Amazon Linux 2の鳥を逃す構成を作成する
一式まとめて作成するCloudFormationテンプレートを作りました。
折りたたみ
AWSTemplateFormatVersion: "2010-09-09"
Description: Free the AL2 Bird - AL2 instance with bird animation on login
Parameters:
InstanceType:
Type: String
Default: t3.micro
Resources:
# VPC
Vpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: free-al2-bird-vpc
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: free-al2-bird-igw
VpcGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref Vpc
InternetGatewayId: !Ref InternetGateway
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc
CidrBlock: 10.0.0.0/24
AvailabilityZone: !Select [0, !GetAZs ""]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: free-al2-bird-subnet-public
RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref Vpc
Tags:
- Key: Name
Value: free-al2-bird-rtb-public
DefaultRoute:
Type: AWS::EC2::Route
DependsOn: VpcGatewayAttachment
Properties:
RouteTableId: !Ref RouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
SubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref RouteTable
# Security Group
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: free-al2-bird-sg
GroupDescription: Allow SSH from EC2 Instance Connect (ap-northeast-1)
VpcId: !Ref Vpc
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 3.112.23.0/29
Description: EC2 Instance Connect ap-northeast-1
Tags:
- Key: Name
Value: free-al2-bird-sg
# EC2
Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-06087cfd700858bee
InstanceType: !Ref InstanceType
SubnetId: !Ref PublicSubnet
SecurityGroupIds:
- !Ref SecurityGroup
Tags:
- Key: Name
Value: free-al2-bird-ec2
UserData:
Fn::Base64: |
#!/bin/bash
cat << 'BIRDSCRIPT' > /etc/profile.d/bird.sh
#!/bin/bash
# SSH ログイン時のみ実行
[ -t 1 ] || return 0
[ -n "$TERM" ] || return 0
[ -n "$SSH_CONNECTION" ] || return 0
Q="'"
BOLD=$'\e[1m'
RESET=$'\e[0m'
RAINBOW=($'\e[31m' $'\e[33m' $'\e[32m' $'\e[36m' $'\e[34m' $'\e[35m')
BIRD_H=10
TRAVEL=60
BANNER=(
" , #_"
" ~\\_ ####_ Amazon Linux 2"
" ~~ \\_#####\\"
" ~~ \\###| AL2 End of Life is 2026-06-30."
" ~~ \\#/ ___"
" ~~ V~${Q} ${Q}->"
" ~~~ / A newer version of Amazon Linux is available!"
" ~~._. _/"
" _/ _/ Amazon Linux 2023, GA and supported until 2028-03-15."
" _/m/${Q} https://aws.amazon.com/linux/amazon-linux-2023/"
)
BIRD=(
" , #_"
" ~\\_ ####_"
" ~~ \\_#####\\"
" ~~ \\###|"
" ~~ \\#/ ___"
" ~~ V~${Q} ${Q}->"
" ~~~ /"
" ~~._. _/"
" _/ _/"
" _/m/${Q}"
)
draw_bird() {
local col=$1 row_off=$2 i row
shift 2
for ((i = 0; i < BIRD_H; i++)); do
row=$(( BASE_ROW + row_off + i ))
if (( row >= 0 && row < ROWS )); then
tput cup "$row" 0
printf '%*s' "$COLS" ''
if (( col < COLS )); then
tput cup "$row" "$col"
if (( flying )); then
printf '%s' "${BOLD}${RAINBOW[$(( (i + col / 4) % 6 ))]}$1${RESET}"
else
printf '%s' "$1"
fi
fi
fi
shift
done
}
clear_rows() {
local row_off=$1 i row
for ((i = 0; i < BIRD_H; i++)); do
row=$(( BASE_ROW + row_off + i ))
if (( row >= 0 && row < ROWS )); then
tput cup "$row" 0
printf '%*s' "$COLS" ''
fi
done
}
draw_trail() {
local bird_col=$1 bird_row_off=$2
local bird_top=$(( BASE_ROW + bird_row_off ))
local bird_bot=$(( bird_top + BIRD_H - 1 ))
local bird_right=$(( bird_col + 22 ))
local chars=('.' ',' '~' '*' '-')
local i tr tc n j dots
for ((i = 0; i < ${#trail_cols[@]}; i++)); do
tr=$(( trail_rows[i] + RANDOM % 3 - 1 ))
tc=$(( trail_cols[i] + RANDOM % 3 - 1 ))
(( tr < 0 || tc < 0 )) && continue
(( tr >= bird_top && tr <= bird_bot && tc >= bird_col && tc <= bird_right )) && continue
dots=''
n=$(( RANDOM % 2 + 1 ))
for ((j = 0; j < n; j++)); do dots+="${chars[$(( RANDOM % 5 ))]}"; done
tput cup "$tr" "$tc"
printf '%s' "$dots"
done
}
COLS=$(tput cols)
ROWS=$(tput lines)
BASE_ROW=0
tput civis
trap 'tput cnorm; tput cup $(( ROWS - 1 )) 0' EXIT INT TERM
clear
flying=0
draw_bird 0 0 "${BANNER[@]}"
sleep 0.8
flying=1
col=0
prev_row_off=0
trail_cols=()
trail_rows=()
while (( col <= TRAVEL )); do
row_off=$(( - col * BIRD_H / TRAVEL ))
clear_rows "$prev_row_off"
trail_cols+=("$(( col + 14 ))")
trail_rows+=("$(( BASE_ROW + row_off + 5 ))")
while (( ${#trail_cols[@]} > 6 )); do
trail_cols=("${trail_cols[@]:1}")
trail_rows=("${trail_rows[@]:1}")
done
draw_bird "$col" "$row_off" "${BIRD[@]}"
draw_trail "$col" "$row_off"
prev_row_off=$row_off
sleep 0.08
(( col += 4 ))
done
for ((i = 0; i < BIRD_H; i++)); do
tput cup "$i" 0
printf '%*s' "$COLS" ''
done
tput cup 0 0
printf '%s\n' "Amazon Linux 2は2026/06/30でEOLです"
LAST=$(last -n 2 -i "$USER" 2>/dev/null | grep -v "still logged" | grep "$USER" | head -1 | awk '{print $4,$5,$6,$7,"from",$3}')
[[ "$LAST" =~ ^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) ]] && printf 'Last login: %s\n' "$LAST"
BIRDSCRIPT
chmod +x /etc/profile.d/bird.sh
Outputs:
InstanceId:
Value: !Ref Instance
PublicIp:
Value: !GetAtt Instance.PublicIp
VPC一式とEC2インスタンスを作成し、ユーザーデータでスクリプトも配置しています。作成されるリソース一覧はこちら。
| 論理ID | リソース種別 | Name タグ |
|---|---|---|
Vpc |
AWS::EC2::VPC | free-al2-bird-vpc |
InternetGateway |
AWS::EC2::InternetGateway | free-al2-bird-igw |
VpcGatewayAttachment |
AWS::EC2::VPCGatewayAttachment | (タグなし) |
PublicSubnet |
AWS::EC2::Subnet | free-al2-bird-subnet-public |
RouteTable |
AWS::EC2::RouteTable | free-al2-bird-rtb-public |
DefaultRoute |
AWS::EC2::Route | (タグなし) |
SubnetRouteTableAssociation |
AWS::EC2::SubnetRouteTableAssociation | (タグなし) |
SecurityGroup |
AWS::EC2::SecurityGroup | free-al2-bird-sg |
Instance |
AWS::EC2::Instance | free-al2-bird-ec2 |
使用するAMI IDはハードコーディングしています。下記の結果から、一番新しいものを指定しています。
~ $ aws ec2 describe-images \
> --owners amazon \
> --filters "Name=name,Values=amzn2-ami-kernel-5.10*x86_64-gp2" \
> --query 'reverse(sort_by(Images, &CreationDate))[].[Name,ImageId]' \
> --output text
amzn2-ami-kernel-5.10-hvm-2.0.20260629.0-x86_64-gp2 ami-06087cfd700858bee
amzn2-ami-kernel-5.10-hvm-2.0.20260622.1-x86_64-gp2 ami-07c647553a2f27949
amzn2-ami-kernel-5.10-hvm-2.0.20260615.0-x86_64-gp2 ami-0187c7df27ec175e1
amzn2-ami-kernel-5.10-hvm-2.0.20260608.0-x86_64-gp2 ami-0464ea504c6b43640
amzn2-ami-kernel-5.10-hvm-2.0.20260526.0-x86_64-gp2 ami-0b268943ac284f0c8
amzn2-ami-kernel-5.10-hvm-2.0.20260515.0-x86_64-gp2 ami-0324af2ca26d828c5
amzn2-ami-kernel-5.10-hvm-2.0.20260511.1-x86_64-gp2 ami-0cc213517bf63b8ad
amzn2-ami-kernel-5.10-hvm-2.0.20260508.0-x86_64-gp2 ami-0e56fdd7002dd4962
amzn2-ami-kernel-5.10-hvm-2.0.20260504.0-x86_64-gp2 ami-04633509de692dab5
amzn2-ami-kernel-5.10-hvm-2.0.20260427.1-x86_64-gp2 ami-0f0cee67f8a8a3f07
amzn2-ami-kernel-5.10-hvm-2.0.20260413.0-x86_64-gp2 ami-0d8fbaea8b647edac
amzn2-ami-kernel-5.10-hvm-2.0.20260406.1-x86_64-gp2 ami-0b23654657ee2874f
作成したEC2インスタンスの/etc/profile.d/に配置されるスクリプトは以下です。
#!/bin/bash
# sourced か直接実行かを判定して早期終了
if (return 0 2>/dev/null); then
_exit() { return "$1"; }
else
_exit() { exit "$1"; }
fi
# SSH ログイン時のみ実行
[ -t 1 ] || _exit 0
[ -n "$TERM" ] || _exit 0
[ -n "$SSH_CONNECTION" ] || _exit 0
Q="'"
BOLD=$'\e[1m'
RESET=$'\e[0m'
RAINBOW=($'\e[31m' $'\e[33m' $'\e[32m' $'\e[36m' $'\e[34m' $'\e[35m')
BIRD_H=10
TRAVEL=60
BANNER=(
" , #_"
" ~\\_ ####_ Amazon Linux 2"
" ~~ \\_#####\\"
" ~~ \\###| AL2 End of Life is 2026-06-30."
" ~~ \\#/ ___"
" ~~ V~${Q} ${Q}->"
" ~~~ / A newer version of Amazon Linux is available!"
" ~~._. _/"
" _/ _/ Amazon Linux 2023, GA and supported until 2028-03-15."
" _/m/${Q} https://aws.amazon.com/linux/amazon-linux-2023/"
)
BIRD=(
" , #_"
" ~\\_ ####_"
" ~~ \\_#####\\"
" ~~ \\###|"
" ~~ \\#/ ___"
" ~~ V~${Q} ${Q}->"
" ~~~ /"
" ~~._. _/"
" _/ _/"
" _/m/${Q}"
)
draw_bird() {
local col=$1 row_off=$2 i row
shift 2
for ((i = 0; i < BIRD_H; i++)); do
row=$(( BASE_ROW + row_off + i ))
if (( row >= 0 && row < ROWS )); then
tput cup "$row" 0
printf '%*s' "$COLS" ''
if (( col < COLS )); then
tput cup "$row" "$col"
if (( flying )); then
printf '%s' "${BOLD}${RAINBOW[$(( (i + col / 4) % 6 ))]}$1${RESET}"
else
printf '%s' "$1"
fi
fi
fi
shift
done
}
clear_rows() {
local row_off=$1 i row
for ((i = 0; i < BIRD_H; i++)); do
row=$(( BASE_ROW + row_off + i ))
if (( row >= 0 && row < ROWS )); then
tput cup "$row" 0
printf '%*s' "$COLS" ''
fi
done
}
draw_trail() {
local bird_col=$1 bird_row_off=$2
local bird_top=$(( BASE_ROW + bird_row_off ))
local bird_bot=$(( bird_top + BIRD_H - 1 ))
local bird_right=$(( bird_col + 22 ))
local chars=('.' ',' '~' '*' '-')
local i tr tc n j dots
for ((i = 0; i < ${#trail_cols[@]}; i++)); do
tr=$(( trail_rows[i] + RANDOM % 3 - 1 ))
tc=$(( trail_cols[i] + RANDOM % 3 - 1 ))
(( tr < 0 || tc < 0 )) && continue
(( tr >= bird_top && tr <= bird_bot && tc >= bird_col && tc <= bird_right )) && continue
dots=''
n=$(( RANDOM % 2 + 1 ))
for ((j = 0; j < n; j++)); do dots+="${chars[$(( RANDOM % 5 ))]}"; done
tput cup "$tr" "$tc"
printf '%s' "$dots"
done
}
COLS=$(tput cols)
ROWS=$(tput lines)
BASE_ROW=0
tput civis
trap 'tput cnorm' EXIT INT TERM
clear
flying=0
draw_bird 0 0 "${BANNER[@]}"
sleep 0.8
flying=1
col=0
prev_row_off=0
trail_cols=()
trail_rows=()
while (( col <= TRAVEL )); do
row_off=$(( - col * BIRD_H / TRAVEL ))
clear_rows "$prev_row_off"
trail_cols+=("$(( col + 14 ))")
trail_rows+=("$(( BASE_ROW + row_off + 5 ))")
while (( ${#trail_cols[@]} > 6 )); do
trail_cols=("${trail_cols[@]:1}")
trail_rows=("${trail_rows[@]:1}")
done
draw_bird "$col" "$row_off" "${BIRD[@]}"
draw_trail "$col" "$row_off"
prev_row_off=$row_off
sleep 0.08
(( col += 4 ))
done
# 鳥が通った可能性のある行をすべてクリア
for ((i = 0; i < BIRD_H; i++)); do
tput cup "$i" 0
printf '%*s' "$COLS" ''
done
tput cup 0 0
printf '%s\n' "Amazon Linux 2は2026/06/30でEOLです"
LAST=$(last -n 2 -i "$USER" 2>/dev/null | grep -v "still logged" | grep "$USER" | head -1 | awk '{print $4,$5,$6,$7,"from",$3}')
[[ "$LAST" =~ ^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) ]] && printf 'Last login: %s\n' "$LAST"
このCloudFormationテンプレートをデプロイしました。いざ、実践です!
Amazon Linux 2の鳥を逃がしてみた
デプロイされたEC2インスタンスに、EC2 Instance Connectで接続してみます。

はい、鳥が逃げました!分かりました?
もう一回載せますね。

はい、逃げてますね!!gifなのでわかりづらいかもしれないですが。
ローカルだともうちょっと動きがわかりやすいかもなので載せておくとこうです。

カラフルに色を変えながら右上に逃げていく鳥がそこにいますね。EOLを告げる役割を課せられた鳥を、空に還すことができました。これがわたしの鳥逃士としてのデビューです。お前を囲む鳥籠など……もはや無いんだよ。
接続するたびにそこに戻ってるんですけどね。細かいことは気にしたら負けですよ。
苦労したこと
生成AIに↓これは何?と聞くと鳥と判別してくれました。
, #_
~\_ ####_
~~ \_#####\
~~ \###|
~~ \#/ ___
~~ V~' '->
~~~ /
~~._. _/
_/ _/
_/m/'
ただ、羽ばたくアニメーションにしたいので3コマくらい別パターンを作って、と頼んでもうまくいきませんでした。「羽を下にしているパターン」と何度頼んでも、人間の脳には理解できない記号の塊が排出されるだけでした。しょうがないので、ポーズは固定のまま飛んでいくパターンにしました。
あとは定期的に湧き上がっている「自分はいま何をやってるんだろう」という思いとの付き合い方にも苦労しました。7割くらいは業務時間外に書いているから許して、と誰かに謝っていました。家族が寝静まった後に鳥を逃がしている時間が、わたしにとって何かの救いだったのかもしれません。
終わりに
Amazon Linux 2が2026年6月30日にEOLになるので、あの鳥を逃がしてみたという話でした。繰り返しになりますが、Amazon Linux 2は2026年6月30日にEOLです。セキュリティアップデートの提供がなくなります。早めの移行を検討しましょう。

ちなみにあの鳥の名前は何て言うんでしょうね?調べてみてもピンとくるものは出てきませんでした。唯一、GitHubのissueで「AL bird」と呼称されている例を見かけました。それに則って読んでいくのもいいかもしれませんね。もし自由に名付けていいなら、「六之助」という名前を推奨したいです。

このブログはAmazon Linux 2のEOLを啓蒙する目的で書きました。断じてふざけているわけではありません。ただ、あまり職場で読むには適していないかもしれません。人に薦める時は、休憩時間とかにこっそり読んでと伝えてあげてください。鳥も空の彼方から、それを望んでいると思います。
以上、チバユキ (@batchicchi)がお送りしました。

参考
- Amazon Linux 2のサポート期限が2025年6月末まで延長されました | DevelopersIO
- セッション「Amazon Linux AL2023 and beyond」参加してこれからの Amazon Linux について聞いてきました #AWSreInvent #CMP206 | DevelopersIO
- Amazon Linux パートナー - Amazon Web Services (AWS)
- [Bug] - motd resets when new AL2023 update is available · Issue #358 · amazonlinux/amazon-linux-2023








