AWSでのサーバーレスアーキテクチャ設計において、中心的な役割を果たすのがAWS Lambdaです。サーバーのプロビジョニングやパッチ適用、容量管理を行うことなく、イベントに応じてコードを実行できるこのサービスは、開発効率の向上と運用コストの最適化を同時に実現します。
本記事では、AWSのデベロッパーとして確実に押さえておくべきLambdaの実行ライフサイクルやメモリ設計の基本、そしてAWS CloudFormationを使用したデプロイ時の「依存関係(暗黙的・明示的)」のベストプラクティスについて解説します。
1. AWS Lambdaの実行環境ライフサイクル
AWS Lambdaを効率的に稼働させ、コストを最適化するためには、その実行環境(Execution Environment)のライフサイクルを深く理解する必要があります。 Lambda関数がトリガーされると、隔離された安全な実行環境(Firecracker microVM)がプロビジョニングされ、コードが実行されます。このライフサイクルは主に以下の3つのフェーズに分かれています。
- INIT(初期化)フェーズ 関数のデプロイパッケージのダウンロード、ランタイム(言語環境)の起動、そしてハンドラー関数外の初期化コード(SDKクライアントの初期化やグローバル変数の読み込みなど)の実行を行います。
- INVOKE(呼び出し)フェーズ 実際にトリガーとなったイベントを受け取り、定義されたハンドラー関数がビジネスロジックを実行します。
- SHUTDOWN(シャットダウン)フェーズ 一定時間、関数への呼び出しがなくなると環境が破棄されます。この際、ランタイムや登録された拡張機能に、クリーンアップ処理用として最大2秒間が割り当てられます。
⚠️ INITフェーズ課金に関する重要な仕様変更
かつて、コールドスタート時に発生するINITフェーズ(初期化処理)の時間は原則として課金対象外(プロバイダー側の負担)でした。しかし、2025年8月1日の仕様変更により、すべてのデプロイ設定(ZIPパッケージ版ランタイムを含む)において、INITフェーズも課金対象となりました。 これにより、コールドスタートの最適化(パッケージサイズの軽量化や初期化処理の遅延ロードなど)は、単なるパフォーマンス向上だけでなく、直接的なコスト削減活動に直結する重要な設計要素となっています。
2. メモリ割り当てとCPU(計算リソース)の比例関係
AWS Lambdaでは、メモリ割り当て量(128 MB〜10,240 MB)を設定することで、関数が使用できるリソースを制御します。 重要なのは、「CPUのパワーは、設定したメモリ量に比例して自動的に割り当てられる」という仕様です。
- 1 vCPUの基準値: Lambdaでは、メモリを「1,769 MB」に設定したタイミングで、ちょうど1 vCPU相当の計算能力が割り当てられます。
- CPUボトルネックの解消: メモリ容量自体はそれほど必要なくても、CPU集約型の重い処理を行う関数の場合、メモリ割り当てを増やすことで処理が高速化し、結果として実行時間(Duration)が短縮されて総コストが安くなるケース(Inflection Point)があります。
3. Lambda関数の呼び出しタイプ(Invocation Type)
Lambda関数を実行する(呼び出す)際、AWS CLIやSDKの Invoke API、あるいはイベントソースからの起動において、主に以下の 3つの呼び出しタイプ(InvocationType パラメータ) を選択・制御できます。用途やシステム構成に合わせて適切に使い分けることが不可欠です。
- RequestResponse(同期呼び出し)
- 概要: 関数を同期的に実行するデフォルトの呼び出しタイプです。関数の実行が完全に完了するまでクライアントは待機し、処理された結果(戻り値やレスポンス)を直接受け取ります。API GatewayやApplication Load Balancerを介したWeb APIなど、即時性が求められるトランザクション処理に最適です。
- 特徴: 要求と応答のデータサイズを決定するペイロードの上限は、 6 MB までに制限されています。
- Event(非同期呼び出し)
- 概要: 関数を非同期的に実行します。AWS側で呼び出しリクエストを受け取り、内部キューに登録した時点で、クライアントには処理の完了を待たずにステータスコード「202 Accepted」を即座に返却します。関数の実際の処理はバックグラウンドで非同期的に実行されるため、S3バケットへのファイルアップロードに連動するバッチ処理や、バックグラウンドの非同期処理に適しています。
- 特徴: ペイロードの上限は、同期呼び出しより小さい 1 MB となります。
- DryRun(検証パラメータ)
- 概要: 実際には関数コード自体を実行(Invoke)することなく、リクエストパラメータが正しいか、および呼び出し元のユーザーやロールが該当するLambda関数を実行する適切な権限(IAMポリシー)を持っているかのみを検証します。
- 特徴: 課金を伴う実際のコンピューティング処理を走らせずに、接続やパーミッションの設定をテストできるため、CI/CDパイプラインでの事前検証やアクセス権のポリシーテストなどで非常に重宝します。
4. CloudFormationによるデプロイと「依存関係」の制御
複数リソースが連携するサーバーレスアプリケーションを開発する場合、AWS CloudFormationなどのIaC(Infrastructure as Code)ツールを用いてLambda関数を安全かつ自動的にデプロイするのが一般的です。
テンプレートからデプロイする際、関数とその他リソースの間の依存関係をどのように定義・制御するかが安定運用の鍵となります。
A. 依存関係の定義:暗黙的な依存関係(DependsOnが不要なケース)
CloudFormationテンプレートにおいて、Lambda関数がIAM実行ロール(AWS::IAM::Role)を必要とする場合を考えます。 関数を定義するプロパティ内で、ロールのARNを !GetAtt MyLambdaRole.Arn や !Ref MyLambdaRole のように記述して直接参照すると、CloudFormationは「暗黙的な依存関係(Implicit Dependency)」を自動的に検出します。これにより、明示的に順番を指定しなくとも、CloudFormationは必ず先にIAMロールの作成を完了させてから、Lambda関数のデプロイを開始します。
B. DependsOn による制御:明示的な依存関係(DependsOnが必要なケース)
一方、リソース間の直接的な「値の参照」はないものの、「あるリソースが完全に作成完了(CREATE_COMPLETE)していなければ、Lambda関数の作成プロセスが正常に動作しない(マウントに失敗するなど)」というケースでは、明示的に DependsOn 属性を指定する必要があります。
- Amazon S3 Filesのマウントターゲットへの依存: Lambda関数からAmazon S3のバケットをローカルファイルシステム(NFS)として直接マウントしてファイル操作を可能にする最新機能(Amazon S3 Files)を使用する場合がこれに該当します。 関数が作成される際、LambdaはVPCネットワークを介してS3 Filesのマウントターゲット(
AWS::S3Files::MountTarget)に接続しにいきます。マウントターゲットがプロビジョニングされ、完全に利用可能になるまでには数分(テスト環境では約5分など)かかることがあります。 もしCloudFormationがマウントターゲットの作成完了を待たずにLambda関数の作成を開始してしまうと、マウント処理が失敗し、関数の作成がエラーでロールバックされてしまいます。
これを防ぐために、以下のように DependsOn 属性に関係するマウントターゲットを明示的に指定します。
MyDurableFunction:
Type: AWS::Serverless::Function
DependsOn:
- S3FilesMountTargetA # マウントターゲットが完全に作成されるまで、関数の作成を待機させる
- S3FilesMountTargetB
Properties:
FunctionName: order-orchestrator-function
Runtime: python3.12
Handler: app.handler
CodeUri: ./src
FileSystemConfigs:
- Arn: !GetAtt S3FilesAccessPoint.AccessPointArn
LocalMountPath: /mnt/workspace
VpcConfig:
SecurityGroupIds:
- !Ref LambdaSecurityGroup
SubnetIds:
- !Ref PrivateSubnetA
- !Ref PrivateSubnetB
このように、暗黙的な参照解決ができないリソースの作成完了順序を厳密に制御したい場合には、DependsOn を記述するのがCloudFormation運用の基本です。
5. まとめ
- コストの最適化: 2025年8月以降、INITフェーズ(初期化フェーズ)の時間も課金対象となったため、コールドスタート時の無駄な読み込み処理を省くことはコスト面でも極めて重要です。
- CPU性能の調整: メモリ量に比例してCPUが自動的に割り当てられます(1,769 MB = 1 vCPU)。
- CloudFormationでの依存制御: IAMロールなどの直接参照が可能なものは暗黙的に解決されますが、S3 Filesなどのネットワークマウントターゲットや、起動・作成完了までに時間を要するリソースとの接続がある場合は、必ず明示的な DependsOn 属性を指定して順序を制御しましょう。
引用先(AWS公式サイト)
本記事で記載しているAWS LambdaおよびCloudFormationの仕様は、以下のAWS公式情報に準拠しています。
- AWS Lambda 料金と実行時間の課金仕様(INITフェーズ課金含む)
- AWS Lambda デベロッパーガイド:Lambda 実行環境ライフサイクルについて
- AWS Lambda デベロッパーガイド:AWS Lambda のクォータと制限値について
- AWS Lambda デベロッパーガイド:Amazon S3 Files のマウントおよび設定方法
- AWS Lambda デベロッパーガイド:Lambda SnapStart による起動最適化
- AWS Lambda デベロッパーガイド:プロビジョニングされた同時実行(Provisioned Concurrency)の設定
- AWS Lambda デベロッパーガイド:サポートされているマネージドランタイム一覧
- AWS Lambda デベロッパーガイド:Durable Functions(耐久性のある長期間実行ワークフロー)
- AWS Lambda デベロッパーガイド:同期呼び出し(Synchronous Invocation)
- AWS Lambda デベロッパーガイド:非同期呼び出し(Asynchronous Invocation)
