implement 'quick mode' for vcpe observer
diff --git a/xos/cord/models.py b/xos/cord/models.py
index eedb794..e593097 100644
--- a/xos/cord/models.py
+++ b/xos/cord/models.py
@@ -236,7 +236,8 @@
                           "cdn_enable": False,
                           "sliver_id": None,
                           "users": [],
-                          "bbs_account": None}
+                          "bbs_account": None,
+                          "last_ansible_hash": None}
 
     def __init__(self, *args, **kwargs):
         super(VCPETenant, self).__init__(*args, **kwargs)
@@ -389,6 +390,14 @@
         return self.set_attribute("bbs_account", value)
 
     @property
+    def last_ansible_hash(self):
+        return self.get_attribute("last_ansible_hash", self.default_attributes["last_ansible_hash"])
+
+    @last_ansible_hash.setter
+    def last_ansible_hash(self, value):
+        return self.set_attribute("last_ansible_hash", value)
+
+    @property
     def ssh_command(self):
         if self.sliver:
             return self.sliver.get_ssh_command()
diff --git a/xos/observers/vcpe/steps/sync_vcpetenant.py b/xos/observers/vcpe/steps/sync_vcpetenant.py
index d6c6b84..910cc4c 100644
--- a/xos/observers/vcpe/steps/sync_vcpetenant.py
+++ b/xos/observers/vcpe/steps/sync_vcpetenant.py
@@ -1,3 +1,4 @@
+import hashlib
 import os
 import socket
 import sys
@@ -111,9 +112,16 @@
                  fields[attribute_name] = getattr(o, attribute_name)
 
         fields.update(self.get_extra_attributes(o))
-        tStart = time.time()
-        run_template_ssh(self.template_name, fields)
-        logger.info("playbook execution time %d" % int(time.time()-tStart))
+
+        ansible_hash = hashlib.md5(repr(sorted(fields.items()))).hexdigest()
+        quick_update = (o.last_ansible_hash == ansible_hash)
+
+        if quick_update:
+            logger.info("quick_update triggered; skipping ansible recipe")
+        else:
+            tStart = time.time()
+            run_template_ssh(self.template_name, fields)
+            logger.info("playbook execution time %d" % int(time.time()-tStart))
 
         if o.url_filter_enable:
             if (str(o.service_specific_id) != "SYNCME"):
@@ -126,6 +134,7 @@
                 bbs.sync(o.url_filter_level, o.users)
                 logger.info("bbs update tiem %d" % int(time.time()-tStart))
 
+        o.last_ansible_hash = ansible_hash
         o.save()
 
     def delete_record(self, m):