GemをLayerに登録する際のAWS Lambda制限への対応

はじめに

AWS LambdaにてAWS SDK for Rubyを使うことになり、単純にgemをLayerとして登録しようとしたら少しトラブったのでその対処方法を以下に記します。

何が起きたか?

前回までのブログ記事のようにgem 'aws-sdk'と書いたGemfileを用いてLayer用のzipファイルを作り、Layerを作ろうとしたらUnzipped size must be smaller than 262144000 bytesというエラーメッセージが出ました。

原因

AWS Lambdaにはさまざまな制限(クォータ)が設定されているのですが、今回は「デプロイパッケージ (.zip ファイルアーカイブ) のサイズ」に引っ掛かっているのが原因です。詳細は以下を参照。

docs.aws.amazon.com

今回、Layerとして登録しようとしていたzipファイルのサイズは62.4MBという大きさ。これぐらいのサイズでクォータに引っかかるんだとちょっとびっくりしました。

対処方法

対処方法の一つとして、gem 'aws-sdk'と書くのではなく、サービスごとに用意されているgem(例えばS3であればgem 'aws-sdk-s3')にすればサイズの縮小が望めます。

ただ、そもそもAWS Lambdaの実行環境にはデフォルトでAWS SDK for Rubyがインストールされています。実際、Gem::Specification.sort_by(&:name).map{ |g| "#{g.name} #{g.version}" }を実行すると以下の結果が得られました(Ruby 3.2のAWS Lambdaランタイム環境)。

["abbrev 0.1.1", "aws-eventstream 1.3.0", "aws-partitions 1.892.0", "aws-sdk 3.2.0", "aws-sdk-accessanalyzer 1.45.0", "aws-sdk-account 1.21.0", "aws-sdk-acm 1.65.0", "aws-sdk-acmpca 1.65.0", (中略), "aws-sdk-xray 1.63.0", "aws-sigv2 1.2.0", "aws-sigv4 1.8.0", "base64 0.2.0", "base64 0.1.1", "benchmark 0.2.1", "bigdecimal 3.1.6", "bigdecimal 3.1.3", "bundler 2.5.6", "bundler 2.3.26", "cgi 0.3.6", "csv 3.2.6", "date 3.3.3", "delegate 0.3.0", "did_you_mean 1.6.3", "digest 3.1.1", "drb 2.1.1", "english 0.7.2", "erb 4.0.2", "error_highlight 0.5.1", "etc 1.4.2", "fcntl 1.0.2", "fiddle 1.1.1", "fileutils 1.7.0", "find 0.1.1", "forwardable 1.3.3", "getoptlong 0.2.0", "io-console 0.6.0", "io-nonblock 0.2.0", "io-wait 0.3.0", "ipaddr 1.2.5", "irb 1.6.2", "jmespath 1.6.2", "json 2.6.3", "logger 1.5.3", "mutex_m 0.1.2", "net-http 0.4.1", "net-protocol 0.2.1", "nkf 0.1.2", "observer 0.1.1", "open-uri 0.3.0", "open3 0.1.2", "openssl 3.1.0", "optparse 0.3.1", "ostruct 0.5.5", "pathname 0.2.1", "pp 0.4.0", "prettyprint 0.1.1", "pstore 0.1.2", "psych 5.0.1", "racc 1.6.2", "rdoc 6.5.0", "readline 0.0.3", "readline-ext 0.1.5", "reline 0.3.2", "resolv 0.2.2", "resolv-replace 0.1.1", "rexml 3.2.6", "rinda 0.1.1", "ruby2_keywords 0.0.5", "rubygems-update 3.5.6", "securerandom 0.2.2", "set 1.0.3", "shellwords 0.1.0", "singleton 0.1.1", "stringio 3.0.4", "strscan 3.0.5", "syntax_suggest 1.1.0", "syslog 0.1.1", "tempfile 0.1.3", "time 0.2.2", "timeout 0.3.1", "tmpdir 0.1.3", "tsort 0.1.1", "un 0.2.1", "uri 0.12.2", "weakref 0.1.2", "yaml 0.2.1", "zlib 3.0.0"]

そもそもLayerとして登録する必要はなく、ソースコードにてrequire 'aws-sdk-サービス名'とすれば使えます。

考察

思いのほかクォータの上限が低く、簡単にクォータに引っかかったのでびっくりしました。zipファイルアーカイブは実装と実行のサイクルが短いのがメリットなのですが、クォータの上限を踏まえると気軽にGemを追加するのはこれまでのブログ記事での検証を踏まえると、厳しいかもしれません。

コンテナイメージを使う場合は10GBがクォータなので、コンテナイメージで動かす方が何かと楽なのかなと考えます。