[ec2_ami_facts] new boto3-based module as a replacement for ec2_ami_find (#32252)

* [ec2_ami_facts] new boto3-based module as a replacement for ec2_ami_find

- new boto3-based module to gather facts about ec2 images
- intended to replace ec2_ami_find which uses boto
- an ami find task (using new module) added to the ec2_ami integration test

* [ec2_ami_facts] Use AnsibleAWSModule. Catch BotoCoreError.

* add ec2_ami_facts alias to tests

* [ec2_ami_facts] return ami launch permissions as well
pull/32475/head
Prasad Katti 7 years ago committed by Will Thames
parent e33c24f585
commit 86141c3e03

@ -0,0 +1,236 @@
#!/usr/bin/python
# Copyright: Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: ec2_ami_facts
version_added: '2.5'
short_description: Gather facts about ec2 AMIs
description: Gather facts about ec2 AMIs
author:
- Prasad Katti, @prasadkatti
requirements: [ boto3 ]
options:
image_ids:
description: One or more image IDs.
aliases: [image_id]
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.
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]
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]
extends_documentation_fragment:
- aws
- ec2
'''
EXAMPLES = '''
# Note: These examples do not set authentication details, see the AWS Guide for details.
- name: gather facts about an AMI using ami-id
ec2_ami_facts:
image_ids: ami-5b488823
- name: gather facts about all AMIs with tag key Name and value webapp
ec2_ami_facts:
filters:
"tag:Name": webapp
- name: gather facts about an AMI with 'AMI Name' equal to foobar
ec2_ami_facts:
filters:
name: foobar
- name: gather facts about Ubuntu 17.04 AMIs published by Canonical (099720109477)
ec2_ami_facts:
owners: 099720109477
filters:
name: "ubuntu/images/ubuntu-zesty-17.04-*"
'''
RETURN = '''
images:
description: a list of images
returned: always
type: complex
contains:
architecture:
description: The architecture of the image
returned: always
type: string
sample: x86_64
block_device_mappings:
description: Any block device mapping entries
returned: always
type: complex
contains:
device_name:
description: The device name exposed to the instance
returned: always
type: string
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: string
sample: '2017-10-16T19:22:13.000Z'
description:
description: The description of the AMI
returned: always
type: string
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: string
sample: xen
image_id:
description: The ID of the AMI
returned: always
type: string
sample: ami-5b466623
image_location:
description: The location of the AMI
returned: always
type: string
sample: 408466080000/Webapp
image_type:
description: The type of image
returned: always
type: string
sample: machine
launch_permissions:
description: launch permissions of the ami
returned: always
type: complex
sample: [{"group": "all"}, {"user_id": "408466080000"}]
name:
description: The name of the AMI that was provided during image creation
returned: always
type: string
sample: Webapp
owner_id:
description: The AWS account ID of the image owner
returned: always
type: string
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: string
sample: /dev/sda1
root_device_type:
description: The type of root device used by the AMI
returned: always
type: string
sample: ebs
sriov_net_support:
description: whether enhanced networking is enabled
returned: always
type: string
sample: simple
state:
description: The current state of the AMI
returned: always
type: string
sample: available
tags:
description: Any tags assigned to the image
returned: always
type: complex
virtualization_type:
description: The type of virtualization of the AMI
returned: always
type: string
sample: hvm
'''
try:
from botocore.exceptions import ClientError, BotoCoreError
except ImportError:
pass
from ansible.module_utils.aws.core import AnsibleAWSModule
from ansible.module_utils.ec2 import (boto3_conn, ec2_argument_spec, get_aws_connection_info, 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")
filters = ansible_dict_to_boto3_filter_list(module.params.get("filters"))
owners = module.params.get("owners")
executable_users = module.params.get("executable_users")
try:
images = ec2_client.describe_images(ImageIds=image_ids, Filters=filters, Owners=owners, 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')
module.exit_json(images=images)
def main():
argument_spec = ec2_argument_spec()
argument_spec.update(
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'])
)
)
module = AnsibleAWSModule(argument_spec=argument_spec, supports_check_mode=True)
region, ec2_url, aws_connect_params = get_aws_connection_info(module, boto3=True)
if region:
ec2_client = boto3_conn(module, conn_type='client', resource='ec2', region=region, endpoint=ec2_url, **aws_connect_params)
else:
module.fail_json(msg="region must be specified")
list_ec2_images(ec2_client, module)
if __name__ == '__main__':
main()

@ -1,2 +1,3 @@
cloud/aws cloud/aws
posix/ci/cloud/group1/aws posix/ci/cloud/group1/aws
ec2_ami_facts

@ -118,6 +118,23 @@
# ============================================================ # ============================================================
- name: gather facts about the image created
ec2_ami_facts:
ec2_region: '{{ec2_region}}'
ec2_access_key: '{{ec2_access_key}}'
ec2_secret_key: '{{ec2_secret_key}}'
security_token: '{{security_token}}'
image_ids: '{{ ec2_ami_image_id }}'
register: ami_facts_result
ignore_errors: true
- name: assert that the right image was found
assert:
that:
- "ami_facts_result.images[0].image_id == ec2_ami_image_id"
# ============================================================
- name: delete the image - name: delete the image
ec2_ami: ec2_ami:
ec2_region: '{{ec2_region}}' ec2_region: '{{ec2_region}}'

Loading…
Cancel
Save