diff --git a/test/ci-bootstrap.py b/test/ci-bootstrap.py
index 547ebdea57b835511c26ae859d3e3078c79946f4..1ab001c36838821da5163e04214e91234acb3fbb 100755
--- a/test/ci-bootstrap.py
+++ b/test/ci-bootstrap.py
@@ -42,7 +42,7 @@ import subprocess
 import sys
 import traceback
 import yaml
-import cosmos
+import greenhost_cloud
 
 SETTINGS_FILE = './group_vars/all/settings.yml'
 ANSIBLE_INVENTORY = './inventory.yml'
@@ -115,9 +115,9 @@ def main():  # pylint: disable=too-many-statements,too-many-branches
     loglevel = logging.DEBUG if verbose else logging.INFO
     init_logging(log, loglevel)
 
-    # Setup logging for cosmos module
-    log_cosmos = logging.getLogger('cosmos')
-    init_logging(log_cosmos, loglevel)
+    # Setup logging for greenhost_cloud module
+    log_greenhost_cloud = logging.getLogger('greenhost_cloud')
+    init_logging(log_greenhost_cloud, loglevel)
 
     if not args.use_existing_inventory:
         # Start bootstrapping
@@ -138,7 +138,7 @@ def main():  # pylint: disable=too-many-statements,too-many-branches
                     random.choice(string.ascii_lowercase + string.digits)
                     for _ in range(10))
 
-            droplet = cosmos.create_droplet(
+            droplet = greenhost_cloud.create_droplet(
                 name='ci-' + instance_id,
                 ssh_key_id=args.ssh_key_id,
                 region='ams1',
@@ -147,15 +147,15 @@ def main():  # pylint: disable=too-many-statements,too-many-branches
                 image=19)
             droplet_id = droplet['droplet']['id']
             log.info('Created droplet id: %s', droplet_id)
-            cosmos.wait_for_state(droplet_id, 'running')
+            greenhost_cloud.wait_for_state(droplet_id, 'running')
         else:
             droplet_id = args.droplet_id
 
         if verbose:
-            cosmos.list_droplets()
+            greenhost_cloud.list_droplets()
 
         # Get droplet ip
-        droplet = cosmos.get_droplet(droplet_id)
+        droplet = greenhost_cloud.get_droplet(droplet_id)
         droplet_ip = droplet['networks']['v4'][0]['ip_address']
         droplet_name = droplet['name']
 
@@ -197,7 +197,7 @@ def main():  # pylint: disable=too-many-statements,too-many-branches
         log.debug(yaml.safe_dump(settings, default_flow_style=False))
 
         # Wait for ssh
-        cosmos.wait_for_ssh(droplet_ip)
+        greenhost_cloud.wait_for_ssh(droplet_ip)
     else:
         # Work with the master node from the inventory
         with open(ANSIBLE_INVENTORY, 'r') as stream:
@@ -212,18 +212,18 @@ def main():  # pylint: disable=too-many-statements,too-many-branches
 
     if args.create_domain_records:
         # Create domain records
-        domain_record = cosmos.create_domain_record(
+        domain_record = greenhost_cloud.create_domain_record(
             domain='openappstack.net', name=droplet_name + '.ci',
             data=droplet_ip, record_type='A', update=True)
         log.info("Domain record: %s", domain_record)
 
-        domain_record = cosmos.create_domain_record(
+        domain_record = greenhost_cloud.create_domain_record(
             domain='openappstack.net', name='*.' + droplet_name + '.ci',
             data=droplet_name + '.ci', record_type='CNAME', update=True)
         log.info("Domain record: %s", domain_record)
 
         if verbose:
-            cosmos.list_domain_records('openappstack.net')
+            greenhost_cloud.list_domain_records('openappstack.net')
 
     if args.run_ansible:
 
@@ -233,7 +233,7 @@ def main():  # pylint: disable=too-many-statements,too-many-branches
         write_behave_config(settings=settings)
 
     if args.terminate:
-        cosmos.terminate_droplets_by_name(droplet_name)
+        greenhost_cloud.terminate_droplets_by_name(droplet_name)
 
 
 def run_ansible(playbook, ansible_params):
diff --git a/test/cosmos.py b/test/cosmos.py
deleted file mode 100755
index 9655052f4b8a741c73d2877d4a70b5170f558774..0000000000000000000000000000000000000000
--- a/test/cosmos.py
+++ /dev/null
@@ -1,327 +0,0 @@
-#!/usr/bin/env python3
-"""Python module with helper functions to use the cosmos API."""
-
-import json
-from datetime import datetime
-from datetime import timedelta
-import logging
-import os
-import re
-import socket
-from time import sleep
-
-import requests
-from tabulate import tabulate
-from pytz import timezone
-
-# Helper functions
-def request_api(resource: str, request_type: str = 'GET',
-                data: str = ''):
-    """Query the cosmos API."""
-    if 'COSMOS_API_TOKEN' in os.environ:
-        api_token = os.environ['COSMOS_API_TOKEN']
-    else:
-        raise ValueError('Please export the COSMOS_API_TOKEN '
-                         'environment variable.')
-
-    headers = {'Content-Type': 'application/json',
-               'Authorization': 'Bearer {0}'.format(api_token)}
-    api_url_base = 'https://service.greenhost.net/api/v2'
-    api_url = '{0}/{1}'.format(api_url_base, resource)
-
-    if request_type == 'GET':
-        response = requests.get(api_url, headers=headers)
-    elif request_type == 'DELETE':
-        response = requests.delete(api_url, headers=headers)
-    elif request_type == 'POST':
-        response = requests.post(
-            api_url, headers=headers, data=json.dumps(data))
-    elif request_type == 'PUT':
-        response = requests.put(
-            api_url, headers=headers, data=json.dumps(data))
-    else:
-        raise ValueError('Specify one of GET/DELETE/POST/PUT as request_type.')
-
-    log.debug('Request: %s, %s, data: %s',
-              response.url, request_type, data)
-    log.debug('Response code: %s', response.status_code)
-
-    status_code_ok = [200, 201, 202, 204]
-    if response.status_code in status_code_ok:
-        if response.content:
-            log.debug('Response: %s\n', response.json())
-            return json.loads(response.content.decode('utf-8'))
-        else:
-            return None
-    else:
-        raise requests.HTTPError('WARNING: Got response code ',
-                                 response.status_code, response.text)
-
-
-# API calls
-def create_domain_record(domain: str, name: str, data: str,
-                         record_type: str = 'A', update: bool = False):
-    """Create domain record.
-
-    If 'update' is set to True, the record will be updated if it exists.
-    """
-    log.info('Creating domain record')
-
-    record = {
-        'name': name,
-        'data': data,
-        'type': record_type
-    }
-    # Check if record exists
-    existing_record = get_domain_record_by_name(domain=domain, name=name,
-                                                record_type=record_type)
-    if existing_record:
-        if update:
-            log.info('Domain record exists - Updating the record.')
-            response = request_api(
-                'domains/%s/records/%s' % (domain, existing_record['id']),
-                'PUT', record)
-        else:
-            raise ValueError('Domain record exists - Doing nothing,'
-                             'please use "update=True" to update existing'
-                             'records.')
-    else:
-        log.info('Creating new record.')
-        response = request_api('domains/%s/records/' % domain, 'POST', record)
-
-    return response['domain_record']
-
-
-def create_droplet(name: str, ssh_key_id: int, region: str = 'ams1',
-                   size: int = 2048, disk: int = 20, image: int = 18):
-    """Create a droplet.
-
-    Required values:
-      - name (str): Name of the droplet
-      - ssh_key_id (int): ssh key id to add
-
-    Optional values with their default values:
-      - image (str): 18 (Ubuntu 18.04 x64)
-      - region (str): 'ams1' (Amsterdam 1)
-      - size (int): 2048 (2GB RAM)
-      - disk (int): 20 (20GB disk space)
-    """
-    log.info('Creating droplet')
-
-    data = {
-        "name": name,
-        "region": region,
-        "size": size,
-        "disk": disk,
-        "image": image,
-        "ssh_keys": ssh_key_id
-    }
-    response = request_api('droplet', 'POST', data)
-    return response
-
-
-def delete_domain_record(domain: str, id: int):
-    """Delete a domain record."""
-    log.info('Deleting domain record %s', id)
-    response = request_api('domains/{0}/records/{1}'.format(domain, id),
-                           'DELETE')
-    return response
-
-
-def delete_domain_records_by_name(domain: str, name_regex: str):
-    """Delete all domain records in a given domain matching a regex.
-
-    Examples:
-      delete_domain_records_by_name('openappstack.net', '^\*.ci-')
-      delete_domain_records_by_name('openappstack.net', '^ci-')
-    """
-    all = get_domain_records_by_name(domain, name_regex)
-    for record in all:
-        delete_domain_record(domain, record['id'])
-
-
-def delete_droplet(id: int):
-    """Delete a droplet. Droplet needs to be stopped first."""
-    log.info('Deleting %s', id)
-    response = request_api('droplets/{0}'.format(id), 'DELETE')
-    return response
-
-
-def get_domain_record(domain: str, id: int):
-    """Get details for given domain record."""
-    response = request_api('domains/{0}/records/{1}'.format(domain, id))
-    return response['domain_record']
-
-
-def get_domain_records(domain: str):
-    """Get domain records for given domain."""
-    response = request_api('domains/{0}/records'.format(domain))
-    return response['domain_records']
-
-
-def get_domain_record_by_name(domain: str, name: str,
-                              record_type: str = 'A'):
-    """
-    Get domain record for given name and type.
-
-    Example:
-    get_domain_record_by_name(domain='openappstack.net', name='varac-oas')
-    """
-    records = get_domain_records(domain=domain)
-    matching = None
-    for record in records:
-        if record['name'] == name and record['type'] == record_type:
-            matching = record
-            break
-    if not matching:
-        log.info('No domain record found.')
-
-    return matching
-
-
-def get_domain_records_by_name(domain: str, name_regex: str):
-    r"""
-    Get all information about domain records matching a regex in their names.
-
-    Example:
-        get_domain_records_by_name(name_regex='^ci\d+')
-    """
-    all_records = get_domain_records(domain)
-    matching = [record for record in all_records
-                if re.match(name_regex, record['name'])]
-    return matching
-
-
-def get_droplets():
-    """Get all information about all droplets."""
-    response = request_api('droplets')
-    return response['droplets']
-
-
-def get_droplets_by_name(name_regex: str):
-    r"""
-    Get all information about droplets matching a regex in their names.
-
-    Example:
-        get_droplets_by_name(name_regex='^ci\d+')
-    """
-    all_droplets = get_droplets()
-    matching = [droplet for droplet in all_droplets
-                if re.match('^ci+', droplet['name'])]
-    return matching
-
-
-def get_droplet(id: int):
-    """Get information about specified droplet."""
-    response = request_api('droplets/{0}'.format(id))
-    return response['droplet']
-
-
-def list_domain_records(domain: str):
-    """List domain records for given domain."""
-    records = get_domain_records(domain)
-
-    log.debug(json.dumps(records, sort_keys=True, indent=2))
-
-    table_records = [[
-        record['id'], record['name'], record['type'], record['data']]
-        for record in records]
-    log.info(tabulate(table_records,
-             headers=['ID', 'Name', 'Type', 'Data']))
-
-
-def list_droplets():
-    """List all droplets by their ID, Name, IP and state."""
-    droplets = get_droplets()
-
-    log.debug(json.dumps(droplets, sort_keys=True, indent=2))
-
-    table_droplets = [
-        [
-            droplet['id'],
-            droplet['name'],
-            ', '.join([x['ip_address'] for x in droplet['networks']['v4']]),
-            droplet['status']
-        ]
-        for droplet in droplets]
-
-    log.info(tabulate(table_droplets,
-                      headers=['ID', 'Name', 'IPv4', 'Status']))
-
-
-def shutdown_droplet(id: int):
-    """Shut down specified droplet (through a power_off call)."""
-    log.info('Shutting down %s', id)
-    data = {"type": "power_off"}
-    response = request_api('droplets/{0}/actions'.format(id), 'POST', data)
-    return response
-
-
-def status_droplet(id: int):
-    """Get status of specified droplet."""
-    response = get_droplet(id)
-    return response['status']
-
-
-def terminate_droplet(id: int):
-    """Terminate a droplet by powering it down and deleting it."""
-    shutdown_droplet(id)
-    wait_for_state(id, 'stopped')
-    delete_droplet(id)
-
-
-def terminate_droplets_by_name(name_regex: str, ndays: int = 0, domain: str = 'openappstack.net'):
-    r"""
-    Terminate droplets matching a regex and for x days older than current day. 
-    Droplets defined on the env variable NO_TERMINATE_DROPLETS will not be delated
-
-    Example how to terminate all CI instances:
-        terminate_old_droplets(name_regex='^ci\d+', ndays=5)
-      will match i.e 'ci1234' , 'ci1', with a creation time older than 5 days
-    """
-
-    threshold_time = (datetime.now(tz=timezone('Europe/Stockholm')) - timedelta(days=ndays)).strftime("%Y-%m-%dT%H:%M:%S+00:00")
-    all = get_droplets()
-
-    noterminate_droplets = []
-    if 'NO_TERMINATE_DROPLETS' in os.environ:
-        noterminate_droplets = os.environ['NO_TERMINATE_DROPLETS'].split(',')
-
-    for droplet in all:
-        if droplet['name'] not in noterminate_droplets:
-            if re.match(name_regex, droplet['name']):
-                if droplet['created_at'] < threshold_time:
-                    delete_domain_records_by_name(domain, '^\*.'+droplet['name'])
-                    delete_domain_records_by_name(domain, '^'+droplet['name'])
-                    terminate_droplet(droplet['id'])
-
-def wait_for_ssh(ip: str):
-    """Wait for ssh to be reachable on port 22."""
-    log.info('Waiting for ssh to become available on ip %s', ip)
-
-    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
-    while sock.connect_ex((ip, 22)) != 0:
-        sleep(1)
-
-
-def wait_for_state(id: int, state):
-    """Wait for a droplet to reach a certain state."""
-    log.info('Waiting for droplet %s to reach %s state...', id, state)
-    status = status_droplet(id)
-    log.debug(status)
-
-    while status != state:
-        sleep(1)
-        status = status_droplet(id)
-
-
-# When called from from ipython, setup
-# logging to console
-try:
-    __IPYTHON__
-    log = logging.getLogger()
-    log.addHandler(logging.StreamHandler())
-    log.setLevel(logging.INFO)
-except NameError:
-    log = logging.getLogger(__name__)
diff --git a/test/requirements.txt b/test/requirements.txt
index 480ce481e2e2b8ef90e6394397a233592401592d..e52588ecc58589dec2786fb48c36b00936315683 100644
--- a/test/requirements.txt
+++ b/test/requirements.txt
@@ -15,4 +15,4 @@ testinfra>=2.0.0
 setuptools>=40.6.2
 wheel>=0.33.1
 pytz>=2019.1
-
+-e git://open.greenhost.net/greenhost/cosmos-api@5fc6125d3cf481bca3639650c7d1983e6db44621#egg=greenhost_cloud