diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7060668..8dd394e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@ Ansible Changes By Release
 * fetch module fixes for SSH connection type
 * modules now consistently all take yes/no for boolean parameters (some accepted true/false)
 * in YAML inventory, hosts can list their groups in inverted order now also (see tests/yaml_hosts)
+* setup module no longer saves to disk, template module now only used in playbooks
 
 0.5 "Amsterdam" ------- July 04, 2012
 
diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py
index e2760ad..e4daa58 100644
--- a/lib/ansible/runner/__init__.py
+++ b/lib/ansible/runner/__init__.py
@@ -545,6 +545,9 @@ class Runner(object):
     def _execute_template(self, conn, tmp):
         ''' handler for template operations '''
 
+        if not self.is_playbook:
+            raise errors.AnsibleError("in current versions of ansible, templates are only usable in playbooks")
+
         # load up options
         options  = utils.parse_kv(self.module_args)
         source   = options.get('src', None)
@@ -571,38 +574,11 @@ class Runner(object):
                 result = dict(failed=True, msg="could not find src in first_available_file list")
                 return ReturnData(host=conn.host, comm_ok=False, result=result)
 
-
         if self.module_vars is not None:
             inject.update(self.module_vars)
 
         source = utils.template(source, inject, self.setup_cache)
 
-        #(host, ok, data, err) = (None, None, None, None)
-
-        if not self.is_playbook:
-
-            # not running from a playbook so we have to fetch the remote
-            # setup file contents before proceeding...
-            if metadata is None:
-                if self.remote_user == 'root':
-                    metadata = '/etc/ansible/setup'
-                else:
-                    # path is expanded on remote side
-                    metadata = "~/.ansible/tmp/setup" 
-            
-            # install the template module
-            slurp_module = self._transfer_module(conn, tmp, 'slurp')
-
-            # run the slurp module to get the metadata file
-            args = "src=%s" % metadata
-            result1  = self._execute_module(conn, tmp, slurp_module, args)
-            if not 'content' in result1.result or result1.result.get('encoding','base64') != 'base64':
-                result1.result['failed'] = True
-                return result1
-            content = base64.b64decode(result1.result['content'])
-            inject = utils.json_loads(content)
-
-
         # install the template module
         copy_module = self._transfer_module(conn, tmp, 'copy')
 
diff --git a/library/fetch b/library/fetch
index f26337a..9132aee 100755
--- a/library/fetch
+++ b/library/fetch
@@ -1,24 +1 @@
-#!/usr/bin/python
-
-# (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
-#
-# This file is part of Ansible
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-#
-
-### THIS FILE IS FOR REFERENCE OR FUTURE USE ###
-
-# See lib/ansible/runner.py for implementation of the fetch functionality #
-
+# this is a virtual module that is entirely implemented server side
diff --git a/library/raw b/library/raw
index adedd46..9132aee 100755
--- a/library/raw
+++ b/library/raw
@@ -1,23 +1 @@
-#!/usr/bin/python
-
-# (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
-#
-# This file is part of Ansible
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-# hey the Ansible raw module isn't really a remote transferred
-# module.  All the magic happens in Runner.py, see the web docs
-# for more details.
-
+# this is a virtual module that is entirely implemented server side
diff --git a/library/setup b/library/setup
index 4cc343b..70bb517 100755
--- a/library/setup
+++ b/library/setup
@@ -17,8 +17,6 @@
 # You should have received a copy of the GNU General Public License
 # along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
 
-DEFAULT_ANSIBLE_SETUP     = "/etc/ansible/setup"
-
 import array
 import fcntl
 import glob
@@ -34,11 +32,6 @@ import traceback
 import syslog
 
 try:
-    from hashlib import md5 as _md5
-except ImportError: 
-    from md5 import md5 as _md5
-
-try:
     import selinux
     HAVE_SELINUX=True
 except ImportError:
@@ -316,20 +309,6 @@ def ansible_facts():
     get_service_facts(facts)
     return facts
 
-def md5(filename):
-    ''' Return MD5 hex digest of local file, or None if file is not present. '''
-    if not os.path.exists(filename):
-        return None
-    digest = _md5()
-    blocksize = 64 * 1024
-    infile = open(filename, 'rb')
-    block = infile.read(blocksize)
-    while block:
-        digest.update(block)
-        block = infile.read(blocksize)
-    infile.close()
-    return digest.hexdigest()
-
 # ===========================================
 
 # load config & template variables
@@ -355,21 +334,6 @@ except:
 syslog.openlog('ansible-%s' % os.path.basename(__file__))
 syslog.syslog(syslog.LOG_NOTICE, 'Invoked with %s' % setup_options)
 
