はじめに
Lambda関数でAWS CLIコマンドを使用して、日本語ファイル名のファイルをS3にアップロードしようとしたところ、エラーが出ました。
'utf-8' codec can't encode characters in ...
Lambda関数のランタイムは Node.js20.x (OS: Amazon Linux 2023)
です。
エラーの原因
まずは、環境変数設定で LANG
に ja_JP.utf8
を設定してみますが、結果は変わらず。
Amazon Linux 2023のDockerコンテナを起動して確認してみると、そもそもデフォルトで日本語のロケールデータが存在していませんでした。
$ docker run -it --rm amazonlinux:2023 bash
$ ls -l /usr/lib/locale
total 4
drwxr-xr-x 3 root root 4096 Jul 5 19:23 C.utf8
対応について
今回は、Lambdaレイヤーとして日本語ロケールデータを登録して、Lambda関数がそれを使用するようにすることで解決しました。
以下にその手順をまとめます。
1. 日本語ロケールデータのzipファイルを作成
Amazon Linux 2023のDockerコンテナを起動します。
この後、コンテナ内でLambdaレイヤーにアップロードするzipファイルを作成しますが、そのzipファイルにローカルからもアクセスできるように、-v
オプションを使用します。
# 任意の作業ディレクトリに移動
$ cd ~/Desktop
# Dockerコンテナを起動して、glibc-langpack-ja と zip をインストール
$ docker run -it --rm -v ./volume:/volume amazonlinux:2023 bash
$ dnf -y install glibc-langpack-ja zip
これで日本語のロケールデータがインストールされました。
$ ls -l /usr/lib/locale
total 12
drwxr-xr-x 3 root root 4096 Jul 5 19:23 C.utf8
drwxr-xr-x 3 root root 4096 Jul 29 08:35 ja_JP.eucjp
drwxr-xr-x 3 root root 4096 Jul 29 08:35 ja_JP.utf8
このロケールデータをzipファイルにまとめます。
$ mkdir /volume/locale
$ cp -r /usr/lib/locale/ja_JP.utf8 /volume/locale/
$ cd /volume
$ zip -r locale.zip locale
2. Lambdaレイヤーを作成
前の手順で、~/Desktop/volume/locale.zip
が作成されています。
このzipファイルを使用してLambdaレイヤーを作成します。
3. 対象のLambda関数にLambdaレイヤーを登録
Lambda関数のレイヤー登録画面から先ほど作成したLambdaレイヤーを登録します。
4. Lambdaレイヤーの日本語ロケールデータを使用できるように環境変数を設定
Lambdaレイヤーは /opt
配下に展開されるため、日本語ロケールデータは /opt/locale
に存在することになります。
LANG
に ja_JP.utf8
を設定し、さらに LOCPATH
に /opt/locale
を設定することで、Lambdaレイヤーで設定した日本語ロケールデータが読み込まれるようにします。
これで問題なく日本語ファイルも処理することができました。