The script is pretty basic -- no AWS authentication (so you'll need to provide an AWS access key ID and secret access key for an account with appropriate permissions), error handling, etc. But it works.
Here's the whole script. The comments explain some of the more interesting points.
#! /usr/bin/python2
from boto import ec2
from datetime import datetime
import time
COPY_FROM_REGION = 'us-east-1' # Region to copy from. Change this if you like.
COPY_TO_REGION = 'eu-west-1' # Region to copy to. Change this if you like.
AMI_ID = 'ami-XXXXXXXX' # Change this to the ID of the AMI you wish to copy. This AMI must already exist.
ec2_conn = ec2.connect_to_region(COPY_TO_REGION) # Boto 2 interface to EC2.
# Give the target AMI a unique name. Not truly necessary, but convenient. I chose seconds since epoch as a source
# of uniquness. The name can really be anything you want.
timestamp = int((datetime.utcnow() - datetime(1970, 1, 1)).total_seconds())
ami_name = 'eu-copy-of-{}-{}'.format(AMI_ID, timestamp)
print 'copying AMI to {}'.format(ami_name)
ec2_conn.copy_image(COPY_FROM_REGION, AMI_ID, name=ami_name) # Initiate copying.
# Now we wait...
while True:
# The image won't even show up in the target region for a while. Wait until it exists.
images = ec2_conn.get_all_images(filters={
'is-public': 'false',
'name': ami_name
})
if images:
image = images[0] # Now the image exists in the target region.
print image.id, image.state
# Now wait for the image to be in the "available" state. This could take a few minutes, especially if it's big.
while True:
images = ec2_conn.get_all_images(filters={
'is-public': 'false',
'name': ami_name,
'state': 'available'
})
if images:
print 'available'
break
print 'not available'
time.sleep(10)
break
print 'not found'
time.sleep(10)
One final tip: I wasn't able to find documentation of the properties of the image objects returned by get_all_images. But Python offers an easy solution: just print out image.__dict__.
Happy copying!