Ensure policy exists.

    name
        The name of the state definition

    policyName
        Name of the policy.

    policyDocument
        The JSON document that describes the policy. The length of the
        policyDocument must be a minimum length of 1, with a maximum length of
        2048, excluding whitespace.

    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.

def policy_present(name, policyName, policyDocument,
            region=None, key=None, keyid=None, profile=None):
    '''
    Ensure policy exists.

    name
        The name of the state definition

    policyName
        Name of the policy.

    policyDocument
        The JSON document that describes the policy. The length of the
        policyDocument must be a minimum length of 1, with a maximum length of
        2048, excluding whitespace.

    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.
    '''
    ret = {'name': policyName,
           'result': True,
           'comment': '',
           'changes': {}
           }

    r = __salt__['boto_iot.policy_exists'](policyName=policyName,
                              region=region, key=key, keyid=keyid, profile=profile)

    if 'error' in r:
        ret['result'] = False
        ret['comment'] = 'Failed to create policy: {0}.'.format(r['error']['message'])
        return ret

    if not r.get('exists'):
        if __opts__['test']:
            ret['comment'] = 'Policy {0} is set to be created.'.format(policyName)
            ret['result'] = None
            return ret
        r = __salt__['boto_iot.create_policy'](policyName=policyName,
                                               policyDocument=policyDocument,
                                               region=region, key=key,
                                               keyid=keyid, profile=profile)
        if not r.get('created'):
            ret['result'] = False
            ret['comment'] = 'Failed to create policy: {0}.'.format(r['error']['message'])
            return ret
        _describe = __salt__['boto_iot.describe_policy'](policyName,
                                   region=region, key=key, keyid=keyid, profile=profile)
        ret['changes']['old'] = {'policy': None}
        ret['changes']['new'] = _describe
        ret['comment'] = 'Policy {0} created.'.format(policyName)
        return ret

    ret['comment'] = os.linesep.join([ret['comment'], 'Policy {0} is present.'.format(policyName)])
    ret['changes'] = {}
    # policy exists, ensure config matches
    _describe = __salt__['boto_iot.describe_policy'](policyName=policyName,
                                  region=region, key=key, keyid=keyid, profile=profile)['policy']

    if isinstance(_describe['policyDocument'], six.string_types):
        describeDict = salt.utils.json.loads(_describe['policyDocument'])
    else:
        describeDict = _describe['policyDocument']

    if isinstance(policyDocument, six.string_types):
        policyDocument = salt.utils.json.loads(policyDocument)

    r = salt.utils.data.compare_dicts(describeDict, policyDocument)
    if bool(r):
        if __opts__['test']:
            msg = 'Policy {0} set to be modified.'.format(policyName)
            ret['comment'] = msg
            ret['result'] = None
            return ret

        ret['comment'] = os.linesep.join([ret['comment'], 'Policy to be modified'])
        policyDocument = salt.utils.json.dumps(policyDocument)

        r = __salt__['boto_iot.create_policy_version'](policyName=policyName,
                                               policyDocument=policyDocument,
                                               setAsDefault=True,
                                               region=region, key=key,
                                               keyid=keyid, profile=profile)
        if not r.get('created'):
            ret['result'] = False
            ret['comment'] = 'Failed to update policy: {0}.'.format(r['error']['message'])
            ret['changes'] = {}
            return ret

        __salt__['boto_iot.delete_policy_version'](policyName=policyName,
                                               policyVersionId=_describe['defaultVersionId'],
                                               region=region, key=key,
                                               keyid=keyid, profile=profile)

        ret['changes'].setdefault('new', {})['policyDocument'] = policyDocument
        ret['changes'].setdefault('old', {})['policyDocument'] = _describe['policyDocument']
    return ret