亚马逊AWS官方博客

使用 Amazon EventBridge 与 AWS Lambda 实现 ALB 流量镜像会话自动化配置

摘要:在使用 AWS Traffic Mirror 对 ALB 流量进行监控时,ALB 的 ENI(弹性网络接口)是动态变化的——每当 ALB 扩容到新可用区或重建时,都需要手动为新 ENI 配置 Traffic Mirror Session。本文介绍一种基于 CloudTrail + EventBridge + Lambda 的事件驱动方案,实现自动配置,并支持标签合规。


1. 背景与挑战

1.1 Traffic Mirror 与 ALB 的动态 ENI 问题

AWS Traffic MirrorAmazon VPC 的一项功能,可以将 ENI 上的网络流量复制到安全和监控设备,广泛用于入侵检测、流量分析和合规审计等场景。

然而,ALB 的 ENI 具有动态性:

  • ALB 在每个可用区(AZ)各创建一个 ENI
  • 当 ALB 扩展到新 AZ 时,会自动创建新的 ENI
  • ALB 重建或更新时,ENI 也会随之变化

在多 ALB、多 AZ 的生产环境中,手动配置极易遗漏,导致部分流量无法被监控。

1.2 企业标签合规要求

企业内部通常还有资源标签规范要求:Name 标签使用 ALB 名称,并打上指定的业务标签。手动操作时,标签的一致性难以保证。

2. 解决方案架构

2.1 整体架构

本方案采用事件驱动架构,完整链路如下图所示:

2.2 方案优势

特性 说明
全自动 ALB 创建后无需人工干预,Session 自动配置
精准过滤 支持通配符模式,只监控目标 ALB
标签合规 Session 自动打上规范标签,保证一致性
幂等安全 重复触发时检查已有 Session,不重复创建
全托管 基于 Lambda + EventBridge,无需维护服务器
一键部署 完整 CloudFormation 模板,参数化配置

2.3 AWS 服务组成

  • AWS CloudTrail:记录 EC2 API 调用,是事件链路的数据源(需提前开启 Management Events)
  • Amazon EventBridge:监听 CloudTrail 事件,过滤 CreateNetworkInterface 调用并触发 Lambda
  • AWS Lambda:执行核心业务逻辑(Python 3.9)
  • Amazon CloudWatch Logs:Lambda 执行日志,保留 30 天

3. 环境准备

