def main(): argument_spec = ec2_argument_spec() argument_spec.update(dict( source_region=dict(required=True), source_image_id=dict(required=True), name=dict(), description=dict(default=""), encrypted=dict(type='bool', required=False), kms_key_id=dict(type='str', required=False), wait=dict(type='bool', default=False), wait_timeout=dict(default=1200), tags=dict(type='dict'))) module = AnsibleModule(argument_spec=argument_spec) if not HAS_BOTO: module.fail_json(msg='boto required for this module') try: ec2 = ec2_connect(module) except boto.exception.NoAuthHandlerFound as e: module.fail_json(msg=str(e)) try: region, ec2_url, boto_params = get_aws_connection_info(module) except boto.exception.NoAuthHandlerFound as e: module.fail_json(msg=str(e)) if not region: module.fail_json(msg="region must be specified") copy_image(module, ec2)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict(source_region=dict(required=True), source_image_id=dict(required=True), name=dict(), description=dict(default=""), encrypted=dict(type='bool', required=False), kms_key_id=dict(type='str', required=False), wait=dict(type='bool', default=False), wait_timeout=dict(default=1200), tags=dict(type='dict'))) module = AnsibleModule(argument_spec=argument_spec) if not HAS_BOTO: module.fail_json(msg='boto required for this module') try: ec2 = ec2_connect(module) except boto.exception.NoAuthHandlerFound as e: module.fail_json(msg=str(e)) try: region, ec2_url, boto_params = get_aws_connection_info(module) except boto.exception.NoAuthHandlerFound as e: module.fail_json(msg=str(e)) if not region: module.fail_json(msg="region must be specified") copy_image(module, ec2)
def main(): module = create_snapshot_ansible_module() if not HAS_BOTO: module.fail_json(msg='boto required for this module') volume_id = module.params.get('volume_id') snapshot_id = module.params.get('snapshot_id') description = module.params.get('description') instance_id = module.params.get('instance_id') device_name = module.params.get('device_name') wait = module.params.get('wait') wait_timeout = module.params.get('wait_timeout') last_snapshot_min_age = module.params.get('last_snapshot_min_age') snapshot_tags = module.params.get('snapshot_tags') state = module.params.get('state') ec2 = ec2_connect(module) create_snapshot(module=module, state=state, description=description, wait=wait, wait_timeout=wait_timeout, ec2=ec2, volume_id=volume_id, instance_id=instance_id, snapshot_id=snapshot_id, device_name=device_name, snapshot_tags=snapshot_tags, last_snapshot_min_age=last_snapshot_min_age)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict(instance_id=dict(), image_id=dict(), architecture=dict(default="x86_64"), kernel_id=dict(), virtualization_type=dict(default="hvm"), root_device_name=dict(), delete_snapshot=dict(default=False, type='bool'), name=dict(), wait=dict(type='bool', default=False), wait_timeout=dict(default=900), description=dict(default=""), no_reboot=dict(default=False, type='bool'), state=dict(default='present'), device_mapping=dict(type='list'), tags=dict(type='dict'), launch_permissions=dict(type='dict'))) module = AnsibleModule(argument_spec=argument_spec) if not HAS_BOTO: module.fail_json(msg='boto required for this module') try: ec2 = ec2_connect(module) except Exception as e: module.fail_json(msg="Error while connecting to aws: %s" % str(e)) if module.params.get('state') == 'absent': if not module.params.get('image_id'): module.fail_json( msg='image_id needs to be an ami image to registered/delete') deregister_image(module, ec2) elif module.params.get('state') == 'present': if module.params.get('image_id') and module.params.get( 'launch_permissions'): # Update image's launch permissions update_image(module, ec2, module.params.get('image_id')) # Changed is always set to true when provisioning new AMI if not module.params.get('instance_id') and not module.params.get( 'device_mapping'): module.fail_json( msg= 'instance_id or device_mapping (register from ebs snapshot) parameter is required for new image' ) if not module.params.get('name'): module.fail_json(msg='name parameter is required for new image') create_image(module, ec2)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict( instance_id=dict(), image_id=dict(), architecture=dict(default="x86_64"), kernel_id=dict(), virtualization_type=dict(default="hvm"), root_device_name=dict(), delete_snapshot=dict(default=False, type='bool'), name=dict(), wait=dict(type='bool', default=False), wait_timeout=dict(default=900), description=dict(default=""), no_reboot=dict(default=False, type='bool'), state=dict(default='present'), device_mapping=dict(type='list'), tags=dict(type='dict'), launch_permissions=dict(type='dict') ) ) module = AnsibleModule(argument_spec=argument_spec) if not HAS_BOTO: module.fail_json(msg='boto required for this module') try: ec2 = ec2_connect(module) except Exception as e: module.fail_json(msg="Error while connecting to aws: %s" % str(e)) if module.params.get('state') == 'absent': if not module.params.get('image_id'): module.fail_json(msg='image_id needs to be an ami image to registered/delete') deregister_image(module, ec2) elif module.params.get('state') == 'present': if module.params.get('image_id') and module.params.get('launch_permissions'): # Update image's launch permissions update_image(module, ec2, module.params.get('image_id')) # Changed is always set to true when provisioning new AMI if not module.params.get('instance_id') and not module.params.get('device_mapping'): module.fail_json(msg='instance_id or device_mapping (register from ebs snapshot) parameter is required for new image') if not module.params.get('name'): module.fail_json(msg='name parameter is required for new image') create_image(module, ec2)
def bind_conn(self, resource): if resource == 'ec2': # bind a connection to a region. we can query off of this object. ec2 has an ansible connector self.aws_conn['ec2'] = ec2.ec2_connect(self) if resource == 'sg': self.aws_conn['sg'] = boto.ec2.connect_to_region(self.aws_region, aws_access_key_id=self.params['aws_access_key_id'], aws_secret_access_key=self.params['aws_secret_access_key']) if resource == 's3': self.aws_conn['s3'] = boto.connect_s3(aws_access_key_id=self.params['aws_access_key_id'], aws_secret_access_key=self.params['aws_secret_access_key']) if resource == 'subnet': self.aws_conn['subnet'] = boto.connect_vpc(aws_access_key_id=self.params['aws_access_key_id'], aws_secret_access_key=self.params['aws_secret_access_key']) if resource == 'routetable': self.aws_conn['routetable'] = boto.connect_vpc(aws_access_key_id=self.params['aws_access_key_id'], aws_secret_access_key=self.params['aws_secret_access_key']) if resource == 'vpc': #might need to get region here by calling get_region(params['region'], **kwargs) self.aws_conn['vpc'] = boto.connect_vpc(aws_access_key_id=self.params['aws_access_key_id'], aws_secret_access_key=self.params['aws_secret_access_key'])
def main(): argument_spec = ec2_argument_spec() argument_spec.update({ 'region': { 'required': True, 'aliases': ['aws_region', 'ec2_region'] }, 'owner': { 'required': False, 'default': None }, 'ami_id': { 'required': False }, 'ami_tags': { 'required': False, 'type': 'dict', 'aliases': ['search_tags', 'image_tags'] }, 'architecture': { 'required': False }, 'hypervisor': { 'required': False }, 'is_public': { 'required': False }, 'name': { 'required': False }, 'platform': { 'required': False }, 'sort': { 'required': False, 'default': None, 'choices': ['name', 'description', 'tag'] }, 'sort_tag': { 'required': False }, 'sort_order': { 'required': False, 'default': 'ascending', 'choices': ['ascending', 'descending'] }, 'sort_start': { 'required': False }, 'sort_end': { 'required': False }, 'state': { 'required': False, 'default': 'available' }, 'virtualization_type': { 'required': False }, 'no_result_action': { 'required': False, 'default': 'success', 'choices': ['success', 'fail'] }, }) module = AnsibleModule(argument_spec=argument_spec, ) if not HAS_BOTO: module.fail_json( msg=""" boto required for this module, install via pip or your package manager""") ec2 = ec2_connect(module) # get the image_results, and parsed filters images_result, filters = get_all_images_filtered(ec2, module) # verify we have results no_result_action = module.params.get('no_result_action') if no_result_action == 'fail' and len(images_result) == 0: module.fail_json(msg="No AMIs matched the attributes: %s" % json.dumps(filters)) results = sort_results(images_result, module) module.exit_json(results=results)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict( resource=dict(required=True), tags=dict(type='dict'), state=dict(default='present', choices=['present', 'absent', 'list']), )) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if not HAS_BOTO: module.fail_json(msg='boto required for this module') resource = module.params.get('resource') tags = module.params.get('tags') state = module.params.get('state') ec2 = ec2_connect(module) # We need a comparison here so that we can accurately report back changed status. # Need to expand the gettags return format and compare with "tags" and then tag or detag as appropriate. filters = {'resource-id': resource} gettags = ec2.get_all_tags(filters=filters) dictadd = {} dictremove = {} baddict = {} tagdict = {} for tag in gettags: tagdict[tag.name] = tag.value if state == 'present': if not tags: module.fail_json( msg="tags argument is required when state is present") if set(tags.items()).issubset(set(tagdict.items())): module.exit_json(msg="Tags already exists in %s." % resource, changed=False) else: for (key, value) in set(tags.items()): if (key, value) not in set(tagdict.items()): dictadd[key] = value if not module.check_mode: ec2.create_tags(resource, dictadd) module.exit_json(msg="Tags %s created for resource %s." % (dictadd, resource), changed=True) if state == 'absent': if not tags: module.fail_json( msg="tags argument is required when state is absent") for (key, value) in set(tags.items()): if (key, value) not in set(tagdict.items()): baddict[key] = value if set(baddict) == set(tags): module.exit_json(msg="Nothing to remove here. Move along.", changed=False) for (key, value) in set(tags.items()): if (key, value) in set(tagdict.items()): dictremove[key] = value if not module.check_mode: ec2.delete_tags(resource, dictremove) module.exit_json(msg="Tags %s removed for resource %s." % (dictremove, resource), changed=True) if state == 'list': module.exit_json(changed=False, tags=tagdict)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict( instance_id=dict(required=True), key_file=dict(required=True, type='path'), key_passphrase=dict(no_log=True, default=None, required=False), wait=dict(type='bool', default=False, required=False), wait_timeout=dict(default=120, required=False, type='int'), )) module = AnsibleModule(argument_spec=argument_spec) if not HAS_BOTO: module.fail_json(msg='Boto required for this module.') if not HAS_CRYPTOGRAPHY: module.fail_json(msg='cryptography package required for this module.') instance_id = module.params.get('instance_id') key_file = module.params.get('key_file') if module.params.get('key_passphrase') is None: b_key_passphrase = None else: b_key_passphrase = to_bytes(module.params.get('key_passphrase'), errors='surrogate_or_strict') wait = module.params.get('wait') wait_timeout = module.params.get('wait_timeout') ec2 = ec2_connect(module) if wait: start = datetime.datetime.now() end = start + datetime.timedelta(seconds=wait_timeout) while datetime.datetime.now() < end: data = ec2.get_password_data(instance_id) decoded = b64decode(data) if not decoded: time.sleep(5) else: break else: data = ec2.get_password_data(instance_id) decoded = b64decode(data) if wait and datetime.datetime.now() >= end: module.fail_json(msg="wait for password timeout after %d seconds" % wait_timeout) try: f = open(key_file, 'rb') except IOError as e: module.fail_json(msg="I/O error (%d) opening key file: %s" % (e.errno, e.strerror)) else: try: with f: key = load_pem_private_key(f.read(), b_key_passphrase, default_backend()) except (ValueError, TypeError) as e: module.fail_json(msg="unable to parse key file") try: decrypted = key.decrypt(decoded, PKCS1v15()) except ValueError as e: decrypted = None if decrypted is None: module.exit_json(win_password='', changed=False) else: if wait: elapsed = datetime.datetime.now() - start module.exit_json(win_password=decrypted, changed=True, elapsed=elapsed.seconds) else: module.exit_json(win_password=decrypted, changed=True)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict( name=dict(required=True), key_material=dict(required=False), force=dict(required=False, type='bool', default=True), state=dict(default='present', choices=['present', 'absent']), wait=dict(type='bool', default=False), wait_timeout=dict(default=300), )) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) if not HAS_BOTO: module.fail_json(msg='boto required for this module') name = module.params['name'] state = module.params.get('state') key_material = module.params.get('key_material') force = module.params.get('force') wait = module.params.get('wait') wait_timeout = int(module.params.get('wait_timeout')) changed = False ec2 = ec2_connect(module) # find the key if present key = ec2.get_key_pair(name) # Ensure requested key is absent if state == 'absent': if key: '''found a match, delete it''' if not module.check_mode: try: key.delete() if wait: start = time.time() action_complete = False while (time.time() - start) < wait_timeout: if not ec2.get_key_pair(name): action_complete = True break time.sleep(1) if not action_complete: module.fail_json( msg= "timed out while waiting for the key to be removed" ) except Exception as e: module.fail_json( msg="Unable to delete key pair '%s' - %s" % (key, e)) key = None changed = True # Ensure requested key is present elif state == 'present': if key: # existing key found if key_material and force: # EC2's fingerprints are non-trivial to generate, so push this key # to a temporary name and make ec2 calculate the fingerprint for us. # # http://blog.jbrowne.com/?p=23 # https://forums.aws.amazon.com/thread.jspa?messageID=352828 # find an unused name test = 'empty' while test: randomchars = [ random.choice(string.ascii_letters + string.digits) for x in range(0, 10) ] tmpkeyname = "ansible-" + ''.join(randomchars) test = ec2.get_key_pair(tmpkeyname) # create tmp key tmpkey = ec2.import_key_pair(tmpkeyname, to_bytes(key_material)) # get tmp key fingerprint tmpfingerprint = tmpkey.fingerprint # delete tmp key tmpkey.delete() if key.fingerprint != tmpfingerprint: if not module.check_mode: key.delete() key = ec2.import_key_pair(name, to_bytes(key_material)) if wait: start = time.time() action_complete = False while (time.time() - start) < wait_timeout: if ec2.get_key_pair(name): action_complete = True break time.sleep(1) if not action_complete: module.fail_json( msg= "timed out while waiting for the key to be re-created" ) changed = True # if the key doesn't exist, create it now else: '''no match found, create it''' if not module.check_mode: if key_material: '''We are providing the key, need to import''' key = ec2.import_key_pair(name, to_bytes(key_material)) else: ''' No material provided, let AWS handle the key creation and retrieve the private key ''' key = ec2.create_key_pair(name) if wait: start = time.time() action_complete = False while (time.time() - start) < wait_timeout: if ec2.get_key_pair(name): action_complete = True break time.sleep(1) if not action_complete: module.fail_json( msg= "timed out while waiting for the key to be created" ) changed = True if key: data = {'name': key.name, 'fingerprint': key.fingerprint} if key.material: data.update({'private_key': key.material}) module.exit_json(changed=changed, key=data) else: module.exit_json(changed=changed, key=None)
def create_launch_config(connection, module): name = module.params.get('name') image_id = module.params.get('image_id') key_name = module.params.get('key_name') try: security_groups = get_ec2_security_group_ids_from_names( module.params.get('security_groups'), ec2_connect(module), vpc_id=None, boto3=False) except ValueError as e: module.fail_json(msg=str(e)) user_data = module.params.get('user_data') user_data_path = module.params.get('user_data_path') volumes = module.params['volumes'] instance_type = module.params.get('instance_type') spot_price = module.params.get('spot_price') instance_monitoring = module.params.get('instance_monitoring') assign_public_ip = module.params.get('assign_public_ip') kernel_id = module.params.get('kernel_id') ramdisk_id = module.params.get('ramdisk_id') instance_profile_name = module.params.get('instance_profile_name') ebs_optimized = module.params.get('ebs_optimized') classic_link_vpc_id = module.params.get('classic_link_vpc_id') classic_link_vpc_security_groups = module.params.get( 'classic_link_vpc_security_groups') bdm = BlockDeviceMapping() if user_data_path: try: with open(user_data_path, 'r') as user_data_file: user_data = user_data_file.read() except IOError as e: module.fail_json(msg=str(e), exception=traceback.format_exc()) if volumes: for volume in volumes: if 'device_name' not in volume: module.fail_json(msg='Device name must be set for volume') # Minimum volume size is 1GB. We'll use volume size explicitly set to 0 # to be a signal not to create this volume if 'volume_size' not in volume or int(volume['volume_size']) > 0: bdm[volume['device_name']] = create_block_device( module, volume) lc = LaunchConfiguration( name=name, image_id=image_id, key_name=key_name, security_groups=security_groups, user_data=user_data, block_device_mappings=[bdm], instance_type=instance_type, kernel_id=kernel_id, spot_price=spot_price, instance_monitoring=instance_monitoring, associate_public_ip_address=assign_public_ip, ramdisk_id=ramdisk_id, instance_profile_name=instance_profile_name, ebs_optimized=ebs_optimized, classic_link_vpc_security_groups=classic_link_vpc_security_groups, classic_link_vpc_id=classic_link_vpc_id, ) launch_configs = connection.get_all_launch_configurations(names=[name]) changed = False if not launch_configs: try: connection.create_launch_configuration(lc) launch_configs = connection.get_all_launch_configurations( names=[name]) changed = True except BotoServerError as e: module.fail_json(msg=str(e)) result = dict( ((a[0], a[1]) for a in vars(launch_configs[0]).items() if a[0] not in ('connection', 'created_time', 'instance_monitoring', 'block_device_mappings'))) result['created_time'] = str(launch_configs[0].created_time) # Looking at boto's launchconfig.py, it looks like this could be a boolean # value or an object with an enabled attribute. The enabled attribute # could be a boolean or a string representation of a boolean. Since # I can't test all permutations myself to see if my reading of the code is # correct, have to code this *very* defensively if launch_configs[0].instance_monitoring is True: result['instance_monitoring'] = True else: try: result['instance_monitoring'] = module.boolean( launch_configs[0].instance_monitoring.enabled) except AttributeError: result['instance_monitoring'] = False if launch_configs[0].block_device_mappings is not None: result['block_device_mappings'] = [] for bdm in launch_configs[0].block_device_mappings: result['block_device_mappings'].append( dict(device_name=bdm.device_name, virtual_name=bdm.virtual_name)) if bdm.ebs is not None: result['block_device_mappings'][-1]['ebs'] = dict( snapshot_id=bdm.ebs.snapshot_id, volume_size=bdm.ebs.volume_size) if user_data_path: result[ 'user_data'] = "hidden" # Otherwise, we dump binary to the user's terminal module.exit_json(changed=changed, name=result['name'], created_time=result['created_time'], image_id=result['image_id'], arn=result['launch_configuration_arn'], security_groups=result['security_groups'], instance_type=result['instance_type'], result=result)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( { 'region': { 'required': True, 'aliases': ['aws_region', 'ec2_region'] }, 'owner': { 'required': False, 'default': None }, 'ami_id': {'required': False}, 'ami_tags': { 'required': False, 'type': 'dict', 'aliases': ['search_tags', 'image_tags'] }, 'architecture': {'required': False}, 'hypervisor': {'required': False}, 'is_public': {'required': False}, 'name': {'required': False}, 'platform': {'required': False}, 'sort': { 'required': False, 'default': None, 'choices': ['name', 'description', 'tag'] }, 'sort_tag': {'required': False}, 'sort_order': { 'required': False, 'default': 'ascending', 'choices': ['ascending', 'descending'] }, 'sort_start': {'required': False}, 'sort_end': {'required': False}, 'state': {'required': False, 'default': 'available'}, 'virtualization_type': {'required': False}, 'no_result_action': { 'required': False, 'default': 'success', 'choices': ['success', 'fail'] }, } ) module = AnsibleModule( argument_spec=argument_spec, ) if not HAS_BOTO: module.fail_json( msg=""" boto required for this module, install via pip or your package manager""" ) ec2 = ec2_connect(module) # get the image_results, and parsed filters images_result, filters = get_all_images_filtered(ec2, module) # verify we have results no_result_action = module.params.get('no_result_action') if no_result_action == 'fail' and len(images_result) == 0: module.fail_json(msg="No AMIs matched the attributes: %s" % json.dumps(filters)) results = sort_results(images_result, module) module.exit_json(results=results)
def main(): argument_spec = ec2_argument_spec() argument_spec.update(dict( device_id=dict(required=False, aliases=['instance_id']), public_ip=dict(required=False, aliases=['ip']), state=dict(required=False, default='present', choices=['present', 'absent']), in_vpc=dict(required=False, type='bool', default=False), reuse_existing_ip_allowed=dict(required=False, type='bool', default=False), release_on_disassociation=dict(required=False, type='bool', default=False), allow_reassociation=dict(type='bool', default=False), wait_timeout=dict(default=300), private_ip_address=dict(required=False, default=None, type='str') )) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True ) if not HAS_BOTO: module.fail_json(msg='boto required for this module') ec2 = ec2_connect(module) device_id = module.params.get('device_id') instance_id = module.params.get('instance_id') public_ip = module.params.get('public_ip') private_ip_address = module.params.get('private_ip_address') state = module.params.get('state') in_vpc = module.params.get('in_vpc') domain = 'vpc' if in_vpc else None reuse_existing_ip_allowed = module.params.get('reuse_existing_ip_allowed') release_on_disassociation = module.params.get('release_on_disassociation') allow_reassociation = module.params.get('allow_reassociation') # Parameter checks if private_ip_address is not None and device_id is None: module.fail_json(msg="parameters are required together: ('device_id', 'private_ip_address')") if instance_id: warnings = ["instance_id is no longer used, please use device_id going forward"] is_instance = True device_id = instance_id else: if device_id and device_id.startswith('i-'): is_instance = True elif device_id: if device_id.startswith('eni-') and not in_vpc: module.fail_json(msg="If you are specifying an ENI, in_vpc must be true") is_instance = False try: if device_id: address = find_address(ec2, public_ip, device_id, isinstance=is_instance) else: address = find_address(ec2, public_ip, None) if state == 'present': if device_id: result = ensure_present(ec2, module, domain, address, private_ip_address, device_id, reuse_existing_ip_allowed, allow_reassociation, module.check_mode, isinstance=is_instance) else: if address: changed = False else: address, changed = allocate_address(ec2, domain, reuse_existing_ip_allowed) result = {'changed': changed, 'public_ip': address.public_ip, 'allocation_id': address.allocation_id} else: if device_id: disassociated = ensure_absent(ec2, domain, address, device_id, module.check_mode, isinstance=is_instance) if release_on_disassociation and disassociated['changed']: released = release_address(ec2, address, module.check_mode) result = {'changed': True, 'disassociated': disassociated, 'released': released} else: result = {'changed': disassociated['changed'], 'disassociated': disassociated, 'released': {'changed': False}} else: released = release_address(ec2, address, module.check_mode) result = {'changed': released['changed'], 'disassociated': {'changed': False}, 'released': released} except (boto.exception.EC2ResponseError, EIPException) as e: module.fail_json(msg=str(e)) if instance_id: result['warnings'] = warnings module.exit_json(**result)
def main(): argument_spec = ec2_argument_spec() argument_spec.update(dict( resource = dict(required=True), tags = dict(type='dict'), state = dict(default='present', choices=['present', 'absent', 'list']), ) ) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if not HAS_BOTO: module.fail_json(msg='boto required for this module') resource = module.params.get('resource') tags = module.params.get('tags') state = module.params.get('state') ec2 = ec2_connect(module) # We need a comparison here so that we can accurately report back changed status. # Need to expand the gettags return format and compare with "tags" and then tag or detag as appropriate. filters = {'resource-id' : resource} gettags = ec2.get_all_tags(filters=filters) dictadd = {} dictremove = {} baddict = {} tagdict = {} for tag in gettags: tagdict[tag.name] = tag.value if state == 'present': if not tags: module.fail_json(msg="tags argument is required when state is present") if set(tags.items()).issubset(set(tagdict.items())): module.exit_json(msg="Tags already exists in %s." %resource, changed=False) else: for (key, value) in set(tags.items()): if (key, value) not in set(tagdict.items()): dictadd[key] = value if not module.check_mode: ec2.create_tags(resource, dictadd) module.exit_json(msg="Tags %s created for resource %s." % (dictadd,resource), changed=True) if state == 'absent': if not tags: module.fail_json(msg="tags argument is required when state is absent") for (key, value) in set(tags.items()): if (key, value) not in set(tagdict.items()): baddict[key] = value if set(baddict) == set(tags): module.exit_json(msg="Nothing to remove here. Move along.", changed=False) for (key, value) in set(tags.items()): if (key, value) in set(tagdict.items()): dictremove[key] = value if not module.check_mode: ec2.delete_tags(resource, dictremove) module.exit_json(msg="Tags %s removed for resource %s." % (dictremove,resource), changed=True) if state == 'list': module.exit_json(changed=False, tags=tagdict)
def main(): argument_spec = ec2_argument_spec() argument_spec.update(dict( owner=dict(required=False, default=None), ami_id=dict(required=False), ami_tags=dict(required=False, type='dict', aliases=['search_tags', 'image_tags']), architecture=dict(required=False), hypervisor=dict(required=False), is_public=dict(required=False, type='bool'), name=dict(required=False), platform=dict(required=False), product_code=dict(required=False), sort=dict(required=False, default=None, choices=['name', 'description', 'tag', 'architecture', 'block_device_mapping', 'creationDate', 'hypervisor', 'is_public', 'location', 'owner_id', 'platform', 'root_device_name', 'root_device_type', 'state', 'virtualization_type']), sort_tag=dict(required=False), sort_order=dict(required=False, default='ascending', choices=['ascending', 'descending']), sort_start=dict(required=False), sort_end=dict(required=False), state=dict(required=False, default='available'), virtualization_type=dict(required=False), no_result_action=dict(required=False, default='success', choices=['success', 'fail']), ) ) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) module.deprecate("The 'ec2_ami_find' module has been deprecated. Use 'ec2_ami_facts' instead.", version=2.9) if not HAS_BOTO: module.fail_json(msg='boto required for this module, install via pip or your package manager') ami_id = module.params.get('ami_id') ami_tags = module.params.get('ami_tags') architecture = module.params.get('architecture') hypervisor = module.params.get('hypervisor') is_public = module.params.get('is_public') name = module.params.get('name') owner = module.params.get('owner') platform = module.params.get('platform') product_code = module.params.get('product_code') root_device_type = module.params.get('root_device_type') sort = module.params.get('sort') sort_tag = module.params.get('sort_tag') sort_order = module.params.get('sort_order') sort_start = module.params.get('sort_start') sort_end = module.params.get('sort_end') state = module.params.get('state') virtualization_type = module.params.get('virtualization_type') no_result_action = module.params.get('no_result_action') filter = {'state': state} if ami_id: filter['image_id'] = ami_id if ami_tags: for tag in ami_tags: filter['tag:' + tag] = ami_tags[tag] if architecture: filter['architecture'] = architecture if hypervisor: filter['hypervisor'] = hypervisor if is_public: filter['is_public'] = 'true' if name: filter['name'] = name if platform: filter['platform'] = platform if product_code: filter['product-code'] = product_code if root_device_type: filter['root_device_type'] = root_device_type if virtualization_type: filter['virtualization_type'] = virtualization_type ec2 = ec2_connect(module) images_result = ec2.get_all_images(owners=owner, filters=filter) if no_result_action == 'fail' and len(images_result) == 0: module.fail_json(msg="No AMIs matched the attributes: %s" % json.dumps(filter)) results = [] for image in images_result: data = { 'ami_id': image.id, 'architecture': image.architecture, 'block_device_mapping': get_block_device_mapping(image), 'creationDate': image.creationDate, 'description': image.description, 'hypervisor': image.hypervisor, 'is_public': image.is_public, 'location': image.location, 'name': image.name, 'owner_id': image.owner_id, 'platform': image.platform, 'root_device_name': image.root_device_name, 'root_device_type': image.root_device_type, 'state': image.state, 'tags': image.tags, 'virtualization_type': image.virtualization_type, } if image.kernel_id: data['kernel_id'] = image.kernel_id if image.ramdisk_id: data['ramdisk_id'] = image.ramdisk_id results.append(data) if sort == 'tag': if not sort_tag: module.fail_json(msg="'sort_tag' option must be given with 'sort=tag'") results.sort(key=lambda e: e['tags'][sort_tag], reverse=(sort_order == 'descending')) elif sort: results.sort(key=lambda e: e[sort], reverse=(sort_order == 'descending')) try: if sort and sort_start and sort_end: results = results[int(sort_start):int(sort_end)] elif sort and sort_start: results = results[int(sort_start):] elif sort and sort_end: results = results[:int(sort_end)] except TypeError: module.fail_json(msg="Please supply numeric values for sort_start and/or sort_end") module.exit_json(results=results)
def main(): argument_spec = ec2_argument_spec() argument_spec.update( dict( name=dict(), group_id=dict(), description=dict(), vpc_id=dict(), rules=dict(type='list'), rules_egress=dict(type='list'), state=dict(default='present', type='str', choices=['present', 'absent']), purge_rules=dict(default=True, required=False, type='bool'), purge_rules_egress=dict(default=True, required=False, type='bool'), )) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, required_one_of=[['name', 'group_id']], required_if=[['state', 'present', ['name']]], ) if not HAS_BOTO: module.fail_json(msg='boto required for this module') name = module.params['name'] group_id = module.params['group_id'] description = module.params['description'] vpc_id = module.params['vpc_id'] rules = deduplicate_rules_args( rules_expand_sources(rules_expand_ports(module.params['rules']))) rules_egress = deduplicate_rules_args( rules_expand_sources(rules_expand_ports( module.params['rules_egress']))) state = module.params.get('state') purge_rules = module.params['purge_rules'] purge_rules_egress = module.params['purge_rules_egress'] if state == 'present' and not description: module.fail_json(msg='Must provide description when state is present.') changed = False ec2 = ec2_connect(module) # find the group if present group = None groups = {} try: security_groups = ec2.get_all_security_groups() except BotoServerError as e: module.fail_json(msg="Error in get_all_security_groups: %s" % e.message, exception=traceback.format_exc()) for curGroup in security_groups: groups[curGroup.id] = curGroup if curGroup.name in groups: # Prioritise groups from the current VPC if vpc_id is None or curGroup.vpc_id == vpc_id: groups[curGroup.name] = curGroup else: groups[curGroup.name] = curGroup if group_id: if curGroup.id == group_id: group = curGroup else: if curGroup.name == name and (vpc_id is None or curGroup.vpc_id == vpc_id): group = curGroup # Ensure requested group is absent if state == 'absent': if group: # found a match, delete it try: if not module.check_mode: group.delete() except BotoServerError as e: module.fail_json( msg="Unable to delete security group '%s' - %s" % (group, e.message), exception=traceback.format_exc()) else: group = None changed = True else: # no match found, no changes required pass # Ensure requested group is present elif state == 'present': if group: # existing group if group.description != description: module.fail_json( msg= "Group description does not match existing group. ec2_group does not support this case." ) # if the group doesn't exist, create it now else: # no match found, create it if not module.check_mode: group = ec2.create_security_group(name, description, vpc_id=vpc_id) # When a group is created, an egress_rule ALLOW ALL # to 0.0.0.0/0 is added automatically but it's not # reflected in the object returned by the AWS API # call. We re-read the group for getting an updated object # amazon sometimes takes a couple seconds to update the security group so wait till it exists while len( ec2.get_all_security_groups( filters={'group_id': group.id})) == 0: time.sleep(0.1) group = ec2.get_all_security_groups(group_ids=(group.id, ))[0] changed = True else: module.fail_json(msg="Unsupported state requested: %s" % state) # create a lookup for all existing rules on the group if group: # Manage ingress rules groupRules = {} addRulesToLookup(group.rules, 'in', groupRules) # Now, go through all provided rules and ensure they are there. if rules is not None: for rule in rules: validate_rule(module, rule) group_id, ip, target_group_created = get_target_from_rule( module, ec2, rule, name, group, groups, vpc_id) if target_group_created: changed = True if rule['proto'] in ('all', '-1', -1): rule['proto'] = -1 rule['from_port'] = None rule['to_port'] = None # Convert ip to list we can iterate over if not isinstance(ip, list): ip = [ip] # If rule already exists, don't later delete it for thisip in ip: ruleId = make_rule_key('in', rule, group_id, thisip) if ruleId not in groupRules: grantGroup = None if group_id: grantGroup = groups[group_id] if not module.check_mode: group.authorize(rule['proto'], rule['from_port'], rule['to_port'], thisip, grantGroup) changed = True else: del groupRules[ruleId] # Finally, remove anything left in the groupRules -- these will be defunct rules if purge_rules: for (rule, grant) in groupRules.values(): grantGroup = None if grant.group_id: if grant.owner_id != group.owner_id: # this is a foreign Security Group. Since you can't fetch it you must create an instance of it group_instance = SecurityGroup(owner_id=grant.owner_id, name=grant.name, id=grant.group_id) groups[grant.group_id] = group_instance groups[grant.name] = group_instance grantGroup = groups[grant.group_id] if not module.check_mode: group.revoke(rule.ip_protocol, rule.from_port, rule.to_port, grant.cidr_ip, grantGroup) changed = True # Manage egress rules groupRules = {} addRulesToLookup(group.rules_egress, 'out', groupRules) # Now, go through all provided rules and ensure they are there. if rules_egress is not None: for rule in rules_egress: validate_rule(module, rule) group_id, ip, target_group_created = get_target_from_rule( module, ec2, rule, name, group, groups, vpc_id) if target_group_created: changed = True if rule['proto'] in ('all', '-1', -1): rule['proto'] = -1 rule['from_port'] = None rule['to_port'] = None # Convert ip to list we can iterate over if not isinstance(ip, list): ip = [ip] # If rule already exists, don't later delete it for thisip in ip: ruleId = make_rule_key('out', rule, group_id, thisip) if ruleId in groupRules: del groupRules[ruleId] # Otherwise, add new rule else: grantGroup = None if group_id: grantGroup = groups[group_id].id if not module.check_mode: ec2.authorize_security_group_egress( group_id=group.id, ip_protocol=rule['proto'], from_port=rule['from_port'], to_port=rule['to_port'], src_group_id=grantGroup, cidr_ip=thisip) changed = True else: # when no egress rules are specified, # we add in a default allow all out rule, which was the # default behavior before egress rules were added default_egress_rule = 'out--1-None-None-None-0.0.0.0/0' if default_egress_rule not in groupRules: if not module.check_mode: ec2.authorize_security_group_egress(group_id=group.id, ip_protocol=-1, from_port=None, to_port=None, src_group_id=None, cidr_ip='0.0.0.0/0') changed = True else: # make sure the default egress rule is not removed del groupRules[default_egress_rule] # Finally, remove anything left in the groupRules -- these will be defunct rules if purge_rules_egress: for (rule, grant) in groupRules.values(): grantGroup = None if grant.group_id: grantGroup = groups[grant.group_id].id if not module.check_mode: ec2.revoke_security_group_egress( group_id=group.id, ip_protocol=rule.ip_protocol, from_port=rule.from_port, to_port=rule.to_port, src_group_id=grantGroup, cidr_ip=grant.cidr_ip) changed = True if group: module.exit_json(changed=changed, group_id=group.id) else: module.exit_json(changed=changed, group_id=None)
def main(): argument_spec = ec2_argument_spec() argument_spec.update(dict( instance_id = dict(required=True), key_file = dict(required=True, type='path'), key_passphrase = dict(no_log=True, default=None, required=False), wait = dict(type='bool', default=False, required=False), wait_timeout = dict(default=120, required=False), ) ) module = AnsibleModule(argument_spec=argument_spec) if not HAS_BOTO: module.fail_json(msg='Boto required for this module.') instance_id = module.params.get('instance_id') key_file = module.params.get('key_file') b_key_passphrase = to_bytes(module.params.get('key_passphrase'), errors='surrogate_or_strict') wait = module.params.get('wait') wait_timeout = int(module.params.get('wait_timeout')) ec2 = ec2_connect(module) if wait: start = datetime.datetime.now() end = start + datetime.timedelta(seconds=wait_timeout) while datetime.datetime.now() < end: data = ec2.get_password_data(instance_id) decoded = b64decode(data) if wait and not decoded: time.sleep(5) else: break else: data = ec2.get_password_data(instance_id) decoded = b64decode(data) if wait and datetime.datetime.now() >= end: module.fail_json(msg = "wait for password timeout after %d seconds" % wait_timeout) try: f = open(key_file, 'rb') except IOError as e: module.fail_json(msg = "I/O error (%d) opening key file: %s" % (e.errno, e.strerror)) else: try: with f: key = load_pem_private_key(f.read(), b_key_passphrase, BACKEND) except (ValueError, TypeError) as e: module.fail_json(msg = "unable to parse key file") try: decrypted = key.decrypt(decoded, PKCS1v15()) except ValueError as e: decrypted = None if decrypted is None: module.exit_json(win_password='', changed=False) else: if wait: elapsed = datetime.datetime.now() - start module.exit_json(win_password=decrypted, changed=True, elapsed=elapsed.seconds) else: module.exit_json(win_password=decrypted, changed=True)