diff --git a/heat/engine/resource.py b/heat/engine/resource.py
index 4f5e73e096..61cc8f3bde 100644
--- a/heat/engine/resource.py
+++ b/heat/engine/resource.py
@@ -1052,9 +1052,12 @@ class Resource(status.ResourceStatus):
             for e in get_attrs(out_attrs - dep_attrs, cacheable_only=True):
                 pass
 
+        # Calculate attribute values *before* reference ID, to potentially
+        # save an extra RPC call in TemplateResource
+        attribute_values = dict(get_attrs(dep_attrs))
+
         return node_data.NodeData(self.id, self.name, self.uuid,
-                                  self.FnGetRefId(),
-                                  dict(get_attrs(dep_attrs)),
+                                  self.FnGetRefId(), attribute_values,
                                   self.action, self.status)
 
     def preview(self):
diff --git a/heat/engine/resources/template_resource.py b/heat/engine/resources/template_resource.py
index 4e87b5b826..7ab803f823 100644
--- a/heat/engine/resources/template_resource.py
+++ b/heat/engine/resources/template_resource.py
@@ -25,11 +25,14 @@ from heat.engine import environment
 from heat.engine import properties
 from heat.engine.resources import stack_resource
 from heat.engine import template
+from heat.rpc import api as rpc_api
 
 
 REMOTE_SCHEMES = ('http', 'https')
 LOCAL_SCHEMES = ('file',)
 
+STACK_ID_OUTPUT = 'OS::stack_id'
+
 
 def generate_class_from_template(name, data, param_defaults):
     tmpl = template.Template(template_format.parse(data))
@@ -300,10 +303,25 @@ class TemplateResource(stack_resource.StackResource):
         if self.resource_id is None:
             return six.text_type(self.name)
 
+        stack_identity = self.nested_identifier()
         try:
-            return self.get_output('OS::stack_id')
-        except exception.InvalidTemplateAttribute:
-            return self.nested_identifier().arn()
+            if self._outputs is not None:
+                return self.get_output(STACK_ID_OUTPUT)
+
+            output = self.rpc_client().show_output(self.context,
+                                                   dict(stack_identity),
+                                                   STACK_ID_OUTPUT)
+            if rpc_api.OUTPUT_ERROR in output:
+                raise exception.TemplateOutputError(
+                    resource=self.name,
+                    attribute=STACK_ID_OUTPUT,
+                    message=output[rpc_api.OUTPUT_ERROR])
+        except (exception.InvalidTemplateAttribute, exception.NotFound):
+            pass
+        else:
+            return output[rpc_api.OUTPUT_VALUE]
+
+        return stack_identity.arn()
 
     def get_attribute(self, key, *path):
         if self.resource_id is None: