Create a volume.

    zone
        The availability zone used to create the volume. Required. String.

    size
        The size of the volume, in GiBs. Defaults to ``10``. Integer.

    snapshot
        The snapshot-id from which to create the volume. Integer.

    type
        The volume type. This can be gp2 for General Purpose SSD, io1 for Provisioned
        IOPS SSD, st1 for Throughput Optimized HDD, sc1 for Cold HDD, or standard for
        Magnetic volumes. String.

    iops
        The number of I/O operations per second (IOPS) to provision for the volume,
        with a maximum ratio of 50 IOPS/GiB. Only valid for Provisioned IOPS SSD
        volumes. Integer.

        This option will only be set if ``type`` is also specified as ``io1``.

    encrypted
        Specifies whether the volume will be encrypted. Boolean.

        If ``snapshot`` is also given in the list of kwargs, then this value is ignored
        since volumes that are created from encrypted snapshots are also automatically
        encrypted.

    tags
        The tags to apply to the volume during creation. Dictionary.

    call
        The ``create_volume`` function must be called with ``-f`` or ``--function``.
        String.

    wait_to_finish
        Whether or not to wait for the volume to be available. Boolean. Defaults to
        ``False``.

    CLI Examples:

    .. code-block:: bash

        salt-cloud -f create_volume my-ec2-config zone=us-east-1b
        salt-cloud -f create_volume my-ec2-config zone=us-east-1b tags='{"tag1": "val1", "tag2", "val2"}'

def create_volume(kwargs=None, call=None, wait_to_finish=False):
    '''
    Create a volume.

    zone
        The availability zone used to create the volume. Required. String.

    size
        The size of the volume, in GiBs. Defaults to ``10``. Integer.

    snapshot
        The snapshot-id from which to create the volume. Integer.

    type
        The volume type. This can be gp2 for General Purpose SSD, io1 for Provisioned
        IOPS SSD, st1 for Throughput Optimized HDD, sc1 for Cold HDD, or standard for
        Magnetic volumes. String.

    iops
        The number of I/O operations per second (IOPS) to provision for the volume,
        with a maximum ratio of 50 IOPS/GiB. Only valid for Provisioned IOPS SSD
        volumes. Integer.

        This option will only be set if ``type`` is also specified as ``io1``.

    encrypted
        Specifies whether the volume will be encrypted. Boolean.

        If ``snapshot`` is also given in the list of kwargs, then this value is ignored
        since volumes that are created from encrypted snapshots are also automatically
        encrypted.

    tags
        The tags to apply to the volume during creation. Dictionary.

    call
        The ``create_volume`` function must be called with ``-f`` or ``--function``.
        String.

    wait_to_finish
        Whether or not to wait for the volume to be available. Boolean. Defaults to
        ``False``.

    CLI Examples:

    .. code-block:: bash

        salt-cloud -f create_volume my-ec2-config zone=us-east-1b
        salt-cloud -f create_volume my-ec2-config zone=us-east-1b tags='{"tag1": "val1", "tag2", "val2"}'
    '''
    if call != 'function':
        log.error(
            'The create_volume function must be called with -f or --function.'
        )
        return False

    if 'zone' not in kwargs:
        log.error('An availability zone must be specified to create a volume.')
        return False

    if 'size' not in kwargs and 'snapshot' not in kwargs:
        # This number represents GiB
        kwargs['size'] = '10'

    params = {'Action': 'CreateVolume',
              'AvailabilityZone': kwargs['zone']}

    if 'size' in kwargs:
        params['Size'] = kwargs['size']

    if 'snapshot' in kwargs:
        params['SnapshotId'] = kwargs['snapshot']

    if 'type' in kwargs:
        params['VolumeType'] = kwargs['type']

    if 'iops' in kwargs and kwargs.get('type', 'standard') == 'io1':
        params['Iops'] = kwargs['iops']

    # You can't set `encrypted` if you pass a snapshot
    if 'encrypted' in kwargs and 'snapshot' not in kwargs:
        params['Encrypted'] = kwargs['encrypted']
        if 'kmskeyid' in kwargs:
            params['KmsKeyId'] = kwargs['kmskeyid']
    if 'kmskeyid' in kwargs and 'encrypted' not in kwargs:
        log.error(
            'If a KMS Key ID is specified, encryption must be enabled'
        )
        return False

    log.debug(params)

    data = aws.query(params,
                     return_url=True,
                     return_root=True,
                     location=get_location(),
                     provider=get_provider(),
                     opts=__opts__,
                     sigver='4')

    r_data = {}
    for d in data[0]:
        for k, v in six.iteritems(d):
            r_data[k] = v
    volume_id = r_data['volumeId']

    # Allow tags to be set upon creation
    if 'tags' in kwargs:
        if isinstance(kwargs['tags'], six.string_types):
            tags = salt.utils.yaml.safe_load(kwargs['tags'])
        else:
            tags = kwargs['tags']

        if isinstance(tags, dict):
            new_tags = set_tags(tags=tags,
                                resource_id=volume_id,
                                call='action',
                                location=get_location())
            r_data['tags'] = new_tags

    # Waits till volume is available
    if wait_to_finish:
        salt.utils.cloud.run_func_until_ret_arg(fun=describe_volumes,
                                                kwargs={'volume_id': volume_id},
                                                fun_call=call,
                                                argument_being_watched='status',
                                                required_argument_response='available')

    return r_data