I have a silly explanation, why udev rules didn't work from the first boot. I might be wrong, but
systemd-udevd resides in initrd image.
So, then when system boots up, udev gets started and it doesn't have access to full copy of /etc
First time NIC will be processed without the rule /etc/udev/rules.d/70-persistent-net.rules (as initrd doesn't contain it)
Cloud-init operates in the middle of system boot a bit later than systemd/initrd.
In order to enforce NIC remaning, you're removing kernel modules for these NIC and loading them back. So, NIC gets enumarated accoring to the generated udev rule.
Perhaps, fuel-agent should just rebuild initrd after generating new udev rules. So, newly generated udev rules gets applied at the first boot during initrd processing.
I have a silly explanation, why udev rules didn't work from the first boot. I might be wrong, but
systemd-udevd resides in initrd image.
So, then when system boots up, udev gets started and it doesn't have access to full copy of /etc
First time NIC will be processed without the rule /etc/udev/ rules.d/ 70-persistent- net.rules (as initrd doesn't contain it)
Cloud-init operates in the middle of system boot a bit later than systemd/initrd.
In order to enforce NIC remaning, you're removing kernel modules for these NIC and loading them back. So, NIC gets enumarated accoring to the generated udev rule.
Perhaps, fuel-agent should just rebuild initrd after generating new udev rules. So, newly generated udev rules gets applied at the first boot during initrd processing.