You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求ALB与Lambda集成的Terraform最佳实践/可运行配置

ALB 关联 Lambda 函数的 Terraform 正确配置方案

我正在备考AWS开发者认证,学习资料多采用AWS控制台操作示例,但我坚持用Terraform复现所有内容(更贴合职场实际场景)。其中一个章节涉及Application Load Balancer(ALB)与Lambda函数关联,尝试多日仍失败。当前配置访问负载均衡器时返回502错误,且无CloudWatch日志生成(尽管已配置ALB相关权限)。

已尝试的排查手段:

  • 查阅Terraform、AWS官方文档,搜索最佳实践示例(仅找到控制台操作指南);
  • 咨询多个AI工具(ChatGPT、Microsoft Copilot、Cody、Amazon Q/CodeWhisperer),但生成的示例均存在严重错误,调整后仍无法部署;
  • 考虑过从控制台导出Terraform代码,但需学习Terraformer/Former2,暂不想投入时间。

可运行的Terraform配置

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 4.41.0"
    }
  }
}

provider "aws" {
  region = "eu-central-1"
}

# Lambda 执行角色:包含CloudWatch日志权限
resource "aws_iam_role" "lambda_role" {
  name = "lambda-execution-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "lambda.amazonaws.com"
        }
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "lambda_basic_execution" {
  role       = aws_iam_role.lambda_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

# Lambda 代码打包
data "archive_file" "lambda_code" {  
  type        = "zip"  
  source_file = "./code/hello_world.py"
  output_path = "./lambda_code.zip"
}

# Lambda 函数
resource "aws_lambda_function" "test_lambda" {
  function_name    = "test-lambda-function"
  filename         = "./lambda_code.zip"
  handler          = "hello_world.handler" # 对应代码文件的函数入口
  role             = aws_iam_role.lambda_role.arn
  runtime          = "python3.9"
  memory_size      = 128
  timeout          = 30
  source_code_hash = data.archive_file.lambda_code.output_base64sha256
}

# ALB 执行角色:用于调用Lambda并访问日志
resource "aws_iam_role" "alb_role" {
  name = "alb-lambda-invoke-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = {
          Service = "elasticloadbalancing.amazonaws.com"
        }
        Action = "sts:AssumeRole"
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "alb_lambda_invoke" {
  role       = aws_iam_role.alb_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSElasticLoadBalancingRole"
}

# Lambda 权限:允许ALB目标组调用Lambda
resource "aws_lambda_permission" "alb_invoke" {
  statement_id  = "AllowALBInvoke"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.test_lambda.function_name
  principal     = "elasticloadbalancing.amazonaws.com"
  source_arn    = aws_lb_target_group.lambda_target_group.arn
}

# Lambda 类型的目标组
resource "aws_lb_target_group" "lambda_target_group" {
  name                 = "lambda-target-group"
  target_type          = "lambda"
  lambda_multi_value_headers_enable = true

  # 核心配置:指定ALB的执行角色,用于调用Lambda
  lambda_role_arn = aws_iam_role.alb_role.arn
}

# 关联Lambda到目标组
resource "aws_lb_target_group_attachment" "lambda_attachment" {
  target_group_arn = aws_lb_target_group.lambda_target_group.arn
  target_id        = aws_lambda_function.test_lambda.arn
}

# ALB 安全组:允许HTTP入站,全量出站
resource "aws_security_group" "alb_sg" {
  name        = "alb-access-sg"
  description = "Allow HTTP traffic to ALB"

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# Application Load Balancer
resource "aws_lb" "application_lb" {
  name               = "lambda-invoke-alb"
  internal           = false
  load_balancer_type = "application"
  subnets            = ["subnet-ce43c7b2", "subnet-6e119a22"] # 替换为你的可用子网
  security_groups    = [aws_security_group.alb_sg.id]
}

# ALB 监听器:转发请求到Lambda目标组
resource "aws_lb_listener" "alb_http_listener" {
  load_balancer_arn = aws_lb.application_lb.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.lambda_target_group.arn
  }
}

配套Lambda代码(./code/hello_world.py)

确保返回符合ALB要求的响应格式:

import json

def handler(event, context):
    return {
        "statusCode": 200,
        "headers": {
            "Content-Type": "application/json"
        },
        "body": json.dumps({
            "message": "Hello from Lambda via ALB!"
        })
    }

关键配置修正说明

  1. Lambda Handler修正:原配置handler = "provider.handler"错误,需与代码文件名和函数名对应,示例中为hello_world.handler
  2. Lambda角色权限补充:添加AWSLambdaBasicExecutionRole托管策略,确保Lambda能生成CloudWatch日志,便于排查执行错误
  3. ALB角色关联目标组:在aws_lb_target_group中指定lambda_role_arn,这是ALB调用Lambda的核心配置——ALB需通过该角色获取调用权限
  4. 权限策略优化:使用AWS托管策略AWSElasticLoadBalancingRole替代自定义策略,避免权限遗漏或过度授权
  5. 依赖关系简化:移除不必要的depends_on,利用Terraform隐式依赖保证资源创建顺序正确

内容的提问来源于stack exchange,提问作者MrTony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 06:43:13