Lambda 调用未处理,3 秒后超时?

问题描述 投票:0回答:1

通过 terraform 定义以下 lambda 函数和 dynamodb:

provider "aws" {
  region                  = "us-east-1"  # Change to your desired region
  access_key              = "test"       # Access key for LocalStack
  secret_key              = "test"       # Secret key for LocalStack
  skip_credentials_validation = true
  skip_requesting_account_id = true

  endpoints {
    dynamodb    = "http://localhost:4566"  # LocalStack DynamoDB endpoint
    lambda      = "http://localhost:4566"
    iam         = "http://localhost:4566"
  }
}

resource "aws_iam_role" "lambda_execution_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_dynamodb_access" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess"
  role       = aws_iam_role.lambda_execution_role.name
}

resource "aws_iam_role_policy" "lambda_execution_policy" {
  name   = "lambda_execution_policy"
  role   = aws_iam_role.lambda_execution_role.id

  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Action = [
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents"
        ],
        Effect   = "Allow",
        Resource = "*"
      },
      {
        Action   = "lambda:InvokeFunction",
        Effect   = "Allow",
        Resource = aws_lambda_function.add_user_post.arn
      }
      # Add more permissions as needed
    ]
  })
}

resource "aws_lambda_function" "add_user_post" {
  function_name = "AddUserPost"
  handler       =   "addUserPostFunction.lambda_handler"
  runtime       = "python3.8"
  filename      = data.archive_file.lambda_function_add_user_post.output_path  # ZIP file containing your Python code
  role          = aws_iam_role.lambda_execution_role.arn
  source_code_hash = filebase64sha256(data.archive_file.lambda_function_add_user_post.output_path)

  environment {
    variables = {
      TABLE_NAME = "UserProfileTable"
    }
  }
}

data "archive_file" "lambda_function_add_user_post" {
  type          = "zip"
  source_dir    = "${path.module}/Source"
  output_path   = "${path.module}/lambda_function_add_user_post.zip"


}

DynamoDB:

 provider "aws" {
      region                  = "us-east-1"  # Change to your desired region
      access_key              = "test"       # Access key for LocalStack
      secret_key              = "test"       # Secret key for LocalStack
      skip_credentials_validation = true
      skip_requesting_account_id = true
    
    
      endpoints {
        dynamodb    = "http://localhost:4566"  # LocalStack DynamoDB endpoint
        lambda      = "http://localhost:4566"
      }
    }
    
    resource "aws_dynamodb_table" "users_table" {
      name           = "UserProfileTable"
      billing_mode   = "PROVISIONED"  # Or use "PAY_PER_REQUEST" for on-demand capacity
      read_capacity  = 5
      write_capacity = 5
      hash_key = "UserID"
      range_key = "PostID"
    
      attribute {
        name = "UserID"
        type = "N"
      }
    
      attribute {
        name = "PostID"
        type = "N"
      }
    
    
    
      tags = {
        Name    = "dynamodb-table-1"
        Environment = "production"
      }
    }

然后是 lambda 执行的 .py 函数:

import boto3
import os


dynamodb = boto3.resource('dynamodb', region_name='us-east-1', endpoint_url='http://localhost:4566')

def lambda_handler(event, context):
    try:
        # Your DynamoDB table name
        table_name = os.environ["TABLE_NAME"]

        # Sample data to be added to DynamoDB
        item = {
            'userid': '1',
            'postid': '1',
            'content': 'Yay!',
        }

        # DynamoDB put operation
        table = dynamodb.Table(table_name)
        result = table.put_item(Item=item)

        print('Item added to DynamoDB:', result)

        return {
            'statusCode': 200,
            'body': 'Item added to DynamoDB successfully',
        }
    except Exception as e:
        print('Error adding item to DynamoDB:', e)

        return {
            'statusCode': 500,
            'body': 'Error adding item to DynamoDB',
        }

Terraform apply
两个基础设施组件不会产生任何错误,我可以通过
awslocal dynamodb list-tables
awslocal lambda list-functions
检查它们是否存在,并且它们返回预期值。

但是,跑步时:

awslocal --endpoint-url=http://localhost:4566 lambda invoke --function-name AddUserPost --payload '{}' output.json

我明白了

{
    "StatusCode": 200,
    "FunctionError": "Unhandled",
    "ExecutedVersion": "$LATEST"
}

output.json
产生:
{"errorMessage":"2024-02-10T16:42:23Z cd163c6c-75d4-4be2-9539-cec447c3624a Task timed out after 3.00 seconds"}

unhandled
函数错误让我认为问题出在 lambda 函数中定义的处理程序,但我已经检查了三次它的语法/拼写,我很确定它是正确的。不知道如何继续。

python aws-lambda terraform amazon-dynamodb localstack
1个回答
0
投票

错误似乎出在您尝试放入 DynamoDB 中的数据中

在表属性声明中我们可以看到:

      attribute {
        name = "UserID"
        type = "N"
      }
    
      attribute {
        name = "PostID"
        type = "N"
      }

当我们致电

table.put_item(Item=item)

时,您必须保留同样的箱子

我让它像这样工作:

        item = {
            'UserID': 1,
            'PostID': 1,
            'content': 'Yay!',
        }

我可以在表中看到正确创建的项目:

© www.soinside.com 2019 - 2024. All rights reserved.