
Lambda Managed InstancesをTerraformでサクッと試してみる。 #AWSreInvent
はじめに
皆様こんにちは、あかいけです。
2025/12/1にAWS Lambdaの新機能「Lambda Managed Instances」が発表されました。
ECSのManaged Instancesに似たような概念で、Lambda関数をEC2インスタンス上で実行できるようになる機能です。
従来のLambdaはFirecrackerマイクロVMによるマルチテナント環境で動作していましたが、Lambda Managed Instancesでは自分のAWSアカウント内の専用EC2インスタンス上でコンテナとして実行されます。
これにより、GPUの利用や特定のインスタンスタイプの選択など、より柔軟な構成が可能になりました。
そんなLambda Managed Instancesですが、実はすでにTerraformが対応していました。
なので今回はTerraformで作成してサクッとLambda Managed Instancesを試してみます。
なお手動での作成/設定手順については、以下記事がわかりやすくてオススメです。
必要となるTerraformリソース
Lambda Managed Instancesを構築するために、以下のTerraformリソースを作成します。
1. aws_lambda_capacity_provider
Lambda Managed Instancesの核となるリソースです。
関数を実行するインフラストラクチャを定義します。
-
必須設定
name: Capacity Providerの名前vpc_config: VPC設定(サブネットID、セキュリティグループID)permissions_config: Lambda がEC2リソースを管理するためのIAMロールARN
-
オプション設定
instance_requirements: インスタンスタイプの指定(アーキテクチャ、許可/除外するインスタンスタイプ)capacity_provider_scaling_policy: スケーリングポリシー設定
2. aws_lambda_function
通常のLambda関数に比べて、以下の設定追加で必要となります。
- Managed Instances固有の設定
capacity_provider_config: Capacity ProviderのARNを指定publish_to:LATEST_PUBLISHEDに設定(バージョン発行が必要)memory_size: 最低2,048 MB以上が必要
3. IAM Role(Operator用)
Lambda がEC2インスタンスを管理するためのIAMロールが必要です。
AWS管理ポリシーAWSLambdaManagedEC2ResourceOperatorをアタッチする必要があります。
4. VPCリソース
EC2を利用する都合上、Capacity Providerには必ずVPC関連のリソースが必要となります。
- VPC
- サブネット
- セキュリティグループ
Terraform実装例
以下に、Lambda Managed Instancesを構築するTerraformコードの例を示します。
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
data "aws_availability_zones" "available" {
state = "available"
}
data "archive_file" "lambda" {
type = "zip"
source_file = "${path.module}/src/index.py"
output_path = "${path.module}/lambda.zip"
}
#--------------------------------------------------
# IAM: Operator Role
# LambdaがEC2インスタンスを管理するために必要なロール
#--------------------------------------------------
data "aws_iam_policy_document" "lambda_assume_role" {
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
actions = ["sts:AssumeRole"]
}
}
resource "aws_iam_role" "lambda_operator" {
name = "lambda-managed-instances-operator"
assume_role_policy = data.aws_iam_policy_document.lambda_assume_role.json
}
# このポリシーにより、LambdaがEC2インスタンスのライフサイクルを管理可能になる
resource "aws_iam_role_policy_attachment" "lambda_operator" {
role = aws_iam_role.lambda_operator.name
policy_arn = "arn:aws:iam::aws:policy/AWSLambdaManagedEC2ResourceOperator"
}
#--------------------------------------------------
# IAM: Lambda Execution Role
# Lambda関数の実行に必要なロール
#--------------------------------------------------
resource "aws_iam_role" "lambda_execution" {
name = "lambda-managed-instances-execution"
assume_role_policy = data.aws_iam_policy_document.lambda_assume_role.json
}
resource "aws_iam_role_policy_attachment" "lambda_basic_execution" {
role = aws_iam_role.lambda_execution.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
resource "aws_iam_role_policy_attachment" "lambda_vpc_access" {
role = aws_iam_role.lambda_execution.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
}
#--------------------------------------------------
# VPC Resources
# Capacity ProviderにはVPC設定が必須
#--------------------------------------------------
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "lambda-managed-instances-vpc"
}
}
# プライベートサブネット(2つのAZに分散配置)
resource "aws_subnet" "private" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = {
Name = "lambda-managed-instances-private-${count.index + 1}"
}
}
# セキュリティグループ(アウトバウンドのみ許可)
resource "aws_security_group" "lambda" {
name = "lambda-managed-instances-sg"
description = "Security group for Lambda Managed Instances"
vpc_id = aws_vpc.main.id
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "lambda-managed-instances-sg"
}
}
#--------------------------------------------------
# Lambda Capacity Provider
# EC2インスタンスの配置先やインスタンス要件を定義
#--------------------------------------------------
resource "aws_lambda_capacity_provider" "main" {
name = "example-capacity-provider"
# VPC設定(必須)
vpc_config {
subnet_ids = aws_subnet.private[*].id
security_group_ids = [aws_security_group.lambda.id]
}
# Operator Roleの指定(必須)
permissions_config {
capacity_provider_operator_role_arn = aws_iam_role.lambda_operator.arn
}
# インスタンス要件(オプション)
# 指定しない場合はLambdaが自動で最適なインスタンスを選択
instance_requirements {
architectures = ["x86_64"]
# 特定のインスタンスタイプに限定する場合は以下を指定
allowed_instance_types = ["m5.large"]
}
tags = {
Name = "example-capacity-provider"
}
}
#--------------------------------------------------
# Lambda Function
# capacity_provider_configを指定することでManaged Instancesとして動作
#--------------------------------------------------
resource "aws_lambda_function" "main" {
filename = data.archive_file.lambda.output_path
function_name = "example-managed-instances-function"
role = aws_iam_role.lambda_execution.arn
handler = "index.handler"
source_code_hash = data.archive_file.lambda.output_base64sha256
runtime = "python3.13" # Managed InstancesではPython 3.13以降が必要
memory_size = 2048 # Managed Instancesでは最低2 GB(2048 MB)が必要
timeout = 30
# $LATEST.PUBLISHED形式のバージョンを作成する
publish = true
publish_to = "LATEST_PUBLISHED"
# このブロックを指定することでManaged Instancesとして動作する
capacity_provider_config {
lambda_managed_instances_capacity_provider_config {
capacity_provider_arn = aws_lambda_capacity_provider.main.arn
}
}
tags = {
Name = "example-managed-instances-function"
}
depends_on = [
aws_iam_role_policy_attachment.lambda_basic_execution,
aws_iam_role_policy_attachment.lambda_vpc_access,
]
}
サンプルLambda関数コード
import json
def handler(event, context):
return {
"statusCode": 200,
"body": json.dumps({
"message": "Hello from Lambda Managed Instances!"
})
}
上記を構築後に関数を呼び出してあげると、正常にレスポンスが返ってくるかと思います。
% aws lambda invoke --function-name example-managed-instances-function outfile && cat outfile
{
"StatusCode": 200,
"ExecutedVersion": "$LATEST.PUBLISHED"
}
{"statusCode": 200, "body": "{\"message\": \"Hello from Lambda Managed Instances!\"}"}
構築時の注意点
ドキュメントを眺めていて、いくつか注意点があったので記載します。
構築時はこれらの点を考慮した上で、検証してみて下さい。
デフォルトで3台のEC2インスタンスが起動
Lambda Managed Instancesでは、AZの冗長性を確保するため、デフォルトで3台のEC2インスタンスが起動します。
そのため検証目的で小規模に試したい場合でもインスタンス料金がかかる点に注意してください。
また、関数バージョンを発行するとLambdaは3つの実行環境を起動してから関数バージョンをACTIVE状態にします。
このため、関数の作成には数分かかる場合があります。
最小メモリは2 GB
従来のLambdaでは128 MBから設定できましたが、Managed Instancesでは最低2 GBのメモリが必要です。
小さいインスタンスタイプは非対応
ドキュメントには記載されていませんが、t3.microなどの小さいインスタンスタイプはサポートされていません。
また基本的にはLambdaに最適なインスタンスタイプを自動選択させることが推奨されています。
サポートされるランタイム
Lambda Managed Instancesでは、以下のランタイムがサポートされています。
そのため前述のTerraformコード例ではpython3.13を指定しています。
- Java 21以降
- Python 3.13以降
- Node.js 22以降
- .NET 8以降
VPCネットワーク設定が必須
Lambda Managed InstancesはVPC内で動作するため、Lamnda関数から外部リソースへのアクセスやCloudWatch Logsへのログ送信にはネットワーク設定が必要です。
以下のいずれかの方法でネットワーク接続を構成してください。
- パブリックサブネット + インターネットゲートウェイ
- プライベートサブネット + NATゲートウェイ
- プライベートサブネット + VPCエンドポイント
Capacity Providerはセキュリティ境界
Capacity Providerは関数のセキュリティ境界として機能します。
同じCapacity Providerに割り当てられた関数はすべて相互に信頼されている必要があります。
なお、コンテナはセキュリティ境界として利用できないため、セキュリティ分離の手段として使用しないでください。
そのため信頼レベルが異なるワークロードは、別々のCapacity Providerに分離することを推奨します。
初期化タイムアウトが長い
Lambda Managed Instancesでは、初期化フェーズに最大15分かかる場合があります。
タイムアウトは130秒または設定された関数タイムアウト(最大900秒)のいずれか大きい方が適用されます。
CPU使用率ベースの非同期スケーリング
従来のLambdaはリクエストが来たときに実行環境がなければスケールアウトする(コールドスタート)方式でしたが、Lambda Managed InstancesはCPU使用率に基づいて非同期にスケールします。
マルチ同時実行モデル
Lambda Managed Instancesの最も大きな特徴の一つが、マルチ同時実行(Multi-concurrent execution)です。
そのためランタイムに応じて、同時実行について考慮が必要となります。
従来のLambdaとの違い
| 項目 | 従来のLambda | Managed Instances |
|---|---|---|
| 同時実行 | 1実行環境 = 1リクエスト | 1実行環境 = 複数リクエスト |
| スレッドセーフ | 考慮不要 | 必須 |
| グローバル変数 | リクエスト間で再利用可能 | 同時アクセスに注意 |
その他ランタイムごとの注意点や実装方法については公式ドキュメントをご参照ください。
余談
Capacity Provider の削除に意外と時間がかかりました。
おそらくEC2インスタンスなどマネージドに管理しているリソースの削除に時間がかかるのかなと思います。
aws_lambda_capacity_provider.main: Still destroying... [name=example-capacity-provider, 10m0s elapsed]
aws_lambda_capacity_provider.main: Destruction complete after 10m5s
さいごに
以上、Lambda Managed InstancesをTerraformで実装する方法でした。
ブログのTerraformコードそのまま構築できるため、皆さんもたくさん検証してみて下さい。
Lambda Managed Instancesは従来のLambdaとは料金モデルやスケーリングの考え方が大きく異なるため、ワークロードの特性に応じて使い分けることが重要だと思います。
定常的で予測可能なワークロードや、EC2の柔軟性が必要なケースでは、Lambda Managed Instancesが有力な選択肢になりそうです。
この記事が誰かのお役に立てば幸いです。








