|
|
|
#!/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()
|