Fixing `/etc/hosts` Being Overwritten on Reboot (Ubuntu with Cloud-Init)

What Happened?
Have you ever edited /etc/hosts
only to find your changes mysteriously gone after a reboot?
We sure did — it actually happened to us here at SNUBmonkey.
Turns out, this annoying quirk often affects cloud-based Ubuntu systems (and sometimes local installs) that use Cloud-Init, especially when its default behavior kicks in and manage_etc_hosts is set — or assumed — to be true.
That means:
On Ubuntu systems that use Cloud-Init, the /etc/hosts
file is automatically regenerated at every boot. This behavior is controlled by the manage_etc_hosts
setting in /etc/cloud/cloud.cfg
.
If that setting isn't present, it defaults to true
, meaning Cloud-Init will overwrite any manual changes to /etc/hosts
using internally generated content.
As a result, any custom edits are wiped on reboot — which can break critical services like rsync, SSH, or hostname resolution, especially if your setup depends on specific hostnames.
This is exactly what we recently encountered here at SNUBmonkey.
The Fix: Use the Master Template
Cloud-init is controlling /etc/hosts
, and it does so using this master template:
/etc/cloud/templates/hosts.debian.tmpl
As stated earlier, when manage_etc_hosts
is set to true
(or left undefined, which defaults to true) in /etc/cloud/cloud.cfg
, Cloud-Init regenerates the /etc/hosts file
at every boot using its internal configuration.
Step-by-Step Guide
1. Confirm the Cause
First, check if cloud-init is managing /etc/hosts
:
$ grep manage_etc_hosts /etc/cloud/cloud.cfg
You'll likely see:
manage_etc_hosts: true
If the line is present and set to true
, Cloud-Init will regenerate /etc/hosts
at every boot. If it's missing entirely, Cloud-Init defaults to true anyway — so it will still manage the file unless explicitly told not to.
2. Open the Template
Edit the cloud-init template file used to generate /etc/hosts
:
sudo nano /etc/cloud/templates/hosts.debian.tmpl
You'll see a familiar structure — it's just a template version of /etc/hosts
.
Add your custom entries at the end, like this:
127.0.1.1 webserver webserver
127.0.0.1 localhost
# Custom entries
192.168.1.50 nas
192.168.1.60 backup
10.8.0.15 vpn-gateway
# IPv6 lines (leave as-is unless needed)
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
Save and close.
3. Regenerate Hosts (Optional)
To apply the template immediately without rebooting:
$ sudo cloud-init single --name update_etc_hosts --frequency always
This command forces Cloud-Init to immediately regenerate /etc/hosts
using its template, without needing a reboot. It runs the update_etc_hosts
module even if it has already run before.
Or simply reboot:
$ sudo reboot
4. Confirm the Change
After reboot, check that your /etc/hosts
reflects the custom entries:
$ cat /etc/hosts
Your entries should now be persistent.
Alternative: Disable Cloud-Init Management (Not Recommended for Cloud Environments)
If you prefer to disable Cloud-Init from managing /etc/hosts
altogether, you can set manage_etc_hosts
to false
.
Edit:
$ sudo nano /etc/cloud/cloud.cfg
Find and change:
manage_etc_hosts: false
⚠️ Caution
Disabling Cloud-Init's management of /etc/hosts
means you'll have to manually manage the file, including ensuring hostname/IP consistency in dynamic setups. In cloud environments, this may lead to issues with IP addresses or hostnames that change on reboot.
When Cloud-Init's management of /etc/hosts
is disabled, you take on full responsibility for ensuring the file's accuracy and consistency.
Here's why:
- Dynamic IP and Hostname Changes: In some environments (especially cloud or dynamically configured systems), IP addresses and hostnames can change after every boot or system modification. For example, in cloud environments like AWS, GCP, or Azure, a system's public IP or internal hostname might change when the instance is stopped and restarted, or when a new instance is launched. If you've disabled Cloud-Init's automatic regeneration of
/etc/hosts
, you must manually ensure that any changes to hostnames or IP addresses are reflected in the/etc/hosts
file, or else services relying on that information might break. - Impact on Services: Many services, like SSH, rsync, and other network-based services, often use
/etc/hosts
for resolving hostnames to IP addresses. If the file isn't updated to reflect changes to hostnames or IPs, these services may fail to connect or behave unexpectedly.
For example:- SSH: If you're connecting to another machine by hostname (e.g., ssh user@myserver), the system will look up myserver in
/etc/hosts
to resolve the IP. If the entry is outdated or missing, SSH will fail to connect. - rsync: If you are using custom hostnames in your sync commands (e.g., rsync user@myhostname:/path), and the hostname is not updated in
/etc/hosts
, it will break the sync.
- SSH: If you're connecting to another machine by hostname (e.g., ssh user@myserver), the system will look up myserver in
- Consistency Across Systems: If you have multiple systems relying on
/etc/hosts
for consistent hostname resolution, you'll need to manually update/etc/hosts
across all machines when changes occur.
For example, in a local network or small infrastructure, if one system's IP changes (e.g., due to DHCP), you must ensure that all other systems are updated with the new IP in their/etc/hosts
files.
By disabling Cloud-Init's automatic management of /etc/hosts
, you take on the responsibility of manually ensuring consistency in a dynamic environment. While this gives you full control, it also requires careful attention to detail to avoid issues with network services.
That's it.
We hope this has been a help!