I've tracked down the blocking use of randomness in cloud-init's python module initialization. There are several nonblocking calls to getrandom(), which I believe should be fine; then a blocking call in the multiprocessing module. # PYTHONHASHSEED=1 gdb --args /usr/bin/python3-dbg /usr/bin/cloud-init init GNU gdb (Ubuntu 8.0.1-0ubuntu1) 8.0.1 [...] (gdb) break getrandom Breakpoint 1 at 0x420b90 (gdb) python >import sys >sys.path.append('/usr/share/doc/python3.6/examples/gdb') >import libpython >end (gdb) run Starting program: /usr/bin/python3-dbg /usr/bin/cloud-init init [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Breakpoint 1, getrandom (buffer=buffer@entry=0x7fffffff8140, length=length@entry=2496, flags=flags@entry=1) at ../sysdeps/unix/sysv/linux/getrandom.c:30 [...] (gdb) cont 4 Will ignore next 3 crossings of breakpoint 1. Continuing. [...] -------+ ci-info: | Route | Destination | Gateway | Genmask | Interface | Flags | ci-info: +-------+---------------+---------------+-----------------+-----------+ -------+ ci-info: | 0 | 0.0.0.0 | 192.168.122.1 | 0.0.0.0 | ens3 | UG | ci-info: | 1 | 192.168.122.0 | 0.0.0.0 | 255.255.255.0 | ens3 | U | ci-info: | 2 | 192.168.122.1 | 0.0.0.0 | 255.255.255.255 | ens3 | UH | ci-info: +-------+---------------+---------------+-----------------+-----------+ -------+ /usr/lib/python3.6/logging/config.py:85: ResourceWarning: unclosed file <_io.Tex tIOWrapper name='/var/log/cloud-init.log' mode='a' encoding='UTF-8'> _install_loggers(cp, handlers, disable_existing_loggers) Breakpoint 1, getrandom (buffer=buffer@entry=0x7ffff21b7340, length=length@entry=32, flags=flags@entry=0) at ../sysdeps/unix/sysv/linux/getrandom.c:30 30 in ../sysdeps/unix/sysv/linux/getrandom.c (gdb) py-bt Traceback (most recent call first): 0x7ffff6b66b20 File "/usr/lib/python3.6/multiprocessing/process.py", line 307, in __init__ self._config = {'authkey': AuthenticationString(os.urandom(32)), File "/usr/lib/python3.6/multiprocessing/process.py", line 320, in _current_process = _MainProcess() File "", line 219, in _call_with_frames_removed File "", line 678, in exec_module File "", line 665, in _load_unlocked File "", line 955, in _find_and_load_unlocked File "", line 971, in _find_and_load File "", line 219, in _call_with_frames_removed File "", line 1017, in _handle_fromlist File "/usr/lib/python3.6/multiprocessing/context.py", line 5, in from . import process File "", line 219, in _call_with_frames_removed File "", line 678, in exec_module File "", line 665, in _load_unlocked File "", line 955, in _find_and_load_unlocked File "", line 971, in _find_and_load File "", line 219, in _call_with_frames_removed File "", line 1017, in _handle_fromlist File "/usr/lib/python3.6/multiprocessing/__init__.py", line 16, in from . import context File "", line 219, in _call_with_frames_removed File "", line 678, in exec_module File "", line 665, in _load_unlocked File "", line 955, in _find_and_load_unlocked File "", line 971, in _find_and_load File "/usr/lib/python3.6/concurrent/futures/process.py", line 53, in import multiprocessing File "", line 219, in _call_with_frames_removed File "", line 678, in exec_module File "", line 665, in _load_unlocked File "", line 955, in _find_and_load_unlocked File "", line 971, in _find_and_load File "/usr/lib/python3.6/concurrent/futures/__init__.py", line 17, in from concurrent.futures.process import ProcessPoolExecutor File "", line 219, in _call_with_frames_removed File "", line 678, in exec_module File "", line 665, in _load_unlocked File "", line 955, in _find_and_load_unlocked File "", line 971, in _find_and_load File "/usr/lib/python3.6/asyncio/base_events.py", line 17, in import concurrent.futures File "", line 219, in _call_with_frames_removed File "", line 678, in exec_module File "", line 665, in _load_unlocked File "", line 955, in _find_and_load_unlocked File "", line 971, in _find_and_load File "/usr/lib/python3.6/asyncio/__init__.py", line 21, in from .base_events import * File "", line 219, in _call_with_frames_removed File "", line 678, in exec_module File "", line 665, in _load_unlocked File "", line 955, in _find_and_load_unlocked File "", line 971, in _find_and_load File "/usr/lib/python3/dist-packages/jinja2/asyncsupport.py", line 13, in import asyncio File "", line 219, in _call_with_frames_removed File "", line 678, in exec_module File "", line 665, in _load_unlocked File "", line 955, in _find_and_load_unlocked File "", line 971, in _find_and_load File "/usr/lib/python3/dist-packages/jinja2/__init__.py", line 77, in _patch_async from jinja2.asyncsupport import patch_all File "/usr/lib/python3/dist-packages/jinja2/__init__.py", line 81, in _patch_async() File "", line 219, in _call_with_frames_removed File "", line 678, in exec_module File "", line 665, in _load_unlocked File "", line 955, in _find_and_load_unlocked File "", line 971, in _find_and_load File "/usr/lib/python3/dist-packages/cloudinit/templater.py", line 23, in import jinja2 File "", line 219, in _call_with_frames_removed File "", line 678, in exec_module File "", line 665, in _load_unlocked File "", line 955, in _find_and_load_unlocked File "", line 971, in _find_and_load File "", line 219, in _call_with_frames_removed File "", line 1017, in _handle_fromlist File "/usr/lib/python3/dist-packages/cloudinit/config/cc_update_etc_hosts.py", line 52, in from cloudinit import templater File "", line 219, in _call_with_frames_removed File "", line 678, in exec_module File "", line 665, in _load_unlocked File "", line 955, in _find_and_load_unlocked File "", line 971, in _find_and_load 0x7ffff6bbf580 File "/usr/lib/python3/dist-packages/cloudinit/importer.py", line 15, in import_module __import__(module_name) File "/usr/lib/python3/dist-packages/cloudinit/importer.py", line 35, in find_module mod = import_module(full_path) File "/usr/lib/python3/dist-packages/cloudinit/stages.py", line 751, in _fixup_modules mod_name, ['', type_utils.obj_name(config)], ['handle']) File "/usr/lib/python3/dist-packages/cloudinit/stages.py", line 818, in run_section mostly_mods = self._fixup_modules(raw_mods) File "/usr/lib/python3/dist-packages/cloudinit/cmd/main.py", line 107, in run_module_section (which_ran, failures) = mods.run_section(full_section_name) File "/usr/lib/python3/dist-packages/cloudinit/cmd/main.py", line 416, in main_init return (init.datasource, run_module_section(mods, name, name)) File "/usr/lib/python3/dist-packages/cloudinit/cmd/main.py", line 638, in status_wrapper ret = functor(name, args) File "/usr/lib/python3/dist-packages/cloudinit/util.py", line 2238, in log_time ret = func(*args, **kwargs) File "/usr/lib/python3/dist-packages/cloudinit/cmd/main.py", line 829, in main get_uptime=True, func=functor, args=(name, args)) File "/usr/bin/cloud-init", line 11, in load_entry_point('cloud-init==17.1', 'console_scripts', 'cloud-init')() (gdb) We have the option to set the authkey to a different value post-initialization, but there's no way to avoid using entropy when importing this module.