Cognito触发Lambda无DynamoDB数据且CloudWatch无日志求助
问题排查:Cognito触发Lambda无日志且未写入DynamoDB
问题描述
已将Cognito与DynamoDB表关联,通过Cognito触发Lambda函数实现数据直接写入表中,已配置必要权限并在函数中引入日志模块。目前遇到两个问题:
- 通过Hosted UI注册Cognito用户后,DynamoDB表中未生成任何数据;
- 无法在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
相关产品推荐
相关产品推荐

