[docs]: the page "Configuration sources" does not include environment configuration source
Documentation request
The current implementation incloudinit.helpers.ConfigMerger._read_cfg() also loads configuration from file specified in environment variable CLOUD_CFG:
https://github.com/canonical/cloud-init/blob/6725c0f896e0c55176dd0674668b527a3b2cbed9/cloudinit/helpers.py#L253
By the code, this environment configuration has higher priority than anything else but kernel parameters.
That is used in Microsoft Azure cloud data source. By default it creates a single partition on the Azure VM ephemeral disk. It also has higher priority than cloud.cfg.d/ directory, so the only way to override it is supplying configuration via environment.
That is also reflected in the Microsoft documentation (options 2 and 3).
FIX: document loading environment configuration in the list "Base configuration".
Reported from: https://cloudinit.readthedocs.io/en/latest/explanation/configuration.html
Documentation request
The current implementation in
cloudinit.helpers.ConfigMerger._read_cfg()also loads configuration from file specified in environment variableCLOUD_CFG:https://github.com/canonical/cloud-init/blob/6725c0f896e0c55176dd0674668b527a3b2cbed9/cloudinit/helpers.py#L253
By the code, this environment configuration has higher priority than anything else but kernel parameters.
Thanks for the report @eprigorodov! This should maybe be documented. However, modifying the systemd environment variables usually shouldn't be required (there are simpler ways to accomplish the same thing), so I'm not sure if we really want to document this.
That is used in Microsoft Azure cloud data source. By default it creates a single partition on the Azure VM ephemeral disk. It also has higher priority than
cloud.cfg.d/directory, so the only way to override it is supplying configuration via environment. That is also reflected in the Microsoft documentation (options 2 and 3).
@cjp256 do you know why the docs recommend setting DefaultEnvironment here? The file location is already in the drop-in directory so I don't understand why using this undocumented option is required (and recommended).
Thank you for the quick response, @holmanb,
The file location is already in the drop-in directory so I don't understand why using this undocumented option is required (and recommended).
I debugged that a bit (still don't have full understanding), this is what I found:
- Azure Ubuntu image ships with
/etc/cloud/cloud.cfg.d/90_dpkg.cfg, which defines Azure cloud data source:
# to update this file, run dpkg-reconfigure cloud-init
datasource_list: [ Azure ]
- cloud-init reads
/etc/cloud/cloud.cfg.d/several times, - at some /unknown for me/ moment cloud-init writes that data source into
/run/cloud-init/cloud.cfg, so it becames a runtime config, - runtime config has higher priority than
/etc/cloud/cloud.cfg.d/, - Azure cloud data source plugin brings in some default configuration for ephemeral disk, https://github.com/canonical/cloud-init/blob/6725c0f896e0c55176dd0674668b527a3b2cbed9/cloudinit/sources/DataSourceAzure.py#L293-L302
- that goes into
utli.mergemanydict()before the basic configuration, so it overrides settings from/etc/cloud/cloud.cfg.d/00-azure-swap.cfg, - unless the same file is also specified in the environment config, which has even higher priority
However, modifying the systemd environment variables usually shouldn't be required (there are simpler ways to accomplish the same thing), so I'm not sure if we really want to document this.
If left undocumented then other users can peek the hack from Microsoft docs and start using it. Then someone can have hard time trying to understand why the config set in other sources does not work.
Also, while researching this I lacked a lot a command which dumps effective config and explains where it comes from.
at some /unknown for me/ moment cloud-init writes that data source into
/run/cloud-init/cloud.cfg, so it becames a runtime config,
This happens as a systemd generator. It ends up being a no-op when a single datasource is defined in datasource_list, but when images aren't custom built for a specific cloud this is how cloud-init identifies which cloud it is running on. That allows the same cloud-init package to work everywhere.
* runtime config has higher priority than `/etc/cloud/cloud.cfg.d/`, * Azure cloud data source plugin brings in some default configuration for ephemeral disk, https://github.com/canonical/cloud-init/blob/6725c0f896e0c55176dd0674668b527a3b2cbed9/cloudinit/sources/DataSourceAzure.py#L293-L302 * that goes into `utli.mergemanydict()` before the basic configuration, so it overrides settings from `/etc/cloud/cloud.cfg.d/00-azure-swap.cfg`,
If a default configuration from the source is overriding an on-disk configuration, that sounds like a bug to me. Are you referring to this line? Or a different call to util.mergemanydict()?
nope, the line in Azure data source just returns its default (hard-coded) disk config,
(maybe if there is user data containing disk config, then it can be passed via crawled_data["cfg"] and thus become effective,
but its just a guess, I didn't read the code that deep)
the actual override happens in helpers.ConfigMerger._read_cfg(), when data source config gets taken before the base config:
https://github.com/canonical/cloud-init/blob/c9dce94d316028b15d9f2781fee959da745aea52/cloudinit/helpers.py#L255-L258