diff --git a/lib/ansible/modules/cloud/amazon/ec2_ami_facts.py b/lib/ansible/modules/cloud/amazon/ec2_ami_facts.py index 5037337286c..882dbc52b5a 100644 --- a/lib/ansible/modules/cloud/amazon/ec2_ami_facts.py +++ b/lib/ansible/modules/cloud/amazon/ec2_ami_facts.py @@ -127,7 +127,7 @@ images: sample: machine launch_permissions: description: launch permissions of the ami - returned: always + returned: when image is owned by calling account type: complex sample: [{"group": "all"}, {"user_id": "408466080000"}] name: @@ -189,21 +189,44 @@ from ansible.module_utils.ec2 import (boto3_conn, ec2_argument_spec, get_aws_con def list_ec2_images(ec2_client, module): image_ids = module.params.get("image_ids") - filters = ansible_dict_to_boto3_filter_list(module.params.get("filters")) owners = module.params.get("owners") executable_users = module.params.get("executable_users") + filters = module.params.get("filters") + owner_param = [] + + # describe_images is *very* slow if you pass the `Owners` + # param (unless it's self), for some reason. + # Converting the owners to filters and removing from the + # owners param greatly speeds things up. + # Implementation based on aioue's suggestion in #24886 + for owner in owners: + if owner.isdigit(): + if 'owner-id' not in filters: + filters['owner-id'] = list() + filters['owner-id'].append(owner) + elif owner == 'self': + # self not a valid owner-alias filter (https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeImages.html) + owner_param.append(owner) + else: + if 'owner-alias' not in filters: + filters['owner-alias'] = list() + filters['owner-alias'].append(owner) + + filters = ansible_dict_to_boto3_filter_list(filters) try: - images = ec2_client.describe_images(ImageIds=image_ids, Filters=filters, Owners=owners, ExecutableUsers=executable_users) + images = ec2_client.describe_images(ImageIds=image_ids, Filters=filters, Owners=owner_param, ExecutableUsers=executable_users) images = [camel_dict_to_snake_dict(image) for image in images["Images"]] - for image in images: - launch_permissions = ec2_client.describe_image_attribute(Attribute='launchPermission', ImageId=image['image_id'])['LaunchPermissions'] - image['launch_permissions'] = [camel_dict_to_snake_dict(perm) for perm in launch_permissions] except (ClientError, BotoCoreError) as err: module.fail_json_aws(err, msg="error describing images") - for image in images: - image['tags'] = boto3_tag_list_to_ansible_dict(image.get('tags', []), 'key', 'value') + try: + image['tags'] = boto3_tag_list_to_ansible_dict(image.get('tags', [])) + launch_permissions = ec2_client.describe_image_attribute(Attribute='launchPermission', ImageId=image['image_id'])['LaunchPermissions'] + image['launch_permissions'] = [camel_dict_to_snake_dict(perm) for perm in launch_permissions] + except (ClientError, BotoCoreError) as err: + # describing launch permissions of images owned by others is not permitted, but shouldn't cause failures + pass module.exit_json(images=images)