diff -rup cloud-init-0.7.9/cloudinit/sources/DataSourceAzure.py cloud-init-0.7.9-1/cloudinit/sources/DataSourceAzure.py
--- cloud-init-0.7.9/cloudinit/sources/DataSourceAzure.py	2016-12-23 08:37:45.000000000 -0800
+++ cloud-init-0.7.9-1/cloudinit/sources/DataSourceAzure.py	2018-02-20 01:21:12.844575653 -0800
@@ -23,12 +23,18 @@ LOG = logging.getLogger(__name__)
 
 DS_NAME = 'Azure'
 DEFAULT_METADATA = {"instance-id": "iid-AZURE-NODE"}
-AGENT_START = ['service', 'walinuxagent', 'start']
+AGENT_START = ['systemctl', 'start', 'waagent']
 AGENT_START_BUILTIN = "__builtin__"
 BOUNCE_COMMAND = [
     'sh', '-xc',
     "i=$interface; x=0; ifdown $i || x=$?; ifup $i || x=$?; exit $x"
 ]
+
+BOUNCE_COMMAND_PHOTON = [
+    'sh', '-xc',
+    ("i=$interface; x=0; ifconfig $i down || x=$?; "
+     "ifconfig $i up || x=$?; exit $x")
+]
 # azure systems will always have a resource disk, and 66-azure-ephemeral.rules
 # ensures that it gets linked to this path.
 RESOURCE_DISK_PATH = '/dev/disk/cloud/azure_resource'
@@ -40,7 +46,7 @@ BUILTIN_DS_CONFIG = {
     'hostname_bounce': {
         'interface': 'eth0',
         'policy': True,
-        'command': BOUNCE_COMMAND,
+        'command': 'builtin',
         'hostname_command': 'hostname',
     },
     'disk_aliases': {'ephemeral0': RESOURCE_DISK_PATH},
@@ -154,7 +160,7 @@ class DataSourceAzureNet(sources.DataSou
 
             missing = util.log_time(logfunc=LOG.debug, msg="waiting for files",
                                     func=wait_for_files,
-                                    args=(fp_files,))
+                                    args=(fp_files,180))
         if len(missing):
             LOG.warn("Did not find files, but going on: %s", missing)
 
@@ -362,7 +368,9 @@ def perform_hostname_bounce(hostname, cf
     env['old_hostname'] = prev_hostname
 
     if command == "builtin":
-        command = BOUNCE_COMMAND
+        LOG.debug(
+                "Skipping network bounce: ifupdown utils aren't present.")
+        return
 
     LOG.debug("pubhname: publishing hostname [%s]", msg)
     shell = not isinstance(command, (list, tuple))
@@ -396,7 +404,7 @@ def pubkeys_from_crt_files(flist):
     return pubkeys
 
 
-def wait_for_files(flist, maxwait=60, naplen=.5, log_pre=""):
+def wait_for_files(flist, maxwait, naplen=.5, log_pre=""):
     need = set(flist)
     waited = 0
     while True:
 
diff -rup cloud-init-0.7.9/cloudinit/sources/helpers/azure.py cloud-init-0.7.9-1/cloudinit/sources/helpers/azure.py
--- cloud-init-0.7.9/cloudinit/sources/helpers/azure.py	2016-12-23 08:37:45.000000000 -0800
+++ cloud-init-0.7.9-1/cloudinit/sources/helpers/azure.py	2018-02-20 01:13:25.885641372 -0800
@@ -8,16 +8,18 @@ import socket
 import struct
 import tempfile
 import time
+import configobj
 
 from cloudinit import stages
 from contextlib import contextmanager
 from xml.etree import ElementTree
 
 from cloudinit import util
+from io import StringIO
 
 
 LOG = logging.getLogger(__name__)
-
+NETWORKD_LEASES_DIR = '/run/systemd/netif/leases'
 
 @contextmanager
 def cd(newdir):
@@ -264,6 +266,32 @@ class WALinuxAgentShim(object):
         return dhcp_options
 
     @staticmethod
+    def networkd_parse_lease(content):
+        """Parse a systemd lease file content as in /run/systemd/netif/leases/
+        Parse this (almost) ini style file even though it says:
+          # This is private data. Do not parse.
+        Simply return a dictionary of key/values."""
+
+        return dict(configobj.ConfigObj(StringIO(content), list_values=False))
+
+    @staticmethod
+    def networkd_load_leases(leases_d=None):
+        """Return a dictionary of dictionaries representing each lease
+        found in lease_d.i
+        The top level key will be the filename, which is typically the ifindex."""
+
+        if leases_d is None:
+            leases_d = NETWORKD_LEASES_DIR
+
+        ret = {}
+        if not os.path.isdir(leases_d):
+            return ret
+        for lfile in os.listdir(leases_d):
+            ret[lfile] = WALinuxAgentShim.networkd_parse_lease(
+                util.load_file(os.path.join(leases_d, lfile)))
+        return ret
+
+    @staticmethod
     def _get_value_from_dhcpoptions(dhcp_options):
         if dhcp_options is None:
             return None
@@ -277,13 +305,28 @@ class WALinuxAgentShim(object):
         return _value
 
     @staticmethod
+    def networkd_get_option_from_leases(keyname, leases_d=None):
+        if leases_d is None:
+            leases_d = NETWORKD_LEASES_DIR
+        leases = WALinuxAgentShim.networkd_load_leases(leases_d=leases_d)
+        for ifindex, data in sorted(leases.items()):
+            if data.get(keyname):
+                return data[keyname]
+        return None
+
+    @staticmethod
+    def _networkd_get_value_from_leases(leases_d=None):
+        return WALinuxAgentShim.networkd_get_option_from_leases(
+            'OPTION_245', leases_d=leases_d)
+
+    @staticmethod
     def find_endpoint(fallback_lease_file=None):
         LOG.debug('Finding Azure endpoint...')
         value = None
         # Option-245 stored in /run/cloud-init/dhclient.hooks/<ifc>.json
         # a dhclient exit hook that calls cloud-init-dhclient-hook
-        dhcp_options = WALinuxAgentShim._load_dhclient_json()
-        value = WALinuxAgentShim._get_value_from_dhcpoptions(dhcp_options)
+        value = WALinuxAgentShim._networkd_get_value_from_leases()
+        LOG.debug('networkd value from lease %s', value)
         if value is None:
             # Fallback and check the leases file if unsuccessful
             LOG.debug("Unable to find endpoint in dhclient logs. "