  def CreateVolumeFromSnapshot(
      self,
      snapshot: AWSSnapshot,
      volume_name: Optional[str] = None,
      volume_name_prefix: Optional[str] = None,
      volume_type: str = 'gp3',
      kms_key_id: Optional[str] = None,
      tags: Optional[Dict[str, str]] = None) -> AWSVolume:
    """Create a new volume based on a snapshot.

    Args:
      snapshot (AWSSnapshot): Snapshot to use.
      volume_name (str): Optional. String to use as new volume name.
      volume_name_prefix (str): Optional. String to prefix the volume name with.
      volume_type (str): Optional. The volume type for the volume to create.
          Can be one of 'standard'|'io1'|'gp2'|'gp3'|'sc1'|'st1'. The default
          is 'gp3'.
      kms_key_id (str): Optional. A KMS key id to encrypt the volume with.
      tags (Dict[str, str]): Optional. A dictionary of tags to add to the
          volume, for example {'TicketID': 'xxx'}. An entry for the volume
          name is added by default.

    Returns:
      AWSVolume: An AWS EBS Volume.

    Raises:
      InvalidNameError: If the volume name does not comply with the RegEx
      ValueError: If the volume type is invalid.
      ResourceCreationError: If the volume could not be created.
    """

    if volume_type not in ['standard', 'io1', 'gp2', 'gp3', 'sc1', 'st1']:
      raise ValueError('Volume type must be one of [standard, io1, gp2, gp3, '
                       'sc1, st1]. Got: {0:s}'.format(volume_type))

    if not volume_name:
      volume_name = self._GenerateVolumeName(
          snapshot, volume_name_prefix=volume_name_prefix)

    if len(volume_name) > 255:
      raise errors.InvalidNameError(
          'Volume name {0:s} is too long (>255 chars)'.format(volume_name),
          __name__)

    if not tags:
      tags = {}
    tags['Name'] = volume_name

    client = self.aws_account.ClientApi(common.EC2_SERVICE)
    create_volume_args = {
        'AvailabilityZone': snapshot.availability_zone,
        'SnapshotId': snapshot.snapshot_id,
        'TagSpecifications': [common.CreateTags(common.VOLUME, tags)],
        'VolumeType': volume_type
    }
    if kms_key_id:
      create_volume_args['Encrypted'] = True  # type: ignore
      create_volume_args['KmsKeyId'] = kms_key_id
    if volume_type == 'io1':
      # If using the io1 volume type, we must specify Iops, see
      # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/
      # services/ec2.html#EC2.Client.create_volume. io1 volumes allow for a
      # ratio of 50 IOPS per 1 GiB.
      create_volume_args['Iops'] = self.aws_account.ResourceApi(
          common.EC2_SERVICE).Snapshot(snapshot.snapshot_id).volume_size * 50
    try:
      volume = client.create_volume(**create_volume_args)
      volume_id = volume['VolumeId']
      # Wait for volume creation completion
      client.get_waiter('volume_available').wait(VolumeIds=[volume_id])
    except (client.exceptions.ClientError,
            botocore.exceptions.WaiterError) as exception:
      raise errors.ResourceCreationError(
          'Could not create volume {0:s} from snapshot {1:s}: {2!s}'.format(
              volume_name, snapshot.name, exception), __name__) from exception

    zone = volume['AvailabilityZone']
    encrypted = volume['Encrypted']

    return AWSVolume(volume_id,
                     self.aws_account,
                     self.aws_account.default_region,
                     zone,
                     encrypted,
                     name=volume_name)
Create a new volume based on a snapshot.

Args:
snapshot (AWSSnapshot): Snapshot to use.
volume_name (str): Optional. String to use as new volume name.
volume_name_prefix (str): Optional. String to prefix the volume name with.
volume_type (str): Optional. The volume type for the volume to create.
Can be one of 'standard'|'io1'|'gp2'|'gp3'|'sc1'|'st1'. The default
is 'gp3'.
kms_key_id (str): Optional. A KMS key id to encrypt the volume with.
tags (Dict[str, str]): Optional. A dictionary of tags to add to the
volume, for example {'TicketID': 'xxx'}. An entry for the volume
name is added by default.

Returns:
AWSVolume: An AWS EBS Volume.

Raises:
InvalidNameError: If the volume name does not comply with the RegEx
ValueError: If the volume type is invalid.
ResourceCreationError: If the volume could not be created.
libcloudforensics/providers/aws/internal/ebs.py