diff --git a/openappstack/__main__.py b/openappstack/__main__.py
index 42284ab1d75ccad545a5ecec9dc1ef320a65065a..720549f936fab601f8dce0dd9ee30eef58ac50bf 100755
--- a/openappstack/__main__.py
+++ b/openappstack/__main__.py
@@ -22,8 +22,9 @@ import argparse
 import logging
 import os
 import sys
+import greenhost_cloud
 from behave.__main__ import main as behave_main
-from openappstack import name, cluster, cosmos, ansible
+from openappstack import name, cluster, ansible
 
 ALL_TESTS = ['behave']
 
@@ -190,9 +191,9 @@ def main():  # pylint: disable=too-many-statements,too-many-branches,too-many-lo
     loglevel = logging.DEBUG if args.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)
 
     log.debug("Parsed arguments: %s", str(args))
 
@@ -204,7 +205,7 @@ def main():  # pylint: disable=too-many-statements,too-many-branches,too-many-lo
     if args.terminate_droplet:
         # In case none of the subparser's functions have been called, load data
         clus.load_data()
-        cosmos.terminate_droplets_by_name('^{}$'.format(clus.hostname))
+        greenhost_cloud.terminate_droplets_by_name('^{}$'.format(clus.hostname))
 
     if not hasattr(args, 'func') and not args.terminate_droplet:
         parser.print_help()
@@ -249,9 +250,9 @@ def create(clus, args):  # pylint: disable=too-many-branches
     if args.create_droplet:
         clus.create_droplet(ssh_key_id=args.ssh_key_id, hostname=args.create_hostname)
         if args.verbose:
-            cosmos.list_droplets()
+            greenhost_cloud.list_droplets()
         # Wait for ssh
-        cosmos.wait_for_ssh(clus.ip_address)
+        greenhost_cloud.wait_for_ssh(clus.ip_address)
     elif args.droplet_id:
         clus.set_info_by_droplet_id(args.droplet_id)
     elif args.ip_address:
@@ -269,7 +270,7 @@ def create(clus, args):  # pylint: disable=too-many-branches
         create_domain_records(
             args.domain, clus.ip_address, subdomain=args.subdomain)
         if args.verbose:
-            cosmos.list_domain_records(args.domain)
+            greenhost_cloud.list_domain_records(args.domain)
 
 
 def install(clus, args):
@@ -340,16 +341,16 @@ def create_domain_records(domain, droplet_ip, subdomain=None):
     if subdomain is None:
         subdomain_arg = "@"
 
-    domain_record = cosmos.create_domain_record(
+    domain_record = greenhost_cloud.create_domain_record(
         domain=domain, name=subdomain_arg,
-        data=droplet_ip, record_type='A', update=True)
+        data=droplet_ip, record_type='A', update=True, ttl=60)
     log.info('Domain record: %s', domain_record)
 
     subdomain_arg = '*'
     if subdomain is not None:
         subdomain_arg += '.' + subdomain
 
