diff --git a/action_plugins/serverdensity.py b/action_plugins/serverdensity.py
index 9961292cdb746e983bdbb9e5005ac3fc8d975fba..8f5d361384727718020c4e11a78b33c433f506cb 100644
--- a/action_plugins/serverdensity.py
+++ b/action_plugins/serverdensity.py
@@ -4,21 +4,30 @@ import requests
 import tempfile
 import yaml
 
-from ansible.callbacks import vv
 from ansible.errors import AnsibleError as ae
-from ansible.runner.return_data import ReturnData
-from ansible.utils import parse_kv
-
-class ActionModule(object):
+from ansible.plugins.action import ActionBase
+from ansible.utils.boolean import boolean
+from ansible.vars import VariableManager
+try:
+    from __main__ import display
+except ImportError:
+    from ansible.utils.display import Display
+    display = Display()
+
+class ActionModule(ActionBase):
     ''' Create new host or sync all of your inventory over at ServerDensity'''
 
     ### We need to be able to modify the inventory
     BYPASS_HOST_LOOP = True
     TRANSFERS_FILES = False
 
-    def __init__(self, runner):
-        self.runner = runner
+    def __init__(self, task, connection, play_context, loader, templar,
+                 shared_loader_obj):
+        super(ActionModule, self).__init__(task, connection, play_context,
+                                           loader, templar, shared_loader_obj)
         self.api_token = None
+        self.args = {}
+        self.vars = {}
 
         self.devices = []
         self.services = []
@@ -29,30 +38,28 @@ class ActionModule(object):
         self.force_update = False
         self.cache_file_name = None
 
-    def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs):
+    def run(self, tmp=None, task_vars=None):
+        ''' handler for file transfer operations '''
+        if task_vars is None:
+            task_vars = dict()
+        self.vars = task_vars
 
-        if self.runner.noop_on_check(inject):
-            return ReturnData(conn=conn, comm_ok=True, result=dict(skipped=True, msg='check mode not supported for this module'))
+        result = super(ActionModule, self).run(tmp, task_vars)
 
-        args = {}
-        if complex_args:
-            args.update(complex_args)
-        args.update(parse_kv(module_args))
-        if 'api_token' in args:
-            self.api_token = args.get('api_token')
-        else:
-            allgroup = self.runner.inventory.get_group('all')
-            allvariables = allgroup.get_variables()
-            if 'sd_api_token' in allvariables:
-                self.api_token = allvariables.get('sd_api_token')
-            else:
-                raise ae("'api_token' is a required argument.")
+        if self._play_context.check_mode:
+            result['skipped'] = True
+            result['msg'] = 'check mode not supported for this module'
+            return result
+
+        self.api_token = self._task.args.get('api_token', task_vars.get('sd_api_token', False))
+        if not self.api_token:
+            raise ae("'api_token' is a required argument or you define the variable 'sd_api_token' in your inventory.")
 
-        self.force_update = args.get('force', False)
-        self.cache_file_name = args.get('cache', False)
-        cleanup = args.get('cleanup', False)
-        just_download = args.get('readonly', False)
-        output = args.get('output', False)
+        self.force_update = boolean(self._task.args.get('force'))
+        self.cache_file_name = self._task.args.get('cache', False)
+        cleanup = boolean(self._task.args.get('cleanup'))
+        just_download = boolean(self._task.args.get('readonly'))
+        output = self._task.args.get('output', False)
 
         if just_download:
             self.force_update = False
@@ -62,30 +69,29 @@ class ActionModule(object):
         if output and self.cache_file_name != 'False':
             self.cache_file_name = tempfile.mktemp(prefix='sd_', suffix='.json')
 
-        result = {}
-
         self.list_all()
 
         if output:
             if os.path.exists(self.cache_file_name):
-                vv('Writing upstream settings to %s' % os.path.abspath(output))
+                display.vv('Writing upstream settings to %s' % os.path.abspath(output))
                 with open(self.cache_file_name, 'r') as content_file:
                     content = json.load(content_file)
                     with open(output, 'w') as output_file:
                         yaml.safe_dump(content, output_file, encoding='utf-8', allow_unicode=True)
 
         if just_download:
-            vv('Downloaded settings to %s' % self.cache_file_name)
-            return ReturnData(conn=conn, comm_ok=True, result=result)
+            result['msg'] = 'Downloaded settings to %s' % self.cache_file_name
+            result['changed'] = False
+            return result
 
         services = {}
         devicegroup_alerts = {}
         servicegroup_alerts = {}
 
-        vv('Ensure hosts...')
-        for host in self.runner.host_set:
-            vv('- ' + host)
-            host_vars = inject['hostvars'][host]
+        display.vv('Ensure hosts...')
+        for host in self.vars.get('ansible_play_hosts'):
+            display.vv('- ' + host)
+            host_vars = self.vars['hostvars'][host]
             facts = host_vars.get('ansible_facts', {})
             location = host_vars.get('location')
             if not location:
@@ -145,50 +151,49 @@ class ActionModule(object):
 
             alerts = host_vars.get('sd_alerts')
             if alerts:
-                vv('- - Ensure device alerts...')
+                display.vv('- - Ensure device alerts...')
                 for alertname in alerts:
