'For the intrinsic function Fn::GetAtt.
:param key: the attribute key.
:param path: a list of path components to select from the attribute.
:returns: the attribute value.'

def FnGetAtt(self, key, *path):

    cache_custom = ((self.attributes.get_cache_mode(key) != attributes.Schema.CACHE_NONE) and (type(self).get_attribute != Resource.get_attribute))
    if cache_custom:
        if path:
            full_key = sync_point.str_pack_tuple(((key,) + path))
        else:
            full_key = key
        if (full_key in self.attributes.cached_attrs):
            return self.attributes.cached_attrs[full_key]
    attr_val = self.get_attribute(key, *path)
    if cache_custom:
        self.attributes.set_cached_attr(full_key, attr_val)
    return attr_val