-    domain_record = cosmos.create_domain_record(
+    domain_record = greenhost_cloud.create_domain_record(
         domain=domain, name=subdomain_arg,
         data=subdomain, record_type='CNAME', update=True)
     log.info('Domain record: %s', domain_record)
diff --git a/openappstack/cluster.py b/openappstack/cluster.py
index 51cf07f4f49b1fbd28d0bfae6677acd08cc9f4a6..12880f030b24284eb12b98f80b554ec410356ca9 100644
--- a/openappstack/cluster.py
+++ b/openappstack/cluster.py
@@ -7,7 +7,8 @@ import random
 import string
 import sys
 import yaml
-from openappstack import ansible, cosmos
+import greenhost_cloud
+from openappstack import ansible
 
 CLUSTER_PATH = os.path.join(os.getcwd(), 'clusters')
 
@@ -89,7 +90,7 @@ class Cluster:
             # Use random generated ID in case we're not running in
             # gitlab CI and there's no CI_PIPELINE_ID env var
             hostname = self.name
-        droplet = cosmos.create_droplet(
+        droplet = greenhost_cloud.create_droplet(
             name=hostname,
             ssh_key_id=ssh_key_id,
             region=DEFAULT_REGION,
@@ -98,7 +99,7 @@ class Cluster:
             image=DEFAULT_IMAGE)
         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')
         self.set_info_by_droplet_id(droplet_id)
 
     def set_info_by_droplet_id(self, droplet_id):
@@ -107,7 +108,7 @@ class Cluster:
 
         :param int droplet_id: Droplet ID at Greenhost
         """
-        droplet = cosmos.get_droplet(droplet_id)
+        droplet = greenhost_cloud.get_droplet(droplet_id)
         self.ip_address = droplet['networks']['v4'][0]['ip_address']
         self.hostname = droplet['name']
 
@@ -117,7 +118,7 @@ class Cluster:
         with the Cosmos API
         """
         hostname = r"^{}$".format(hostname)
-        droplets = cosmos.get_droplets_by_name(hostname)
+        droplets = greenhost_cloud.get_droplets_by_name(hostname)
         if droplets == []:
             log.error("Droplet with hostname %s not found", hostname)
             sys.exit(3)
diff --git a/openappstack/cosmos.py b/openappstack/cosmos.py
deleted file mode 100755
index 1d2bd36cc6e5db125bc6f3bdab1903edcaf34ebf..0000000000000000000000000000000000000000
--- a/openappstack/cosmos.py
+++ /dev/null
@@ -1,338 +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'))
-        return None
-    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',  # pylint: disable=too-many-arguments
-                   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, record_id: int):
-    """Delete a domain record."""
-    log.info('Deleting domain record %s', record_id)
-    response = request_api('domains/{0}/records/{1}'.format(domain, record_id),
-                           'DELETE')
-    return response
-
-
-def delete_domain_records_by_name(domain: str, name_regex: str):
-    r"""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_records = get_domain_records_by_name(domain, name_regex)
-    for record in all_records:
-        delete_domain_record(domain, record['id'])
-
-
-def delete_droplet(droplet_id: int):
-    """Delete a droplet. Droplet needs to be stopped first."""
-    log.info('Deleting %s', droplet_id)
-    response = request_api('droplets/{0}'.format(droplet_id), 'DELETE')
-    return response
-
-
-def get_domain_record(domain: str, droplet_id: int):
-    """Get details for given domain record."""
-    response = request_api('domains/{0}/records/{1}'.format(domain, droplet_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()
-    log.debug(all_droplets)
-    matching = [droplet for droplet in all_droplets
-                if re.match(name_regex, droplet['name'])]
-    return matching
-
-
-def get_droplet(droplet_id: int):
-    """Get information about specified droplet."""
-    response = request_api('droplets/{0}'.format(droplet_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(droplet_id: int):
-    """Shut down specified droplet (through a power_off call)."""
-    log.info('Shutting down %s', droplet_id)
-    data = {"type": "power_off"}
-    response = request_api('droplets/{0}/actions'.format(droplet_id), 'POST', data)
-    return response
-
-
-def status_droplet(droplet_id: int):
-    """Get status of specified droplet."""
-    response = get_droplet(droplet_id)
-    return response['status']
-
-
-def terminate_droplet(droplet_id: int):
-    """Terminate a droplet by powering it down and deleting it."""
-    shutdown_droplet(droplet_id)
-    wait_for_state(droplet_id, 'stopped')
-    delete_droplet(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_droplets = get_droplets()
-
-    noterminate_droplets = []
-    if 'NO_TERMINATE_DROPLETS' in os.environ:
-        noterminate_droplets = os.environ['NO_TERMINATE_DROPLETS'].split(',')
-
-    for droplet in all_droplets:
-        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, r'^\*.'+droplet['name'])
-                    delete_domain_records_by_name(domain, '^'+droplet['name'])
-                    terminate_droplet(droplet['id'])
-
-
-def wait_for_ssh(droplet_ip: str):
-    """Wait for ssh to be reachable on port 22."""
-    log.info('Waiting for ssh to become available on ip %s', droplet_ip)
-
-    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
-    while sock.connect_ex((droplet_ip, 22)) != 0:
-        sleep(1)
-
-    log.info('SSH became available on ip %s', droplet_ip)
-
-
-def wait_for_state(droplet_id: int, state):
-    """Wait for a droplet to reach a certain state."""
-    log.info('Waiting for droplet %s to reach %s state...', droplet_id, state)
-    status = status_droplet(droplet_id)
-    log.debug(status)
-
-    while status != state:
-        sleep(1)
-        status = status_droplet(droplet_id)
-
-
-# When called from from ipython, setup
-# logging to console
-try:
-    __IPYTHON__  # pylint: disable=pointless-statement
-    log = logging.getLogger()  # pylint: disable=invalid-name
-    log.addHandler(logging.StreamHandler())
-    log.setLevel(logging.INFO)
-except NameError:
-    log = logging.getLogger(__name__)  # pylint: disable=invalid-name