Create a new Route53 Hosted Zone. Returns a Python data structure with information about the
    newly created Hosted Zone.

    domain_name
        The name of the domain. This must be fully-qualified, terminating with a period.  This is
        the name you have registered with your domain registrar.  It is also the name you will
        delegate from your registrar to the Amazon Route 53 delegation servers returned in response
        to this request.

    caller_ref
        A unique string that identifies the request and that allows create_hosted_zone() calls to
        be retried without the risk of executing the operation twice.  It can take several minutes
        for the change to replicate globally, and change from PENDING to INSYNC status. Thus it's
        best to provide some value for this where possible, since duplicate calls while the first
        is in PENDING status will be accepted and can lead to multiple copies of the zone being
        created.  On the other hand, if a zone is created with a given caller_ref, then deleted,
        a second attempt to create a zone with the same caller_ref will fail until that caller_ref
        is flushed from the Route53 system, which can take upwards of 24 hours.

    comment
        Any comments you want to include about the hosted zone.

    private_zone
        Set True if creating a private hosted zone.

    vpc_id
        When creating a private hosted zone, either the VPC ID or VPC Name to associate with is
        required.  Exclusive with vpe_name.  Ignored when creating a non-private zone.

    vpc_name
        When creating a private hosted zone, either the VPC ID or VPC Name to associate with is
        required.  Exclusive with vpe_id.  Ignored when creating a non-private zone.

    vpc_region
        When creating a private hosted zone, the region of the associated VPC is required.  If not
        provided, an effort will be made to determine it from vpc_id or vpc_name, where possible.
        If this fails, you'll need to provide an explicit value for this option.  Ignored when
        creating a non-private zone.

    region
        Region endpoint to connect to.

    key
        AWS key to bind with.

    keyid
        AWS keyid to bind with.

    profile
        Dict, or pillar key pointing to a dict, containing AWS region/key/keyid.

    CLI Example::

        salt myminion boto_route53.create_hosted_zone example.org

def create_hosted_zone(domain_name, caller_ref=None, comment='', private_zone=False, vpc_id=None,
                       vpc_name=None, vpc_region=None, region=None, key=None, keyid=None,
                       profile=None):
    '''
    Create a new Route53 Hosted Zone. Returns a Python data structure with information about the
    newly created Hosted Zone.

    domain_name
        The name of the domain. This must be fully-qualified, terminating with a period.  This is
        the name you have registered with your domain registrar.  It is also the name you will
        delegate from your registrar to the Amazon Route 53 delegation servers returned in response
        to this request.

    caller_ref
        A unique string that identifies the request and that allows create_hosted_zone() calls to
        be retried without the risk of executing the operation twice.  It can take several minutes
        for the change to replicate globally, and change from PENDING to INSYNC status. Thus it's
        best to provide some value for this where possible, since duplicate calls while the first
        is in PENDING status will be accepted and can lead to multiple copies of the zone being
        created.  On the other hand, if a zone is created with a given caller_ref, then deleted,
        a second attempt to create a zone with the same caller_ref will fail until that caller_ref
        is flushed from the Route53 system, which can take upwards of 24 hours.

    comment
        Any comments you want to include about the hosted zone.

    private_zone
        Set True if creating a private hosted zone.

    vpc_id
        When creating a private hosted zone, either the VPC ID or VPC Name to associate with is
        required.  Exclusive with vpe_name.  Ignored when creating a non-private zone.

    vpc_name
        When creating a private hosted zone, either the VPC ID or VPC Name to associate with is
        required.  Exclusive with vpe_id.  Ignored when creating a non-private zone.

    vpc_region
        When creating a private hosted zone, the region of the associated VPC is required.  If not
        provided, an effort will be made to determine it from vpc_id or vpc_name, where possible.
        If this fails, you'll need to provide an explicit value for this option.  Ignored when
        creating a non-private zone.

    region
        Region endpoint to connect to.

    key
        AWS key to bind with.

    keyid
        AWS keyid to bind with.

    profile
        Dict, or pillar key pointing to a dict, containing AWS region/key/keyid.

    CLI Example::

        salt myminion boto_route53.create_hosted_zone example.org
    '''
    if region is None:
        region = 'universal'

    if not domain_name.endswith('.'):
        raise SaltInvocationError('Domain MUST be fully-qualified, complete '
                                  'with ending period.')

    conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)

    deets = conn.get_hosted_zone_by_name(domain_name)
    if deets:
        log.info('Route53 hosted zone %s already exists', domain_name)
        return None

    args = {'domain_name': domain_name,
            'caller_ref': caller_ref,
            'comment': comment,
            'private_zone': private_zone}

    if private_zone:
        if not _exactly_one((vpc_name, vpc_id)):
            raise SaltInvocationError('Either vpc_name or vpc_id is required '
                                      'when creating a private zone.')
        vpcs = __salt__['boto_vpc.describe_vpcs'](
                vpc_id=vpc_id, name=vpc_name, region=region, key=key,
                keyid=keyid, profile=profile).get('vpcs', [])
        if vpc_region and vpcs:
            vpcs = [v for v in vpcs if v['region'] == vpc_region]
        if not vpcs:
            log.error('Private zone requested but a VPC matching given criteria'
                      ' not found.')
            return None
        if len(vpcs) > 1:
            log.error('Private zone requested but multiple VPCs matching given '
                      'criteria found: %s.', [v['id'] for v in vpcs])
            return None
        vpc = vpcs[0]
        if vpc_name:
            vpc_id = vpc['id']
        if not vpc_region:
            vpc_region = vpc['region']
        args.update({'vpc_id': vpc_id, 'vpc_region': vpc_region})
    else:
        if any((vpc_id, vpc_name, vpc_region)):
            log.info('Options vpc_id, vpc_name, and vpc_region are ignored '
                     'when creating non-private zones.')

    r = _try_func(conn, 'create_hosted_zone', **args)
    if r is None:
        log.error('Failed to create hosted zone %s', domain_name)
        return None
    r = r.get('CreateHostedZoneResponse', {})
    # Pop it since it'll be irrelevant by the time we return
    status = r.pop('ChangeInfo', {}).get('Id', '').replace('/change/', '')
    synced = _wait_for_sync(status, conn, wait=600)
    if not synced:
        log.error('Hosted zone %s not synced after 600 seconds.', domain_name)
        return None
    return r