async def create_vm(self, preset_name, image, flavor, security_groups=None,
                        userdata=None, key_name=None, availability_zone=None, subnets=None):
        '''
          Create VM
         :arg preset_name: string
         :arg image: string image id
         :arg flavor: string flavor id
         :arg security_groups:  list
         :arg userdata: string
         :arg key_name: string
         :arg availability_zone: string
         :arg subnets: list
         :returns list Vm objects
         @TODO
         1. returns image id
        '''
        image_id = self.images_map.inv.get(image)
        flavor_id = self.flavors_map.inv.get(flavor)
        spec = {
            "name": preset_name,
            "flavorRef": flavor_id,
            "imageRef": image_id,
            "security_groups": [{"name": group} for group in security_groups],
            "user_data": userdata
        }
        if availability_zone is not None:
            spec.update({"availability_zone": availability_zone})
        if subnets is not None:
            spec.update({"networks": [{'uuid': subnet['net-id']} for subnet in subnets]})
        if userdata is not None:
            userdata = userdata.encode('utf-8')
            userdata = base64.b64encode(userdata).decode('utf-8')
            spec.update({"user_data": userdata})

        result = await self.nova.servers.create(server=spec)
        return result["server"]