Creates a new server instance.  This call blocks until the server is
        created and available for normal use, or :attr:`timeout_s` has elapsed.

        :param str basename:  An identifier for the server.  A random postfix
            will be appended to this basename to work around OpenStack Nova
            REST API limitations.

        :param str disk_image_id:  The identifier of the base disk image to use
            as the rootfs.

        :param str instance_type:  The name of an EC2 instance type.

        :param str ssh_key_name:  The name of the ssh key to inject into the
            target server's ``authorized_keys`` file.  The key must already
            have been registered in the target EC2 region.

        :param tags:  Up to 5 key-value pairs of arbitrary strings to use as
            *tags* for the server instance.
        :type tags:  :class:`Mapping`

        :param str availability_zone:  The name of the availability zone in
            which to place the server.

        :param float timeout_s:  The number of seconds to poll for an active
            server before failing.  Defaults to ``0`` (i.e. Expect server to be
            active immediately).

        :rtype:  :class:`dict`

def create_server(self, basename, disk_image_id, instance_type,
            ssh_key_name, tags=None, availability_zone=None,
            timeout_s=DEFAULT_TIMEOUT_S, **provider_extras):
        """
        Creates a new server instance.  This call blocks until the server is
        created and available for normal use, or :attr:`timeout_s` has elapsed.

        :param str basename:  An identifier for the server.  A random postfix
            will be appended to this basename to work around OpenStack Nova
            REST API limitations.

        :param str disk_image_id:  The identifier of the base disk image to use
            as the rootfs.

        :param str instance_type:  The name of an EC2 instance type.

        :param str ssh_key_name:  The name of the ssh key to inject into the
            target server's ``authorized_keys`` file.  The key must already
            have been registered in the target EC2 region.

        :param tags:  Up to 5 key-value pairs of arbitrary strings to use as
            *tags* for the server instance.
        :type tags:  :class:`Mapping`

        :param str availability_zone:  The name of the availability zone in
            which to place the server.

        :param float timeout_s:  The number of seconds to poll for an active
            server before failing.  Defaults to ``0`` (i.e. Expect server to be
            active immediately).

        :rtype:  :class:`dict`

        """
        log.info(
                'Launching server %s... this could take a while...'
                % basename
                )
        if 'disable_api_termination' not in provider_extras:
            provider_extras['disable_api_termination'] = True

        # ec2 api has the following rule:
        #
        #     if you specify a subnet_id, you must specify secgroups as
        #     security_group_ids
        #
        # so, we'll assume that if you specify a subnet_id, you don't mean to
        # have secgroups
        if 'subnet_id' in provider_extras:
            secgroups = provider_extras.pop('security_groups', None)
            if secgroups:
                log.warn(
                        "... When using subnet_id you must use"
                        " security_group_ids.  Ignoring security_groups %s."
                        % secgroups
                        )

        res = self.ec2.run_instances(
                disk_image_id,
                instance_type=instance_type,
                key_name=ssh_key_name,
                placement=availability_zone,
                **provider_extras
                )
        instance = res.instances[0]

        # we're too fast for EC2... slow down a little bit, twice
        time.sleep(2)

        def apply_tags():
            try:
                for key, val in tags.items():
                    instance.add_tag(key, val)
                return True
            except EC2ResponseError:
                pass
        if not poll_with_timeout(timeout_s, apply_tags, 5):
            raise TimeoutError('Could not tag server %s' % instance.id)

        def find_running_instance():
            if instance.update() == 'running':
                return instance
        running = poll_with_timeout(timeout_s, find_running_instance, 5)
        if not running:
            raise TimeoutError('Could not launch server within allotted time.')
        return server_to_dict(running)