Exemplo n.º 1
0
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)
Exemplo n.º 2
0
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)
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
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)
Exemplo n.º 6
0
    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'])
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
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)
Exemplo n.º 9
0
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)
Exemplo n.º 10
0
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)
Exemplo n.º 11
0
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)
Exemplo n.º 13
0
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)
Exemplo n.º 14
0
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)
Exemplo n.º 15
0
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)
Exemplo n.º 16
0
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)
Exemplo n.º 17
0
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)
Exemplo n.º 18
0
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)