-                    vv('- - - ' + alertname)
+                    display.vv('- - - ' + alertname)
                     alert = alerts.get(alertname)
                     alert.__setitem__('host', host)
                     self.ensure_alert(alert, 'device')
 
-        vv('Ensure device group alerts...')
+        display.vv('Ensure device group alerts...')
         for groupname in devicegroup_alerts:
-            vv('- ' + groupname)
+            display.vv('- ' + groupname)
             group_alerts = devicegroup_alerts.get(groupname)
             for alertname in group_alerts:
-                vv('- - ' + alertname)
+                display.vv('- - ' + alertname)
                 alert = group_alerts.get(alertname)
                 self.ensure_alert(alert, 'deviceGroup', groupname)
 
-        vv('Ensure services...')
+        display.vv('Ensure services...')
         for servicename in services:
-            vv('- ' + servicename)
+            display.vv('- ' + servicename)
             service = services.get(servicename)
             self.ensure_service(servicename, service)
             alerts = service.get('alerts')
             if alerts:
-                vv('- - Ensure service alerts...')
+                display.vv('- - Ensure service alerts...')
                 for alertname in alerts:
-                    vv('- - - ' + alertname)
+                    display.vv('- - - ' + alertname)
                     alert = alerts.get(alertname)
                     alert.__setitem__('service', service.get('name'))
                     self.ensure_alert(alert, 'service')
 
-        vv('Ensure service group alerts...')
+        display.vv('Ensure service group alerts...')
         for servicegroupname in servicegroup_alerts:
-            vv('- ' + servicegroupname)
+            display.vv('- ' + servicegroupname)
             alert = servicegroup_alerts.get(servicegroupname)
             groupname = alert.get('group')
             self.ensure_alert(alert, 'serviceGroup', groupname)
 
         if cleanup:
-            vv('Cleanup unused alerts...')
+            display.vv('Cleanup unused alerts...')
             self.cleanup_alerts()
 
-        vv('Completed successfully!')
-
-        return ReturnData(conn=conn, comm_ok=True, result=result)
+        result['msg'] = 'Completed successfully!'
+        return result
 
     def _request(self, path, data = None, method = 'GET'):
         encoder = json.JSONEncoder()
@@ -300,27 +305,18 @@ class ActionModule(object):
         return False
 
     def _list_objects(self, type, path):
-        vv("Reading %s from SD" % type)
+        display.vv("Reading %s from SD" % type)
         changed = False
-        allgroup = self.runner.inventory.get_group('all')
-        allvariables = allgroup.get_variables()
-        if '_serverdensity_' + type not in allvariables:
+        if not self.vars.has_key('_serverdensity_' + type):
             changed = True
-            objects = self._request(path)
-            allgroup.set_variable('_serverdensity_' + type, objects)
-        else:
-            objects = allvariables.get('_serverdensity_' + type)
-        return changed, objects
+            self.vars.__setitem__('_serverdensity_' + type, self._request(path))
+        return changed, self.vars.get('_serverdensity_' + type)
 
     def _list_devices_agent_key(self):
         for device in self.devices:
             hostname = device.get('name')
-            if hostname in self.runner.inventory._hosts_cache:
-                host = self.runner.inventory._hosts_cache[hostname]
-                host.set_variable('sd_agent_key', device.get('agentKey'))
-            if hostname in self.runner.inventory._vars_per_host:
-                hostvars = self.runner.inventory._vars_per_host.get(hostname)
-                hostvars.__setitem__('sd_agent_key', device.get('agentKey'))
+            if hostname in self.vars['ansible_play_hosts']:
+                self.vars['hostvars'][hostname]['sd_agent_key'] = device.get('agentKey')
 
     def list_devices(self):
         if len(self.devices) == 0:
@@ -342,12 +338,10 @@ class ActionModule(object):
 
     def list_notifications(self):
         if len(self.notifications) == 0:
-            allgroup = self.runner.inventory.get_group('all')
-            allvariables = allgroup.get_variables()
-            if 'sd_notifications' in allvariables:
-                self.notifications = allvariables.get('sd_notifications')
+            if self.vars.has_key('sd_notifications'):
+                self.notifications = self.vars.get('sd_notifications')
             else:
-                filename = self.runner.inventory.basedir() + '/sd_notifications.json'
+                filename = self.vars.get('inventory_dir') + '/sd_notifications.json'
                 if os.path.exists(filename):
                     with open(filename, 'r') as content_file:
                         self.notifications = json.load(content_file)
@@ -428,13 +422,7 @@ class ActionModule(object):
                 self.devices.remove(old_device)
         self.devices.append(device)
         self.cache_update(False)
-
-        if hostname in self.runner.inventory._hosts_cache:
-            host = self.runner.inventory._hosts_cache[hostname]
-            host.set_variable('sd_agent_key', device.get('agentKey'))
-        if hostname in self.runner.inventory._vars_per_host:
-            hostvars = self.runner.inventory._vars_per_host.get(hostname)
-            hostvars.__setitem__('sd_agent_key', device.get('agentKey'))
+        self.vars['hostvars'][hostname]['sd_agent_key'] = device.get('agentKey')
 
     def ensure_service(self, servicename, service):
         serviceId = self._get_service_id(servicename)