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

Cognito触发Lambda无DynamoDB数据且CloudWatch无日志求助

问题排查:Cognito触发Lambda无日志且未写入DynamoDB

问题描述

已将Cognito与DynamoDB表关联,通过Cognito触发Lambda函数实现数据直接写入表中,已配置必要权限并在函数中引入日志模块。目前遇到两个问题:

  1. 通过Hosted UI注册Cognito用户后,DynamoDB表中未生成任何数据;
  2. 无法在CloudWatch中找到该Lambda函数的日志。
  • 相同配置在朋友的账号中可正常运行,不清楚我的账号中问题出在哪里?

相关配置代码

Lambda函数代码

import json
import boto3
from datetime import datetime
import logging
import os

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

dynamodb = boto3.resource('dynamodb')
s3 = boto3.client('s3')

def read_items_from_dynamodb(table_name):
    table_name = os.environ["DYNAMODB_TABLE"]
    table = dynamodb.Table(table_name)
    
    response = table.scan()
    return response['Items']

def upload_to_s3(bucket_name, file_name, data):
    response = s3.put_object(Bucket=bucket_name, Key=file_name, Body=json.dumps(data))
    return response

def lambda_handler(event, context):
    
    try:
        logger.debug('## ENVIRONMENT VARIABLES')
        logger.debug(os.environ['LOG_BUCKET'])
        logger.debug(os.environ['DYNAMODB_TABLE'])
        logger.debug(os.environ['AWS_LAMBDA_LOG_GROUP_NAME'])
        logger.debug(os.environ['AWS_LAMBDA_LOG_STREAM_NAME'])
        logger.debug('## EVENT')
        logger.debug(event)


        items = []
        table_name = os.environ['DYNAMODB_TABLE']
        user_name = event['userName']
        trigger_source = event['triggerSource']
        user_attributes = event['request']['userAttributes']
        email = user_attributes.get('email', '')
        login_time = datetime.now().isoformat()
        status = 'success' if trigger_source == 'PostAuthentication_Authentication' else 'failed'


        logger.debug(f"Event: {event}")
        logger.debug(f"Read 2 {len(items)} items from DynamoDB")
        logger.debug(f"Putting item to table: {table_name}") 
        logger.debug(f"Item to be written: {items}")
        table_name = os.environ["DYNAMODB_TABLE"]
        table = dynamodb.Table(table_name)
        print(table)
        
        table.put_item(
                    TableName=table_name,Item={
                'user_id': user_name,
                'email': email,
                'login_time': login_time,
                'status': status    
            }
        )
        
        bucket_name = os.environ['LOG_BUCKET']
        items = read_items_from_dynamodb(table_name)
        logger.debug(f"Read {len(items)} items")
        file_name = 'dynamodb_items.json'
        upload_to_s3(bucket_name, file_name, items)

        return event
    except Exception as e:
        logger.exception("Error processing event")
        raise e

IAM Terraform配置

resource "aws_iam_role" "lambda_role" {
  name = "api-lambda-role"
  assume_role_policy = jsonencode(
    {
      "Version" : "2012-10-17",
      "Statement" : [
        {
          "Sid" : "",
          "Effect" : "Allow",
          "Principal" : {
            "Service" : "lambda.amazonaws.com"
          },
          "Action" : "sts:AssumeRole"
        }
      ]
    }
  )
}

resource "aws_iam_policy" "lambda_policy" {
  name        = "lambda-policy"
  description = "IAM policy for a lambda"
  policy = jsonencode(
    {
      "Version" : "2012-10-17",
      "Statement" : [
        {
          "Effect" : "Allow",
          "Action" : [
            "ec2:CreateNetworkInterface",
            "ec2:DescribeNetworkInterfaces",
            "ec2:DeleteNetworkInterface",
            "ec2:DescribeInstances",
            "ec2:AttachNetworkInterface",
            "ssm:PutParameter",
          "ssm:DeleteParameter",
          "ssm:GetParameterHistory",
          "ssm:GetParameter"
          ],
          "Resource" : "*"
        },
        {
          "Effect" : "Allow",
          "Action" : ["dynamodb:PutItem", "dynamodb:Scan"],
          "Resource" : "*"
        },
        {
          "Effect" : "Allow",
          "Action" : [
            "s3:PutObject",
            "s3:GetObject"
          ],
          "Resource" : ["arn:aws:s3:::mybucket", "arn:aws:s3:::mybucket/*"]

        },
        {
          "Effect" : "Allow",
          "Action" : [
            "logs:CreateLogGroup",
            "logs:CreateLogStream",
            "logs:DescribeLogGroups",
            "logs:DescribeLogStreams",
            "logs:PutLogEvents",
            "logs:GetLogEvents",
            "logs:FilterLogEvents"
          ],
          "Resource" : "*"
        },
        {
          "Effect" : "Allow",
          "Action" : "lambda:InvokeFunction",
          "Resource" : ["*"]
        }
      ]
    }
  )
}

