Lambda SnapStart での一意性の取り扱い
SnapStart 関数での呼び出しがスケールアップすると、Lambda は単一の初期化されたスナップショットを使用して、複数の実行環境を再開します。スナップショットに包含される一意のコンテンツを初期化コードが生成する場合、そのコンテンツは、複数の実行環境で再利用されるときに一意にならない可能性があります。SnapStart の使用時に一意性を維持するには、初期化後に一意のコンテンツを生成する必要があります。これには、一意の ID、一意のシークレット、および疑似ランダム性を生成するために使用されるエントロピーが含まれます。
コードで一意性を維持できるように、以下のベストプラクティスをお勧めします。Java 関数の場合、Lambda は、一意性を前提とするコードのチェックに役立つ、オープンソースの SnapStart スキャンツールも提供します。初期化フェーズ中に一意のデータを生成する場合は、ランタイムフックを使用して一意性を復元することができます。ランタイムフックを使用すると、Lambda がスナップショットを取得する直前、または Lambda がスナップショットから関数を再開した直後に、特定のコードを実行できます。
一意性に依存する状態を初期化中に保存しない
関数の初期化フェーズ中は、ロギング用またはランダム関数のシードの設定用の一意の ID の生成など、一意であることが意図されたデータをキャッシュしないでください。その代わりに、関数ハンドラー内で一意のデータの生成やランダム関数のシードの設定を行うか、ランタイムフックを使用することをお勧めします。
次の例は、関数ハンドラーで UUID を生成する方法を示しています。
暗号論的擬似乱数生成器 (CSPRNG) を使用する
SnapStart を有効にすると、Lambda はすべてのアプリケーションとシステムメモリを含む、関数の実行環境のスナップショットを作成します。つまり、すべての乱数生成器 (RNG) の内部の状態は、アプリケーションまたはその依存関係が既に生成してメモリバッファに保存しているランダムバイトとともに、スナップショット時とまったく同じ状態で保持されます。
Lambda は、スナップショットから実行環境を復元すると、/dev/random および /dev/urandom から新しいエントロピーを使用してカーネル乱数ジェネレーターを再シードします。これらのデバイスから乱数を直接読み取るソフトウェアは、SnapStart でランダム性を維持します。
アプリケーションがランダム性に依存している場合は、暗号論的擬似乱数生成器 (CSPRNG) を使用することをお勧めします。AL が提供する OpenSSL に加えて、SnapStart (Java バージョン 11 以降、Python バージョン 3.12 以降、.NET バージョン 8 以降) をサポートする Lambda マネージドランタイムには、次の組み込み CSPRNG が含まれています。
-
Java:
java.security.SecureRandom -
Python:
random.SystemRandom -
.NET:
System.Security.Cryptography.RandomNumberGenerator
注記
Go Lambda ランタイムでは、関数が、デフォルトで SnapStart 互換である標準ライブラリの crypto/rand を使用している場合、変更は不要です。
関数をコンテナイメージとしてパッケージ化する場合、SnapStart との互換性はベースイメージによって決まります。
-
マネージドランタイム (Java バージョン 11 以降、Python バージョン 3.12 以降、.NET バージョン 8 以降) の Lambda ベースイメージ – 上記のとおり SnapStart と互換性があります。
-
provided.al2023 ベースイメージ – プログラミング言語ランタイムが
/dev/random、/dev/urandom、Amazon Linux 2023 パッケージリスト に記載されている OpenSSL の SnapStart 互換ビルド (openssl-snapsafe-libs) からエントロピーを取得する場合、互換性があります。ランタイムが他のエントロピーソースに依存している場合は、以下の「独自のベースイメージ」で説明されている手順に従います。 -
独自のベースイメージ – 暗号化ライブラリを調査し、復元後のランタイムフックを使用して、キャッシュされた乱数生成器 (RNG) のステータスまたはバッファされたランダムバイトを破棄します。それにより、ライブラリは復元後にシステムから新しいエントロピーを読み取ることができます。例えば、
rand::rngs::ThreadRngを使用する Rust 関数は、復元後にreseed()を呼び出す必要があります。可能な限り Lambda ベースイメージを使用してビルドすることが推奨されます。特に、ベースイメージに独自のバージョンの OpenSSL または OpenSSL フォーク (BoringSSL や LibreSSL など) が含まれる場合は、OpenSSL の SnapStart 互換ビルド (openssl-snapsafe-libs) を含む provided.al2023 ベースイメージに切り替えるか、AWSlibcrypto (AWS-LC) を使用します。
サポートされているライブラリの最小バージョン
AWS 暗号化ライブラリは、次の表で指定されている最小バージョンから始まる SnapStart でのランダム性を自動的に維持します。これらのライブラリを Lambda 関数で使用する場合は、次の最小バージョン以降を使用していることを確認してください。
| Library | サポートされている最小バージョン (x86) | サポートされている最小バージョン (ARM) |
|---|---|---|
| AWS libcrypto (AWS-LC) |
1.16.0 |
1.30.0 |
| AWS libcrypto FIPS |
2.0.13 |
2.0.13 |
次のライブラリを介して、前述の暗号化ライブラリを推移的な依存関係として Lambda 関数にパッケージ化する場合は、次の最小バージョン以降を使用していることを確認してください。
| Library | サポートされている最小バージョン (x86) | サポートされている最小バージョン (ARM) |
|---|---|---|
| AWS SDK for Java 2.x |
2.23.20 |
2.26.12 |
| AWS Common Runtime for Java |
0.29.8 |
0.29.25 |
| Amazon Corretto Crypto Provider |
2.4.1 |
2.4.1 |
| Amazon Corretto Crypto Provider FIPS |
2.4.1 |
2.4.1 |
次の例は、関数がスナップショットから復元された場合でも、CSPRNG を使用して一意の数列が保証されるようにする方法を示します。
SnapStart スキャンツール (Java のみ)
Lambda は、一意性を前提としたコードをチェックするのに役立つ、Java 用のスキャンツールを提供しています。SnapStart スキャンツールは、一連のルールに照らして静的分析を実行する、オープンソースの SpotBugs
SnapStart による一意性の処理について詳しくは、AWS コンピューティングブログの「AWS Lambda SnapStart による迅速なスタートアップ