Ensure the IAM role exists.

    name
        Name of the IAM role.

    policy_document
        The policy that grants an entity permission to assume the role.
        (See https://boto.readthedocs.io/en/latest/ref/iam.html#boto.iam.connection.IAMConnection.create_role)

    policy_document_from_pillars
        A pillar key that contains a role policy document. The statements
        defined here will be appended with the policy document statements
        defined in the policy_document argument.

        .. versionadded:: 2017.7.0

    path
        The path to the role/instance profile.
        (See https://boto.readthedocs.io/en/latest/ref/iam.html#boto.iam.connection.IAMConnection.create_role)

    policies
        A dict of IAM role policies.

    policies_from_pillars
        A list of pillars that contain role policy dicts. Policies in the
        pillars will be merged in the order defined in the list and key
        conflicts will be handled by later defined keys overriding earlier
        defined keys. The policies defined here will be merged with the
        policies defined in the policies argument. If keys conflict, the keys
        in the policies argument will override the keys defined in
        policies_from_pillars.

    managed_policies
        A list of (AWS or Customer) managed policies to be attached to the role.

    create_instance_profile
        A boolean of whether or not to create an instance profile and associate
        it with this role.

    region
        Region to connect to.

    key
        Secret key to be used.

    keyid
        Access key to be used.

    profile
        A dict with region, key and keyid, or a pillar key (string)
        that contains a dict with region, key and keyid.

    delete_policies
        Deletes existing policies that are not in the given list of policies. Default
        value is ``True``. If ``False`` is specified, existing policies will not be deleted
        allowing manual modifications on the IAM role to be persistent.

        .. versionadded:: 2015.8.0

def present(
        name,
        policy_document=None,
        policy_document_from_pillars=None,
        path=None,
        policies=None,
        policies_from_pillars=None,
        managed_policies=None,
        create_instance_profile=True,
        region=None,
        key=None,
        keyid=None,
        profile=None,
        delete_policies=True):
    '''
    Ensure the IAM role exists.

    name
        Name of the IAM role.

    policy_document
        The policy that grants an entity permission to assume the role.
        (See https://boto.readthedocs.io/en/latest/ref/iam.html#boto.iam.connection.IAMConnection.create_role)

    policy_document_from_pillars
        A pillar key that contains a role policy document. The statements
        defined here will be appended with the policy document statements
        defined in the policy_document argument.

        .. versionadded:: 2017.7.0

    path
        The path to the role/instance profile.
        (See https://boto.readthedocs.io/en/latest/ref/iam.html#boto.iam.connection.IAMConnection.create_role)

    policies
        A dict of IAM role policies.

    policies_from_pillars
        A list of pillars that contain role policy dicts. Policies in the
        pillars will be merged in the order defined in the list and key
        conflicts will be handled by later defined keys overriding earlier
        defined keys. The policies defined here will be merged with the
        policies defined in the policies argument. If keys conflict, the keys
        in the policies argument will override the keys defined in
        policies_from_pillars.

    managed_policies
        A list of (AWS or Customer) managed policies to be attached to the role.

    create_instance_profile
        A boolean of whether or not to create an instance profile and associate
        it with this role.

    region
        Region to connect to.

    key
        Secret key to be used.

    keyid
        Access key to be used.

    profile
        A dict with region, key and keyid, or a pillar key (string)
        that contains a dict with region, key and keyid.

    delete_policies
        Deletes existing policies that are not in the given list of policies. Default
        value is ``True``. If ``False`` is specified, existing policies will not be deleted
        allowing manual modifications on the IAM role to be persistent.

        .. versionadded:: 2015.8.0
    '''
    ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
    # Build up _policy_document
    _policy_document = {}
    if policy_document_from_pillars:
        from_pillars = __salt__['pillar.get'](policy_document_from_pillars)
        if from_pillars:
            _policy_document['Version'] = from_pillars['Version']
            _policy_document.setdefault('Statement', [])
            _policy_document['Statement'].extend(from_pillars['Statement'])
    if policy_document:
        _policy_document['Version'] = policy_document['Version']
        _policy_document.setdefault('Statement', [])
        _policy_document['Statement'].extend(policy_document['Statement'])
    _ret = _role_present(name, _policy_document, path, region, key, keyid,
                         profile)

    # Build up _policies
    if not policies:
        policies = {}
    if not policies_from_pillars:
        policies_from_pillars = []
    if not managed_policies:
        managed_policies = []
    _policies = {}
    for policy in policies_from_pillars:
        _policy = __salt__['pillar.get'](policy)
        _policies.update(_policy)
    _policies.update(policies)
    ret['changes'] = _ret['changes']
    ret['comment'] = ' '.join([ret['comment'], _ret['comment']])
    if not _ret['result']:
        ret['result'] = _ret['result']
        if ret['result'] is False:
            return ret
    if create_instance_profile:
        _ret = _instance_profile_present(name, region, key, keyid, profile)
        ret['changes'] = dictupdate.update(ret['changes'], _ret['changes'])
        ret['comment'] = ' '.join([ret['comment'], _ret['comment']])
        if not _ret['result']:
            ret['result'] = _ret['result']
            if ret['result'] is False:
                return ret
        _ret = _instance_profile_associated(name, region, key, keyid, profile)
        ret['changes'] = dictupdate.update(ret['changes'], _ret['changes'])
        ret['comment'] = ' '.join([ret['comment'], _ret['comment']])
        if not _ret['result']:
            ret['result'] = _ret['result']
            if ret['result'] is False:
                return ret
    _ret = _policies_present(name, _policies, region, key, keyid, profile,
                             delete_policies)
    ret['changes'] = dictupdate.update(ret['changes'], _ret['changes'])
    ret['comment'] = ' '.join([ret['comment'], _ret['comment']])
    if not _ret['result']:
        ret['result'] = _ret['result']
    _ret = _policies_attached(name, managed_policies, region, key, keyid, profile)
    ret['changes'] = dictupdate.update(ret['changes'], _ret['changes'])
    ret['comment'] = ' '.join([ret['comment'], _ret['comment']])
    if not _ret['result']:
        ret['result'] = _ret['result']
    return ret