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

如何实现创建并复制加密AMI的正确流程以避免Lambda超时?

Lambda实现EC2 AMI备份加密的正确流程

你的问题核心是单个Lambda同步等待AMI创建完成导致超时——Lambda最长仅支持15分钟超时,而AMI创建(尤其是大实例)往往会超过这个时间。正确的做法是把任务拆成异步触发+事件驱动的多阶段流程,避免长时间阻塞。

具体实现步骤

1. 拆分任务为两个独立Lambda

把原函数拆成两个职责单一的Lambda,通过事件触发衔接:

  • Lambda 1:初始化AMI创建:仅负责触发EC2创建AMI,记录关键信息到DynamoDB后立即结束,不等待AMI完成。
  • Lambda 2:处理加密复制:当AMI状态变为available时,自动触发该Lambda执行加密复制操作。

2. 用DynamoDB追踪AMI状态

创建一个DynamoDB表(比如ami-backup-tracker),主键设为ami_id(字符串类型),用于记录每个AMI的实例ID、所属区域、创建时间、状态等信息,确保后续能准确识别我们需要处理的AMI。

3. 配置EventBridge监听AMI状态变化

通过EventBridge监听EC2的EC2 Image State-change Notification事件,当AMI状态变为available时,自动触发第二个Lambda。


代码实现

Lambda 1:初始化AMI创建

import boto3
import os
from datetime import datetime

def lambda_handler(event, context):
    ec2 = boto3.client('ec2')
    dynamodb = boto3.resource('dynamodb')
    tracker_table = dynamodb.Table(os.environ['AMI_TRACKER_TABLE'])
    
    instance_ids = os.environ['INSTANCE_IDS'].split(",")
    current_region = context.invoked_function_arn.split(":")[3]
    
    for instance_id in instance_ids:
        ami_name = f"Backup-{instance_id}-{datetime.now().strftime('%Y-%m-%d-%H-%M-%S')}"
        # 触发AMI创建,立即返回,不等待
        create_response = ec2.create_image(
            InstanceId=instance_id,
            Name=ami_name,
            NoReboot=True
        )
        new_ami_id = create_response['ImageId']
        
        # 把AMI信息写入DynamoDB追踪
        tracker_table.put_item(
            Item={
                'ami_id': new_ami_id,
                'instance_id': instance_id,
                'region': current_region,
                'status': 'pending',
                'created_at': datetime.now().isoformat()
            }
        )
        print(f"已触发实例 {instance_id} 的AMI创建,ID:{new_ami_id}")
    
    return {"status": "所有AMI创建任务已触发"}

Lambda 2:加密复制可用的AMI

import boto3
import os
from datetime import datetime

def lambda_handler(event, context):
    ec2 = boto3.client('ec2')
    dynamodb = boto3.resource('dynamodb')
    tracker_table = dynamodb.Table(os.environ['AMI_TRACKER_TABLE'])
    
    # 从EventBridge事件中提取AMI信息
    event_detail = event['detail']
    target_ami_id = event_detail['image-id']
    source_instance_id = event_detail['source-instance-id']
    current_region = context.invoked_function_arn.split(":")[3]
    
    # 仅处理状态为available的AMI
    if event_detail['state'] != 'available':
        return {"status": f"AMI {target_ami_id} 状态不是available,跳过处理"}
    
    # 验证该AMI是我们追踪的任务
    tracker_response = tracker_table.get_item(Key={'ami_id': target_ami_id})
    if 'Item' not in tracker_response:
        return {"status": f"AMI {target_ami_id} 不在追踪列表中,跳过处理"}
    
    # 执行加密复制
    encrypted_ami_name = f"Encrypted-Backup-{source_instance_id}-{datetime.now().strftime('%Y-%m-%d-%H-%M-%S')}"
    copy_response = ec2.copy_image(
        SourceImageId=target_ami_id,
        SourceRegion=current_region,
        Name=encrypted_ami_name,
        Encrypted=True
    )
    encrypted_ami_id = copy_response['ImageId']
    
    # 更新DynamoDB中的状态
    tracker_table.update_item(
        Key={'ami_id': target_ami_id},
        UpdateExpression="set status = :new_status, encrypted_ami_id = :enc_id",
        ExpressionAttributeValues={
            ':new_status': 'encrypted',
            ':enc_id': encrypted_ami_id
        }
    )
    print(f"已完成AMI {target_ami_id} 的加密复制,新AMI ID:{encrypted_ami_id}")
    
    # 可选:添加旧AMI清理逻辑,比如删除7天前的非加密AMI
    # 这里可以根据保留策略实现
    
    return {"status": f"加密AMI {encrypted_ami_id} 创建成功"}

EventBridge规则配置

  1. 创建新规则,选择事件模式
  2. 事件源选择AWS EC2,事件类型选择EC2 Image State-change Notification
  3. 事件模式JSON如下:
{
  "source": ["aws.ec2"],
  "detail-type": ["EC2 Image State-change Notification"],
  "detail": {
    "state": ["available"]
  }
}
  1. 目标选择第二个Lambda函数,完成配置。

权限注意事项

  • Lambda 1需要权限:ec2:CreateImage、dynamodb:PutItem
  • Lambda 2需要权限:ec2:CopyImage、dynamodb:GetItem、dynamodb:UpdateItem
  • EventBridge需要权限触发Lambda 2

内容的提问来源于stack exchange,提问作者Max Koretskyi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 11:24:50