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

求助:使用Python通过AWS Lambda获取带Period:active标签的EC2实例运行时长并发送SNS通知时仅返回单个实例

问题排查与代码修复:获取所有符合标签的EC2实例运行时长并发送SNS通知

我帮你梳理下代码里的几个关键问题,这些问题导致你只拿到了单个实例的信息,甚至可能出现逻辑错误:


核心问题分析

  1. 区域配置不一致
    你在函数外定义了region='ap-south-1',但在lambda_handler里又重新初始化了ec2 = boto3.resource('ec2'),没有传入区域参数。这会导致EC2资源默认使用你的AWS账号默认区域,可能不是你需要的ap-south-1,进而获取的实例不全。

  2. 错误的循环逻辑
    第二个循环for x in active:完全是错误的——active是你拼接的字符串,这个循环会遍历字符串的每个字符,而不是遍历实例。同时timeDiff变量只保留了最后一个实例的运行时长,所以你只会判断最后一个实例是否满足条件,还会重复发送N次SNS通知(N是字符串的字符数)。

  3. 时间计算冗余且易出错
    你把启动时间和当前时间转成字符串再解析回datetime对象,完全没必要,直接用datetime对象做减法更高效准确。


修复后的完整代码

import json
import boto3
from datetime import datetime

# 把固定配置抽成常量,方便维护
REGION = 'ap-south-1'
SNS_TOPIC_ARN = 'arn:aws:sns:ap-south-1:123456789:SNS-Notification'

def lambda_handler(event, context):
    # 统一初始化带区域的EC2资源和SNS客户端
    ec2 = boto3.resource('ec2', region_name=REGION)
    sns = boto3.client('sns', region_name=REGION)
    
    # 过滤带有Period:active标签的实例
    instances = ec2.instances.filter(Filters=[{'Name':'tag:Period', 'Values':['active']}])
    
    active_instances_info = []
    current_time = datetime.now()  # 只获取一次当前时间,保证所有实例的时间基准一致
    
    for instance in instances:
        # 直接用datetime对象计算运行时长,避免字符串转换的冗余
        running_hours = (current_time - instance.launch_time).total_seconds() / 3600.0
        
        # 拼接单个实例的信息
        instance_details = (
            f"\nInstance Id : {instance.id}"
            f"\nInstance Start Time : {instance.launch_time.strftime('%Y-%m-%d %H:%M:%S')}"
            f"\nCurrent Time : {current_time.strftime('%Y-%m-%d %H:%M:%S')}"
            f"\nRunning Time : {round(running_hours, 2)} hours\n\n"
        )
        active_instances_info.append(instance_details)
    
    # 只有当存在符合条件的实例时才发送通知
    if active_instances_info:
        # 合并所有实例信息,发送一次SNS通知
        message = "Current Active Instances:\n" + "".join(active_instances_info)
        response = sns.publish(
            TopicArn=SNS_TOPIC_ARN,
            Message=message
        )
        return response
    else:
        return {"message": "No active instances found with Period:active tag"}

额外说明(按需调整)

如果你想单独通知每个运行时长超过8小时的实例,可以在遍历实例的循环里添加判断逻辑,替换上面的合并发送逻辑:

# 在for instance in instances:循环内添加
if running_hours >= 8.0:
    sns.publish(
        TopicArn=SNS_TOPIC_ARN,
        Message=f"Long-running active instance detected:\n{instance_details}"
    )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 20:03:09