使用Lambda函数获取IAM访问密钥时长触发NameError错误排查
解决AWS Lambda中NameError: name 'days_remaining' is not defined错误
问题原因
- 变量作用域错误:
days_remaining是在lambda_handler函数内部定义的局部变量,函数外部的print和消息拼接代码无法访问该变量。Lambda执行时会先运行函数外的代码,此时days_remaining尚未定义,直接引用就会触发NameError。 - 逻辑缺陷:即使修复作用域,原代码只会保留最后一个用户的剩余天数,无法对应每个告警用户的实际情况;如果没有符合条件的用户或用户列表为空,
days_remaining根本不会被初始化,同样会报错。
修复方案
把所有业务逻辑移到lambda_handler函数内部,调整告警逻辑,为每个用户单独计算剩余天数并收集告警信息,同时处理用户无访问密钥的异常情况。
修复后的Lambda代码:
import os import boto3 from datetime import date min_age = 10 max_age = 90 user_list = [] slackchannel = os.environ['slackchannel'] hook_url = os.environ['hook_url'] account_id = boto3.client("sts").get_caller_identity()["Account"] user = f'user-{account_id}' def lambda_handler(event, context): client = boto3.client('iam') response = client.list_users() for x in response['Users']: if x['UserName'] != user: user_list.append(x['UserName']) # 收集每个告警用户的信息 alert_messages = [] for username in user_list: try: res = client.list_access_keys(UserName=username) # 处理用户有多个访问密钥的情况 for key in res['AccessKeyMetadata']: accesskeydate = key['CreateDate'].date() currentdate = date.today() active_days = (currentdate - accesskeydate).days days_remaining = max_age - active_days # 到期前70天触发告警,即剩余天数<=70 if days_remaining <= 70 and active_days > min_age: alert_messages.append(f"用户 {username} 的访问密钥剩余有效天数:{days_remaining} 天") except Exception as e: print(f"处理用户 {username} 时出错:{str(e)}") continue # 生成最终消息 if alert_messages: message = f"账号 {account_id} 中发现以下用户的访问密钥即将到期:\n" + "\n".join(alert_messages) else: message = f"账号 {account_id} 中没有需要告警的访问密钥" print(message) # 这里可以添加发送Slack告警的逻辑,比如调用hook_url发送消息 # import requests # slack_message = {"channel": slackchannel, "text": message} # requests.post(hook_url, json=slack_message) return { 'statusCode': 200, 'body': message }
额外说明
- 新增了多访问密钥的处理:原代码只取第一个密钥,现在遍历用户所有的访问密钥。
- 添加了异常捕获:避免因用户无访问密钥或其他API调用错误导致Lambda执行失败。
- 调整告警触发条件:原代码逻辑是活跃天数大于min_age,但需求是到期前70天告警,所以判断条件改为
days_remaining <=70,更符合需求。 - 所有逻辑都在函数内部执行,彻底避免了作用域问题。
内容的提问来源于stack exchange,提问作者Santosh Garole
相关产品推荐
相关产品推荐