resource "aws_iam_role_policy_attachment" "lambda_policy_attach" {
  role       = aws_iam_role.lambda_role.id
  policy_arn = aws_iam_policy.lambda_policy.id
}
resource "aws_iam_role_policy_attachment" "lambda_dynamodb" {
  role       = aws_iam_role.lambda_role.id
  policy_arn = "arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess"
}

resource "aws_iam_role_policy_attachment" "lambda_cognito" {
  role       = aws_iam_role.lambda_role.id
  policy_arn = "arn:aws:iam::aws:policy/AmazonCognitoPowerUser"
}
resource "aws_iam_role_policy_attachment" "full_admin" {
  role       = aws_iam_role.lambda_role.id
  policy_arn = "arn:aws:iam::aws:policy/AmazonS3FullAccess"
}

Lambda Terraform配置

resource "aws_lambda_permission" "allow_cognito" {
  statement_id  = "AllowExecutionFromCognito"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.myfunction.arn
  principal     = "cognito-idp.amazonaws.com"
  source_arn    = aws_cognito_user_pool.user_pool.arn
}

resource "aws_lambda_function" "myfunction" {
  filename         = data.archive_file.post_authentication.output_path  
  function_name    = "myfunction"
  role             = aws_iam_role.lambda_role.arn
  handler          = "myfunction.lambda_handler"
  runtime          = "python3.9"
  timeout          = 300
  source_code_hash = data.archive_file.post_authentication.output_base64sha256
  depends_on = [
    aws_iam_role_policy_attachment.lambda_policy_attach
  ]
  vpc_config {
    subnet_ids         = aws_subnet.public_subnets[*].id
    security_group_ids = ["${aws_security_group.vpc_endpoints.id}"]
  }
  environment {
    variables = {
      DYNAMODB_TABLE = aws_dynamodb_table.my_table.name
      LOG_BUCKET = aws_s3_bucket.bucket.id
      
  }
}
}

排查步骤

1. 确认Cognito触发器类型是否匹配

用户通过Hosted UI注册用户时,Cognito触发的是PostConfirmation_ConfirmSignUp触发器,而你的Lambda代码中仅当trigger_source == 'PostAuthentication_Authentication'时标记状态为success,若未将Lambda关联到Post confirmation触发器,注册动作根本不会触发Lambda。

  • 检查Cognito用户池的触发器配置:是否将Lambda关联到了Post confirmation触发器?
  • 若需要在注册时写入数据,需修改Lambda代码中的触发源判断逻辑,或调整Cognito触发器类型。

2. 检查Lambda的VPC网络配置

你的Lambda配置了VPC公网子网和安全组,网络不通会导致无法访问DynamoDB、CloudWatch和S3:

  • 确认安全组允许出站流量:需允许到DynamoDB(443端口)、CloudWatch Logs(443端口)、S3(443端口)的出站访问;
  • 确认公网子网是否关联了互联网网关(IGW),且Lambda能获取公网IP(或配置NAT网关);
  • 若使用VPC端点,需确认已创建DynamoDB、CloudWatch Logs的VPC端点,且安全组允许访问这些端点。

3. 验证Lambda是否被触发

  • 查看CloudTrail日志:搜索lambda:InvokeFunction事件,确认Cognito是否调用了你的Lambda;
  • 在Lambda控制台手动测试:传入模拟的Cognito触发事件(如PostConfirmation结构的事件),观察是否生成日志和写入数据。

4. 代码错误排查

  • table.put_item调用中同时传入了TableName参数,但通过dynamodb.Table(table_name)创建的对象调用put_item无需该参数,可能引发错误;
  • 手动测试Lambda时,查看是否有报错信息(若网络正常,CloudWatch会生成日志)。

5. 环境变量与权限验证

  • 确认Lambda的环境变量DYNAMODB_TABLE和LOG_BUCKET是否正确注入:在Lambda控制台查看环境变量值,是否与实际的DynamoDB表名、S3桶名一致;
  • 使用IAM Access Analyzer检查角色权限:确认角色拥有足够权限访问所需资源,特别是VPC相关权限(如创建弹性网卡)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:52:32