3.1 前提条件

  • AWS 账号,且目标 Region 已开启 CloudTrail(Management Events 记录)
  • 已创建 Traffic Mirror Target(tmt-xxx)和 Traffic Mirror Filter(tmf-xxx
  • 具备 CloudFormation 部署权限

3.2 确认 Traffic Mirror 资源

# 查看已有 Mirror Target
aws ec2 describe-traffic-mirror-targets --region us-east-1 \
  --query 'TrafficMirrorTargets[].[TrafficMirrorTargetId,Description]' \
  --output table

# 查看已有 Mirror Filter
aws ec2 describe-traffic-mirror-filters --region us-east-1 \
  --query 'TrafficMirrorFilters[].[TrafficMirrorFilterId,Description]' \
  --output table

4. 核心实现

4.1 CloudFormation 模板结构

资源类型 资源名称 说明
AWS::IAM::Role ALBENIMonitorRole Lambda 执行角色
AWS::Lambda::Function ALBENIMonitorFunction 核心处理函数
AWS::Events::Rule ALBENIChangeMonitorRule EventBridge 规则
AWS::Lambda::Permission LambdaPermissionForEventBridge 授权 EventBridge 调用 Lambda
AWS::Logs::LogGroup ALBENIMonitorLogGroup CloudWatch 日志组

模板参数:

参数 说明 默认值
ALBDNSPatterns ALB 名称匹配模式,逗号分隔,支持通配符 my-alb*
TrafficMirrorTargetId Mirror Target ID(必填)
TrafficMirrorFilterId Mirror Filter ID(必填)
SessionNumber Session 优先级编号 100
LambdaTimeout Lambda 超时时间(秒) 30
LambdaMemorySize Lambda 内存(MB) 128

4.2 Lambda 核心逻辑

4.2.1 步骤一:解析 ENI 归属的 ALB 名称

现代格式:ELB app/{alb-name}/{hash}
旧格式:  ELB {alb-name}
if ' app/' in description or ' net/' in description:
    # 现代格式:ELB app/my-alb-prod/4b11d32e → my-alb-prod
    alb_full_name = description.split('/')[1]
else:
    # 旧格式:ELB my-alb-prod → my-alb-prod
    alb_full_name = description.replace('ELB ', '').strip()

4.2.2 步骤二:通配符模式匹配

import fnmatch
patterns = [p.strip() for p in ALB_DNS_PATTERNS.split(',') if p.strip()]
matched = False
for pattern in patterns:
    if fnmatch.fnmatch(alb_full_name.lower(), pattern.lower()):
        matched = True
        break
模式 匹配示例
prod-alb-* prod-alb-webprod-alb-api
*-staging-* app-staging-v2api-staging-v1
my-alb-001 精确匹配 my-alb-001
* 匹配所有 ALB

4.2.3 步骤三:等待 ENI 就绪

def wait_for_eni_attached(ec2_client, eni_id, max_attempts=12, delay=10):
    for attempt in range(max_attempts):
        response = ec2_client.describe_network_interfaces(
            NetworkInterfaceIds=[eni_id])
        eni = response['NetworkInterfaces'][0]
        status = eni.get('Status')
        attachment_state = eni.get('Attachment', {}).get('Status', 'none')
        if status == 'in-use' and attachment_state == 'attached':
            return True
        time.sleep(delay)  # 每次等待 10 秒,最多 120 秒
    return False

4.2.4 步骤四:创建 Traffic Mirror Session(含合规标签)

session_response = ec2_client.create_traffic_mirror_session(
    NetworkInterfaceId=eni_id,
    TrafficMirrorTargetId=TRAFFIC_MIRROR_TARGET_ID,
    TrafficMirrorFilterId=TRAFFIC_MIRROR_FILTER_ID,
    SessionNumber=SESSION_NUMBER,
    Description=f'ALB ENI {eni_id} Traffic Mirror Session',
    TagSpecifications=[{
        'ResourceType': 'traffic-mirror-session',
        'Tags': [
            {'Key': 'Name',         'Value': alb_full_name},   # ALB 名称
            {'Key': 'custom_tag_1', 'Value': 'your-value-1'},  # 自定义业务标签
            {'Key': 'custom_tag_2', 'Value': 'your-value-2'},
            {'Key': 'custom_tag_3', 'Value': 'your-value-3'},
            {'Key': 'AutoCreated',  'Value': 'true'}
        ]
    }]
)

ℹ️ 注意:

Name 标签使用 ALB 完整名称(如 prod-alb-web),而非 ENI ID。custom_tag_* 可替换为企业内部资源管理系统要求的标签键值对。

4.3 EventBridge 规则配置

EventPattern:
  source:
    - aws.ec2
  detail-type:
    - 'AWS API Call via CloudTrail'
  detail:
    eventSource:
      - ec2.amazonaws.com
    eventName:
      - CreateNetworkInterface
      - DeleteNetworkInterface       # 预留
      - ModifyNetworkInterfaceAttribute  # 预留

4.4 IAM 权限

Action:
  - ec2:DescribeNetworkInterfaces
  - ec2:DescribeTrafficMirrorSessions
  - ec2:DescribeTrafficMirrorTargets
  - ec2:DescribeTrafficMirrorFilters
  - ec2:CreateTrafficMirrorSession
  - ec2:DeleteTrafficMirrorSession
  - ec2:CreateTrafficMirrorTarget
  - ec2:DeleteTrafficMirrorTarget
  - ec2:CreateTags

5. 部署与验证

5.1 部署监控系统

aws cloudformation create-stack \
  --stack-name alb-eni-monitor \
  --template-body file://alb-monitor.yaml \
  --parameters \
    ParameterKey=ALBDNSPatterns,ParameterValue="prod-alb-*,api-gw-*" \
    ParameterKey=TrafficMirrorTargetId,ParameterValue="tmt-0123456789abcdef0" \
    ParameterKey=TrafficMirrorFilterId,ParameterValue="tmf-0123456789abcdef0" \
  --capabilities CAPABILITY_IAM \
  --region us-east-1

# 等待部署完成
aws cloudformation wait stack-create-complete \
  --stack-name alb-eni-monitor --region us-east-1

5.2 验证端到端流程

部署完成后,创建一个名称匹配监控模式的 ALB,观察系统自动响应。

5.2.1 确认 Lambda 被触发

aws logs tail /aws/lambda/ALBENIMonitorFunction --follow --region us-east-1

正常执行的关键日志:

[INFO] Matched ALB ENI: prod-alb-web with pattern(s): prod-alb-*
[INFO] Found new ALB ENI: eni-0123456789abcdef0
[INFO] ENI eni-0123456789abcdef0 is now in-use and attached
[INFO] Creating Traffic Mirror session for ENI eni-0123456789abcdef0
[INFO] Created Traffic Mirror session tms-0123456789abcdef0 for ALB prod-alb-web

5.2.2 验证 Session 创建及标签

aws ec2 describe-traffic-mirror-sessions --region us-east-1 \
  --query 'TrafficMirrorSessions[].[TrafficMirrorSessionId,NetworkInterfaceId,Tags]' \
  --output json

5.3 端到端测试结果

在 us-east-1 环境的实际测试中,创建跨 2 个 AZ 的 ALB,系统自动完成以下操作:

步骤 时间 结果
ALB 创建,ENI 触发 T+0s EventBridge 自动触发 Lambda
Lambda 匹配 ALB 名称 T+4s 模式匹配成功
等待 ENI attached T+90s ENI 进入 in-use 状态
Session 创建完成 T+92s 2 个 Session 均创建成功

Session 标签验证结果:

标签 Key 期望值 结果
Name ALB 名称 ✅ 通过
custom_tag_1 自定义值 ✅ 通过
custom_tag_2 自定义值 ✅ 通过
custom_tag_3 自定义值 ✅ 通过
AutoCreated true ✅ 通过

6. 关键技术细节

6.1 Lambda 超时与 EventBridge 重试机制

Lambda 默认超时 30 秒,但 ENI 从创建到 attached 状态通常需要 60-120 秒。Lambda 第一次执行时往往会超时。

这里利用了 EventBridge 的自动重试机制:Lambda 执行失败后,EventBridge 约 1 分钟后自动重试,此时 ENI 通常已就绪。

如需在单次执行内完成,可将 LambdaTimeout 参数设置为 150(秒)。

6.2 幂等性保证

existing_sessions = ec2_client.describe_traffic_mirror_sessions(
    Filters=[{'Name': 'network-interface-id', 'Values': [eni_id]}]
)
if existing_sessions.get('TrafficMirrorSessions'):
    # 已有 Session,直接返回,不重复创建
    return existing_sessions['TrafficMirrorSessions'][0]['TrafficMirrorSessionId']

6.3 ALB 名称解析的注意事项

# ✅ 正确:使用 ' app/' 和 ' net/'(带前置空格)
if ' app/' in description or ' net/' in description:

# ❌ 错误:使用 '/app/' 和 '/net/'(不带前置空格)
# 会导致 ALB 名称解析失败
if '/app/' in description or '/net/' in description:

7. 总结

方面 说明
触发机制 事件驱动,ALB 创建 ENI 时自动响应,无需轮询
过滤能力 通配符模式匹配,精准控制监控范围
标签合规 Session 自动打标,Name 使用 ALB 名称,支持自定义业务标签
可靠性 幂等设计 + EventBridge 自动重试,保证最终一致
运维成本 全 Serverless,无需维护基础设施
部署方式 单一 CloudFormation 模板,参数化配置,一键部署

完整 CloudFormation 模板:alb-eni-monitor-cf-template.yaml(GitHub)

➡️ 下一步行动:

相关产品:

相关文章:

8. 参考资料

*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。

本篇作者

韩坤尧

亚马逊云科技解决方案架构师,负责基于亚马逊云科技方案架构的咨询、设计和评估。在运维、安全、网络方面有丰富的经验,目前侧重于AI/大数据领域的研究。在加入 AWS 之前曾就职于 Juniper、Cisco 等公司,担任高级系统工程师,主要服务于国内外企业客户。

张振华

亚马逊云科技解决方案架构师,负责基于亚马逊云科技的云计算方案的架构和设计,在 Edge、Serverless 、容器化,微服务架构,云原生 DevOps 等方向具有丰富的实践经验。自加入亚马逊云科技后,专注于游戏行业,以及 GenAI 在游戏行业的应用。


AWS 架构师中心:云端创新的引领者

探索 AWS 架构师中心,获取经实战验证的最佳实践与架构指南,助您高效构建安全、可靠的云上应用