
AWS Lambda Managed Instances で AZ 数による起動時の挙動の違いを確認してみた
こんにちは、製造ビジネステクノロジー部の若槻です。
AWS Lambda Managed Instances (LMI) では、関数公開時にデフォルトで3つのマネージドインスタンスと、3つの実行環境が起動されます。
キャパシティープロバイダーを使用して関数バージョンを公開すると、Lambda はアカウント内でマネージドインスタンスを起動します。AZ の回復性を確保するために、デフォルトで 3 つのマネージドインスタンスが起動され、関数バージョンを ACTIVE にする前に 3 つの実行環境が起動されます。
マネージドインスタンスと実行環境の実体はそれぞれ EC2 インスタンスとコンテナです。当然ながらそれらは VPC 内で起動されます。
そこで気になったのが、VPC が利用する AZ (Availability Zone) 数によって起動時の挙動に違いはあるのか?という点です。もし違いがあれば、開発・検証環境で最小構成を取る際の参考になりそうです。
ということで、実際に確認してみました。
確認してみた
検証環境の準備
まず検証環境の準備です。リソースは AWS CDK で作成します。
構築上の便利のため、利用する AZ 数をパラメーターとして CDK スタックをデプロイ可能としています。
import * as ec2 from "aws-cdk-lib/aws-ec2";
import { Construct } from "constructs";
export interface VpcConstructProps {
maxAzs: number;
}
/**
* VPC 実装
*/
export class VpcConstruct extends Construct {
public readonly vpc: ec2.Vpc;
constructor(scope: Construct, id: string, props: VpcConstructProps) {
super(scope, id);
this.vpc = new ec2.Vpc(this, "Default", {
maxAzs: props.maxAzs,
subnetConfiguration: [
/**
* NAT Gateway を配置するためのパブリックサブネット
*/
{
name: "Public",
subnetType: ec2.SubnetType.PUBLIC,
},
/**
* Lambda 関数を配置するためのプライベートサブネット
*/
{
name: "PrivateWithEgress",
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
},
],
});
}
}
import * as cdk from "aws-cdk-lib";
import * as ec2 from "aws-cdk-lib/aws-ec2";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as lambda_nodejs from "aws-cdk-lib/aws-lambda-nodejs";
import { Construct } from "constructs";
import { VpcConstruct, VpcConstructProps } from "./constructs/vpc";
export class SampleStack extends cdk.Stack {
constructor(
scope: Construct,
id: string,
props: cdk.StackProps & VpcConstructProps
) {
super(scope, id, props);
/**
* VPC 作成
*/
const vpcConstruct = new VpcConstruct(this, "Vpc", {
maxAzs: props.maxAzs,
});
const vpc = vpcConstruct.vpc;
/**
* セキュリティグループ作成
*
* MEMO: Capacity Provider 用に作成
*/
const securityGroup = new ec2.SecurityGroup(this, "SecurityGroup", {
vpc,
});
/**
* Capacity Provider 作成
*
* MEMO: LMI のコア要素となるリソース
*/
const capacityProvider = new lambda.CapacityProvider(
this,
"CapacityProvider",
{
subnets: vpc.selectSubnets({
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
}).subnets,
securityGroups: [securityGroup],
}
);
/**
* LMI 用 Lambda 関数作成
*/
const lmiFunction = new lambda_nodejs.NodejsFunction(this, "LmiFunction", {
entry: "src/handler.ts",
runtime: lambda.Runtime.NODEJS_24_X, // Lambda Managed Instances では Node.js 18.x 以上が必須
memorySize: 2048, // Lambda Managed Instances では 2048MB 以上が必須
tracing: lambda.Tracing.ACTIVE, // コールドスタート発生状況の観測のために、AWS X-Ray を有効化
});
/**
* Capacity Provider に Lambda 関数を追加
*/
capacityProvider.addFunction(lmiFunction);
}
}
注意点として、2つ以上の AZ を使用する VPC を作成する際には、アカウントとリージョンを指定する必要があります。
上記のデプロイにより構築した各スタックの「Capacity provider instance counts」および「Execution environment count」のメトリクスを AWS CloudWatch コンソールで確認します。
2AZ の場合
実行環境数は 3 となりました。

インスタンス数は 2 となりました。

3AZ の場合
実行環境数は 3 となりました。

インスタンス数は 3 となりました。

4AZ の場合
実行環境数は 3 となりました。

インスタンス数は 3 となりました。

結論
結論として次のようになりました。
| AZ 数 | インスタンス数 | 実行環境数 |
|---|---|---|
| 2 | 2 | 3 |
| 3 | 3 | 3 |
| 4 | 3 | 3 |
- インスタンス数は AZ 数に依存する。ただし、最大で 3 まで。
- 実行環境数は常に 3。
おわりに
AWS Lambda Managed Instances で AZ 数による起動時の挙動の違いを確認してみました。
起動時のインスタンス数は AZ 数に依存するが、最大で 3 まで。実行環境数は常に 3、という結果になりました。開発・検証環境で最小構成を取る場合は、2AZ(または 1AZ)の VPC を利用すればインスタンス数を抑えられそうです。その分コスト削減にもつながるかと思います。
ちなみに、実行環境数やインスタンス数の上限数の指定でも挙動が変わりそうだと考えましたが、そもそもその設定は無さそうでした。また、さらにスケーリングした際の挙動についても気になりましたが次回以降で確認します。
以上







