cloud-init icon indicating copy to clipboard operation
cloud-init copied to clipboard

[docs]: the page "Configuration sources" does not include environment configuration source

Open eprigorodov opened this issue 1 year ago • 4 comments

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

eprigorodov avatar Sep 24 '24 19:09 eprigorodov

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.

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).

holmanb avatar Sep 24 '24 20:09 holmanb

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.

eprigorodov avatar Sep 25 '24 11:09 eprigorodov

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()?

holmanb avatar Sep 25 '24 14:09 holmanb

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

eprigorodov avatar Sep 25 '24 14:09 eprigorodov