Speed up ec2_ami_facts and handle permissions issue (#34385)

* describe_images is very slow if not filtered to owner accounts
  *or* if the Owners parameter is passed (unless the Owners parameter
  is `self`). Convert Owners parameters to `owner-id` and `owner-alias`
  filters where possible. Tests with CLI show that `--owners self` is
  fast, `--owners 123456789012` is slow (with or without owner-id filter).

* describe_image_attributes fails against accounts other than your
  own. Launch permissions are useful information, but not critical.
pull/34970/head
Will Thames 7 years ago committed by ansibot
parent 7d05a86bbc
commit 8e48793654

@ -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)

Loading…
Cancel
Save