diff --git a/lib/ansible/config/manager.py b/lib/ansible/config/manager.py
index 46024a3404c..0b60e88dcb6 100644
--- a/lib/ansible/config/manager.py
+++ b/lib/ansible/config/manager.py
@@ -27,7 +27,7 @@ Setting = namedtuple('Setting', 'name value origin type')
 
 
 # FIXME: see if we can unify in module_utils with similar function used by argspec
-def ensure_type(value, value_type):
+def ensure_type(value, value_type, origin=None):
     ''' return a configuration variable with casting
     :arg value: The value to ensure correct typing of
     :kwarg value_type: The type of the value.  This can be any of the following strings:
@@ -44,6 +44,11 @@ def ensure_type(value, value_type):
             means colon separated strings.)  Split the value and then expand
             each part for environment variables and tildes.
     '''
+
+    basedir = None
+    if origin and os.path.isabs(origin) and os.path.exists(origin):
+        basedir = origin
+
     if value_type:
         value_type = value_type.lower()
 
@@ -66,10 +71,10 @@ def ensure_type(value, value_type):
                 value = None
 
         elif value_type == 'path':
-            value = resolve_path(value)
+            value = resolve_path(value, basedir=basedir)
 
         elif value_type in ('tmp', 'temppath', 'tmppath'):
-            value = resolve_path(value)
+            value = resolve_path(value, basedir=basedir)
             if not os.path.exists(value):
                 makedirs_safe(value, 0o700)
             prefix = 'ansible-local-%s' % os.getpid()
@@ -78,12 +83,12 @@ def ensure_type(value, value_type):
         elif value_type == 'pathspec':
             if isinstance(value, string_types):
                 value = value.split(os.pathsep)
-            value = [resolve_path(x) for x in value]
+            value = [resolve_path(x, basedir=basedir) for x in value]
 
         elif value_type == 'pathlist':
             if isinstance(value, string_types):
                 value = value.split(',')
-            value = [resolve_path(x) for x in value]
+            value = [resolve_path(x, basedir=basedir) for x in value]
 
         # defaults to string types
         elif isinstance(value, string_types):
@@ -93,12 +98,12 @@ def ensure_type(value, value_type):
 
 
 # FIXME: see if this can live in utils/path
-def resolve_path(path):
+def resolve_path(path, basedir=None):
     ''' resolve relative or 'varaible' paths '''
     if '{{CWD}}' in path:  # allow users to force CWD using 'magic' {{CWD}}
         path = path.replace('{{CWD}}', os.getcwd())
 
-    return unfrackpath(path, follow=False)
+    return unfrackpath(path, follow=False, basedir=basedir)
 
 
 # FIXME: generic file type?
@@ -323,7 +328,7 @@ class ConfigManager(object):
 
         # ensure correct type
         try:
-            value = ensure_type(value, defs[config].get('type'))
+            value = ensure_type(value, defs[config].get('type'), origin=origin)
         except Exception as e:
             self.UNABLE.append(config)
 
diff --git a/lib/ansible/utils/path.py b/lib/ansible/utils/path.py
index 771aab30cb4..717cef6cf01 100644
--- a/lib/ansible/utils/path.py
+++ b/lib/ansible/utils/path.py
@@ -27,7 +27,7 @@ from ansible.module_utils._text import to_bytes, to_native, to_text
 __all__ = ['unfrackpath', 'makedirs_safe']
 
 
-def unfrackpath(path, follow=True):
+def unfrackpath(path, follow=True, basedir=None):
     '''
     Returns a path that is free of symlinks (if follow=True), environment variables, relative path traversals and symbols (~)
 
@@ -43,12 +43,20 @@ def unfrackpath(path, follow=True):
         '$HOME/../../var/mail' becomes '/var/spool/mail'
     '''
 
-    if follow:
-        final_path = os.path.normpath(os.path.realpath(os.path.expanduser(os.path.expandvars(to_bytes(path, errors='surrogate_or_strict')))))
-    else:
-        final_path = os.path.normpath(os.path.abspath(os.path.expanduser(os.path.expandvars(to_bytes(path, errors='surrogate_or_strict')))))
+    if basedir is None:
+        basedir = os.getcwd()
+    elif os.path.isfile(basedir):
+        basedir = os.path.dirname(basedir)
 
-    return to_text(final_path, errors='surrogate_or_strict')
+    final_path = os.path.expanduser(os.path.expandvars(to_bytes(path, errors='surrogate_or_strict')))
+
+    if not os.path.isabs(final_path):
+        final_path = os.path.join(to_bytes(basedir, errors='surrogate_or_strict'), final_path)
+
+    if follow:
+        final_path = os.path.realpath(final_path)
+
+    return to_text(os.path.normpath(final_path), errors='surrogate_or_strict')
 
 
 def makedirs_safe(path, mode=None):