locale設定をしてAMIを作成したのに設定が戻っていた話

2022.09.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

つい先日Amazon Linux2でゴールデンイメージを作成してEC2を起動した際にlocale設定が「en_US.UTF-8」に戻っていたのでその時に調べたことと設定したことをブログに残しておきます。

なんで設定が戻っていたのか

結論から話すと「cloud-init」というものが原因でした。
以下のドキュメントに記載されている通りAmazon Linuxのcloud-initでは以下のことをEC2の作成時に行っています。
Amazon Linuxのcloud-init

デフォルトのロケールを設定.
ホスト名を設定.
ユーザーデータの解析と処理.
ホスト プライベート SSH キーの生成.
容易にログインおよび管理できるように、ユーザーのパブリック SSH キーを .ssh/authorized_keys に追加する.
パッケージ管理のためにリポジトリを準備する
ユーザーデータで定義されたパッケージアクションの処理.
ユーザーデータにあるユーザースクリプトの実行.
インスタンスストアボリュームをマウントする (該当する場合)

上記引用の「デフォルトのロケールを設定」の影響で「en_US.UTF-8」に戻っていました。

設定検証

cloud-initのlocale設定を変更する検証をしてみました。

失敗例

まずは設定が戻ってしまう方法を確認します。
Amazon Linux2のEC2で以下のコマンドを実行してからAMIを作成します。

sudo localectl set-locale LANG=ja_JP.utf8
sudo localectl status

localeの設定ができたらAMIを作成します。
今回はAWS CLIを使用して作成しました。
以下のコマンドを実行してAMIを作成します。

aws ec2 create-image --instance-id インスタンスID --name AMIに付ける名前

AMIが作成出来たら以下のコマンドでEC2を起動します。

aws ec2 run-instances --image-id 作成したAMI ID --instance-type t2.micro --key-name キーペア名 --security-group-ids セキュリティグループID --subnet-id サブネットID

作成が完了したら以下のコマンドでlocale設定を確認します。

sudo localectl status

実行すると「en_US.UTF-8」に戻っていることがわかります。

   System Locale: LANG=en_US.UTF-8
       VC Keymap: n/a
      X11 Layout: n/a

成功例

ここからはcloud-initに設定を入れてlocale設定が変更された状態で起動できるようにしていきます。
まずはcloud-initの設定ファイル「/etc/cloud/cloud.cfg」を確認します。
以下のドキュメントを読むと設定ファイルにyaml形式で設定すれば良さそうなのが分かりました。
User-Data Formats
Cloud config examples
localeを設定するには「Locale」というモジュールを使って設定することが可能なようです。
Module Reference
なので以下のコマンドを実行して「/etc/cloud/cloud.cfg」の最終行に追加します。

sudo sed '$a locale: ja_JP.UTF-8' -i /etc/cloud/cloud.cfg

追記ができたら失敗例の時と同じようにAMIを作成してEC2を起動してみます。

aws ec2 create-image --instance-id インスタンスID --name AMIに付ける名前
aws ec2 run-instances --image-id 作成したAMI ID --instance-type t2.micro --key-name キーペア名 --security-group-ids セキュリティグループID --subnet-id サブネットID

作成が完了したら以下のコマンドでlocale設定を確認します。

sudo localectl status

実行すると「ja_JP.UTF-8」になっていることがわかります。

   System Locale: LANG=ja_JP.UTF-8
       VC Keymap: n/a
      X11 Layout: n/a

さいごに

cloud-initはEC2の作成時に一度だけ実行されるのでEC2起動後は意識しませんが、AutoScalingやEC2のコピーなどをするときは多少意識しておく必要があると思いました。