I implemented lambda function like this
import boto3
import os
from datetime import datetime
def lambda_handler(event, context):
ec2 = boto3.client('ec2')
instance_ids = os.environ['INSTANCE_IDS'].split(",")
for instance_id in instance_ids:
new_ami = ec2.create_image(
InstanceId=instance_id,
Name=f"Backup-{instance_id}-{datetime.now().strftime('%Y-%m-%d-%H-%M-%S')}",
NoReboot=True
)
new_ami_id = new_ami['ImageId']
waiter = ec2.get_waiter('image_available')
waiter.wait(ImageIds=[new_ami_id])
print(f"AMI {new_ami_id} is now available")
encrypted_ami = ec2.copy_image(
SourceImageId=new_ami_id,
SourceRegion=context.invoked_function_arn.split(":")[3],
Name=f"Encrypted-Backup-{instance_id}-{datetime.now().strftime('%Y-%m-%d-%H-%M-%S')}",
Encrypted=True
)
return {"status": "AMIs created, encrypted, and old AMIs managed"}
Since taking a snapshot ec2.get_waiter
requires considerable amount of time the function times out even if I put maximum amount of ms. What is the correct flow to achieve this task?
You should split the Lambda function into two separate Lambda functions, one that creates the AMI, and another function that performs the AMI copy.
To automatically trigger the second Lambda function when the AMI has been created, you would configure an EventBridge rule to trigger the Lambda function when an AMI event occurs with a State
value of available
. You could add a filter to the rule to only trigger when the AMI name starts with Backup
.