-ansible_file = os.path.expandvars(setup_options.get('metadata', DEFAULT_ANSIBLE_SETUP))
-ansible_dir = os.path.dirname(ansible_file)
-
-# create the config dir if it doesn't exist
-
-if not os.path.exists(ansible_dir):
-    os.makedirs(ansible_dir)
-
-changed = False
-md5sum = None
-if not os.path.exists(ansible_file):
-    changed = True
-else:
-    md5sum = md5(ansible_file)
-
 # Get some basic facts in case facter or ohai are not installed
 for (k, v) in ansible_facts().items():
     setup_options["ansible_%s" % k] = v
@@ -409,23 +373,7 @@ if os.path.exists("/usr/bin/ohai"):
                k2 = "ohai_%s" % k
                setup_options[k2] = v
 
-# write the template/settings file using
-# instructions from server
-
-f = open(ansible_file, "w+")
-reformat = json.dumps(setup_options, sort_keys=True, indent=4)
-f.write(reformat)
-f.close()
-
-md5sum2 = md5(ansible_file)
-
-if md5sum != md5sum2:
-   changed = True
-
 setup_result = {}
-setup_result['written'] = ansible_file
-setup_result['changed'] = changed
-setup_result['md5sum']  = md5sum2 
 setup_result['ansible_facts'] = setup_options
 
 # hack to keep --verbose from showing all the setup module results
diff --git a/library/shell b/library/shell
index 345deea..3c8e63d 100644
--- a/library/shell
+++ b/library/shell
@@ -1,6 +1,3 @@
-# VIRTUAL
-
-There is actually no actual shell module source, when you use 'shell' in ansible, 
-it runs the 'command' module with special arguments and it behaves differently.  
-See the command source and the comment "#USE_SHELL".
-
+# There is actually no actual shell module source, when you use 'shell' in ansible, 
+# it runs the 'command' module with special arguments and it behaves differently.  
+# See the command source and the comment "#USE_SHELL".
diff --git a/library/template b/library/template
index a290899..9132aee 100755
--- a/library/template
+++ b/library/template
@@ -1,24 +1 @@
-#!/usr/bin/python
-
-# (c) 2012, Michael DeHaan <michael.dehaan@gmail.com>
-#
-# This file is part of Ansible
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-# hey the Ansible template module isn't really a remote transferred
-# module.  All the magic happens in Runner.py making use of the
-# copy module, and if not running from a playbook, also the 'slurp'
-# module.
-
+# this is a virtual module that is entirely implemented server side
diff --git a/test/TestRunner.py b/test/TestRunner.py
index 76c85f7..3349f4d 100644
--- a/test/TestRunner.py
+++ b/test/TestRunner.py
@@ -119,28 +119,6 @@ class TestRunner(unittest.TestCase):
         ])
         assert result['changed'] == False
 
-    def test_template(self):
-        input_ = self._get_test_file('sample.j2')
-        metadata = self._get_test_file('metadata.json')
-        output = self._get_stage_file('sample.out')
-        result = self._run('template', [
-            "src=%s" % input_,
-            "dest=%s" % output,
-            "metadata=%s" % metadata
-        ])
-        assert os.path.exists(output)
-        out = file(output).read()
-        assert out.find("duck") != -1
-        assert result['changed'] == True
-        assert 'md5sum' in result
-        assert 'failed' not in result
-        result = self._run('template', [
-            "src=%s" % input_,
-            "dest=%s" % output,
-            "metadata=%s" % metadata
-        ])
-        assert result['changed'] == False
-
     def test_command(self):
         # test command module, change trigger, etc
         result = self._run('command', [ "/bin/echo", "hi" ])
@@ -177,21 +155,6 @@ class TestRunner(unittest.TestCase):
         assert len(result['stdout']) > 100000
         assert result['stderr'] == ''
 
-    def test_setup(self):
-        output = self._get_stage_file('output.json')
-        result = self._run('setup', [ "metadata=%s" % output, "a=2", "b=3", "c=4" ])
-        assert 'failed' not in result
-        assert 'md5sum' in result
-        assert result['changed'] == True
-        outds = json.loads(file(output).read())
-        assert outds['c'] == '4'
-        # not bothering to test change hooks here since ohai/facter results change
-        # almost every time so changed is always true, this just tests that
-        # rewriting the file is ok
-        result = self._run('setup', [ "metadata=%s" % output, "a=2", "b=3", "c=4" ])
-        print "RAW RESULT=%s" % result
-        assert 'md5sum' in result
-
     def test_async(self):
         # test async launch and job status
         # of any particular module
diff --git a/test/metadata.json b/test/metadata.json
deleted file mode 100644
index 8af3133..0000000
--- a/test/metadata.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-    "answer" : "Where will we find a duck and a hose at this hour?"
-}