def deregister_image(module, ec2): """ Deregisters AMI """ image_id = module.params.get('image_id') delete_snapshot = module.params.get('delete_snapshot') wait = module.params.get('wait') wait_timeout = int(module.params.get('wait_timeout')) img = ec2.get_image(image_id) if img is None: module.fail_json(msg="Image %s does not exist" % image_id, changed=False) # Get all associated snapshot ids before deregistering image otherwise this information becomes unavailable snapshots = [] if hasattr(img, 'block_device_mapping'): for key in img.block_device_mapping: snapshots.append(img.block_device_mapping[key].snapshot_id) # When trying to re-delete already deleted image it doesn't raise an exception # It just returns an object without image attributes if hasattr(img, 'id'): try: params = {'image_id': image_id, 'delete_snapshot': delete_snapshot} ec2.deregister_image(**params) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) else: module.exit_json(msg="Image %s has already been deleted" % image_id, changed=False) # wait here until the image is gone img = ec2.get_image(image_id) wait_timeout = time.time() + wait_timeout while wait and wait_timeout > time.time() and img is not None: img = ec2.get_image(image_id) time.sleep(3) if wait and wait_timeout <= time.time(): # waiting took too long module.fail_json( msg="timed out waiting for image to be deregistered/deleted") # Boto library has hardcoded the deletion of the snapshot for the root volume mounted as '/dev/sda1' only # Make it possible to delete all snapshots which belong to image, including root block device mapped as '/dev/xvda' if delete_snapshot: try: for snapshot_id in snapshots: ec2.delete_snapshot(snapshot_id) except boto.exception.BotoServerError as e: if e.error_code == 'InvalidSnapshot.NotFound': # Don't error out if root volume snapshot was already deleted as part of deregister_image pass module.exit_json(msg="AMI deregister/delete operation complete", changed=True, snapshots_deleted=snapshots) else: module.exit_json(msg="AMI deregister/delete operation complete", changed=True)
def deregister_image(module, ec2): """ Deregisters AMI """ image_id = module.params.get('image_id') delete_snapshot = module.params.get('delete_snapshot') wait = module.params.get('wait') wait_timeout = int(module.params.get('wait_timeout')) img = ec2.get_image(image_id) if img is None: module.fail_json(msg="Image %s does not exist" % image_id, changed=False) # Get all associated snapshot ids before deregistering image otherwise this information becomes unavailable snapshots = [] if hasattr(img, 'block_device_mapping'): for key in img.block_device_mapping: snapshots.append(img.block_device_mapping[key].snapshot_id) # When trying to re-delete already deleted image it doesn't raise an exception # It just returns an object without image attributes if hasattr(img, 'id'): try: params = {'image_id': image_id, 'delete_snapshot': delete_snapshot} ec2.deregister_image(**params) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) else: module.exit_json(msg="Image %s has already been deleted" % image_id, changed=False) # wait here until the image is gone img = ec2.get_image(image_id) wait_timeout = time.time() + wait_timeout while wait and wait_timeout > time.time() and img is not None: img = ec2.get_image(image_id) time.sleep(3) if wait and wait_timeout <= time.time(): # waiting took too long module.fail_json(msg="timed out waiting for image to be deregistered/deleted") # Boto library has hardcoded the deletion of the snapshot for the root volume mounted as '/dev/sda1' only # Make it possible to delete all snapshots which belong to image, including root block device mapped as '/dev/xvda' if delete_snapshot: try: for snapshot_id in snapshots: ec2.delete_snapshot(snapshot_id) except boto.exception.BotoServerError as e: if e.error_code == 'InvalidSnapshot.NotFound': # Don't error out if root volume snapshot was already deleted as part of deregister_image pass module.exit_json(msg="AMI deregister/delete operation complete", changed=True, snapshots_deleted=snapshots) else: module.exit_json(msg="AMI deregister/delete operation complete", changed=True)
def update_image(module, ec2, image_id): """ Updates AMI """ launch_permissions = module.params.get('launch_permissions') or [] if 'user_ids' in launch_permissions: launch_permissions['user_ids'] = [str(user_id) for user_id in launch_permissions['user_ids']] img = ec2.get_image(image_id) if img is None: module.fail_json(msg = "Image %s does not exist" % image_id, changed=False) try: set_permissions = img.get_launch_permissions() if set_permissions != launch_permissions: if (('user_ids' in launch_permissions and launch_permissions['user_ids']) or ('group_names' in launch_permissions and launch_permissions['group_names'])): res = img.set_launch_permissions(**launch_permissions) elif ('user_ids' in set_permissions and set_permissions['user_ids']) or ('group_names' in set_permissions and set_permissions['group_names']): res = img.remove_launch_permissions(**set_permissions) else: module.exit_json(msg="AMI not updated", launch_permissions=set_permissions, changed=False) module.exit_json(msg="AMI launch permissions updated", launch_permissions=launch_permissions, set_perms=set_permissions, changed=True) else: module.exit_json(msg="AMI not updated", launch_permissions=set_permissions, changed=False) except boto.exception.BotoServerError as e: module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message))
def create_machine(): ec2 = boto.ec2.connect_to_region(region) key_name = "vpn-key" image = ec2.get_image(ami) reservation = image.run(1, 1, key_name, instance_type="t1.micro", security_groups=["vpn"]) itrs = 0 found = False instance = reservation.instances[0] while not found and itrs < 10: instance.update() time.sleep(5) if instance.state == "running": found = True itrs += 1 if not found: print "ERROR* Could not start instance" exit(1) n = instance.public_dns_name print "NOTICE* Started instance %s" % n f = open(".machine", "w") f.write(n + "\n") f.close()
def create_ami(instance_id, name, description): params = {'instance_id': instance_id, 'name': name, 'description': description, 'no_reboot': True} image_id = ec2.create_image(**params) for _ in xrange(AMI_TIMEOUT): try: img = ec2.get_image(image_id) if img.state == 'available': break else: time.sleep(1) except EC2ResponseError as e: if e.error_code == 'InvalidAMIID.NotFound': time.sleep(1) else: raise Exception("Unexpected error code: {}".format( e.error_code)) time.sleep(1) else: raise Exception("Timeout waiting for AMI to finish") return image_id
def create_ami(instance_id, name, description): params = { 'instance_id': instance_id, 'name': name, 'description': description, 'no_reboot': True } image_id = ec2.create_image(**params) for _ in xrange(AMI_TIMEOUT): try: img = ec2.get_image(image_id) if img.state == 'available': break else: time.sleep(1) except EC2ResponseError as e: if e.error_code == 'InvalidAMIID.NotFound': time.sleep(1) else: raise Exception("Unexpected error code: {}".format( e.error_code)) time.sleep(1) else: raise Exception("Timeout waiting for AMI to finish") return image_id
def update_image(module, ec2): """ Updates AMI """ image_id = module.params.get('image_id') launch_permissions = module.params.get('launch_permissions') if 'user_ids' in launch_permissions: launch_permissions['user_ids'] = [str(user_id) for user_id in launch_permissions['user_ids']] img = ec2.get_image(image_id) if img == None: module.fail_json(msg = "Image %s does not exist" % image_id, changed=False) try: set_permissions = img.get_launch_permissions() if set_permissions != launch_permissions: if ('user_ids' in launch_permissions and launch_permissions['user_ids']) or ('group_names' in launch_permissions and launch_permissions['group_names']): res = img.set_launch_permissions(**launch_permissions) elif ('user_ids' in set_permissions and set_permissions['user_ids']) or ('group_names' in set_permissions and set_permissions['group_names']): res = img.remove_launch_permissions(**set_permissions) else: module.exit_json(msg="AMI not updated", launch_permissions=set_permissions, changed=False) module.exit_json(msg="AMI launch permissions updated", launch_permissions=launch_permissions, set_perms=set_permissions, changed=True) else: module.exit_json(msg="AMI not updated", launch_permissions=set_permissions, changed=False) except boto.exception.BotoServerError, e: module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message))
def deregister_image(module, ec2): """ Deregisters AMI """ image_id = module.params.get('image_id') delete_snapshot = module.params.get('delete_snapshot') wait = module.params.get('wait') wait_timeout = int(module.params.get('wait_timeout')) img = ec2.get_image(image_id) if img == None: module.fail_json(msg="Image %s does not exist" % image_id, changed=False) # Get all associated snapshot ids before deregistering image otherwise this information becomes unavailable snapshots = [] if hasattr(img, 'block_device_mapping'): for key in img.block_device_mapping: snapshots.append(img.block_device_mapping[key].snapshot_id) # When trying to re-delete already deleted image it doesn't raise an exception # It just returns an object without image attributes if hasattr(img, 'id'): try: params = {'image_id': image_id, 'delete_snapshot': delete_snapshot} res = ec2.deregister_image(**params) except boto.exception.BotoServerError, e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message))
def create_ami(instance_id, name, description): params = {'instance_id': instance_id, 'name': name, 'description': description, 'no_reboot': True} image_id = ec2.create_image(**params) for _ in xrange(AMI_TIMEOUT): try: img = ec2.get_image(image_id) if img.state == 'available': img.add_tag("environment", args.environment) img.add_tag("deployment", args.deployment) img.add_tag("play", args.play) img.add_tag("configuration_ref", args.configuration_version) img.add_tag("configuration_secure_ref", args.configuration_secure_version) img.add_tag("configuration_secure_repo", args.configuration_secure_repo) img.add_tag("build_id", args.jenkins_build) for repo,ref in git_refs.items(): key = "vars:{}".format(repo) img.add_tag(key, ref) else: time.sleep(1) except EC2ResponseError as e: if e.error_code == 'InvalidAMIID.NotFound': time.sleep(1) else: raise Exception("Unexpected error code: {}".format( e.error_code)) time.sleep(1) else: raise Exception("Timeout waiting for AMI to finish") return image_id
def create_ami(instance_id, name, description): params = { 'instance_id': instance_id, 'name': name, 'description': description, 'no_reboot': True } AWS_API_WAIT_TIME = 1 image_id = ec2.create_image(**params) print("Checking if image is ready.") for _ in xrange(AMI_TIMEOUT): try: img = ec2.get_image(image_id) if img.state == 'available': print("Tagging image.") img.add_tag("environment", args.environment) time.sleep(AWS_API_WAIT_TIME) img.add_tag("deployment", args.deployment) time.sleep(AWS_API_WAIT_TIME) img.add_tag("cluster", args.play) time.sleep(AWS_API_WAIT_TIME) img.add_tag("play", args.play) time.sleep(AWS_API_WAIT_TIME) conf_tag = "{} {}".format( "http://github.com/edx/configuration", args.configuration_version) img.add_tag("version:configuration", conf_tag) time.sleep(AWS_API_WAIT_TIME) conf_secure_tag = "{} {}".format( args.configuration_secure_repo, args.configuration_secure_version) img.add_tag("version:configuration_secure", conf_secure_tag) time.sleep(AWS_API_WAIT_TIME) img.add_tag("cache_id", args.cache_id) time.sleep(AWS_API_WAIT_TIME) # Get versions from the instance. tags = ec2.get_all_tags(filters={'resource-id': instance_id}) for tag in tags: if tag.name.startswith('version:'): img.add_tag(tag.name, tag.value) time.sleep(AWS_API_WAIT_TIME) break else: time.sleep(1) except EC2ResponseError as e: if e.error_code == 'InvalidAMIID.NotFound': time.sleep(1) else: raise Exception("Unexpected error code: {}".format( e.error_code)) time.sleep(1) else: raise Exception("Timeout waiting for AMI to finish") return image_id
def wait_until_image_is_copied(module, ec2, wait_timeout, img, image_id, wait): wait_timeout = time.time() + wait_timeout while wait and wait_timeout > time.time() and (img is None or img.state != 'available'): img = ec2.get_image(image_id) time.sleep(3) if wait and wait_timeout <= time.time(): # waiting took too long module.fail_json(msg="timed out waiting for image to be copied") return img
def create_ami(instance_id, name, description): params = {'instance_id': instance_id, 'name': name, 'description': description, 'no_reboot': False} AWS_API_WAIT_TIME = 1 image_id = ec2.create_image(**params) print("Checking if image is ready.") for _ in xrange(AMI_TIMEOUT): try: img = ec2.get_image(image_id) if img.state == 'available': print("Tagging image.") img.add_tag("environment", args.environment) time.sleep(AWS_API_WAIT_TIME) img.add_tag("deployment", args.deployment) time.sleep(AWS_API_WAIT_TIME) img.add_tag("cluster", args.play) time.sleep(AWS_API_WAIT_TIME) img.add_tag("play", args.play) time.sleep(AWS_API_WAIT_TIME) conf_tag = "{} {}".format("http://github.com/edx/configuration", args.configuration_version) img.add_tag("version:configuration", conf_tag) time.sleep(AWS_API_WAIT_TIME) conf_secure_tag = "{} {}".format(args.configuration_secure_repo, args.configuration_secure_version) img.add_tag("version:configuration_secure", conf_secure_tag) time.sleep(AWS_API_WAIT_TIME) conf_internal_tag = "{} {}".format(args.configuration_internal_repo, args.configuration_internal_version) img.add_tag("version:configuration_internal", conf_internal_tag) time.sleep(AWS_API_WAIT_TIME) img.add_tag("cache_id", args.cache_id) time.sleep(AWS_API_WAIT_TIME) # Get versions from the instance. tags = ec2.get_all_tags(filters={'resource-id': instance_id}) for tag in tags: if tag.name.startswith('version:'): img.add_tag(tag.name, tag.value) time.sleep(AWS_API_WAIT_TIME) break else: time.sleep(1) except EC2ResponseError as e: if e.error_code == 'InvalidAMIID.NotFound': time.sleep(1) else: raise Exception("Unexpected error code: {}".format( e.error_code)) time.sleep(1) else: raise Exception("Timeout waiting for AMI to finish") return image_id
def wait_until_image_is_recognized(module, ec2, wait_timeout, image_id, wait): for i in range(wait_timeout): try: return ec2.get_image(image_id) except boto.exception.EC2ResponseError, e: # This exception we expect initially right after registering the copy with EC2 API if 'InvalidAMIID.NotFound' in e.error_code and wait: time.sleep(1) else: # On any other exception we should fail module.fail_json( msg="Error while trying to find the new image. Using wait=yes and/or a longer wait_timeout may help: " + str( e))
def create_ami(instance_id, name, description): params = { 'instance_id': instance_id, 'name': name, 'description': description, 'no_reboot': True } AWS_API_WAIT_TIME = 1 image_id = ec2.create_image(**params) print("Checking if image is ready.") for _ in xrange(AMI_TIMEOUT): try: img = ec2.get_image(image_id) if img.state == 'available': print("Tagging image.") img.add_tag("environment", args.environment) time.sleep(AWS_API_WAIT_TIME) img.add_tag("deployment", args.deployment) time.sleep(AWS_API_WAIT_TIME) img.add_tag("play", args.play) time.sleep(AWS_API_WAIT_TIME) img.add_tag("configuration_ref", args.configuration_version) time.sleep(AWS_API_WAIT_TIME) img.add_tag("configuration_secure_ref", args.configuration_secure_version) time.sleep(AWS_API_WAIT_TIME) img.add_tag("configuration_secure_repo", args.configuration_secure_repo) time.sleep(AWS_API_WAIT_TIME) img.add_tag("cache_id", args.cache_id) time.sleep(AWS_API_WAIT_TIME) for repo, ref in git_refs.items(): key = "vars:{}".format(repo) img.add_tag(key, ref) time.sleep(AWS_API_WAIT_TIME) break else: time.sleep(1) except EC2ResponseError as e: if e.error_code == 'InvalidAMIID.NotFound': time.sleep(1) else: raise Exception("Unexpected error code: {}".format( e.error_code)) time.sleep(1) else: raise Exception("Timeout waiting for AMI to finish") return image_id
def create_ami(instance_id, name, description): params = {"instance_id": instance_id, "name": name, "description": description, "no_reboot": True} AWS_API_WAIT_TIME = 1 image_id = ec2.create_image(**params) print ("Checking if image is ready.") for _ in xrange(AMI_TIMEOUT): try: img = ec2.get_image(image_id) if img.state == "available": print ("Tagging image.") img.add_tag("environment", args.environment) time.sleep(AWS_API_WAIT_TIME) img.add_tag("deployment", args.deployment) time.sleep(AWS_API_WAIT_TIME) img.add_tag("play", args.play) time.sleep(AWS_API_WAIT_TIME) img.add_tag("configuration_ref", args.configuration_version) time.sleep(AWS_API_WAIT_TIME) img.add_tag("configuration_secure_ref", args.configuration_secure_version) time.sleep(AWS_API_WAIT_TIME) img.add_tag("configuration_secure_repo", args.configuration_secure_repo) time.sleep(AWS_API_WAIT_TIME) img.add_tag("cache_id", args.cache_id) time.sleep(AWS_API_WAIT_TIME) for repo, ref in git_refs.items(): key = "vars:{}".format(repo) img.add_tag(key, ref) time.sleep(AWS_API_WAIT_TIME) break else: time.sleep(1) except EC2ResponseError as e: if e.error_code == "InvalidAMIID.NotFound": time.sleep(1) else: raise Exception("Unexpected error code: {}".format(e.error_code)) time.sleep(1) else: raise Exception("Timeout waiting for AMI to finish") return image_id
def deregister_image(module, ec2): """ Deregisters AMI """ image_id = module.params.get('image_id') delete_snapshot = module.params.get('delete_snapshot') wait = module.params.get('wait') wait_timeout = int(module.params.get('wait_timeout')) img = ec2.get_image(image_id) if img == None: module.fail_json(msg = "Image %s does not exist" % image_id, changed=False) try: params = {'image_id': image_id, 'delete_snapshot': delete_snapshot} res = ec2.deregister_image(**params) except boto.exception.BotoServerError, e: module.fail_json(msg = "%s: %s" % (e.error_code, e.error_message))
def create_ami(instance_id, name, description): params = {"instance_id": instance_id, "name": name, "description": description, "no_reboot": True} image_id = ec2.create_image(**params) for _ in xrange(AMI_TIMEOUT): try: img = ec2.get_image(image_id) if img.state == "available": break else: time.sleep(1) except boto.exception.EC2ResponseError as e: if e.error_code == "InvalidAMIID.NotFound": time.sleep(1) else: raise Exception("Unexpected error code: {}".format(e.error_code)) time.sleep(1) else: raise Exception("Timeout waiting for AMI to finish") return image_id
def create_image(module, ec2): """ Creates new AMI module : AnsibleModule object ec2: authenticated ec2 connection object """ instance_id = module.params.get('instance_id') name = module.params.get('name') wait = module.params.get('wait') wait_timeout = int(module.params.get('wait_timeout')) description = module.params.get('description') architecture = module.params.get('architecture') kernel_id = module.params.get('kernel_id') root_device_name = module.params.get('root_device_name') virtualization_type = module.params.get('virtualization_type') no_reboot = module.params.get('no_reboot') device_mapping = module.params.get('device_mapping') tags = module.params.get('tags') launch_permissions = module.params.get('launch_permissions') try: params = {'name': name, 'description': description} images = ec2.get_all_images(filters={'name': name}) if images and images[0]: # ensure that launch_permissions are up to date update_image(module, ec2, images[0].id) bdm = None if device_mapping: bdm = BlockDeviceMapping() for device in device_mapping: if 'device_name' not in device: module.fail_json(msg='Device name must be set for volume') device_name = device['device_name'] del device['device_name'] bd = BlockDeviceType(**device) bdm[device_name] = bd if instance_id: params['instance_id'] = instance_id params['no_reboot'] = no_reboot if bdm: params['block_device_mapping'] = bdm image_id = ec2.create_image(**params) else: params['architecture'] = architecture params['virtualization_type'] = virtualization_type if kernel_id: params['kernel_id'] = kernel_id if root_device_name: params['root_device_name'] = root_device_name if bdm: params['block_device_map'] = bdm image_id = ec2.register_image(**params) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) # Wait until the image is recognized. EC2 API has eventual consistency, # such that a successful CreateImage API call doesn't guarantee the success # of subsequent DescribeImages API call using the new image id returned. for i in range(wait_timeout): try: img = ec2.get_image(image_id) if img.state == 'available': break elif img.state == 'failed': module.fail_json(msg="AMI creation failed, please see the AWS console for more details") except boto.exception.EC2ResponseError as e: if ('InvalidAMIID.NotFound' not in e.error_code and 'InvalidAMIID.Unavailable' not in e.error_code) and wait and i == wait_timeout - 1: module.fail_json(msg="Error while trying to find the new image. Using wait=yes and/or a longer " "wait_timeout may help. %s: %s" % (e.error_code, e.error_message)) finally: time.sleep(1) if img.state != 'available': module.fail_json(msg="Error while trying to find the new image. Using wait=yes and/or a longer wait_timeout may help.") if tags: try: ec2.create_tags(image_id, tags) except boto.exception.EC2ResponseError as e: module.fail_json(msg="Image tagging failed => %s: %s" % (e.error_code, e.error_message)) if launch_permissions: try: img = ec2.get_image(image_id) img.set_launch_permissions(**launch_permissions) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message), image_id=image_id) module.exit_json(msg="AMI creation operation complete", changed=True, **get_ami_info(img))
import boto.ec2.image import boto.exception import os import re import sys ec2 = boto.ec2.connect_to_region( 'ap-northeast-1', aws_access_key_id=os.getenv('AWS_ACCESS_KEY_ID'), aws_secret_access_key=os.getenv('AWS_SECRET_ACCESS_KEY')) snapshot_to_ami = {} for ami in ec2.get_all_images(owners=['self']): for (device, volume) in ami.block_device_mapping.iteritems(): if volume.snapshot_id: snapshot_to_ami[volume.snapshot_id] = ami snapshots = dict([(snapshot.id, snapshot) for snapshot in ec2.get_all_snapshots(owner='self')]) for (snapshot_id, snapshot) in snapshots.iteritems(): if not snapshot_to_ami.has_key(snapshot_id): if snapshot.description: # confirmation matched = re.search(r'ami-[0-9A-Fa-f]+', snapshot.description) if matched: ami = ec2.get_image(matched.group()) if ami: continue print "orphaned: %s # %s" % (snapshot_id, snapshot.description) # vim:set ft=python :
def create_image(module, ec2): """ Creates new AMI module : AnsibleModule object ec2: authenticated ec2 connection object """ instance_id = module.params.get('instance_id') name = module.params.get('name') wait = module.params.get('wait') wait_timeout = int(module.params.get('wait_timeout')) description = module.params.get('description') architecture = module.params.get('architecture') kernel_id = module.params.get('kernel_id') root_device_name = module.params.get('root_device_name') virtualization_type = module.params.get('virtualization_type') no_reboot = module.params.get('no_reboot') device_mapping = module.params.get('device_mapping') tags = module.params.get('tags') launch_permissions = module.params.get('launch_permissions') try: params = {'name': name, 'description': description} images = ec2.get_all_images(filters={'name': name}) if images and images[0]: # ensure that launch_permissions are up to date update_image(module, ec2, images[0].id) bdm = None if device_mapping: bdm = BlockDeviceMapping() for device in device_mapping: if 'device_name' not in device: module.fail_json(msg='Device name must be set for volume') device_name = device['device_name'] del device['device_name'] bd = BlockDeviceType(**device) bdm[device_name] = bd if instance_id: params['instance_id'] = instance_id params['no_reboot'] = no_reboot if bdm: params['block_device_mapping'] = bdm image_id = ec2.create_image(**params) else: params['architecture'] = architecture params['virtualization_type'] = virtualization_type if kernel_id: params['kernel_id'] = kernel_id if root_device_name: params['root_device_name'] = root_device_name if bdm: params['block_device_map'] = bdm image_id = ec2.register_image(**params) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) # Wait until the image is recognized. EC2 API has eventual consistency, # such that a successful CreateImage API call doesn't guarantee the success # of subsequent DescribeImages API call using the new image id returned. for i in range(wait_timeout): try: img = ec2.get_image(image_id) if img.state == 'available': break elif img.state == 'failed': module.fail_json( msg= "AMI creation failed, please see the AWS console for more details" ) except boto.exception.EC2ResponseError as e: if ('InvalidAMIID.NotFound' not in e.error_code and 'InvalidAMIID.Unavailable' not in e.error_code) and wait and i == wait_timeout - 1: module.fail_json( msg= "Error while trying to find the new image. Using wait=yes and/or a longer " "wait_timeout may help. %s: %s" % (e.error_code, e.error_message)) finally: time.sleep(1) if img.state != 'available': module.fail_json( msg= "Error while trying to find the new image. Using wait=yes and/or a longer wait_timeout may help." ) if tags: try: ec2.create_tags(image_id, tags) except boto.exception.EC2ResponseError as e: module.fail_json(msg="Image tagging failed => %s: %s" % (e.error_code, e.error_message)) if launch_permissions: try: img = ec2.get_image(image_id) img.set_launch_permissions(**launch_permissions) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message), image_id=image_id) module.exit_json(msg="AMI creation operation complete", changed=True, **get_ami_info(img))
images = ec2.get_all_images() for img in images: if img.name == name: module.exit_json(msg="AMI name already present", image_id=img.id, state=img.state, changed=False) sys.exit(0) else: module.fail_json(msg="Error in retrieving duplicate AMI details") else: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) # Wait until the image is recognized. EC2 API has eventual consistency, # such that a successful CreateImage API call doesn't guarantee the success # of subsequent DescribeImages API call using the new image id returned. for i in range(wait_timeout): try: img = ec2.get_image(image_id) break except boto.exception.EC2ResponseError, e: if 'InvalidAMIID.NotFound' in e.error_code and wait: time.sleep(1) else: module.fail_json(msg="Error while trying to find the new image. Using wait=yes and/or a longer wait_timeout may help.") else: module.fail_json(msg="timed out waiting for image to be recognized") # wait here until the image is created wait_timeout = time.time() + wait_timeout while wait and wait_timeout > time.time() and (img is None or img.state != 'available'): img = ec2.get_image(image_id) time.sleep(3) if wait and wait_timeout <= time.time():
if e.error_code == 'InvalidAMIName.Duplicate': images = ec2.get_all_images() for img in images: if img.name == name: module.exit_json(msg="AMI name already present", image_id=img.id, state=img.state, changed=False) else: module.fail_json(msg="Error in retrieving duplicate AMI details") else: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) # Wait until the image is recognized. EC2 API has eventual consistency, # such that a successful CreateImage API call doesn't guarantee the success # of subsequent DescribeImages API call using the new image id returned. for i in range(wait_timeout): try: img = ec2.get_image(image_id) break except boto.exception.EC2ResponseError, e: if 'InvalidAMIID.NotFound' in e.error_code and wait: time.sleep(1) else: module.fail_json(msg="Error while trying to find the new image. Using wait=yes and/or a longer wait_timeout may help.") else: module.fail_json(msg="timed out waiting for image to be recognized") # wait here until the image is created wait_timeout = time.time() + wait_timeout while wait and wait_timeout > time.time() and (img is None or img.state != 'available'): img = ec2.get_image(image_id) time.sleep(3) if wait and wait_timeout <= time.time():
def create_image(module, ec2): """ Creates new AMI module : AnsibleModule object ec2: authenticated ec2 connection object """ instance_id = module.params.get("instance_id") name = module.params.get("name") wait = module.params.get("wait") wait_timeout = int(module.params.get("wait_timeout")) description = module.params.get("description") no_reboot = module.params.get("no_reboot") device_mapping = module.params.get("device_mapping") tags = module.params.get("tags") launch_permissions = module.params.get("launch_permissions") try: params = {"instance_id": instance_id, "name": name, "description": description, "no_reboot": no_reboot} images = ec2.get_all_images(filters={"name": name}) if images and images[0]: module.exit_json( msg="AMI name already present", image_id=images[0].id, state=images[0].state, changed=False ) if device_mapping: bdm = BlockDeviceMapping() for device in device_mapping: if "device_name" not in device: module.fail_json(msg="Device name must be set for volume") device_name = device["device_name"] del device["device_name"] bd = BlockDeviceType(**device) bdm[device_name] = bd params["block_device_mapping"] = bdm image_id = ec2.create_image(**params) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message)) # Wait until the image is recognized. EC2 API has eventual consistency, # such that a successful CreateImage API call doesn't guarantee the success # of subsequent DescribeImages API call using the new image id returned. for i in range(wait_timeout): try: img = ec2.get_image(image_id) if img.state == "available": break elif img.state == "failed": module.fail_json(msg="AMI creation failed, please see the AWS console for more details") except boto.exception.EC2ResponseError as e: if ( ("InvalidAMIID.NotFound" not in e.error_code and "InvalidAMIID.Unavailable" not in e.error_code) and wait and i == wait_timeout - 1 ): module.fail_json( msg="Error while trying to find the new image. Using wait=yes and/or a longer wait_timeout may help. %s: %s" % (e.error_code, e.error_message) ) finally: time.sleep(1) if img.state != "available": module.fail_json( msg="Error while trying to find the new image. Using wait=yes and/or a longer wait_timeout may help." ) if tags: try: ec2.create_tags(image_id, tags) except boto.exception.EC2ResponseError as e: module.fail_json(msg="Image tagging failed => %s: %s" % (e.error_code, e.error_message)) if launch_permissions: try: img = ec2.get_image(image_id) img.set_launch_permissions(**launch_permissions) except boto.exception.BotoServerError as e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message), image_id=image_id) module.exit_json(msg="AMI creation operation complete", changed=True, **get_ami_info(img))