#!/usr/bin/python # Copyright: Ansible Project # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function __metaclass__ = type ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} DOCUMENTATION = ''' --- module: ec2_ami_info version_added: '2.5' short_description: Gather information about ec2 AMIs description: - Gather information about ec2 AMIs - This module was called C(ec2_ami_facts) before Ansible 2.9. The usage did not change. author: - Prasad Katti (@prasadkatti) requirements: [ boto3 ] options: image_ids: description: One or more image IDs. aliases: [image_id] type: list elements: str filters: description: - A dict of filters to apply. Each dict item consists of a filter key and a filter value. - See U(https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeImages.html) for possible filters. - Filter names and values are case sensitive. type: dict owners: description: - Filter the images by the owner. Valid options are an AWS account ID, self, or an AWS owner alias ( amazon | aws-marketplace | microsoft ). aliases: [owner] type: list elements: str executable_users: description: - Filter images by users with explicit launch permissions. Valid options are an AWS account ID, self, or all (public AMIs). aliases: [executable_user] type: list elements: str describe_image_attributes: description: - Describe attributes (like launchPermission) of the images found. default: no type: bool extends_documentation_fragment: - aws - ec2 ''' EXAMPLES = ''' # Note: These examples do not set authentication details, see the AWS Guide for details. - name: gather information about an AMI using ami-id ec2_ami_info: image_ids: ami-5b488823 - name: gather information about all AMIs with tag key Name and value webapp ec2_ami_info: filters: "tag:Name": webapp - name: gather information about an AMI with 'AMI Name' equal to foobar ec2_ami_info: filters: name: foobar - name: gather information about Ubuntu 17.04 AMIs published by Canonical (099720109477) ec2_ami_info: owners: 099720109477 filters: name: "ubuntu/images/ubuntu-zesty-17.04-*" ''' RETURN = ''' images: description: A list of images. returned: always type: list elements: dict contains: architecture: description: The architecture of the image. returned: always type: str sample: x86_64 block_device_mappings: description: Any block device mapping entries. returned: always type: list elements: dict contains: device_name: description: The device name exposed to the instance. returned: always type: str sample: /dev/sda1 ebs: description: EBS volumes returned: always type: complex creation_date: description: The date and time the image was created. returned: always type: str sample: '2017-10-16T19:22:13.000Z' description: description: The description of the AMI. returned: always type: str sample: '' ena_support: description: Whether enhanced networking with ENA is enabled. returned: always type: bool sample: true hypervisor: description: The hypervisor type of the image. returned: always type: str sample: xen image_id: description: The ID of the AMI. returned: always type: str sample: ami-5b466623 image_location: description: The location of the AMI. returned: always type: str sample: 408466080000/Webapp image_type: description: The type of image. returned: always type: str sample: machine launch_permissions: description: A List of AWS accounts may launch the AMI. returned: When image is owned by calling account and I(describe_image_attributes) is yes. type: list elements: dict contains: group: description: A value of 'all' means the AMI is public. type: str user_id: description: An AWS account ID with permissions to launch the AMI. type: str sample: [{"group": "all"}, {"user_id": "408466080000"}] name: description: The name of the AMI that was provided during image creation. returned: always type: str sample: Webapp owner_id: description: The AWS account ID of the image owner. returned: always type: str sample: '408466080000' public: description: Whether the image has public launch permissions. returned: always type: bool sample: true root_device_name: description: The device name of the root device. returned: always type: str sample: /dev/sda1 root_device_type: description: The type of root device used by the AMI. returned: always type: str sample: ebs sriov_net_support: description: Whether enhanced networking is enabled. returned: always type: str sample: simple state: description: The current state of the AMI. returned: always type: str sample: available tags: description: Any tags assigned to the image. returned: always type: dict virtualization_type: description: The type of virtualization of the AMI. returned: always type: str sample: hvm ''' try: from botocore.exceptions import ClientError, BotoCoreError except ImportError: pass # caught by AnsibleAWSModule from ansible.module_utils.aws.core import AnsibleAWSModule from ansible.module_utils.ec2 import ansible_dict_to_boto3_filter_list, camel_dict_to_snake_dict, boto3_tag_list_to_ansible_dict def list_ec2_images(ec2_client, module): image_ids = module.params.get("image_ids") 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=owner_param, ExecutableUsers=executable_users) images = [camel_dict_to_snake_dict(image) for image in images["Images"]] except (ClientError, BotoCoreError) as err: module.fail_json_aws(err, msg="error describing images") for image in images: try: image['tags'] = boto3_tag_list_to_ansible_dict(image.get('tags', [])) if module.params.get("describe_image_attributes"): 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 images.sort(key=lambda e: e.get('creation_date', '')) # it may be possible that creation_date does not always exist module.exit_json(images=images) def main(): argument_spec = dict( image_ids=dict(default=[], type='list', aliases=['image_id']), filters=dict(default={}, type='dict'), owners=dict(default=[], type='list', aliases=['owner']), executable_users=dict(default=[], type='list', aliases=['executable_user']), describe_image_attributes=dict(default=False, type='bool') ) module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True) if module._module._name == 'ec2_ami_facts': module._module.deprecate("The 'ec2_ami_facts' module has been renamed to 'ec2_ami_info'", version='2.13', collection_name='ansible.builtin') ec2_client = module.client('ec2') list_ec2_images(ec2_client, module) if __name__ == '__main__': main()