Attached the cloud-init collected logs by a root user. Here is the contents of the /etc/resolv.conf ; Created by cloud-init on instance boot automatically, do not edit. ; ### /etc/resolv.conf file autogenerated by netconfig! # # Before you change this file manually, consider to define the # static DNS configuration using the following variables in the # /etc/sysconfig/network/config file: # NETCONFIG_DNS_STATIC_SEARCHLIST # NETCONFIG_DNS_STATIC_SERVERS # NETCONFIG_DNS_FORWARDER # or disable DNS configuration updates via netconfig by setting: # NETCONFIG_DNS_POLICY='' # # See also the netconfig(8) manual page and other documentation. # # Note: Manual change of this file disables netconfig too, but # may get lost when this file contains comments or empty lines # only, the netconfig settings are same with settings in this # file and in case of a "netconfig update -f" call. # ### Please remove (at least) this line when you modify the file! And the contents of /etc/sysconfig/network/ifcfg-eth0 # Created by cloud-init on instance boot automatically, do not edit. # BOOTPROTO=dhcp DEVICE=eth0 HWADDR=00:0d:3a:6e:6f:8f NM_CONTROLLED=no ONBOOT=yes STARTMODE=auto TYPE=Ethernet USERCTL=no Also please note that I am running "ifup eth0" to be able to ssh into the machine, but this is just a local change. Cloud-init is writing a /etc/resolv.conf that only has commented lines and the cloud-init header, When i debugged the following code in sysconfig.py content = resolv_conf.ResolvConf("") if existing_dns_path and os.path.isfile(existing_dns_path): content = resolv_conf.ResolvConf(util.load_file(existing_dns_path)) for nameserver in network_state.dns_nameservers: content.add_nameserver(nameserver) for searchdomain in network_state.dns_searchdomains: content.add_search_domain(searchdomain) if not str(content): return None the content is copied from the old /etc/resolv.conf but there is no name servers or search domains that are added to the content from the network_state. Who is responsible for adding the name server and the search domain to the network_state ? When I manually added explicit name server and search domain from DataSourceAzure.py in the parse_network_config function as following: netconfig = {'version': 2, 'ethernets': {}} LOG.debug('Azure: generating network configuration from IMDS') netconfig['nameservers'] = {} netconfig['nameservers']['addresses'] = '168.63.129.16' netconfig['nameservers']['search'] = 'xkf00b0rtzgejkug4xc2pcinre.xx.internal.cloudapp.net' network_metadata = imds_metadata['network'] And then changed the _V2_common in network_state.py to build the name_cmd with the "address" key instead of the "addresses" key. Because the "address" key is required in the handle_nameserver function which is called from _v2_common as following: def _v2_common(self, cfg): LOG.debug('v2_common: handling config:\n%s', cfg) if 'nameservers' in cfg: search = cfg.get('nameservers').get('search', []) dns = cfg.get('nameservers').get('addresses', []) name_cmd = {'type': 'nameserver'} if len(search) > 0: name_cmd.update({'search': search}) if len(dns) > 0: - name_cmd.update({'addresses': dns}) + name_cmd.update({'address': dns}) LOG.debug('v2(nameserver) -> v1(nameserver):\n%s', name_cmd) self.handle_nameserver(name_cmd) Note the requirement of the "address" key in the handle_server function @ensure_command_keys(['address']) def handle_nameserver(self, command): With my above changes, cloud-init managed to write the correct /etc/resolv.conf which contains the name server and the search domain.