Module reference¶
Deprecation schedule and versions¶
Keys can be documented as deprecated, new, or changed.
This allows cloud-init to evolve as requirements change, and to adopt
better practices without maintaining design decisions indefinitely.
Keys marked as deprecated or changed may be removed or changed 5
years from the deprecation date. For example, if a key is deprecated in
version 22.1 (the first release in 2022) it is scheduled to be removed in
27.1 (first release in 2027). Use of deprecated keys may cause warnings in
the logs. If a key’s expected value changes, the key will be marked
changed with a date. A 5 year timeline also applies to changed keys.
Modules¶
Ansible¶
Configure Ansible for instance
This module provides Ansible integration for augmenting cloud-init’s configuration of the local node.
This module installs ansible during boot and then uses ansible-pull to run the playbook repository at the remote URL.
Internal name: cc_ansible
Module frequency: once-per-instance
Supported distros: all
Activate only on keys: ansible
- ansible: (object) Each object in ansible list supports the following keys: - install_method: ( - distro/- pip) The type of installation for ansible. It can be one of the following values:- distro
- pip.
 
- run_user: (string) User to run module commands as. If install_method: pip, the pip install runs as this user as well. 
- ansible_config: (string) Sets the ANSIBLE_CONFIG environment variable. If set, overrides default config. 
- setup_controller: (object) Each object in setup_controller list supports the following keys: - repositories: (array of object) Each object in repositories list supports the following keys: - path: (string) 
- source: (string) 
 
- run_ansible: (array of object) Each object in run_ansible list supports the following keys: - playbook_name: (string) 
- playbook_dir: (string) 
- become_password_file: (string) 
- connection_password_file: (string) 
- list_hosts: (boolean) 
- syntax_check: (boolean) 
- timeout: (number) 
- vault_id: (string) 
- vault_password_file: (string) 
- background: (number) 
- check: (boolean) 
- diff: (boolean) 
- module_path: (string) 
- poll: (number) 
- args: (string) 
- extra_vars: (string) 
- forks: (number) 
- inventory: (string) 
- scp_extra_args: (string) 
- sftp_extra_args: (string) 
- private_key: (string) 
- connection: (string) 
- module_name: (string) 
- sleep: (string) 
- tags: (string) 
- skip_tags: (string) 
 
 
- galaxy: (object) Each object in galaxy list supports the following keys: - actions: (array of array of string) 
 
- package_name: (string) 
- pull: (array of object/object) pull playbooks from a VCS repo and run them on the host Each object in pull list supports the following keys: - Deprecated in version 25.2: Expect ansible.pull as list of objects instead of a single object. - accept_host_key: (boolean) 
- clean: (boolean) 
- full: (boolean) 
- diff: (boolean) 
- ssh_common_args: (string) 
- scp_extra_args: (string) 
- sftp_extra_args: (string) 
- private_key: (string) 
- checkout: (string) 
- module_path: (string) 
- timeout: (string) 
- url: (string) 
- connection: (string) 
- vault_id: (string) 
- vault_password_file: (string) 
- verify_commit: (boolean) 
- inventory: (string) 
- module_name: (string) 
- sleep: (string) 
- tags: (string) 
- skip_tags: (string) 
- playbook_name: (string) Single playbook_name to run with ansible-pull - Deprecated in version 25.2: Use playbook_names key instead. 
- playbook_names: (array of string) List of playbook_names to run with ansible-pull 
- accept_host_key: (boolean) 
- clean: (boolean) 
- full: (boolean) 
- diff: (boolean) 
- ssh_common_args: (string) 
- scp_extra_args: (string) 
- sftp_extra_args: (string) 
- private_key: (string) 
- checkout: (string) 
- module_path: (string) 
- timeout: (string) 
- url: (string) 
- connection: (string) 
- vault_id: (string) 
- vault_password_file: (string) 
- verify_commit: (boolean) 
- inventory: (string) 
- module_name: (string) 
- sleep: (string) 
- tags: (string) 
- skip_tags: (string) 
- playbook_name: (string) Single playbook_name to run with ansible-pull - Deprecated in version 25.2: Use playbook_names key instead. 
- playbook_names: (array of string) List of playbook_names to run with ansible-pull 
 
 
Example 1:
#cloud-config
ansible:
  package_name: ansible-core
  install_method: distro
  pull:
    - url: https://github.com/holmanb/vmboot.git
      playbook_names: [ubuntu.yml]
Example 2: Multiple ansible-pull URLs can be provided by providing a list of pull objects. Additionally, multiple playbooks can be provided as a space-separated playbook_name value.
#cloud-config
ansible:
  package_name: ansible-core
  install_method: pip
  pull:
    - url: https://github.com/holmanb/vmboot.git
      playbook_names: [ubuntu.yml, watermark.yml]
APK Configure¶
Configure APK repositories file
This module handles configuration of the Alpine Package Keeper (APK)
/etc/apk/repositories file.
Note
To ensure that APK configuration is valid YAML, any strings containing special characters, especially colons, should be quoted (“:”).
Internal name: cc_apk_configure
Module frequency: once-per-instance
Supported distros: alpine
Activate only on keys: apk_repos
- apk_repos: (object) Each object in apk_repos list supports the following keys: - preserve_repositories: (boolean) By default, cloud-init will generate a new repositories file - /etc/apk/repositoriesbased on any valid configuration settings specified within a apk_repos section of cloud config. To disable this behavior and preserve the repositories file from the pristine image, set preserve_repositories to- true.- The preserve_repositories option overrides all other config keys that would alter - /etc/apk/repositories.
- alpine_repo: (object/null) Each object in alpine_repo list supports the following keys: - base_url: (string) The base URL of an Alpine repository, or mirror, to download official packages from. If not specified then it defaults to - https://alpine.global.ssl.fastly.net/alpine.
- community_enabled: (boolean) Whether to add the Community repo to the repositories file. By default the Community repo is not included. 
- testing_enabled: (boolean) Whether to add the Testing repo to the repositories file. By default the Testing repo is not included. It is only recommended to use the Testing repo on a machine running the - Edgeversion of Alpine as packages installed from Testing may have dependencies that conflict with those in non-Edge Main or Community repos.
- version: (string) The Alpine version to use (e.g. - v3.12or- edge).
 
- local_repo_base_url: (string) The base URL of an Alpine repository containing unofficial packages. 
 
Example 1: Keep the existing /etc/apk/repositories file unaltered.
#cloud-config
apk_repos:
  preserve_repositories: true
Example 2: Create repositories file for Alpine v3.12 main and community using default mirror site.
#cloud-config
apk_repos:
  alpine_repo:
    community_enabled: true
    version: 'v3.12'
Example 3: Create repositories file for Alpine Edge main, community, and testing using a specified mirror site and also a local repo.
#cloud-config
apk_repos:
  alpine_repo:
    base_url: https://some-alpine-mirror/alpine
    community_enabled: true
    testing_enabled: true
    version: edge
  local_repo_base_url: https://my-local-server/local-alpine
Apt Configure¶
Configure APT for the user
This module handles configuration of advanced package tool (APT) options
and adding source lists. There are configuration options such as
apt_get_wrapper` and apt_get_command that control how cloud-init
invokes apt-get. These configuration options are handled on a
per-distro basis, so consult documentation for cloud-init’s distro support
for instructions on using these config options.
By default, cloud-init will generate default APT sources information in
deb822 format at /etc/apt/sources.list.d/<distro>.sources. When
the value of sources_list does not appear to be deb822 format, or
stable distribution releases disable deb822 format,
/etc/apt/sources.list will be written instead.
Note
To ensure that APT configuration is valid YAML, any strings containing special characters, especially colons, should be quoted (“:”).
Note
For more information about APT configuration, see the “Additional APT configuration” example.
Internal name: cc_apt_configure
Module frequency: once-per-instance
Supported distros: ubuntu, debian, raspberry-pi-os
- apt: (object) Each object in apt list supports the following keys: - preserve_sources_list: (boolean) By default, cloud-init will generate a new sources list in - /etc/apt/sources.list.dbased on any changes specified in cloud config. To disable this behavior and preserve the sources list from the pristine image, set preserve_sources_list to- true.- The preserve_sources_list option overrides all other config keys that would alter - sources.listor- sources.list.d, except for additional sources to be added to- sources.list.d.
- disable_suites: (array of string) Entries in the sources list can be disabled using disable_suites, which takes a list of suites to be disabled. If the string - $RELEASEis present in a suite in the disable_suites list, it will be replaced with the release name. If a suite specified in disable_suites is not present in- sources.listit will be ignored. For convenience, several aliases are provided for disable_suites:- updates=>- $RELEASE-updates
- backports=>- $RELEASE-backports
- security=>- $RELEASE-security
- proposed=>- $RELEASE-proposed
- release=>- $RELEASE.
 - When a suite is disabled using disable_suites, its entry in - sources.listis not deleted; it is just commented out.
- primary: (array of object) The primary and security archive mirrors can be specified using the primary and security keys, respectively. Both the primary and security keys take a list of configs, allowing mirrors to be specified on a per-architecture basis. Each config is a dictionary which must have an entry for arches, specifying which architectures that config entry is for. The keyword - defaultapplies to any architecture not explicitly listed. The mirror url can be specified with the uri key, or a list of mirrors to check can be provided in order, with the first mirror that can be resolved being selected. This allows the same configuration to be used in different environment, with different hosts used for a local APT mirror. If no mirror is provided by uri or search, search_dns may be used to search for dns names in the format- <distro>-mirrorin each of the following:- fqdn of this host per cloud metadata, 
- localdomain, 
- domains listed in - /etc/resolv.conf.
 - If there is a dns entry for - <distro>-mirror, then it is assumed that there is a distro mirror at- http://<distro>-mirror.<domain>/<distro>. If the primary key is defined, but not the security key, then then configuration for primary is also used for security. If search_dns is used for the security key, the search pattern will be- <distro>-security-mirror.- Each mirror may also specify a key to import via any of the following optional keys: - keyid: a key to import via shortid or fingerprint. 
- key: a raw PGP key. 
- keyserver: alternate keyserver to pull keyid key from. 
 - If no mirrors are specified, or all lookups fail, then default mirrors defined in the datasource are used. If none are present in the datasource either the following defaults are used: - primary => - http://archive.ubuntu.com/ubuntu.
- security => - http://security.ubuntu.com/ubuntu. Each object in primary list supports the following keys:
 - arches: (array of string) 
- uri: (string) 
- search: (array of string) 
- search_dns: (boolean) 
- keyid: (string) 
- key: (string) 
- keyserver: (string) 
 
- security: (array of object) Please refer to the primary config documentation. Each object in security list supports the following keys: - arches: (array of string) 
- uri: (string) 
- search: (array of string) 
- search_dns: (boolean) 
- keyid: (string) 
- key: (string) 
- keyserver: (string) 
 
- add_apt_repo_match: (string) All source entries in - apt-sourcesthat match regex in add_apt_repo_match will be added to the system using- add-apt-repository. If add_apt_repo_match is not specified, it defaults to- ^[\w-]+:\w.
- debconf_selections: (object) Debconf additional configurations can be specified as a dictionary under the debconf_selections config key, with each key in the dict representing a different set of configurations. The value of each key must be a string containing all the debconf configurations that must be applied. We will bundle all of the values and pass them to debconf-set-selections. Therefore, each value line must be a valid entry for - debconf-set-selections, meaning that they must possess for distinct fields:- pkgname question type answer- Where: - pkgnameis the name of the package.
- questionthe name of the questions.
- typeis the type of question.
- answeris the value used to answer the question.
 - For example: - ippackage ippackage/ip string 127.0.01. Each object in debconf_selections list supports the following keys:- ^.+$: (string) 
 
- sources_list: (string) Specifies a custom template for rendering - sources.list. If no sources_list template is given, cloud-init will use sane default. Within this template, the following strings will be replaced with the appropriate values:- $MIRROR
- $RELEASE
- $PRIMARY
- $SECURITY
- $KEY_FILE
 
- conf: (string) Specify configuration for apt, such as proxy configuration. This configuration is specified as a string. For multi-line APT configuration, make sure to follow YAML syntax. 
- https_proxy: (string) More convenient way to specify https APT proxy. https proxy url is specified in the format - https://[[user][:pass]@]host[:port]/.
- http_proxy: (string) More convenient way to specify http APT proxy. http proxy url is specified in the format - http://[[user][:pass]@]host[:port]/.
- proxy: (string) Alias for defining a http APT proxy. 
- ftp_proxy: (string) More convenient way to specify ftp APT proxy. ftp proxy url is specified in the format - ftp://[[user][:pass]@]host[:port]/.
- sources: (object) Source list entries can be specified as a dictionary under the sources config key, with each key in the dict representing a different source file. The key of each source entry will be used as an id that can be referenced in other config entries, as well as the filename for the source’s configuration under - /etc/apt/sources.list.d. If the name does not end with- .list, it will be appended. If there is no configuration for a key in sources, no file will be written, but the key may still be referred to as an id in other sources entries.- Each entry under sources is a dictionary which may contain any of the following optional keys: - source: a sources.list entry (some variable replacements apply). 
- keyid: a key to import via shortid or fingerprint. 
- key: a raw PGP key. 
- keyserver: alternate keyserver to pull keyid key from. 
- filename: specify the name of the list file. 
- append: If - true, append to sources file, otherwise overwrite it. Default:- true.
 - The source key supports variable replacements for the following strings: - $MIRROR
- $PRIMARY
- $SECURITY
- $RELEASE
- $KEY_FILEEach object in sources list supports the following keys:
 - ^.+$: (object) Each object in ^.+$ list supports the following keys: - source: (string) 
- keyid: (string) 
- key: (string) 
- keyserver: (string) 
- filename: (string) 
- append: (boolean) 
 
 
 
Example 1:
#cloud-config
apt:
  preserve_sources_list: false
  disable_suites:
    - $RELEASE-updates
    - backports
    - $RELEASE
    - mysuite
  primary:
    - arches:
        - amd64
        - i386
        - default
      uri: http://us.archive.ubuntu.com/ubuntu
      search:
        - http://cool.but-sometimes-unreachable.com/ubuntu
        - http://us.archive.ubuntu.com/ubuntu
      search_dns: false
    - arches:
        - s390x
        - arm64
      uri: http://archive-to-use-for-arm64.example.com/ubuntu
  security:
    - arches:
        - default
      search_dns: true
  sources_list: |
      deb $MIRROR $RELEASE main restricted
      deb-src $MIRROR $RELEASE main restricted
      deb $PRIMARY $RELEASE universe restricted
      deb $SECURITY $RELEASE-security multiverse
  debconf_selections:
      set1: the-package the-package/some-flag boolean true
  conf: |
      APT {
          Get {
              Assume-Yes 'true';
              Fix-Broken 'true';
          }
      }
  proxy: http://[[user][:pass]@]host[:port]/
  http_proxy: http://[[user][:pass]@]host[:port]/
  ftp_proxy: ftp://[[user][:pass]@]host[:port]/
  https_proxy: https://[[user][:pass]@]host[:port]/
  sources:
      source1:
          keyid: keyid
          keyserver: keyserverurl
          source: deb [signed-by=$KEY_FILE] http://<url>/ bionic main
      source2:
          source: ppa:<ppa-name>
      source3:
          source: deb $MIRROR $RELEASE multiverse
          key: |
              ------BEGIN PGP PUBLIC KEY BLOCK-------
              <key data>
              ------END PGP PUBLIC KEY BLOCK-------
      source4:
          source: deb $MIRROR $RELEASE multiverse
          append: false
          key: |
              ------BEGIN PGP PUBLIC KEY BLOCK-------
              <key data>
              ------END PGP PUBLIC KEY BLOCK-------
Example 2: Cloud-init version 23.4 will generate a deb822-formatted sources file at /etc/apt/sources.list.d/<distro>.sources instead of /etc/apt/sources.list when sources_list content is in deb822 format.
#cloud-config
apt:
    sources_list: |
      Types: deb
      URIs: http://archive.ubuntu.com/ubuntu/
      Suites: $RELEASE
      Components: main
Apt Pipelining¶
Configure APT pipelining
This module configures APT’s Acquire::http::Pipeline-Depth option,
which controls how APT handles HTTP pipelining. It may be useful for
pipelining to be disabled, because some web servers (such as S3) do not
pipeline properly (LP: #948461).
Value configuration options for this module are:
- os: (Default) use distro default
- false: Disable pipelining altogether
- <number>: Manually specify pipeline depth. This is not recommended.
Internal name: cc_apt_pipelining
Module frequency: once-per-instance
Supported distros: ubuntu, debian, raspberry-pi-os
Activate only on keys: apt_pipelining
- apt_pipelining: (integer/boolean/string) 
Example 1:
#cloud-config
apt_pipelining: false
Example 2:
#cloud-config
apt_pipelining: os
Example 3:
#cloud-config
apt_pipelining: 3
Bootcmd¶
Run arbitrary commands early in the boot process
This module runs arbitrary commands very early in the boot process, only
slightly after a boothook would run. This is very similar to a boothook,
but more user friendly. Commands can be
specified either as lists or strings. For invocation details, see
runcmd.
Note
bootcmd should only be used for things that could not be done later
in the boot process.
Note
When writing files, do not use /tmp dir as it races with
systemd-tmpfiles-clean (LP: #1707222). Use /run/somedir instead.
Warning
Use of INSTANCE_ID variable within this module is deprecated.
Use jinja templates with
v1.instance_id instead.
Internal name: cc_bootcmd
Module frequency: always
Supported distros: all
Activate only on keys: bootcmd
- bootcmd: (array of array of string/string) 
Example 1:
#cloud-config
bootcmd:
- echo 192.168.1.130 us.archive.ubuntu.com > /etc/hosts
- [cloud-init-per, once, mymkfs, mkfs, /dev/vdb]
Byobu¶
Enable/disable Byobu system-wide and for the default user
This module controls whether Byobu is enabled or disabled system-wide and for the default system user. If Byobu is to be enabled, this module will ensure it is installed. Likewise, if Byobu is to be disabled, it will be removed (if installed).
Valid configuration options for this module are:
- enable-system: enable Byobu system-wide
- enable-user: enable Byobu for the default user
- disable-system: disable Byobu system-wide
- disable-user: disable Byobu for the default user
- enable: enable Byobu both system-wide and for the default user
- disable: disable Byobu for all users
- user: alias for- enable-user
- system: alias for- enable-system
Internal name: cc_byobu
Module frequency: once-per-instance
Supported distros: ubuntu, debian, raspberry-pi-os
- byobu_by_default: ( - enable-system/- enable-user/- disable-system/- disable-user/- enable/- disable/- user/- system)
Example 1:
#cloud-config
byobu_by_default: enable-user
Example 2:
#cloud-config
byobu_by_default: disable-system
CA Certificates¶
Add CA certificates
This module adds CA certificates to the system’s CA store and updates any
related files using the appropriate OS-specific utility. The default CA
certificates can be disabled/deleted from use by the system with the
configuration option remove_defaults.
Note
Certificates must be specified using valid YAML. To specify a multi-line certificate, the YAML multi-line list syntax must be used.
Note
Alpine Linux requires the ca-certificates package to be installed
in order to provide the update-ca-certificates command.
Internal name: cc_ca_certs
Module frequency: once-per-instance
Supported distros: almalinux, aosc, centos, cloudlinux, alpine, debian, fedora, raspberry-pi-os, rhel, rocky, opensuse, opensuse-microos, opensuse-tumbleweed, opensuse-leap, sle_hpc, sle-micro, sles, ubuntu, photon
Activate only on keys: ca_certs, ca-certs
- ca_certs: (object) Each object in ca_certs list supports the following keys: - remove-defaults: (boolean) - Deprecated in version 22.3: Use remove_defaults instead. 
- remove_defaults: (boolean) Remove default CA certificates if true. Default: - false.
- trusted: (array of string) List of trusted CA certificates to add. 
 
- ca-certs: (object) Each object in ca-certs list supports the following keys: - Deprecated in version 22.3: Use ca_certs instead. - remove-defaults: (boolean) - Deprecated in version 22.3: Use remove_defaults instead. 
- remove_defaults: (boolean) Remove default CA certificates if true. Default: - false.
- trusted: (array of string) List of trusted CA certificates to add. 
 
Example 1:
#cloud-config
ca_certs:
  remove_defaults: true
  trusted:
  - single_line_cert
  - |
    -----BEGIN CERTIFICATE-----
    YOUR-ORGS-TRUSTED-CA-CERT-HERE
    -----END CERTIFICATE-----
Chef¶
Module that installs, configures, and starts Chef
This module enables Chef to be installed (from packages, gems, or from
omnibus). Before this occurs, Chef configuration is written to disk
(validation.pem, client.pem, firstboot.json, client.rb),
and required directories are created (/etc/chef and /var/log/chef
and so on).
If configured, Chef will be installed and started in either daemon or
non-daemon mode. If run in non-daemon mode, post-run actions are executed
to do finishing activities such as removing validation.pem.
Internal name: cc_chef
Module frequency: always
Supported distros: all
Activate only on keys: chef
- chef: (object) Each object in chef list supports the following keys: - directories: (array of string) Create the necessary directories for chef to run. By default, it creates the following directories: - /etc/chef
- /var/log/chef
- /var/lib/chef
- /var/chef/backup
- /var/chef/cache
- /var/run/chef
 
- config_path: (string) Optional path for Chef configuration file. Default: - /etc/chef/client.rb
- validation_cert: (string) Optional string to be written to file validation_key. Special value - systemmeans set use existing file.
- validation_key: (string) Optional path for validation_cert. Default: - /etc/chef/validation.pem.
- firstboot_path: (string) Path to write run_list and initial_attributes keys that should also be present in this configuration. Default: - /etc/chef/firstboot.json.
- exec: (boolean) Set true if we should run or not run chef (defaults to false, unless a gem installed is requested where this will then default to true). 
- client_key: (string) Optional path for client_cert. Default: - /etc/chef/client.pem.
- encrypted_data_bag_secret: (string) Specifies the location of the secret key used by chef to encrypt data items. By default, this path is set to null, meaning that chef will have to look at the path - /etc/chef/encrypted_data_bag_secretfor it.
- environment: (string) Specifies which environment chef will use. By default, it will use the - _defaultconfiguration.
- file_backup_path: (string) Specifies the location in which backup files are stored. By default, it uses the - /var/chef/backuplocation.
- file_cache_path: (string) Specifies the location in which chef cache files will be saved. By default, it uses the - /var/chef/cachelocation.
- json_attribs: (string) Specifies the location in which some chef json data is stored. By default, it uses the - /etc/chef/firstboot.jsonlocation.
- log_level: (string) Defines the level of logging to be stored in the log file. By default this value is set to - :info.
- log_location: (string) Specifies the location of the chef log file. By default, the location is specified at - /var/log/chef/client.log.
- node_name: (string) The name of the node to run. By default, we will use th instance id as the node name. 
- omnibus_url: (string) Omnibus URL if chef should be installed through Omnibus. By default, it uses the - https://www.chef.io/chef/install.sh.
- omnibus_url_retries: (integer) The number of retries that will be attempted to reach the Omnibus URL. Default: - 5.
- omnibus_version: (string) Optional version string to require for omnibus install. 
- pid_file: (string) The location in which a process identification number (pid) is saved. By default, it saves in the - /var/run/chef/client.pidlocation.
- server_url: (string) The URL for the chef server. 
- show_time: (boolean) Show time in chef logs. 
- ssl_verify_mode: (string) Set the verify mode for HTTPS requests. We can have two possible values for this parameter: - :verify_none: No validation of SSL certificates.
- :verify_peer: Validate all SSL certificates.
 - By default, the parameter is set as - :verify_none.
- validation_name: (string) The name of the chef-validator key that Chef Infra Client uses to access the Chef Infra Server during the initial Chef Infra Client run. 
- force_install: (boolean) If set to - true, forces chef installation, even if it is already installed.
- initial_attributes: (object of string) Specify a list of initial attributes used by the cookbooks. 
- install_type: ( - packages/- gems/- omnibus) The type of installation for chef. It can be one of the following values:- packages
- gems
- omnibus
 
- run_list: (array of string) A run list for a first boot json. 
- chef_license: ( - accept/- accept-silent/- accept-no-persist) string that indicates if user accepts or not license related to some of chef products. See https://docs.chef.io/licensing/accept/.
 
Example 1:
#cloud-config
chef:
  directories: [/etc/chef, /var/log/chef]
  encrypted_data_bag_secret: /etc/chef/encrypted_data_bag_secret
  environment: _default
  initial_attributes:
    apache:
      keepalive: false
      prefork: {maxclients: 100}
  install_type: omnibus
  log_level: :auto
  omnibus_url_retries: 2
  run_list: ['recipe[apache2]', 'role[db]']
  server_url: https://chef.yourorg.com:4000
  ssl_verify_mode: :verify_peer
  validation_cert: system
  validation_name: yourorg-validator
Disable EC2 Instance Metadata Service¶
Disable AWS EC2 Instance Metadata Service
This module can disable the EC2 datasource by rejecting the route to
169.254.169.254, the usual route to the datasource. This module is
disabled by default.
Internal name: cc_disable_ec2_metadata
Module frequency: always
Supported distros: all
Activate only on keys: disable_ec2_metadata
- disable_ec2_metadata: (boolean) Set true to disable IPv4 routes to EC2 metadata. Default: - false.
Example 1:
#cloud-config
disable_ec2_metadata: true
Disk Setup¶
Configure partitions and filesystems
This module configures simple partition tables and filesystems.
Note
For more detail about configuration options for disk setup, see the disk setup example.
Note
If a swap partition is being created via disk_setup, then an
fs_entry entry is also needed in order for mkswap to be run,
otherwise when swap activation is later attempted it will fail.
For convenience, aliases can be specified for disks using the
device_aliases config key, which takes a dictionary of alias: path
mappings. There are automatic aliases for swap and ephemeral<X>,
where swap will always refer to the active swap partition and
ephemeral<X> will refer to the block device of the ephemeral image.
Disk partitioning is done using the disk_setup directive. This config
directive accepts a dictionary where each key is either a path to a
block device or an alias specified in device_aliases, and each value is
the configuration options for the device. File system configuration is done
using the fs_setup directive. This config directive accepts a list of
filesystem configs.
Internal name: cc_disk_setup
Module frequency: once-per-instance
Supported distros: all
Activate only on keys: disk_setup, fs_setup
- device_aliases: (object) Each object in device_aliases list supports the following keys: - <alias_name>: (string) Path to disk to be aliased by this name. 
 
- disk_setup: (object) Each object in disk_setup list supports the following keys: - <alias name/path>: (object) Each object in <alias name/path> list supports the following keys: - table_type: ( - mbr/- gpt) Specifies the partition table type, either- mbror- gpt. Default:- mbr.
- layout: ( - remove/boolean/array of integer/array of ) If set to- true, a single partition using all the space on the device will be created. If set to- false, no partitions will be created. If set to- remove, any existing partition table will be purged. Partitions can be specified by providing a list to- layout, where each entry in the list is either a size or a list containing a size and the numerical value for a partition type. The size for partitions is specified in percentage of disk space, not in bytes (e.g. a size of 33 would take up 1/3 of the disk space). The partition type defaults to ‘83’ (Linux partition), for other types of partition, such as Linux swap, the type must be passed as part of a list along with the size. Default:- false.
- overwrite: (boolean) Controls whether this module tries to be safe about writing partition tables or not. If - overwrite: falseis set, the device will be checked for a partition table and for a file system and if either is found, the operation will be skipped. If- overwrite: trueis set, no checks will be performed. Using- overwrite: trueis dangerous and can lead to data loss, so double check that the correct device has been specified if using this option. Default:- false.
 
 
- fs_setup: (array of object) Each object in fs_setup list supports the following keys: - label: (string) Label for the filesystem. 
- filesystem: (string) Filesystem type to create. E.g., - ext4or- btrfs.
- device: (string) Specified either as a path or as an alias in the format - <alias name>.<y>where- <y>denotes the partition number on the device. If specifying device using the- <alias name>.<partition number>format, the value of partition will be overwritten.
- partition: (string/integer) The partition can be specified by setting partition to the desired partition number. The partition option may also be set to - auto, in which this module will search for the existence of a filesystem matching the label, filesystem and device of the fs_setup entry and will skip creating the filesystem if one is found. The partition option may also be set to- any, in which case any filesystem that matches filesystem and device will cause this module to skip filesystem creation for the fs_setup entry, regardless of label matching or not. To write a filesystem directly to a device, use- partition: none.- partition: nonewill always write the filesystem, even when the label and filesystem are matched, and- overwriteis- false.
- overwrite: (boolean) If - true, overwrite any existing filesystem. Using- overwrite: truefor filesystems is dangerous and can lead to data loss, so double check the entry in fs_setup. Default:- false.
- replace_fs: (string) Ignored unless partition is - autoor- any. Default- false.
- extra_opts: ([‘array’, ‘string’] of string) Optional options to pass to the filesystem creation command. Ignored if you using cmd directly. 
- cmd: ([‘array’, ‘string’] of string) Optional command to run to create the filesystem. Can include string substitutions of the other fs_setup config keys. This is only necessary if you need to override the default command. 
 
Example 1:
#cloud-config
device_aliases: {my_alias: /dev/sdb, swap_disk: /dev/sdc}
disk_setup:
  /dev/sdd: {layout: true, overwrite: true, table_type: mbr}
  my_alias:
    layout: [50, 50]
    overwrite: true
    table_type: gpt
  swap_disk:
    layout:
    - [100, 82]
    overwrite: true
    table_type: gpt
fs_setup:
- {cmd: mkfs -t %(filesystem)s -L %(label)s %(device)s, device: my_alias.1, filesystem: ext4,
  label: fs1}
- {device: my_alias.2, filesystem: ext4, label: fs2}
- {device: swap_disk.1, filesystem: swap, label: swap}
- {device: /dev/sdd1, filesystem: ext4, label: fs3}
mounts:
- [my_alias.1, /mnt1]
- [my_alias.2, /mnt2]
- [swap_disk.1, none, swap, sw, '0', '0']
- [/dev/sdd1, /mnt3]
Fan¶
Configure Ubuntu fan networking
This module installs, configures and starts the Ubuntu fan network system (Read more about Ubuntu Fan).
If cloud-init sees a fan entry in cloud-config it will:
- Write - config_pathwith the contents of the- configkey
- Install the package - ubuntu-fanif it is not installed
- Ensure the service is started (or restarted if was previously running) 
Additionally, the ubuntu-fan package will be automatically installed
if not present.
Internal name: cc_fan
Module frequency: once-per-instance
Supported distros: ubuntu
Activate only on keys: fan
- fan: (object) Each object in fan list supports the following keys: - config: (string) The fan configuration to use as a single multi-line string. 
- config_path: (string) The path to write the fan configuration to. Default: - /etc/network/fan.
 
Example 1:
#cloud-config
fan:
  config: |
    # fan 240
    10.0.0.0/8 eth0/16 dhcp
    10.0.0.0/8 eth1/16 dhcp off
    # fan 241
    241.0.0.0/8 eth0/16 dhcp
  config_path: /etc/network/fan
Final Message¶
Output final message when cloud-init has finished
This module configures the final message that cloud-init writes. The message is specified as a Jinja template with the following variables set:
- version: cloud-init version
- timestamp: time at cloud-init finish
- datasource: cloud-init data source
- uptime: system uptime
This message is written to the cloud-init log (usually
/var/log/cloud-init.log) as well as stderr (which usually redirects to
/var/log/cloud-init-output.log).
Upon exit, this module writes the system uptime, timestamp, and cloud-init
version to /var/lib/cloud/instance/boot-finished independent of any
user data specified for this module.
Internal name: cc_final_message
Module frequency: always
Supported distros: all
- final_message: (string) The message to display at the end of the run. 
Example 1:
#cloud-config
final_message: |
  cloud-init has finished
  version: $version
  timestamp: $timestamp
  datasource: $datasource
  uptime: $uptime
Growpart¶
Grow partitions
Growpart resizes partitions to fill the available disk space. This is useful for cloud instances with a larger amount of disk space available than the pristine image uses, as it allows the instance to automatically make use of the extra space.
Note that this only works if the partition to be resized is the last one on a disk with classic partitioning scheme (MBR, BSD, GPT). LVM, Btrfs and ZFS have no such restrictions.
The devices on which to run growpart are specified as a list under the
devices key.
There is some functionality overlap between this module and the
growroot functionality of cloud-initramfs-tools. However, there
are some situations where one tool is able to function and the other is
not. The default configuration for both should work for most cloud
instances. To explicitly prevent cloud-initramfs-tools from running
growroot, the file /etc/growroot-disabled can be created.
By default, both growroot and cc_growpart will check for the
existence of this file and will not run if it is present. However, this
file can be ignored for cc_growpart by setting
ignore_growroot_disabled to true.
Read more about
cloud-initramfs-tools.
On FreeBSD, there is also the growfs service, which has a lot of
overlap with cc_growpart and cc_resizefs, but only works on the
root partition. In that configuration, we use it, otherwise, we fall back
to gpart.
Note
growfs may insert a swap partition, if none is present, unless
instructed not to via growfs_swap_size=0 in either kenv(1), or
rc.conf(5).
Growpart is enabled by default on the root partition. The default config for growpart is:
growpart:
  mode: auto
  devices: [\"/\"]
  ignore_growroot_disabled: false
Internal name: cc_growpart
Module frequency: always
Supported distros: all
- growpart: (object) Each object in growpart list supports the following keys: - mode: ( - auto/- growpart/- gpart/- off/- False) The utility to use for resizing. Default:- auto- Possible options: - auto- Use any available utility
- growpart- Use growpart utility
- gpart- Use BSD gpart utility
- 'off'- Take no action.
 - Changed in version 22.3.Specifying a boolean ``false`` value for **mode* is deprecated. Use the string - 'off'instead.*
- devices: (array of string) The devices to resize. Each entry can either be the path to the device’s mountpoint in the filesystem or a path to the block device in ‘/dev’. Default: - [/].
- ignore_growroot_disabled: (boolean) If - true, ignore the presence of- /etc/growroot-disabled. If- falseand the file exists, then don’t resize. Default:- false.
 
Example 1:
#cloud-config
growpart:
  devices: [/]
  ignore_growroot_disabled: false
  mode: auto
Example 2:
#cloud-config
growpart:
  devices: [/, /dev/vdb1]
  ignore_growroot_disabled: true
  mode: growpart
GRUB dpkg¶
Configure GRUB debconf installation device
Configure which device is used as the target for GRUB installation. This
module can be enabled/disabled using the enabled config key in the
grub_dpkg config dict. This module automatically selects a disk using
grub-probe if no installation device is specified.
The value placed into the debconf database is in the format expected by the
GRUB post-install script expects. Normally, this is a /dev/disk/by-id/
value, but we do fallback to the plain disk name if a by-id name is not
present.
If this module is executed inside a container, then the debconf database is
seeded with empty values, and install_devices_empty is set to true.
Internal name: cc_grub_dpkg
Module frequency: once-per-instance
Supported distros: ubuntu, debian
Activate only on keys: grub_dpkg, grub-dpkg
- grub_dpkg: (object) Each object in grub_dpkg list supports the following keys: - enabled: (boolean) Whether to configure which device is used as the target for grub installation. Default: - false.
- grub-pc/install_devices: (string) Device to use as target for grub installation. If unspecified, - grub-probeof- /bootwill be used to find the device.
- grub-pc/install_devices_empty: (boolean/string) Sets values for grub-pc/install_devices_empty. If unspecified, will be set to - trueif grub-pc/install_devices is empty, otherwise- false.- Changed in version 22.3.Use a boolean value instead. 
- grub-efi/install_devices: (string) Partition to use as target for grub installation. If unspecified, - grub-probeof- /boot/efiwill be used to find the partition.
 
- grub-dpkg: (object) - Deprecated in version 22.2: Use grub_dpkg instead. 
Example 1:
#cloud-config
grub_dpkg:
  enabled: true
  # BIOS mode (install_devices needs disk)
  grub-pc/install_devices: /dev/sda
  grub-pc/install_devices_empty: false
  # EFI mode (install_devices needs partition)
  grub-efi/install_devices: /dev/sda
Install Hotplug¶
Install hotplug udev rules if supported and enabled
This module will install the udev rules to enable hotplug if supported by
the datasource and enabled in the user-data. The udev rules will be
installed as /etc/udev/rules.d/90-cloud-init-hook-hotplug.rules.
When hotplug is enabled, newly added network devices will be added to the system by cloud-init. After udev detects the event, cloud-init will refresh the instance metadata from the datasource, detect the device in the updated metadata, then apply the updated network configuration.
Udev rules are installed while cloud-init is running, which means that devices which are added during boot might not be configured. To work around this limitation, one can wait until cloud-init has completed before hotplugging devices.
Currently supported datasources: Openstack, EC2, Hetzner
Internal name: cc_install_hotplug
Module frequency: once-per-instance
Supported distros: all
- updates: (object) Each object in updates list supports the following keys: - network: (object) Each object in network list supports the following keys: - when: (array of - boot-new-instance/- boot-legacy/- boot/- hotplug)
 
 
Example 1: Enable hotplug of network devices
#cloud-config
updates:
  network:
    when: [hotplug]
Example 2: Enable network hotplug alongside boot event
#cloud-config
updates:
  network:
    when: [boot, hotplug]
Keyboard¶
Set keyboard layout
Handle keyboard configuration.
Internal name: cc_keyboard
Module frequency: once-per-instance
Supported distros: alpine, arch, debian, ubuntu, raspberry-pi-os, almalinux, amazon, azurelinux, centos, cloudlinux, eurolinux, fedora, mariner, miraclelinux, openmandriva, photon, rhel, rocky, virtuozzo, opensuse, opensuse-leap, opensuse-microos, opensuse-tumbleweed, sle_hpc, sle-micro, sles, suse
Activate only on keys: keyboard
- keyboard: (object) Each object in keyboard list supports the following keys: - layout: (string) Required. Keyboard layout. Corresponds to XKBLAYOUT. 
- model: (string) Optional. Keyboard model. Corresponds to XKBMODEL. Default: - pc105.
- variant: (string) Required for Alpine Linux, optional otherwise. Keyboard variant. Corresponds to XKBVARIANT. 
- options: (string) Optional. Keyboard options. Corresponds to XKBOPTIONS. 
 
Example 1: Set keyboard layout to “us”
#cloud-config
keyboard:
  layout: us
Example 2: Set specific keyboard layout, model, variant, options
#cloud-config
keyboard:
  layout: de
  model: pc105
  variant: nodeadkeys
  options: compose:rwin
Example 3: For Alpine Linux, set specific keyboard layout and variant, as used by setup-keymap. Model and options are ignored.
#cloud-config
keyboard:
  layout: gb
  variant: gb-extd
Keys to Console¶
Control which SSH host keys may be written to console
For security reasons it may be desirable not to write SSH host keys and
their fingerprints to the console. To avoid either of them being written
to the console, the emit_keys_to_console config key under the main
ssh config key can be used.
To avoid the fingerprint of types of SSH host keys being written to
console the ssh_fp_console_blacklist config key can be used. By
default, all types of keys will have their fingerprints written to console.
To avoid host keys of a key type being written to console the
ssh_key_console_blacklist config key can be used. By default,
all supported host keys are written to console.
Internal name: cc_keys_to_console
Module frequency: once-per-instance
Supported distros: all
- ssh: (object) Each object in ssh list supports the following keys: - emit_keys_to_console: (boolean) Set false to avoid printing SSH keys to system console. Default: - true.
 
- ssh_key_console_blacklist: (array of string) Avoid printing matching SSH key types to the system console. 
- ssh_fp_console_blacklist: (array of string) Avoid printing matching SSH fingerprints to the system console. 
Example 1: Do not print any SSH keys to system console
#cloud-config
ssh:
  emit_keys_to_console: false
Example 2: Do not print certain SSH key types to console
#cloud-config
ssh_key_console_blacklist: [rsa]
Example 3: Do not print specific SSH key fingerprints to console
#cloud-config
ssh_fp_console_blacklist:
- E25451E0221B5773DEBFF178ECDACB160995AA89
- FE76292D55E8B28EE6DB2B34B2D8A784F8C0AAB0
Landscape¶
Install and configure Landscape client
This module installs and configures landscape-client. The Landscape
client will only be installed if the key landscape is present in
config.
Landscape client configuration is given under the client key under the
main landscape config key. The config parameters are not interpreted by
cloud-init, but rather are converted into a ConfigObj-formatted file
and written out to the [client] section in
/etc/landscape/client.conf. The following default client config is
provided, but can be overridden
landscape:
  client:
    log_level: "info"
    url: "https://landscape.canonical.com/message-system"
    ping_url: "http://landscape.canonical.com/ping"
    data_path: "/var/lib/landscape/client"
Note
See Landscape documentation for client config keys.
Note
If tags is defined, its contents should be a string delimited with
a comma (“,”) rather than a list.
Internal name: cc_landscape
Module frequency: once-per-instance
Supported distros: ubuntu
Activate only on keys: landscape
- landscape: (object) Each object in landscape list supports the following keys: - client: (object) Each object in client list supports the following keys: - url: (string) The Landscape server URL to connect to. Default: - https://landscape.canonical.com/message-system.
- ping_url: (string) The URL to perform lightweight exchange initiation with. Default: - https://landscape.canonical.com/ping.
- data_path: (string) The directory to store data files in. Default: - /var/lib/land‐scape/client/.
- log_level: ( - debug/- info/- warning/- error/- critical) The log level for the client. Default:- info.
- computer_title: (string) The title of this computer. 
- account_name: (string) The account this computer belongs to. 
- registration_key: (string) The account-wide key used for registering clients. 
- tags: (string) Comma separated list of tag names to be sent to the server. 
- http_proxy: (string) The URL of the HTTP proxy, if one is needed. 
- https_proxy: (string) The URL of the HTTPS proxy, if one is needed. 
 
 
To discover additional supported client keys, run man landscape-config.
Example 1:
#cloud-config
landscape:
  client:
    url: https://landscape.canonical.com/message-system
    ping_url: http://landscape.canonical.com/ping
    data_path: /var/lib/landscape/client
    http_proxy: http://my.proxy.com/foobar
    https_proxy: https://my.proxy.com/foobar
    tags: server,cloud
    computer_title: footitle
    registration_key: fookey
    account_name: fooaccount
Example 2: Minimum viable config requires account_name and computer_title.
#cloud-config
landscape:
  client:
    computer_title: kiosk 1
    account_name: Joe's Biz
Example 3: To install landscape-client from a PPA, specify apt.sources.
#cloud-config
apt:
  sources:
    trunk-testing-ppa:
      source: ppa:landscape/self-hosted-beta
landscape:
  client:
    account_name: myaccount
    computer_title: himom
Locale¶
Set system locale
Configure the system locale and apply it system-wide. By default, use the locale specified by the datasource.
Internal name: cc_locale
Module frequency: once-per-instance
Supported distros: all
- locale: (boolean/string) The locale to set as the system’s locale (e.g. ar_PS). 
- locale_configfile: (string) The file in which to write the locale configuration (defaults to the distro’s default location). 
Example 1: Set the locale to "ar_AE"
#cloud-config
locale: ar_AE
Example 2: Set the locale to "fr_CA" in /etc/alternate_path/locale
#cloud-config
locale: fr_CA
locale_configfile: /etc/alternate_path/locale
Example 3: Skip performing any locale setup or generation
#cloud-config
locale: false
LXD¶
Configure LXD with lxd init and (optionally) lxd-bridge
This module configures LXD with user-specified options using lxd init.
- If - lxdis not present on the system but LXD configuration is provided, then- lxdwill be installed.
- If the selected storage backend userspace utility is not installed, it will be installed. 
- If network bridge configuration is provided, then - lxd-bridgewill be configured accordingly.
Internal name: cc_lxd
Module frequency: once-per-instance
Supported distros: ubuntu
Activate only on keys: lxd
- lxd: (object) Each object in lxd list supports the following keys: - init: (object) LXD init configuration values to provide to lxd init –auto command. Can not be combined with lxd.preseed. Each object in init list supports the following keys: - network_address: (string) IP address for LXD to listen on. 
- network_port: (integer) Network port to bind LXD to. 
- storage_backend: ( - zfs/- dir/- lvm/- btrfs) Storage backend to use. Default:- dir.
- storage_create_device: (string) Setup device based storage using DEVICE. 
- storage_create_loop: (integer) Setup loop based storage with SIZE in GB. 
- storage_pool: (string) Name of storage pool to use or create. 
- trust_password: (string) The password required to add new clients. 
 
- bridge: (object) LXD bridge configuration provided to setup the host lxd bridge. Can not be combined with lxd.preseed. Each object in bridge list supports the following keys: - mode: ( - none/- existing/- new) Whether to setup LXD bridge, use an existing bridge by name or create a new bridge. none will avoid bridge setup, existing will configure lxd to use the bring matching name and new will create a new bridge.
- name: (string) Name of the LXD network bridge to attach or create. Default: - lxdbr0.
- mtu: (integer) Bridge MTU, defaults to LXD’s default value. 
- ipv4_address: (string) IPv4 address for the bridge. If set, ipv4_netmask key required. 
- ipv4_netmask: (integer) Prefix length for the ipv4_address key. Required when ipv4_address is set. 
- ipv4_dhcp_first: (string) First IPv4 address of the DHCP range for the network created. This value will combined with ipv4_dhcp_last key to set LXC ipv4.dhcp.ranges. 
- ipv4_dhcp_last: (string) Last IPv4 address of the DHCP range for the network created. This value will combined with ipv4_dhcp_first key to set LXC ipv4.dhcp.ranges. 
- ipv4_dhcp_leases: (integer) Number of DHCP leases to allocate within the range. Automatically calculated based on ipv4_dhcp_first and ipv4_dhcp_last when unset. 
- ipv4_nat: (boolean) Set - trueto NAT the IPv4 traffic allowing for a routed IPv4 network. Default:- false.
- ipv6_address: (string) IPv6 address for the bridge (CIDR notation). When set, ipv6_netmask key is required. When absent, no IPv6 will be configured. 
- ipv6_netmask: (integer) Prefix length for ipv6_address provided. Required when ipv6_address is set. 
- ipv6_nat: (boolean) Whether to NAT. Default: - false.
- domain: (string) Domain to advertise to DHCP clients and use for DNS resolution. 
 
- preseed: (string) Opaque LXD preseed YAML config passed via stdin to the command: lxd init –preseed. See: https://documentation.ubuntu.com/lxd/en/latest/howto/initialize/#non-interactive-configuration or lxd init –dump for viable config. Can not be combined with either lxd.init or lxd.bridge. 
 
Example 1: Simplest working directory-backed LXD configuration.
#cloud-config
lxd:
  init:
    storage_backend: dir
Example 2: lxd-init showcasing cloud-init’s LXD config options.
#cloud-config
lxd:
  init:
    network_address: 0.0.0.0
    network_port: 8443
    storage_backend: zfs
    storage_pool: datapool
    storage_create_loop: 10
  bridge:
    mode: new
    mtu: 1500
    name: lxdbr0
    ipv4_address: 10.0.8.1
    ipv4_netmask: 24
    ipv4_dhcp_first: 10.0.8.2
    ipv4_dhcp_last: 10.0.8.3
    ipv4_dhcp_leases: 250
    ipv4_nat: true
    ipv6_address: fd98:9e0:3744::1
    ipv6_netmask: 64
    ipv6_nat: true
    domain: lxd
Example 3: For more complex non-interactive LXD configuration of networks, storage pools, profiles, projects, clusters and core config, lxd:preseed config will be passed as stdin to the command: lxd init --preseed.
See the LXD non-interactive configuration or run lxd init --dump to see viable preseed YAML allowed.
Preseed settings configuring the LXD daemon for HTTPS connections on 192.168.1.1 port 9999, a nested profile which allows for LXD nesting on containers and a limited project allowing for RBAC approach when defining behavior for sub-projects.
#cloud-config
lxd:
  preseed: |
    config:
      core.https_address: 192.168.1.1:9999
    networks:
      - config:
          ipv4.address: 10.42.42.1/24
          ipv4.nat: true
          ipv6.address: fd42:4242:4242:4242::1/64
          ipv6.nat: true
        description: ""
        name: lxdbr0
        type: bridge
        project: default
    storage_pools:
      - config:
          size: 5GiB
          source: /var/snap/lxd/common/lxd/disks/default.img
        description: ""
        name: default
        driver: zfs
    profiles:
      - config: {}
        description: Default LXD profile
        devices:
          eth0:
            name: eth0
            network: lxdbr0
            type: nic
          root:
            path: /
            pool: default
            type: disk
        name: default
      - config: {}
        security.nesting: true
        devices:
          eth0:
            name: eth0
            network: lxdbr0
            type: nic
          root:
            path: /
            pool: default
            type: disk
        name: nested
    projects:
      - config:
          features.images: true
          features.networks: true
          features.profiles: true
          features.storage.volumes: true
        description: Default LXD project
        name: default
      - config:
          features.images: false
          features.networks: true
          features.profiles: false
          features.storage.volumes: false
        description: Limited Access LXD project
        name: limited
MCollective¶
Install, configure and start MCollective
This module installs, configures and starts MCollective. If the
mcollective key is present in config, then MCollective will be
installed and started.
Configuration for mcollective can be specified in the conf key
under mcollective. Each config value consists of a key-value pair and
will be written to /etc/mcollective/server.cfg. The public-cert
and private-cert keys, if present in conf may be used to specify the
public and private certificates for MCollective. Their values will be
written to /etc/mcollective/ssl/server-public.pem and
/etc/mcollective/ssl/server-private.pem.
Warning
The EC2 metadata service is a network service and thus is readable by
non-root users on the system (i.e., ec2metadata --user-data). If
security is a concern, use include-once and SSL URLS.
Internal name: cc_mcollective
Module frequency: once-per-instance
Supported distros: all
Activate only on keys: mcollective
- mcollective: (object) Each object in mcollective list supports the following keys: - conf: (object) Each object in conf list supports the following keys: - ^.+$: (boolean/integer/string) Optional config key: value pairs which will be appended to - /etc/mcollective/server.cfg.
- public-cert: (string) Optional value of server public certificate which will be written to - /etc/mcollective/ssl/server-public.pem.
- private-cert: (string) Optional value of server private certificate which will be written to - /etc/mcollective/ssl/server-private.pem.
 
 
Example 1: Provide server private and public key, and provide the loglevel: debug and plugin.stomp.host: dbhost config settings in /etc/mcollective/server.cfg:
#cloud-config
mcollective:
  conf:
    loglevel: debug
    plugin.stomp.host: dbhost
    public-cert: |
      -------BEGIN CERTIFICATE--------
      <cert data>
      -------END CERTIFICATE--------
    private-cert: |
      -------BEGIN CERTIFICATE--------
      <cert data>
      -------END CERTIFICATE--------
Mounts¶
Configure mount points and swap files
This module can add or remove mount points from /etc/fstab as well as
configure swap. The mounts config key takes a list of fstab entries
to add. Each entry is specified as a list of [ fs_spec, fs_file,
fs_vfstype, fs_mntops, fs_freq, fs_passno ].
For more information on these options, consult the manual for
/etc/fstab. When specifying the fs_spec, if the device name starts
with one of xvd, sd, hd, or vd, the leading /dev may be
omitted. Any mounts that do not appear to either an attached block device
or network resource will be skipped with a log like “Ignoring nonexistent
mount …”.
Cloud-init will attempt to add the following mount directives if available
and unconfigured in /etc/fstab:
mounts:
- ["ephemeral0", "/mnt", "auto", "defaults,nofail,x-systemd.after=cloud-init-network.service", "0", "2"]
- ["swap", "none", "swap", "sw", "0", "0"]
In order to remove a previously-listed mount, an entry can be added to the
mounts list containing fs_spec for the device to be removed but no
mount point (i.e. [ swap ] or [ swap, null ]).
The mount_default_fields config key allows default values to be
specified for the fields in a mounts entry that are not specified,
aside from the fs_spec and the fs_file fields. If specified, this
must be a list containing 6 values. It defaults to:
mount_default_fields: [none, none, "auto", "defaults,nofail,x-systemd.after=cloud-init-network.service", "0", "2"]
Non-systemd init systems will vary in mount_default_fields.
Swap files can be configured by setting the path to the swap file to create
with filename, the size of the swap file with size, maximum size
of the swap file if using an size: auto with maxsize. By default,
no swap file is created.
Note
If multiple mounts are specified, where a subsequent mount’s mount point
is inside of a previously-declared mount’s mount point, (i.e. the 1st
mount has a mount point of /abc and the 2nd mount has a mount point
of /abc/def) then this will not work as expected – cc_mounts
first creates the directories for all the mount points before it
starts to perform any mounts and so the sub-mount point directory will
not be created correctly inside the parent mount point.
For systems using util-linux’s mount program, this issue can be
worked around by specifying X-mount.mkdir as part of a fs_mntops
value for the subsequent mount entry.
Internal name: cc_mounts
Module frequency: once-per-instance
Supported distros: all
- mounts: (array of array of string) List of lists. Each inner list entry is a list of - /etc/fstabmount declarations of the format: [ fs_spec, fs_file, fs_vfstype, fs_mntops, fs_freq, fs_passno ]. A mount declaration with less than 6 items will get remaining values from mount_default_fields. A mount declaration with only fs_spec and no fs_file mountpoint will be skipped.
- mount_default_fields: (array of string/null) Default mount configuration for any mount entry with less than 6 options provided. When specified, 6 items are required and represent - /etc/fstabentries. Default:- defaults,nofail,x-systemd.after=cloud-init-network.service,_netdev.
- swap: (object) Each object in swap list supports the following keys: - filename: (string) Path to the swap file to create. 
- size: ( - auto/integer/string) The size in bytes of the swap file, ‘auto’ or a human-readable size abbreviation of the format <float_size><units> where units are one of B, K, M, G or T. WARNING: Attempts to use IEC prefixes in your configuration prior to cloud-init version 23.1 will result in unexpected behavior. SI prefixes names (KB, MB) are required on pre-23.1 cloud-init, however IEC values are used. In summary, assume 1KB == 1024B, not 1000B.
- maxsize: (integer/string) The maxsize in bytes of the swap file. 
 
Example 1: Mount ephemeral0 with noexec flag, /dev/sdc with mount_default_fields, and /dev/xvdh with custom fs_passno "0" to avoid fsck on the mount.
Also provide an automatically-sized swap with a max size of 10485760 bytes.
#cloud-config
mounts:
- [ /dev/ephemeral0, /mnt, auto, "defaults,noexec" ]
- [ sdc, /opt/data ]
- [ xvdh, /opt/data, auto, "defaults,nofail", "0", "0" ]
mount_default_fields: [None, None, auto, "defaults,nofail", "0", "2"]
swap:
  filename: /my/swapfile
  size: auto
  maxsize: 10485760
Example 2: Create a 2 GB swap file at /swapfile using human-readable values.
#cloud-config
swap:
  filename: /swapfile
  size: 2G
  maxsize: 2G
NTP¶
Enable and configure NTP
Handle Network Time Protocol (NTP) configuration. If ntp is not
installed on the system and NTP configuration is specified, ntp will
be installed.
If there is a default NTP config file in the image or one is present in the
distro’s ntp package, it will be copied to a file with .dist
appended to the filename before any changes are made.
A list of NTP pools and NTP servers can be provided under the ntp
config key.
If no NTP servers or pools are provided, 4 pools will be used
in the format:
{0-3}.{distro}.pool.ntp.org
Internal name: cc_ntp
Module frequency: once-per-instance
Supported distros: almalinux, alpine, aosc, azurelinux, centos, cloudlinux, cos, debian, eurolinux, fedora, freebsd, mariner, miraclelinux, openbsd, openeuler, OpenCloudOS, openmandriva, opensuse, opensuse-microos, opensuse-tumbleweed, opensuse-leap, photon, raspberry-pi-os, rhel, rocky, sle_hpc, sle-micro, sles, TencentOS, ubuntu, virtuozzo
Activate only on keys: ntp
- ntp: (null/object) Each object in ntp list supports the following keys: - pools: (array of string) List of ntp pools. If both pools and servers are empty, 4 default pool servers will be provided of the format - {0-3}.{distro}.pool.ntp.org. NOTE: for Alpine Linux when using the Busybox NTP client this setting will be ignored due to the limited functionality of Busybox’s ntpd.
- servers: (array of string) List of ntp servers. If both pools and servers are empty, 4 default pool servers will be provided with the format - {0-3}.{distro}.pool.ntp.org.
- peers: (array of string) List of ntp peers. 
- allow: (array of string) List of CIDRs to allow. 
- ntp_client: (string) Name of an NTP client to use to configure system NTP. When unprovided or ‘auto’ the default client preferred by the distribution will be used. The following built-in client names can be used to override existing configuration defaults: chrony, ntp, openntpd, ntpdate, systemd-timesyncd. 
- enabled: (boolean) Attempt to enable ntp clients if set to True. If set to - false, ntp client will not be configured or installed.
- config: (object) Configuration settings or overrides for the ntp_client specified. Each object in config list supports the following keys: - confpath: (string) The path to where the ntp_client configuration is written. 
- check_exe: (string) The executable name for the ntp_client. For example, ntp service check_exe is ‘ntpd’ because it runs the ntpd binary. 
- packages: (array of string) List of packages needed to be installed for the selected ntp_client. 
- service_name: (string) The systemd or sysvinit service name used to start and stop the ntp_client service. 
- template: (string) Inline template allowing users to customize their ntp_client configuration with the use of the Jinja templating engine. The template content should start with - ## template:jinja. Within the template, you can utilize any of the following ntp module config keys: servers, pools, allow, and peers. Each cc_ntp schema config key and expected value type is defined above.
 
 
Example 1: Override NTP with chrony configuration on Ubuntu.
#cloud-config
ntp:
  enabled: true
  ntp_client: chrony  # Uses cloud-init default chrony configuration
Example 2: Provide a custom NTP client configuration.
#cloud-config
ntp:
  enabled: true
  ntp_client: myntpclient
  config:
    confpath: /etc/myntpclient/myntpclient.conf
    check_exe: myntpclientd
    packages:
    - myntpclient
    service_name: myntpclient
    template: |
      ## template:jinja
      # My NTP Client config
      {% if pools -%}# pools{% endif %}
      {% for pool in pools -%}
      pool {{pool}} iburst
      {% endfor %}
      {%- if servers %}# servers
      {% endif %}
      {% for server in servers -%}
      server {{server}} iburst
      {% endfor %}
      {% if peers -%}# peers{% endif %}
      {% for peer in peers -%}
      peer {{peer}}
      {% endfor %}
      {% if allow -%}# allow{% endif %}
      {% for cidr in allow -%}
      allow {{cidr}}
      {% endfor %}
  pools: [0.int.pool.ntp.org, 1.int.pool.ntp.org, ntp.myorg.org]
  servers:
  - ntp.server.local
  - ntp.ubuntu.com
  - 192.168.23.2
  allow:
  - 192.168.23.0/32
  peers:
  - km001
  - km002
Package Update Upgrade Install¶
Update, upgrade, and install packages
This module allows packages to be updated, upgraded or installed during
boot using any available package manager present on a system such as apt,
pkg, snap, yum or zypper. If any packages are to be installed or an upgrade
is to be performed then the package cache will be updated first. If a
package installation or upgrade requires a reboot, then a reboot can be
performed if package_reboot_if_required is specified.
Internal name: cc_package_update_upgrade_install
Module frequency: once-per-instance
Supported distros: all
Activate only on keys: apt_update, package_update, apt_upgrade, package_upgrade, packages
- packages: (array of object/array of string/string) An array containing either a package specification, or an object consisting of a package manager key having a package specification value . A package specification can be either a package name or a list with two entries, the first being the package name and the second being the specific package version to install. Each object in packages list supports the following keys: - apt: (array of array of string/string) 
- snap: (array of array of string/string) 
- apt: (array of array of string/string) 
- snap: (array of array of string/string) 
 
- package_update: (boolean) Set - trueto update packages. Happens before upgrade or install. Default:- false.
- package_upgrade: (boolean) Set - trueto upgrade packages. Happens before install. Default:- false.
- package_reboot_if_required: (boolean) Set - trueto reboot the system if required by presence of /var/run/reboot-required. Default:- false.
- apt_update: (boolean) - Deprecated in version 22.2: Use package_update instead. 
- apt_upgrade: (boolean) - Deprecated in version 22.2: Use package_upgrade instead. 
- apt_reboot_if_required: (boolean) - Deprecated in version 22.2: Use package_reboot_if_required instead. 
Example 1:
#cloud-config
package_reboot_if_required: true
package_update: true
package_upgrade: true
packages:
- pwgen
- pastebinit
- [libpython3.8, 3.8.10-0ubuntu1~20.04.2]
- snap:
  - certbot
  - [juju, --edge]
  - [lxd, --channel=5.15/stable]
- apt: [mg]
By default, package_upgrade: true performs upgrades on any installed package manager. To avoid calling snap refresh in images with snap installed, set snap refresh.hold to forever will prevent cloud-init’s snap interaction during any boot
#cloud-config
package_update: true
package_upgrade: true
snap:
  commands:
    00: snap refresh --hold=forever
package_reboot_if_required: true
Phone Home¶
Post data to URL
This module can be used to post data to a remote host after boot is complete.
Either all data can be posted, or a list of keys to post.
Available keys are:
- pub_key_rsa
- pub_key_ecdsa
- pub_key_ed25519
- instance_id
- hostname
- fqdn
Data is sent as x-www-form-urlencoded arguments.
Example HTTP POST:
POST / HTTP/1.1
Content-Length: 1337
User-Agent: Cloud-Init/21.4
Accept-Encoding: gzip, deflate
Accept: */*
Content-Type: application/x-www-form-urlencoded
pub_key_rsa=rsa_contents&pub_key_ecdsa=ecdsa_contents&pub_key_ed25519=ed25519_contents&instance_id=i-87018aed&hostname=myhost&fqdn=myhost.internal
Warning
Use of INSTANCE_ID variable within this module is deprecated.
Use jinja templates with
v1.instance_id instead.
Internal name: cc_phone_home
Module frequency: once-per-instance
Supported distros: all
Activate only on keys: phone_home
- phone_home: (object) Each object in phone_home list supports the following keys: - url: (string) The URL to send the phone home data to. 
- post: ( - all/array of- pub_key_rsa/- pub_key_ecdsa/- pub_key_ed25519/- instance_id/- hostname/- fqdn) A list of keys to post or- all. Default:- all.
- tries: (integer) The number of times to try sending the phone home data. Default: - 10.
 
Example 1:
## template: jinja
#cloud-config
phone_home: {post: all, url: 'http://example.com/{{ v1.instance_id }}/'}
Example 2:
## template: jinja
#cloud-config
phone_home:
  post: [pub_key_rsa, pub_key_ecdsa, pub_key_ed25519, instance_id, hostname, fqdn]
  tries: 5
  url: http://example.com/{{ v1.instance_id }}/
Power State Change¶
Change power state
This module handles shutdown/reboot after all config modules have been
run. By default it will take no action, and the system will keep running
unless a package installation/upgrade requires a system reboot (e.g.
installing a new kernel) and package_reboot_if_required is true.
Using this module ensures that cloud-init is entirely finished with modules that would be executed. An example to distinguish delay from timeout:
If you delay 5 (5 minutes) and have a timeout of 120 (2 minutes), the max time until shutdown will be 7 minutes, though it could be as soon as 5 minutes. Cloud-init will invoke ‘shutdown +5’ after the process finishes, or when ‘timeout’ seconds have elapsed.
Note
With Alpine Linux any message value specified is ignored as Alpine’s
halt, poweroff, and reboot commands do not support
broadcasting a message.
Internal name: cc_power_state_change
Module frequency: once-per-instance
Supported distros: all
Activate only on keys: power_state
- power_state: (object) Each object in power_state list supports the following keys: - delay: (integer/string/ - now) Time in minutes to delay after cloud-init has finished. Can be- nowor an integer specifying the number of minutes to delay. Default:- now.- Changed in version 22.3.Use of type string for this value is deprecated. Use ``now`` or integer type. 
- mode: ( - poweroff/- reboot/- halt) Must be one of- poweroff,- halt, or- reboot.
- message: (string) Optional message to display to the user when the system is powering off or rebooting. 
- timeout: (integer) Time in seconds to wait for the cloud-init process to finish before executing shutdown. Default: - 30.
- condition: (string/boolean/array) Apply state change only if condition is met. May be boolean true (always met), false (never met), or a command string or list to be executed. For command formatting, see the documentation for - cc_runcmd. If exit code is 0, condition is met, otherwise not. Default:- true.
 
Example 1:
#cloud-config
power_state:
  delay: now
  mode: poweroff
  message: Powering off
  timeout: 2
  condition: true
Example 2:
#cloud-config
power_state:
  delay: 30
  mode: reboot
  message: Rebooting machine
  condition: test -f /var/tmp/reboot_me
Puppet¶
Install, configure and start Puppet
This module handles Puppet installation and configuration. If the
puppet key does not exist in global configuration, no action will be
taken.
If a config entry for puppet is present, then by default the latest
version of Puppet will be installed. If the puppet config key exists in
the config archive, this module will attempt to start puppet even if no
installation was performed.
The module also provides keys for configuring the new Puppet 4 paths and
installing the puppet package from the
puppetlabs repositories.
The keys are package_name, conf_file, ssl_dir and
csr_attributes_path. If unset, their values will default to ones that
work with Puppet 3.X, and with distributions that ship modified Puppet 4.X,
that use the old paths.
Internal name: cc_puppet
Module frequency: once-per-instance
Supported distros: all
Activate only on keys: puppet
- puppet: (object) Each object in puppet list supports the following keys: - install: (boolean) Whether or not to install puppet. Setting to - falsewill result in an error if puppet is not already present on the system. Default:- true.
- version: (string) Optional version to pass to the installer script or package manager. If unset, the latest version from the repos will be installed. 
- install_type: ( - packages/- aio) Valid values are- packagesand- aio. Agent packages from the puppetlabs repositories can be installed by setting- aio. Based on this setting, the default config/SSL/CSR paths will be adjusted accordingly. Default:- packages.
- collection: (string) Puppet collection to install if install_type is - aio. This can be set to one of- puppet(rolling release),- puppet6,- puppet7(or their nightly counterparts) in order to install specific release streams.
- aio_install_url: (string) If install_type is - aio, change the url of the install script.
- cleanup: (boolean) Whether to remove the puppetlabs repo after installation if install_type is - aioDefault:- true.
- conf_file: (string) The path to the puppet config file. Default depends on install_type. 
- ssl_dir: (string) The path to the puppet SSL directory. Default depends on install_type. 
- csr_attributes_path: (string) The path to the puppet csr attributes file. Default depends on install_type. 
- package_name: (string) Name of the package to install if install_type is - packages. Default:- puppet.
- exec: (boolean) Whether or not to run puppet after configuration finishes. A single manual run can be triggered by setting exec to - true, and additional arguments can be passed to- puppet agentvia the exec_args key (by default the agent will execute with the- --testflag). Default:- false.
- exec_args: (array of string) A list of arguments to pass to ‘puppet agent’ if ‘exec’ is true Default: - ['--test'].
- start_service: (boolean) By default, the puppet service will be automatically enabled after installation and set to automatically start on boot. To override this in favor of manual puppet execution set start_service to - false.
- conf: (object) Every key present in the conf object will be added to puppet.conf. As such, section names should be one of: - main,- server,- agentor- userand keys should be valid puppet configuration options. The configuration is specified as a dictionary containing high-level- <section>keys and lists of- <key>=<value>pairs within each section. The- certnamekey supports string substitutions for- %iand- %f, corresponding to the instance id and fqdn of the machine respectively.- ca_certis a special case. It won’t be added to puppet.conf. It holds the puppetserver certificate in pem format. It should be a multi-line string (using the | YAML notation for multi-line strings). Each object in conf list supports the following keys:- main: (object) 
- server: (object) 
- agent: (object) 
- user: (object) 
- ca_cert: (string) 
 
- csr_attributes: (object) create a - csr_attributes.yamlfile for CSR attributes and certificate extension requests. See https://puppet.com/docs/puppet/latest/config_file_csr_attributes.html. Each object in csr_attributes list supports the following keys:- custom_attributes: (object) 
- extension_requests: (object) 
 
 
Example 1:
#cloud-config
puppet:
  install: true
  version: "7.7.0"
  install_type: "aio"
  collection: "puppet7"
  aio_install_url: 'https://git.io/JBhoQ'
  cleanup: true
  conf_file: "/etc/puppet/puppet.conf"
  ssl_dir: "/var/lib/puppet/ssl"
  csr_attributes_path: "/etc/puppet/csr_attributes.yaml"
  exec: true
  exec_args: ['--test']
  conf:
    agent:
      server: "puppetserver.example.org"
      certname: "%i.%f"
    ca_cert: |
      -----BEGIN CERTIFICATE-----
      MIICCTCCAXKgAwIBAgIBATANBgkqhkiG9w0BAQUFADANMQswCQYDVQQDDAJjYTAe
      Fw0xMDAyMTUxNzI5MjFaFw0xNTAyMTQxNzI5MjFaMA0xCzAJBgNVBAMMAmNhMIGf
      MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCu7Q40sm47/E1Pf+r8AYb/V/FWGPgc
      b014OmNoX7dgCxTDvps/h8Vw555PdAFsW5+QhsGr31IJNI3kSYprFQcYf7A8tNWu
      1MASW2CfaEiOEi9F1R3R4Qlz4ix+iNoHiUDTjazw/tZwEdxaQXQVLwgTGRwVa+aA
      qbutJKi93MILLwIDAQABo3kwdzA4BglghkgBhvhCAQ0EKxYpUHVwcGV0IFJ1Ynkv
      T3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwDwYDVR0TAQH/BAUwAwEB/zAd
      BgNVHQ4EFgQUu4+jHB+GYE5Vxo+ol1OAhevspjAwCwYDVR0PBAQDAgEGMA0GCSqG
      SIb3DQEBBQUAA4GBAH/rxlUIjwNb3n7TXJcDJ6MMHUlwjr03BDJXKb34Ulndkpaf
      +GAlzPXWa7bO908M9I8RnPfvtKnteLbvgTK+h+zX1XCty+S2EQWk29i2AdoqOTxb
      hppiGMp0tT5Havu4aceCXiy2crVcudj3NFciy8X66SoECemW9UYDCb9T5D0d
      -----END CERTIFICATE-----
  csr_attributes:
    custom_attributes:
      1.2.840.113549.1.9.7: 342thbjkt82094y0uthhor289jnqthpc2290
    extension_requests:
      pp_uuid: ED803750-E3C7-44F5-BB08-41A04433FE2E
      pp_image_name: my_ami_image
      pp_preshared_key: 342thbjkt82094y0uthhor289jnqthpc2290
Example 2:
#cloud-config
puppet:
  install_type: "packages"
  package_name: "puppet"
  exec: false
Raspberry Pi Configuration¶
Configure Raspberry Pi ARM interfaces and enable Raspberry Pi USB Gadget mode
This module handles ARM interface configuration for Raspberry Pi.
It also handles Raspberry Pi USB Gadget setup. The USB Gadget mode will be enabled to auto start on boot. Make sure you read the documentation on it carefully before enabling it.
This only works on Raspberry Pi OS (trixie and later).
Internal name: cc_raspberry_pi
Module frequency: once-per-instance
Supported distros: raspberry-pi-os
Activate only on keys: rpi
- rpi: (object) Each object in rpi list supports the following keys: - interfaces: (object) Each object in interfaces list supports the following keys: - spi: (boolean) Enable SPI interface. Default: - false.
- i2c: (boolean) Enable I2C interface. Default: - false.
- serial: (boolean/object) Enable serial console. Default: - false. Each object in serial list supports the following keys:- console: (boolean) Enable login shell to be accessible over serial. Default: - false.
- hardware: (boolean) Enable serial port hardware. Default: - false.
 
- onewire: (boolean) Enable 1-Wire interface. Default: - false.
 
- enable_usb_gadget: (boolean) Enable Raspberry Pi USB Gadget mode. Default: - false.
 
This example will enable the SPI and I2C interfaces on Raspberry Pi.
#cloud-config
rpi:
  interfaces:
    spi: true
    i2c: true
This example will enable the serial console (login shell) on Raspberry Pi. On models prior to Pi 5, enabling the console also enables the UART hardware.
#cloud-config
rpi:
  interfaces:
    serial: true
This example will enable the serial console on Raspberry Pi 5 while disabling the UART hardware (only Pi 5 allows this combination).
#cloud-config
rpi:
  interfaces:
    serial:
      # Pi 5 only | disabling hardware while enabling console
      console: true
      hardware: false
This example will enable the UART hardware without binding it to the serial console, allowing applications to use the port directly.
#cloud-config
rpi:
  interfaces:
    # works on all Pi models
    # only enables the UART hardware without binding it to the console
    serial:
      console: false
      hardware: true
This example will enable the Raspberry Pi USB Gadget mode.
#cloud-config
rpi:
  enable_usb_gadget: true
Resizefs¶
Resize filesystem
Resize a filesystem to use all available space on partition. This module is
useful along with cc_growpart and will ensure that if the root
partition has been resized, the root filesystem will be resized along with
it.
By default, cc_resizefs will resize the root partition and will block
the boot process while the resize command is running.
Optionally, the resize operation can be performed in the background
while cloud-init continues running modules. This can be enabled by setting
resize_rootfs to noblock.
This module can be disabled altogether by setting resize_rootfs to
false.
Internal name: cc_resizefs
Module frequency: always
Supported distros: all
- resize_rootfs: ( - True/- False/- noblock) Whether to resize the root partition.- noblockwill resize in the background. Default:- true.
Example 1: Disable root filesystem resize operation.
#cloud-config
resize_rootfs: false
Example 2: Runs resize operation in the background.
#cloud-config
resize_rootfs: noblock
Resolv Conf¶
Configure resolv.conf
You should not use this module unless manually editing
/etc/resolv.conf is the correct way to manage nameserver
information on your operating system.
Many distros have moved away from manually editing resolv.conf so
please verify that this is the preferred nameserver management method for
your distro before using this module. Note that using Network configuration
is preferred, rather than using this module, when possible.
This module is intended to manage resolv.conf in environments where
early configuration of resolv.conf is necessary for further
bootstrapping and/or where configuration management such as Puppet or Chef
own DNS configuration.
When using a Config drive and a RHEL-like system,
resolv.conf will also be managed automatically due to the available
information provided for DNS servers in the Networking config Version 2
format. For those who wish to have different settings, use this module.
For the resolv_conf section to be applied, manage_resolv_conf must
be set true.
Note
For Red Hat with sysconfig, be sure to set PEERDNS=no for all
DHCP-enabled NICs.
Internal name: cc_resolv_conf
Module frequency: once-per-instance
Supported distros: alpine, azurelinux, fedora, mariner, opensuse, opensuse-leap, opensuse-microos, opensuse-tumbleweed, photon, rhel, sle_hpc, sle-micro, sles, openeuler
Activate only on keys: manage_resolv_conf
- manage_resolv_conf: (boolean) Whether to manage the resolv.conf file. resolv_conf block will be ignored unless this is set to - true. Default:- false.
- resolv_conf: (object) Each object in resolv_conf list supports the following keys: - nameservers: (array) A list of nameservers to use to be added as - nameserverlines.
- searchdomains: (array) A list of domains to be added - searchline.
- domain: (string) The domain to be added as - domainline.
- sortlist: (array) A list of IP addresses to be added to - sortlistline.
- options: (object) Key/value pairs of options to go under - optionsheading. A unary option should be specified as- true.
 
Example 1:
#cloud-config
manage_resolv_conf: true
resolv_conf:
  domain: example.com
  nameservers: [8.8.8.8, 8.8.4.4]
  options: {rotate: true, timeout: 1}
  searchdomains: [foo.example.com, bar.example.com]
  sortlist: [10.0.0.1/255, 10.0.0.2]
Red Hat Subscription¶
Register Red Hat Enterprise Linux-based system
Register a Red Hat system, either by username and password or by activation and org.
Following a successful registration, you can:
- auto_attach subscriptions 
- set the service level 
- add subscriptions based on pool ID 
- enable/disable yum repositories based on repo ID 
- alter the - rhsm_baseurland- server_hostnamein- /etc/rhsm/rhs.conf.
Internal name: cc_rh_subscription
Module frequency: once-per-instance
Supported distros: fedora, rhel
Activate only on keys: rh_subscription
- rh_subscription: (object) Each object in rh_subscription list supports the following keys: - username: (string) The username to use. Must be used with password. Should not be used with activation_key or org. 
- password: (string) The password to use. Must be used with username. Should not be used with activation_key or org. 
- activation_key: (string) The activation key to use. Must be used with org. Should not be used with username or password. 
- activation-key: (string) The activation key to use. Must be used with org. Should not be used with username or password. - Deprecated in version 25.3: Use activation_key instead. 
- org: (string/integer) The organization to use. Must be used with activation_key. Should not be used with username or password. - Deprecated in version 24.2: Use of type integer for this value is deprecated. Use a string instead. 
- auto_attach: (boolean) Whether to attach subscriptions automatically. 
- auto-attach: (boolean) Whether to attach subscriptions automatically. - Deprecated in version 25.3: Use auto_attach instead. 
- service_level: (string) The service level to use when subscribing to RH repositories. - auto_attachmust be true for this to be used.
- service-level: (string) The service level to use when subscribing to RH repositories. - auto_attachmust be true for this to be used.- Deprecated in version 25.3: Use service_level instead. 
- add_pool: (array of string) A list of pool IDs add to the subscription. 
- add-pool: (array of string) A list of pool IDs add to the subscription. - Deprecated in version 25.3: Use add_pool instead. 
- enable_repo: (array of string) A list of repositories to enable. 
- enable-repo: (array of string) A list of repositories to enable. - Deprecated in version 25.3: Use enable_repo instead. 
- disable_repo: (array of string) A list of repositories to disable. 
- disable-repo: (array of string) A list of repositories to disable. - Deprecated in version 25.3: Use disable_repo instead. 
- release_version: (string) Sets the release_version via``subscription-manager release –set=<release_version>`` then deletes the package manager cache - /var/cache/{dnf,yum}. These steps are applied after any pool attachment and/or enabling/disabling repos. For more information about this key, check https://access.redhat.com/solutions/238533 .
- rhsm_baseurl: (string) Sets the baseurl in - /etc/rhsm/rhsm.conf.
- rhsm-baseurl: (string) Sets the baseurl in - /etc/rhsm/rhsm.conf.- Deprecated in version 25.3: Use rhsm_baseurl instead. 
- server_hostname: (string) Sets the serverurl in - /etc/rhsm/rhsm.conf.
- server-hostname: (string) Sets the serverurl in - /etc/rhsm/rhsm.conf.- Deprecated in version 25.3: Use server_hostname instead. 
 
Example 1:
#cloud-config
rh_subscription:
  username: [email protected]
  ## Quote your password if it has symbols to be safe
  password: '1234abcd'
Example 2:
#cloud-config
rh_subscription:
  activation_key: foobar
  org: "ABC"
Example 3:
#cloud-config
rh_subscription:
  activation_key: foobar
  org: 12345
  auto_attach: true
  service_level: self-support
  add_pool:
    - 1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a
    - 2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
  enable_repo:
    - repo-id-to-enable
    - other-repo-id-to-enable
  disable_repo:
    - repo-id-to-disable
    - other-repo-id-to-disable
  # Alter the baseurl in /etc/rhsm/rhsm.conf
  rhsm_baseurl: http://url
  # Alter the server hostname in /etc/rhsm/rhsm.conf
  server_hostname: foo.bar.com
  # Set `subscription-manager release --set=6Server` then
  # delete /var/cache/{dnf,yum}
  release_version: 6Server
Rsyslog¶
Configure system logging via rsyslog
This module configures remote system logging using rsyslog.
Configuration for remote servers can be specified in configs, but for
convenience it can be specified as key-value pairs in remotes.
This module can install rsyslog if not already present on the system using
the install_rsyslog, packages, and check_exe options.
Installation may not work on systems where this module runs before
networking is up.
Note
On BSD, cloud-init will attempt to disable and stop the base system
syslogd. This may fail on a first run. We recommend creating images
with service syslogd disable.
Internal name: cc_rsyslog
Module frequency: once-per-instance
Supported distros: all
Activate only on keys: rsyslog
- rsyslog: (object) Each object in rsyslog list supports the following keys: - config_dir: (string) The directory where rsyslog configuration files will be written. Default: - /etc/rsyslog.d.
- config_filename: (string) The name of the rsyslog configuration file. Default: - 20-cloud-config.conf.
- configs: (array of string/object) Each entry in configs is either a string or an object. Each config entry contains a configuration string and a file to write it to. For config entries that are an object, filename sets the target filename and content specifies the config string to write. For config entries that are only a string, the string is used as the config string to write. If the filename to write the config to is not specified, the value of the config_filename key is used. A file with the selected filename will be written inside the directory specified by config_dir. Each object in configs list supports the following keys: - filename: (string) 
- content: (string) 
- filename: (string) 
- content: (string) 
 
- remotes: (object) Each key is the name for an rsyslog remote entry. Each value holds the contents of the remote config for rsyslog. The config consists of the following parts: - filter for log messages (defaults to - *.*)
- optional leading - @or- @@, indicating udp and tcp respectively (defaults to- @, for udp)
- ipv4 or ipv6 hostname or address. ipv6 addresses must be in - [::1]format, (e.g.- @[fd00::1]:514)
- optional port number (defaults to - 514)
 - This module will provide sane defaults for any part of the remote entry that is not specified, so in most cases remote hosts can be specified just using - <name>: <address>.
- service_reload_command: ( - auto/array of string) The command to use to reload the rsyslog service after the config has been updated. If this is set to- auto, then an appropriate command for the distro will be used. This is the default behavior. To manually set the command, use a list of command args (e.g.- [systemctl, restart, rsyslog]).
- install_rsyslog: (boolean) Install rsyslog. Default: - false.
- check_exe: (string) The executable name for the rsyslog daemon. - For example, - rsyslogd, or- /opt/sbin/rsyslogdif the rsyslog binary is in an unusual path. This is only used if- install_rsyslogis- true. Default:- rsyslogd.
- packages: (array of string) List of packages needed to be installed for rsyslog. This is only used if install_rsyslog is - true. Default:- [rsyslog].
 
Example 1:
#cloud-config
rsyslog:
  remotes: {juju: 10.0.4.1, maas: 192.168.1.1}
  service_reload_command: auto
Example 2:
#cloud-config
rsyslog:
  config_dir: /opt/etc/rsyslog.d
  config_filename: 99-late-cloud-config.conf
  configs:
  - '*.* @@192.158.1.1'
  - {content: '*.*   @@192.0.2.1:10514', filename: 01-example.conf}
  - {content: '*.*   @@syslogd.example.com
      '}
  remotes: {juju: 10.0.4.1, maas: 192.168.1.1}
  service_reload_command: [your, syslog, restart, command]
Example 3: Default (no) configuration with package installation on FreeBSD.
#cloud-config
rsyslog:
  check_exe: rsyslogd
  config_dir: /usr/local/etc/rsyslog.d
  install_rsyslog: true
  packages: [rsyslogd]
Runcmd¶
Run arbitrary commands
Run arbitrary commands at a rc.local-like time-frame with output to the
console. Each item can be either a list or a string. The item type affects
how it is executed:
- If the item is a string, it will be interpreted by - sh.
- If the item is a list, the items will be executed as if passed to - execve(3)(with the first argument as the command).
The runcmd module only writes the script to be run later. The module
that actually runs the script is scripts_user in the
Final boot stage.
Note
All commands must be proper YAML, so you must quote any characters YAML would eat (“:” can be problematic).
Note
When writing files, do not use /tmp dir as it races with
systemd-tmpfiles-clean (LP: #1707222). Use /run/somedir instead.
Internal name: cc_runcmd
Module frequency: once-per-instance
Supported distros: all
Activate only on keys: runcmd
- runcmd: (array of array of string/string/null) 
Example 1:
#cloud-config
runcmd:
- [ls, -l, /]
- [sh, -xc, 'echo $(date) '': hello world!''']
- [sh, -c, echo "=========hello world'========="]
- ls -l /root
Salt Minion¶
Set up and run Salt Minion
This module installs, configures and starts Salt Minion. If the
salt_minion key is present in the config parts, then Salt Minion will
be installed and started.
Configuration for Salt Minion can be specified in the conf key under
salt_minion. Any config values present there will be assigned in
/etc/salt/minion. The public and private keys to use for Salt Minion
can be specified with public_key and private_key respectively.
If you have a custom package name, service name, or config directory, you
can specify them with pkg_name, service_name, and config_dir
respectively.
Salt keys can be manually generated by salt-key --gen-keys=GEN_KEYS,
where GEN_KEYS is the name of the keypair, e.g. ‘’minion’’. The keypair
will be copied to /etc/salt/pki on the Minion instance.
Internal name: cc_salt_minion
Module frequency: once-per-instance
Supported distros: all
Activate only on keys: salt_minion
- salt_minion: (object) Each object in salt_minion list supports the following keys: - pkg_name: (string) Package name to install. Default: - salt-minion.
- service_name: (string) Service name to enable. Default: - salt-minion.
- config_dir: (string) Directory to write config files to. Default: - /etc/salt.
- conf: (object) Configuration to be written to config_dir/minion. 
- grains: (object) Configuration to be written to config_dir/grains. 
- public_key: (string) Public key to be used by the salt minion. 
- private_key: (string) Private key to be used by salt minion. 
- pki_dir: (string) Directory to write key files. Default: config_dir/pki/minion. 
 
Example 1:
#cloud-config
salt_minion:
  conf:
    file_client: local
    fileserver_backend: [gitfs]
    gitfs_remotes: ['https://github.com/_user_/_repo_.git']
    master: salt.example.com
  config_dir: /etc/salt
  grains:
    role: [web]
  pkg_name: salt-minion
  pki_dir: /etc/salt/pki/minion
  private_key: '------BEGIN PRIVATE KEY------
    <key data>
    ------END PRIVATE KEY-------
    '
  public_key: '------BEGIN PUBLIC KEY-------
    <key data>
    ------END PUBLIC KEY-------
    '
  service_name: salt-minion
Scripts Per Boot¶
Run per-boot scripts
Any scripts in the scripts/per-boot directory on the datasource will
be run every time the system boots. Scripts will be run in alphabetical
order. This module does not accept any config keys.
Internal name: cc_scripts_per_boot
Module frequency: always
Supported distros: all
No schema definitions for this module
No examples for this module
Scripts Per Instance¶
Run per-instance scripts
Any scripts in the scripts/per-instance directory on the datasource
will be run when a new instance is first booted. Scripts will be run in
alphabetical order. This module does not accept any config keys.
Some cloud platforms change instance-id if a significant change was
made to the system. As a result, per-instance scripts will run again.
Internal name: cc_scripts_per_instance
Module frequency: once-per-instance
Supported distros: all
No schema definitions for this module
No examples for this module
Scripts Per Once¶
Run one-time scripts
Any scripts in the scripts/per-once directory on the datasource will
be run only once. Changes to the instance will not force a re-run. The
only way to re-run these scripts is to run the clean subcommand and
reboot. Scripts will be run in alphabetical order. This module does not
accept any config keys.
Internal name: cc_scripts_per_once
Module frequency: once
Supported distros: all
No schema definitions for this module
No examples for this module
Scripts User¶
Run user scripts
This module runs all user scripts present in the scripts directory in
the instance configuration. Any cloud-config parts with a #! will be
treated as a script and run. Scripts specified as cloud-config parts will
be run in the order they are specified in the configuration. This module
does not accept any config keys.
Internal name: cc_scripts_user
Module frequency: once-per-instance
Supported distros: all
No schema definitions for this module
No examples for this module
Scripts Vendor¶
Run vendor scripts
On select Datasources, vendors have a channel for the consumption of all
supported user data types via a special channel called vendor data. Any
scripts in the scripts/vendor directory in the datasource will be run
when a new instance is first booted. Scripts will be run in alphabetical
order. This module allows control over the execution of vendor data.
Internal name: cc_scripts_vendor
Module frequency: once-per-instance
Supported distros: all
- vendor_data: (object) Each object in vendor_data list supports the following keys: - enabled: (boolean/string) Whether vendor-data is enabled or not. Default: - true.- Deprecated in version 22.3: Use of type string for this value is deprecated. Use a boolean instead. 
- prefix: ([‘array’, ‘string’] of string/integer) The command to run before any vendor scripts. Its primary use case is for profiling a script, not to prevent its run. 
 
Example 1:
#cloud-config
vendor_data: {enabled: true, prefix: /usr/bin/ltrace}
Example 2:
#cloud-config
vendor_data:
  enabled: true
  prefix: [timeout, 30]
Example 3: Vendor data will not be processed.
#cloud-config
vendor_data: {enabled: false}
Seed Random¶
Provide random seed data
All cloud instances started from the same image will produce similar data when they are first booted as they are all starting with the same seed for the kernel’s entropy keyring. To avoid this, random seed data can be provided to the instance, either as a string or by specifying a command to run to generate the data.
Configuration for this module is under the random_seed config key. If
the cloud provides its own random seed data, it will be appended to
data before it is written to file.
If the command key is specified, the given command will be executed.
This will happen after file has been populated. That command’s
environment will contain the value of the file key as
RANDOM_SEED_FILE. If a command is specified that cannot be run, no
error will be reported unless command_required is set to true.
Internal name: cc_seed_random
Module frequency: once-per-instance
Supported distros: all
- random_seed: (object) Each object in random_seed list supports the following keys: - file: (string) File to write random data to. Default: - /dev/urandom.
- data: (string) This data will be written to file before data from the datasource. When using a multi-line value or specifying binary data, be sure to follow YAML syntax and use the - |and- !binaryYAML format specifiers when appropriate.
- encoding: ( - raw/- base64/- b64/- gzip/- gz) Used to decode data provided. Allowed values are- raw,- base64,- b64,- gzip, or- gz. Default:- raw.
- command: (array of string) Execute this command to seed random. The command will have RANDOM_SEED_FILE in its environment set to the value of file above. 
- command_required: (boolean) If true, and command is not available to be run then an exception is raised and cloud-init will record failure. Otherwise, only debug error is mentioned. Default: - false.
 
Example 1:
#cloud-config
random_seed:
  command: [sh, -c, dd if=/dev/urandom of=$RANDOM_SEED_FILE]
  command_required: true
  data: my random string
  encoding: raw
  file: /dev/urandom
Example 2: Use pollinate to gather data from a remote entropy server and write it to /dev/urandom:
#cloud-config
random_seed:
  command: [pollinate, '--server=http://local.pollinate.server']
  command_required: true
  file: /dev/urandom
Set Hostname¶
Set hostname and FQDN
This module handles setting the system hostname and fully qualified domain
name (FQDN). If preserve_hostname is set, then the hostname will not be
altered.
A hostname and FQDN can be provided by specifying a full domain name under
the fqdn key. Alternatively, a hostname can be specified using the
hostname key, and the FQDN of the cloud will be used. If a FQDN is
specified with the hostname key, it will be handled properly, although
it is better to use the fqdn config key. If both fqdn and
hostname are set, then prefer_fqdn_over_hostname will force use of
FQDN in all distros when true, and when false it will force the short
hostname. Otherwise, the hostname to use is distro-dependent.
Note
Cloud-init performs no hostname input validation before sending the hostname to distro-specific tools, and most tools will not accept a trailing dot on the FQDN.
This module will run in the init-local stage before networking is configured if the hostname is set by metadata or user data on the local system.
This will occur on datasources like NoCloud and OVF where metadata and user data are available locally. This ensures that the desired hostname is applied before any DHCP requests are performed on these platforms where dynamic DNS is based on initial hostname.
Internal name: cc_set_hostname
Module frequency: once-per-instance
Supported distros: all
- preserve_hostname: (boolean) If true, the hostname will not be changed. Default: - false.
- hostname: (string) The hostname to set. 
- fqdn: (string) The fully qualified domain name to set. 
- prefer_fqdn_over_hostname: (boolean) If true, the fqdn will be used if it is set. If false, the hostname will be used. If unset, the result is distro-dependent. 
- create_hostname_file: (boolean) If - false, the hostname file (e.g. /etc/hostname) will not be created if it does not exist. On systems that use systemd, setting create_hostname_file to- falsewill set the hostname transiently. If- true, the hostname file will always be created and the hostname will be set statically on systemd systems. Default:- true.
Example 1:
#cloud-config
preserve_hostname: true
Example 2:
#cloud-config
hostname: myhost
create_hostname_file: true
fqdn: myhost.example.com
prefer_fqdn_over_hostname: true
Example 3: On a machine without an /etc/hostname file, don’t create it. In most clouds, this will result in a DHCP-configured hostname provided by the cloud.
#cloud-config
create_hostname_file: false
Set Passwords¶
Set user passwords and enable/disable SSH password auth
This module consumes three top-level config keys: ssh_pwauth,
chpasswd and password.
The ssh_pwauth config key determines whether or not sshd will be
configured to accept password authentication. Disabling SSH password
authentication is limited to setting the specific sshd_config value
PasswordAuthentication no in sshd_config.
Note
If your image uses PAM for authentication, providing
PasswordAuthentication no may not be sufficient if your
distribution default is to provide KbdInteractiveAuthentication yes
in sshd_config. See Example 3 for suggested user-data in this case.
The chpasswd config key accepts a dictionary containing either (or
both) of users and expire.
- The - userskey is used to assign a password to a corresponding pre-existing user.
- The - expirekey is used to set whether to expire all user passwords specified by this module, such that a password will need to be reset on the user’s next login.
Note
Prior to cloud-init 22.3, the expire key only applies to plain text
(including RANDOM) passwords. Post-22.3, the expire key applies
to both plain text and hashed passwords.
The password config key is used to set the default user’s password. It
is ignored if the chpasswd users is used. Note that the list
keyword is deprecated in favor of users.
Internal name: cc_set_passwords
Module frequency: once-per-instance
Supported distros: all
- ssh_pwauth: (boolean/string) Sets whether or not to accept password authentication. - truewill enable password auth.- falsewill disable. Default: leave the value unchanged. In order for this config to be applied, SSH may need to be restarted. On systemd systems, this restart will only happen if the SSH service has already been started. On non-systemd systems, a restart will be attempted regardless of the service state.- Changed in version 22.3.Use of non-boolean values for this field is deprecated. 
- chpasswd: (object) Each object in chpasswd list supports the following keys: - expire: (boolean) Whether to expire all user passwords such that a password will need to be reset on the user’s next login. Default: - true.
- users: (array of object) This key represents a list of existing users to set passwords for. Each item under users contains the following required keys: name and password or in the case of a randomly generated password, name and type. The type key has a default value of - hash, and may alternatively be set to- textor- RANDOM. Randomly generated passwords may be insecure, use at your own risk.
- list: (string/array of string) - Deprecated in version 22.2: Use users instead. 
 
- password: (string) Set the default user’s password. Ignored if chpasswd - listis used.
Example 1: Set a default password, to be changed at first login.
#cloud-config
{password: password1, ssh_pwauth: true}
Example 2:
- Disable SSH password authentication. 
- Don’t require users to change their passwords on next login. 
- Set the password for user1 to be ‘password1’ (OS does hashing). 
- Set the password for user2 to a pre-hashed password. 
- Set the password for user3 to be a randomly generated password, which - will be written to the system console. 
#cloud-config
chpasswd:
  expire: false
  users:
  - {name: user1, password: password1, type: text}
  - {name: user2, password: $6$rounds=4096$5DJ8a9WMTEzIo5J4$Yms6imfeBvf3Yfu84mQBerh18l7OR1Wm1BJXZqFSpJ6BVas0AYJqIjP7czkOaAZHZi1kxQ5Y1IhgWN8K9NgxR1}
  - {name: user3, type: RANDOM}
ssh_pwauth: false
Example 3: Disable SSH password authentication and PAM interactive
password authentication by manually supplementing cloud-init’s default
sshd_config.
#cloud-config
ssh_pwauth: false
# Supplement sshd_config part with overrides for images using PAM
# for authentication on distributions which default to
# KbdInteractiveAuthentication yes in sshd_config.
write_files:
- path: /etc/ssh/sshd_config.d/70-no-pam-password-auth.conf
  content: 'KbdInteractiveAuthentication no'
  permissions: '0500'
Snap¶
Install, configure and manage snapd and snap packages
This module provides a simple configuration namespace in cloud-init for setting up snapd and installing snaps.
Both assertions and commands values can be either a dictionary or a
list. If these configs are provided as a dictionary, the keys are only used
to order the execution of the assertions or commands and the dictionary is
merged with any vendor data the snap configuration provided. If a list is
provided by the user instead of a dict, any vendor data snap configuration
is ignored.
The assertions configuration option is a dictionary or list of
properly-signed snap assertions, which will run before any snap commands.
They will be added to snapd’s assertion database by invoking
snap ack <aggregate_assertion_file>.
Snap commands is a dictionary or list of individual snap commands to
run on the target system. These commands can be used to create snap users,
install snaps, and provide snap configuration.
Note
If ‘side-loading’ private/unpublished snaps on an instance, it is best
to create a snap seed directory and seed.yaml manifest in
/var/lib/snapd/seed/ which snapd automatically installs on startup.
Internal name: cc_snap
Module frequency: once-per-instance
Supported distros: ubuntu
Activate only on keys: snap
- snap: (object) Each object in snap list supports the following keys: - assertions: ([‘object’, ‘array’] of string) Properly-signed snap assertions which will run before and snap commands. 
- commands: ([‘object’, ‘array’] of string/array of string) Snap commands to run on the target system. 
 
Example 1:
#cloud-config
snap:
  assertions:
    00: |
      signed_assertion_blob_here
    02: |
      signed_assertion_blob_here
  commands:
    00: snap create-user --sudoer --known <snap-user>@mydomain.com
    01: snap install canonical-livepatch
    02: canonical-livepatch enable <AUTH_TOKEN>
Example 2: For convenience, the snap command can be omitted when specifying commands as a list - snap will be automatically prepended. The following commands are all equivalent:
#cloud-config
snap:
  commands:
    0: [install, vlc]
    1: [snap, install, vlc]
    2: snap install vlc
    3: snap install vlc
Example 3: You can use a list of commands.
#cloud-config
snap:
  assertions:
    - signed_assertion_blob_here
    - |
      signed_assertion_blob_here
Example 4: You can also use a list of assertions.
#cloud-config
snap:
  assertions:
    - signed_assertion_blob_here
    - |
      signed_assertion_blob_here
Spacewalk¶
Install and configure spacewalk
This module installs Spacewalk and applies basic configuration. If the
Spacewalk config key is present, Spacewalk will be installed. The server
to connect to after installation must be provided in the server in
Spacewalk configuration. A proxy to connect through and an activation key
may optionally be specified.
For more details about spacewalk see the Fedora documentation.
Internal name: cc_spacewalk
Module frequency: once-per-instance
Supported distros: rhel, fedora, openeuler
Activate only on keys: spacewalk
- spacewalk: (object) Each object in spacewalk list supports the following keys: - server: (string) The Spacewalk server to use. 
- proxy: (string) The proxy to use when connecting to Spacewalk. 
- activation_key: (string) The activation key to use when registering with Spacewalk. 
 
Example 1:
#cloud-config
spacewalk: {activation_key: <key>, proxy: <proxy host>, server: <url>}
SSH¶
Configure SSH and SSH keys
This module handles most configuration for SSH, and for both host and authorized SSH keys.
Authorized keys
Authorized keys are a list of public SSH keys that are allowed to connect
to a user account on a system. They are stored in .ssh/authorized_keys
in that account’s home directory. Authorized keys for the default user
defined in users can be specified using ssh_authorized_keys. Keys
should be specified as a list of public keys.
Note
See the cc_set_passwords module documentation to enable/disable SSH
password authentication.
Root login can be enabled/disabled using the disable_root config key.
Root login options can be manually specified with disable_root_opts.
Supported public key types for the ssh_authorized_keys are:
- rsa 
- ecdsa 
- ed25519 
- ecdsa-sha2-nistp256 
- ecdsa-sha2-nistp384 
- ecdsa-sha2-nistp521 
- ssh-ed25519 
- ssh-rsa 
Note
This list has been filtered out from the supported key types of
OpenSSH
source, where the sigonly keys are removed. See ssh_util for
more information.
rsa, ecdsa and ed25519 are added for legacy, as they are
valid public keys in some older distros. They may be removed in the
future when support for the older distros is dropped.
Host keys
Host keys are for authenticating a specific instance. Many images have
default host SSH keys, which can be removed using ssh_deletekeys.
Host keys can be added using the ssh_keys configuration key.
When host keys are generated the output of the ssh-keygen command(s)
can be displayed on the console using the ssh_quiet_keygen
configuration key.
Note
When specifying private host keys in cloud-config, take care to ensure that communication between the data source and the instance is secure.
If no host keys are specified using ssh_keys, then keys will be
generated using ssh-keygen. By default, one public/private pair of
each supported host key type will be generated. The key types to generate
can be specified using the ssh_genkeytypes config flag, which accepts a
list of host key types to use. For each host key type for which this module
has been instructed to create a keypair, if a key of the same type is
already present on the system (i.e. if ssh_deletekeys was set to
false), no key will be generated.
Supported host key types for the ssh_keys and the ssh_genkeytypes
config flags are:
- ecdsa 
- ed25519 
- rsa 
Unsupported host key types for the ssh_keys and the ssh_genkeytypes
config flags are:
- ecdsa-sk 
- ed25519-sk 
Internal name: cc_ssh
Module frequency: once-per-instance
Supported distros: all
- ssh_keys: (object) A dictionary entries for the public and private host keys of each desired key type. Entries in the ssh_keys config dict should have keys in the format - <key type>_private,- <key type>_public, and, optionally,- <key type>_certificate, e.g.- rsa_private: <key>,- rsa_public: <key>, and- rsa_certificate: <key>. Not all key types have to be specified, ones left unspecified will not be used. If this config option is used, then separate keys will not be automatically generated. In order to specify multi-line private host keys and certificates, use YAML multi-line syntax. Note: Your ssh keys might possibly be visible to unprivileged users on your system, depending on your cloud’s security model. Each object in ssh_keys list supports the following keys:- <key_type>: (string) 
 
- ssh_authorized_keys: (array of string) The SSH public keys to add - .ssh/authorized_keysin the default user’s home directory.
- ssh_deletekeys: (boolean) Remove host SSH keys. This prevents re-use of a private host key from an image with default host SSH keys. Default: - true.
- ssh_genkeytypes: (array of - ecdsa/- ed25519/- rsa) The SSH key types to generate. Default:- [rsa, ecdsa, ed25519].
- disable_root: (boolean) Disable root login. Default: - true.
- disable_root_opts: (string) Disable root login options. If disable_root_opts is specified and contains the string - $USER, it will be replaced with the username of the default user. Default:- no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="echo 'Please login as the user \"$USER\" rather than the user \"$DISABLE_USER\".';echo;sleep 10;exit 142".
- allow_public_ssh_keys: (boolean) If - true, will import the public SSH keys from the datasource’s metadata to the user’s- .ssh/authorized_keysfile. Default:- true.
- ssh_quiet_keygen: (boolean) If - true, will suppress the output of key generation to the console. Default:- false.
- ssh_publish_hostkeys: (object) Each object in ssh_publish_hostkeys list supports the following keys: - enabled: (boolean) If true, will read host keys from - /etc/ssh/*.puband publish them to the datasource (if supported). Default:- true.
- blacklist: (array of string) The SSH key types to ignore when publishing. Default: - []to publish all SSH key types.
 
Example 1:
#cloud-config
allow_public_ssh_keys: true
disable_root: true
disable_root_opts: no-port-forwarding,no-agent-forwarding,no-X11-forwarding
ssh_authorized_keys: [ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEA3FSyQwBI6Z+nCSjUU ..., ssh-rsa
    AAAAB3NzaC1yc2EAAAABIwAAAQEA3I7VUf2l5gSn5uavROsc5HRDpZ ...]
ssh_deletekeys: true
ssh_genkeytypes: [rsa, ecdsa, ed25519]
ssh_keys: {rsa_certificate: '[email protected] AAAAIHNzaC1lZDI1NTE5LWNlcnQt
    ...
    ', rsa_private: '-----BEGIN RSA PRIVATE KEY-----
    MIIBxwIBAAJhAKD0YSHy73nUgysO13XsJmd4fHiFyQ+00R7VVu2iV9Qco
    ...
    -----END RSA PRIVATE KEY-----
    ', rsa_public: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAGEAoPRhIfLvedSDKw7Xd ...}
ssh_publish_hostkeys:
  blacklist: [rsa]
  enabled: true
ssh_quiet_keygen: true
SSH AuthKey Fingerprints¶
Log fingerprints of user SSH keys
Write fingerprints of authorized keys for each user to log. This is enabled
by default, but can be disabled using no_ssh_fingerprints. The hash
type for the keys can be specified, but defaults to sha256.
Internal name: cc_ssh_authkey_fingerprints
Module frequency: once-per-instance
Supported distros: all
- no_ssh_fingerprints: (boolean) If true, SSH fingerprints will not be written. Default: - false.
- authkey_hash: (string) The hash type to use when generating SSH fingerprints. Default: - sha256.
Example 1:
#cloud-config
no_ssh_fingerprints: true
Example 2:
#cloud-config
authkey_hash: sha512
SSH Import ID¶
Import SSH ID
This module imports SSH keys from either a public keyserver (usually
Launchpad), or GitHub, using ssh-import-id. Keys are referenced by the
username they are associated with on the keyserver. The keyserver can be
specified by prepending either lp: for Launchpad or gh: for
GitHub to the username.
Internal name: cc_ssh_import_id
Module frequency: once-per-instance
Supported distros: alpine, cos, debian, raspberry-pi-os, ubuntu
- ssh_import_id: (array of string) 
Example 1:
#cloud-config
ssh_import_id: [user, 'gh:user', 'lp:user']
Timezone¶
Set the system timezone
Sets the system timezone based on the value provided.
Internal name: cc_timezone
Module frequency: once-per-instance
Supported distros: all
Activate only on keys: timezone
- timezone: (string) The timezone to use as represented in /usr/share/zoneinfo. 
Example 1:
#cloud-config
timezone: America/New_York
Ubuntu Drivers¶
Interact with third party drivers in Ubuntu
This module interacts with the ubuntu-drivers command to install third
party driver packages.
Internal name: cc_ubuntu_drivers
Module frequency: once-per-instance
Supported distros: ubuntu
Activate only on keys: drivers
- drivers: (object) Each object in drivers list supports the following keys: - nvidia: (object) Each object in nvidia list supports the following keys: - license-accepted: (boolean) Do you accept the NVIDIA driver license? 
- version: (string) The version of the driver to install (e.g. “390”, “410”). Default: latest version. 
 
 
Example 1:
#cloud-config
drivers:
  nvidia: {license-accepted: true}
Ubuntu Autoinstall¶
Autoinstall configuration is ignored (but validated) by cloud-init.
Cloud-init is used by the Ubuntu installer in two stages.
The autoinstall key may contain a configuration for the Ubuntu
installer.
Cloud-init verifies that an autoinstall key contains a version key
and that the installer package is present on the system.
Note
The Ubuntu installer might pass part of this configuration to cloud-init during a later boot as part of the install process. See the Ubuntu installer documentation for more information. Please direct Ubuntu installer questions to their IRC channel (#ubuntu-server on Libera).
Internal name: cc_ubuntu_autoinstall
Module frequency: once
Supported distros: ubuntu
Activate only on keys: autoinstall
- autoinstall: (object) Cloud-init ignores this key and its values. It is used by Subiquity, the Ubuntu Autoinstaller. See: https://ubuntu.com/server/docs/install/autoinstall-reference. Each object in autoinstall list supports the following keys: - version: (integer) 
 
Example 1:
#cloud-config
autoinstall:
  version: 1
Ubuntu Pro¶
Configure Ubuntu Pro support services
Attach machine to an existing Ubuntu Pro support contract and enable or disable support services such as Livepatch, ESM, FIPS and FIPS Updates.
When attaching a machine to Ubuntu Pro, one can also specify services to
enable. When the enable list is present, only named services will be
activated. If the enable list is not present, the contract’s default
services will be enabled.
On Pro instances, when ubuntu_pro config is provided to cloud-init,
Pro’s auto-attach feature will be disabled and cloud-init will perform
the Pro auto-attach, ignoring the token key. The enable and
enable_beta values will strictly determine what services will be
enabled, ignoring contract defaults.
Note that when enabling FIPS or FIPS updates you will need to schedule a reboot to ensure the machine is running the FIPS-compliant kernel. See the Power State Change module for information on how to configure cloud-init to perform this reboot.
Internal name: cc_ubuntu_pro
Module frequency: once-per-instance
Supported distros: ubuntu
Activate only on keys: ubuntu_pro, ubuntu-advantage, ubuntu_advantage
- ubuntu_pro: (object) Each object in ubuntu_pro list supports the following keys: - enable: (array of string) Optional list of Ubuntu Pro services to enable. Any of: cc-eal, cis, esm-infra, fips, fips-updates, livepatch. By default, a given contract token will automatically enable a number of services, use this list to supplement which services should additionally be enabled. Any service unavailable on a given Ubuntu release or unentitled in a given contract will remain disabled. In Ubuntu Pro instances, if this list is given, then only those services will be enabled, ignoring contract defaults. Passing beta services here will cause an error. 
- enable_beta: (array of string) Optional list of Ubuntu Pro beta services to enable. By default, a given contract token will automatically enable a number of services, use this list to supplement which services should additionally be enabled. Any service unavailable on a given Ubuntu release or unentitled in a given contract will remain disabled. In Ubuntu Pro instances, if this list is given, then only those services will be enabled, ignoring contract defaults. 
- token: (string) Contract token obtained from https://ubuntu.com/pro to attach. Required for non-Pro instances. 
- features: (object) Ubuntu Pro features. Each object in features list supports the following keys: - disable_auto_attach: (boolean) Optional boolean for controlling if ua-auto-attach.service (in Ubuntu Pro instances) will be attempted each boot. Default: - false.
 
- config: (object) Configuration settings or override Ubuntu Pro config. Each object in config list supports the following keys: - http_proxy: (string/null) Ubuntu Pro HTTP Proxy URL or null to unset. 
- https_proxy: (string/null) Ubuntu Pro HTTPS Proxy URL or null to unset. 
- global_apt_http_proxy: (string/null) HTTP Proxy URL used for all APT repositories on a system or null to unset. Stored at - /etc/apt/apt.conf.d/90ubuntu-advantage-aptproxy.
- global_apt_https_proxy: (string/null) HTTPS Proxy URL used for all APT repositories on a system or null to unset. Stored at - /etc/apt/apt.conf.d/90ubuntu-advantage-aptproxy.
- ua_apt_http_proxy: (string/null) HTTP Proxy URL used only for Ubuntu Pro APT repositories or null to unset. Stored at - /etc/apt/apt.conf.d/90ubuntu-advantage-aptproxy.
- ua_apt_https_proxy: (string/null) HTTPS Proxy URL used only for Ubuntu Pro APT repositories or null to unset. Stored at - /etc/apt/apt.conf.d/90ubuntu-advantage-aptproxy.
 
 
- ubuntu_advantage: (object) Each object in ubuntu_advantage list supports the following keys: - Deprecated in version 24.1: Use ubuntu_pro instead. - enable: (array of string) Optional list of Ubuntu Pro services to enable. Any of: cc-eal, cis, esm-infra, fips, fips-updates, livepatch. By default, a given contract token will automatically enable a number of services, use this list to supplement which services should additionally be enabled. Any service unavailable on a given Ubuntu release or unentitled in a given contract will remain disabled. In Ubuntu Pro instances, if this list is given, then only those services will be enabled, ignoring contract defaults. Passing beta services here will cause an error. 
- enable_beta: (array of string) Optional list of Ubuntu Pro beta services to enable. By default, a given contract token will automatically enable a number of services, use this list to supplement which services should additionally be enabled. Any service unavailable on a given Ubuntu release or unentitled in a given contract will remain disabled. In Ubuntu Pro instances, if this list is given, then only those services will be enabled, ignoring contract defaults. 
- token: (string) Contract token obtained from https://ubuntu.com/pro to attach. Required for non-Pro instances. 
- features: (object) Ubuntu Pro features. Each object in features list supports the following keys: - disable_auto_attach: (boolean) Optional boolean for controlling if ua-auto-attach.service (in Ubuntu Pro instances) will be attempted each boot. Default: - false.
 
- config: (object) Configuration settings or override Ubuntu Pro config. Each object in config list supports the following keys: - http_proxy: (string/null) Ubuntu Pro HTTP Proxy URL or null to unset. 
- https_proxy: (string/null) Ubuntu Pro HTTPS Proxy URL or null to unset. 
- global_apt_http_proxy: (string/null) HTTP Proxy URL used for all APT repositories on a system or null to unset. Stored at - /etc/apt/apt.conf.d/90ubuntu-advantage-aptproxy.
- global_apt_https_proxy: (string/null) HTTPS Proxy URL used for all APT repositories on a system or null to unset. Stored at - /etc/apt/apt.conf.d/90ubuntu-advantage-aptproxy.
- ua_apt_http_proxy: (string/null) HTTP Proxy URL used only for Ubuntu Pro APT repositories or null to unset. Stored at - /etc/apt/apt.conf.d/90ubuntu-advantage-aptproxy.
- ua_apt_https_proxy: (string/null) HTTPS Proxy URL used only for Ubuntu Pro APT repositories or null to unset. Stored at - /etc/apt/apt.conf.d/90ubuntu-advantage-aptproxy.
 
 
Example 1: Attach the machine to an Ubuntu Pro support contract with a Pro contract token obtained from https://ubuntu.com/pro.
#cloud-config
ubuntu_pro: {token: <ubuntu_pro_token>}
Example 2: Attach the machine to an Ubuntu Pro support contract, enabling only FIPS and ESM services. Services will only be enabled if the environment supports that service. Otherwise, warnings will be logged for incompatible services.
#cloud-config
ubuntu_pro:
  enable: [fips, esm]
  token: <ubuntu_pro_token>
Example 3: Attach the machine to an Ubuntu Pro support contract and enable the FIPS service. Perform a reboot once cloud-init has completed.
#cloud-config
power_state: {mode: reboot}
ubuntu_pro:
  enable: [fips]
  token: <ubuntu_pro_token>
Example 4: Set a HTTP(s) proxy before attaching the machine to an Ubuntu Pro support contract and enabling the FIPS service.
#cloud-config
ubuntu_pro:
  token: <ubuntu_pro_token>
  config:
    http_proxy: 'http://some-proxy:8088'
    https_proxy: 'https://some-proxy:8088'
    global_apt_https_proxy: 'https://some-global-apt-proxy:8088/'
    global_apt_http_proxy: 'http://some-global-apt-proxy:8088/'
    ua_apt_http_proxy: 'http://10.0.10.10:3128'
    ua_apt_https_proxy: 'https://10.0.10.10:3128'
  enable:
  - fips
Example 5: On Ubuntu Pro instances, auto-attach but don’t enable any Pro services.
#cloud-config
ubuntu_pro:
  enable: []
  enable_beta: []
Example 6: Enable ESM and beta Real-time Ubuntu services in Ubuntu Pro instances.
#cloud-config
ubuntu_pro:
  enable: [esm]
  enable_beta: [realtime-kernel]
Example 7: Disable auto-attach in Ubuntu Pro instances.
#cloud-config
ubuntu_pro:
  features: {disable_auto_attach: true}
Update Etc Hosts¶
Update the hosts file (usually /etc/hosts)
This module will update the contents of the local hosts database (hosts
file, usually /etc/hosts) based on the hostname/FQDN specified in
config. Management of the hosts file is controlled using
manage_etc_hosts. If this is set to false, cloud-init will not
manage the hosts file at all. This is the default behavior.
If set to true, cloud-init will generate the hosts file using the
template located in /etc/cloud/templates/hosts.tmpl. In the
/etc/cloud/templates/hosts.tmpl template, the strings $hostname
and $fqdn will be replaced with the hostname and FQDN respectively.
If manage_etc_hosts is set to localhost, then cloud-init will not
rewrite the hosts file entirely, but rather will ensure that an entry for
the FQDN with a distribution-dependent IP is present (i.e.,
ping <hostname> will ping 127.0.0.1 or 127.0.1.1 or other IP).
Note
If manage_etc_hosts is set to true, the contents of the
hosts file will be updated every boot. To make any changes to the
hosts file persistent they must be made in
/etc/cloud/templates/hosts.tmpl.
Note
For instructions on specifying hostname and FQDN, see documentation for
the cc_set_hostname module.
Internal name: cc_update_etc_hosts
Module frequency: always
Supported distros: all
Activate only on keys: manage_etc_hosts
- manage_etc_hosts: ( - True/- False/- localhost/- template) Whether to manage- /etc/hostson the system. If- true, render the hosts file using- /etc/cloud/templates/hosts.tmplreplacing- $hostnameand- $fqdn. If- localhost, append a- 127.0.1.1entry that resolves from FQDN and hostname every boot. Default:- false.- Changed in version 22.3.Use of **template* is deprecated, use - trueinstead.*
- fqdn: (string) Optional fully qualified domain name to use when updating - /etc/hosts. Preferred over hostname if both are provided. In absence of hostname and fqdn in cloud-config, the- local-hostnamevalue will be used from datasource metadata.
- hostname: (string) Hostname to set when rendering - /etc/hosts. If fqdn is set, the hostname extracted from fqdn overrides hostname.
Example 1: Do not update or manage /etc/hosts at all. This is the default behavior. Whatever is present at instance boot time will be present after boot. User changes will not be overwritten.
#cloud-config
manage_etc_hosts: false
Example 2: Manage /etc/hosts with cloud-init. On every boot, /etc/hosts will be re-written from /etc/cloud/templates/hosts.tmpl.
The strings $hostname and $fqdn are replaced in the template with the appropriate values, either from the config-config fqdn or hostname if provided. When absent, the meta-data will be checked for local-hostname which can be split into <hostname>.<fqdn>.
To make modifications persistent across a reboot, you must modify /etc/cloud/templates/hosts.tmpl.
#cloud-config
manage_etc_hosts: true
Example 3: Update /etc/hosts every boot, providing a “localhost” 127.0.1.1 entry with the latest hostname and FQDN as provided by either IMDS or cloud-config. All other entries will be left alone. ping hostname will ping 127.0.1.1.
#cloud-config
manage_etc_hosts: localhost
Update Hostname¶
Update hostname and FQDN
This module will update the system hostname and FQDN. If
preserve_hostname is set to true, then the hostname will not be
altered.
Note
For instructions on specifying hostname and FQDN, see documentation for
the cc_set_hostname module.
Internal name: cc_update_hostname
Module frequency: always
Supported distros: all
- preserve_hostname: (boolean) Do not update system hostname when - true. Default:- false.
- prefer_fqdn_over_hostname: (boolean) By default, it is distro-dependent whether cloud-init uses the short hostname or fully qualified domain name when both - local-hostname` and ``fqdnare both present in instance metadata. When set- true, use fully qualified domain name if present as hostname instead of short hostname. When set- false, use hostname config value if present, otherwise fallback to fqdn.
- create_hostname_file: (boolean) If - false, the hostname file (e.g. /etc/hostname) will not be created if it does not exist. On systems that use systemd, setting create_hostname_file to- falsewill set the hostname transiently. If- true, the hostname file will always be created and the hostname will be set statically on systemd systems. Default:- true.
Example 1: By default, when preserve_hostname is not specified, cloud-init updates /etc/hostname per-boot based on the cloud provided local-hostname setting. If you manually change /etc/hostname after boot cloud-init will no longer modify it.
This default cloud-init behavior is equivalent to this cloud-config:
#cloud-config
preserve_hostname: false
Example 2: Prevent cloud-init from updating the system hostname.
#cloud-config
preserve_hostname: true
Example 3: Prevent cloud-init from updating /etc/hostname.
#cloud-config
preserve_hostname: true
Example 4: Set hostname to external.fqdn.me instead of myhost.
#cloud-config
fqdn: external.fqdn.me
hostname: myhost
prefer_fqdn_over_hostname: true
create_hostname_file: true
Example 5: Set hostname to external instead of external.fqdn.me when meta-data provides the local-hostname: external.fqdn.me.
#cloud-config
prefer_fqdn_over_hostname: false
Example 6: On a machine without an /etc/hostname file, don’’t create it. In most clouds, this will result in a DHCP-configured hostname provided by the cloud.
#cloud-config
create_hostname_file: false
Users and Groups¶
Configure users and groups
This module configures users and groups. For more detailed information on user options, see the Including users and groups config example.
Groups to add to the system can be specified under the groups key as a
string of comma-separated groups to create, or a list. Each item in the
list should either contain a string of a single group to create, or a
dictionary with the group name as the key and string of a single user as a
member of that group or a list of users who should be members of the group.
Note
Groups are added before users, so any users in a group list must already exist on the system.
Users to add can be specified as a string or list under the users key.
Each entry in the list should either be a string or a dictionary. If a
string is specified, that string can be comma-separated usernames to
create, or the reserved string default which represents the primary
admin user used to access the system. The default user varies per
distribution and is generally configured in /etc/cloud/cloud.cfg by the
default_user key.
Each users dictionary item must contain either a name or
snapuser key, otherwise it will be ignored. Omission of default as
the first item in the users list skips creation the default user. If
no users key is provided, the default behavior is to create the
default user via this config:
users:
- default
Note
Specifying a hash of a user’s password with passwd is a security
risk if the cloud-config can be intercepted. SSH authentication is
preferred.
Note
If specifying a doas rule for a user, ensure that the syntax for
the rule is valid, as the only checking performed by cloud-init is to
ensure that the user referenced in the rule is the correct user.
Note
If specifying a sudo rule for a user, ensure that the syntax for
the rule is valid, as it is not checked by cloud-init.
Note
Most of these configuration options will not be honored if the user
already exists. The following options are the exceptions, and are
applied to already-existing users; plain_text_passwd, doas,
hashed_passwd, lock_passwd, sudo, ssh_authorized_keys,
ssh_redirect_user.
The user key can be used to override the default_user configuration
defined in /etc/cloud/cloud.cfg. The user value should be a
dictionary which supports the same config keys as the users dictionary
items.
Internal name: cc_users_groups
Module frequency: once-per-instance
Supported distros: all
- groups: ([‘string’, ‘object’, ‘array’] of string/object) Each object in groups list supports the following keys: - <group_name>: ([‘string’, ‘array’] of string) Optional string of single username or a list of usernames to add to the group. 
 
- user: (string/object) The user dictionary values override the default_user configuration from - /etc/cloud/cloud.cfg. The user dictionary keys supported for the default_user are the same as the users schema. Each object in user list supports the following keys:- name: (string) The user’s login name. Required otherwise user creation will be skipped for this user. 
- doas: (array of string) List of doas rules to add for a user. doas or opendoas must be installed for rules to take effect. 
- expiredate: (string) Optional. Date on which the user’s account will be disabled. Default: - null.
- gecos: (string) Optional comment about the user, usually a comma-separated string of real name and contact information. 
- groups: (string/array of string/object) Optional comma-separated string of groups to add the user to. Each object in groups list supports the following keys: 
- homedir: (string) Optional home dir for user. Default: - /home/<username>.
- inactive: (string) Optional string representing the number of days until the user is disabled. 
- lock-passwd: (boolean) - Deprecated in version 22.3: Use lock_passwd instead. 
- lock_passwd: (boolean) Disable password login. Default: - true.
- no-create-home: (boolean) - Deprecated in version 24.2: Use no_create_home instead. 
- no_create_home: (boolean) Do not create home directory. Default: - false.
- no-log-init: (boolean) - Deprecated in version 24.2: Use no_log_init instead. 
- no_log_init: (boolean) Do not initialize lastlog and faillog for user. Default: - false.
- no-user-group: (boolean) - Deprecated in version 24.2: Use no_user_group instead. 
- no_user_group: (boolean) Do not create group named after user. Default: - false.
- passwd: (string) Hash of user password applied when user does not exist. This will NOT be applied if the user already exists. To generate this hash, run: - mkpasswd --method=SHA-512 --rounds=500000Note: Your password might possibly be visible to unprivileged users on your system, depending on your cloud’s security model. Check if your cloud’s IMDS server is visible from an unprivileged user to evaluate risk.
- hashed-passwd: (string) - Deprecated in version 24.2: Use hashed_passwd instead. 
- hashed_passwd: (string) Hash of user password to be applied. This will be applied even if the user is preexisting. To generate this hash, run: - mkpasswd --method=SHA-512 --rounds=500000. Note: Your password might possibly be visible to unprivileged users on your system, depending on your cloud’s security model. Check if your cloud’s IMDS server is visible from an unprivileged user to evaluate risk.
- plain-text-passwd: (string) - Deprecated in version 24.2: Use plain_text_passwd instead. 
- plain_text_passwd: (string) Clear text of user password to be applied. This will be applied even if the user is preexisting. Note: SSH keys or certificates are a safer choice for logging in to your system. For local escalation, supplying a hashed password is a safer choice than plain text. Your password might possibly be visible to unprivileged users on your system, depending on your cloud’s security model. An exposed plain text password is an immediate security concern. Check if your cloud’s IMDS server is visible from an unprivileged user to evaluate risk. 
- create-groups: (boolean) - Deprecated in version 24.2: Use create_groups instead. 
- create_groups: (boolean) Boolean set - falseto disable creation of specified user- groups. Default:- true.
- primary-group: (string) - Deprecated in version 24.2: Use primary_group instead. 
- primary_group: (string) Primary group for user. Default: - <username>.
- selinux-user: (string) - Deprecated in version 24.2: Use selinux_user instead. 
- selinux_user: (string) SELinux user for user’s login. Default: the default SELinux user. 
- shell: (string) Path to the user’s login shell. Default: the host system’s default shell. 
- snapuser: (string) Specify an email address to create the user as a Snappy user through - snap create-user. If an Ubuntu SSO account is associated with the address, username and SSH keys will be requested from there.
- ssh_authorized_keys: (array of string) List of SSH keys to add to user’s authkeys file. Can not be combined with ssh_redirect_user. 
- ssh-authorized-keys: (array of string) - Deprecated in version 18.3: Use ssh_authorized_keys instead. 
- ssh-import-id: (array of string) - Deprecated in version 24.2: Use ssh_import_id instead. 
- ssh_import_id: (array of string) List of ssh ids to import for user. Can not be combined with ssh_redirect_user. See the man page[1] for more details. [1] https://manpages.ubuntu.com/manpages/noble/en/man1/ssh-import-id.1.html. 
- ssh-redirect-user: (boolean) - Deprecated in version 24.2: Use ssh_redirect_user instead. 
- ssh_redirect_user: (boolean) Boolean set to true to disable SSH logins for this user. When specified, all cloud-provided public SSH keys will be set up in a disabled state for this username. Any SSH login as this username will timeout and prompt with a message to login instead as the default_username for this instance. Default: - false. This key can not be combined with ssh_import_id or ssh_authorized_keys.
- system: (boolean) Optional. Create user as system user with no home directory. Default: - false.
- sudo: (string/null/array of string/null/boolean) - Changed in version 22.2.The value ``false`` is deprecated for this key, use ``null`` instead. 
- uid: (integer/string) The user’s ID. Default value [system default]. - Changed in version 22.3.The use of ``string`` type is deprecated. Use an ``integer`` instead. 
 
- users: ([‘string’, ‘array’, ‘object’] of string/array of string/object) Each object in users list supports the following keys: - name: (string) The user’s login name. Required otherwise user creation will be skipped for this user. 
- doas: (array of string) List of doas rules to add for a user. doas or opendoas must be installed for rules to take effect. 
- expiredate: (string) Optional. Date on which the user’s account will be disabled. Default: - null.
- gecos: (string) Optional comment about the user, usually a comma-separated string of real name and contact information. 
- groups: (string/array of string/object) Optional comma-separated string of groups to add the user to. 
- homedir: (string) Optional home dir for user. Default: - /home/<username>.
- inactive: (string) Optional string representing the number of days until the user is disabled. 
- lock-passwd: (boolean) - Deprecated in version 22.3: Use lock_passwd instead. 
- lock_passwd: (boolean) Disable password login. Default: - true.
- no-create-home: (boolean) - Deprecated in version 24.2: Use no_create_home instead. 
- no_create_home: (boolean) Do not create home directory. Default: - false.
- no-log-init: (boolean) - Deprecated in version 24.2: Use no_log_init instead. 
- no_log_init: (boolean) Do not initialize lastlog and faillog for user. Default: - false.
- no-user-group: (boolean) - Deprecated in version 24.2: Use no_user_group instead. 
- no_user_group: (boolean) Do not create group named after user. Default: - false.
- passwd: (string) Hash of user password applied when user does not exist. This will NOT be applied if the user already exists. To generate this hash, run: - mkpasswd --method=SHA-512 --rounds=500000Note: Your password might possibly be visible to unprivileged users on your system, depending on your cloud’s security model. Check if your cloud’s IMDS server is visible from an unprivileged user to evaluate risk.
- hashed-passwd: (string) - Deprecated in version 24.2: Use hashed_passwd instead. 
- hashed_passwd: (string) Hash of user password to be applied. This will be applied even if the user is preexisting. To generate this hash, run: - mkpasswd --method=SHA-512 --rounds=500000. Note: Your password might possibly be visible to unprivileged users on your system, depending on your cloud’s security model. Check if your cloud’s IMDS server is visible from an unprivileged user to evaluate risk.
- plain-text-passwd: (string) - Deprecated in version 24.2: Use plain_text_passwd instead. 
- plain_text_passwd: (string) Clear text of user password to be applied. This will be applied even if the user is preexisting. Note: SSH keys or certificates are a safer choice for logging in to your system. For local escalation, supplying a hashed password is a safer choice than plain text. Your password might possibly be visible to unprivileged users on your system, depending on your cloud’s security model. An exposed plain text password is an immediate security concern. Check if your cloud’s IMDS server is visible from an unprivileged user to evaluate risk. 
- create-groups: (boolean) - Deprecated in version 24.2: Use create_groups instead. 
- create_groups: (boolean) Boolean set - falseto disable creation of specified user- groups. Default:- true.
- primary-group: (string) - Deprecated in version 24.2: Use primary_group instead. 
- primary_group: (string) Primary group for user. Default: - <username>.
- selinux-user: (string) - Deprecated in version 24.2: Use selinux_user instead. 
- selinux_user: (string) SELinux user for user’s login. Default: the default SELinux user. 
- shell: (string) Path to the user’s login shell. Default: the host system’s default shell. 
- snapuser: (string) Specify an email address to create the user as a Snappy user through - snap create-user. If an Ubuntu SSO account is associated with the address, username and SSH keys will be requested from there.
- ssh_authorized_keys: (array of string) List of SSH keys to add to user’s authkeys file. Can not be combined with ssh_redirect_user. 
- ssh-authorized-keys: (array of string) - Deprecated in version 18.3: Use ssh_authorized_keys instead. 
- ssh-import-id: (array of string) - Deprecated in version 24.2: Use ssh_import_id instead. 
- ssh_import_id: (array of string) List of ssh ids to import for user. Can not be combined with ssh_redirect_user. See the man page[1] for more details. [1] https://manpages.ubuntu.com/manpages/noble/en/man1/ssh-import-id.1.html. 
- ssh-redirect-user: (boolean) - Deprecated in version 24.2: Use ssh_redirect_user instead. 
- ssh_redirect_user: (boolean) Boolean set to true to disable SSH logins for this user. When specified, all cloud-provided public SSH keys will be set up in a disabled state for this username. Any SSH login as this username will timeout and prompt with a message to login instead as the default_username for this instance. Default: - false. This key can not be combined with ssh_import_id or ssh_authorized_keys.
- system: (boolean) Optional. Create user as system user with no home directory. Default: - false.
- sudo: (string/null/array of string/null/boolean) - Changed in version 22.2.The value ``false`` is deprecated for this key, use ``null`` instead. 
- uid: (integer/string) The user’s ID. Default value [system default]. - Changed in version 22.3.The use of ``string`` type is deprecated. Use an ``integer`` instead. 
- name: (string) The user’s login name. Required otherwise user creation will be skipped for this user. 
- doas: (array of string) List of doas rules to add for a user. doas or opendoas must be installed for rules to take effect. 
- expiredate: (string) Optional. Date on which the user’s account will be disabled. Default: - null.
- gecos: (string) Optional comment about the user, usually a comma-separated string of real name and contact information. 
- groups: (string/array of string/object) Optional comma-separated string of groups to add the user to. 
- homedir: (string) Optional home dir for user. Default: - /home/<username>.
- inactive: (string) Optional string representing the number of days until the user is disabled. 
- lock-passwd: (boolean) - Deprecated in version 22.3: Use lock_passwd instead. 
- lock_passwd: (boolean) Disable password login. Default: - true.
- no-create-home: (boolean) - Deprecated in version 24.2: Use no_create_home instead. 
- no_create_home: (boolean) Do not create home directory. Default: - false.
- no-log-init: (boolean) - Deprecated in version 24.2: Use no_log_init instead. 
- no_log_init: (boolean) Do not initialize lastlog and faillog for user. Default: - false.
- no-user-group: (boolean) - Deprecated in version 24.2: Use no_user_group instead. 
- no_user_group: (boolean) Do not create group named after user. Default: - false.
- passwd: (string) Hash of user password applied when user does not exist. This will NOT be applied if the user already exists. To generate this hash, run: - mkpasswd --method=SHA-512 --rounds=500000Note: Your password might possibly be visible to unprivileged users on your system, depending on your cloud’s security model. Check if your cloud’s IMDS server is visible from an unprivileged user to evaluate risk.
- hashed-passwd: (string) - Deprecated in version 24.2: Use hashed_passwd instead. 
- hashed_passwd: (string) Hash of user password to be applied. This will be applied even if the user is preexisting. To generate this hash, run: - mkpasswd --method=SHA-512 --rounds=500000. Note: Your password might possibly be visible to unprivileged users on your system, depending on your cloud’s security model. Check if your cloud’s IMDS server is visible from an unprivileged user to evaluate risk.
- plain-text-passwd: (string) - Deprecated in version 24.2: Use plain_text_passwd instead. 
- plain_text_passwd: (string) Clear text of user password to be applied. This will be applied even if the user is preexisting. Note: SSH keys or certificates are a safer choice for logging in to your system. For local escalation, supplying a hashed password is a safer choice than plain text. Your password might possibly be visible to unprivileged users on your system, depending on your cloud’s security model. An exposed plain text password is an immediate security concern. Check if your cloud’s IMDS server is visible from an unprivileged user to evaluate risk. 
- create-groups: (boolean) - Deprecated in version 24.2: Use create_groups instead. 
- create_groups: (boolean) Boolean set - falseto disable creation of specified user- groups. Default:- true.
- primary-group: (string) - Deprecated in version 24.2: Use primary_group instead. 
- primary_group: (string) Primary group for user. Default: - <username>.
- selinux-user: (string) - Deprecated in version 24.2: Use selinux_user instead. 
- selinux_user: (string) SELinux user for user’s login. Default: the default SELinux user. 
- shell: (string) Path to the user’s login shell. Default: the host system’s default shell. 
- snapuser: (string) Specify an email address to create the user as a Snappy user through - snap create-user. If an Ubuntu SSO account is associated with the address, username and SSH keys will be requested from there.
- ssh_authorized_keys: (array of string) List of SSH keys to add to user’s authkeys file. Can not be combined with ssh_redirect_user. 
- ssh-authorized-keys: (array of string) - Deprecated in version 18.3: Use ssh_authorized_keys instead. 
- ssh-import-id: (array of string) - Deprecated in version 24.2: Use ssh_import_id instead. 
- ssh_import_id: (array of string) List of ssh ids to import for user. Can not be combined with ssh_redirect_user. See the man page[1] for more details. [1] https://manpages.ubuntu.com/manpages/noble/en/man1/ssh-import-id.1.html. 
- ssh-redirect-user: (boolean) - Deprecated in version 24.2: Use ssh_redirect_user instead. 
- ssh_redirect_user: (boolean) Boolean set to true to disable SSH logins for this user. When specified, all cloud-provided public SSH keys will be set up in a disabled state for this username. Any SSH login as this username will timeout and prompt with a message to login instead as the default_username for this instance. Default: - false. This key can not be combined with ssh_import_id or ssh_authorized_keys.
- system: (boolean) Optional. Create user as system user with no home directory. Default: - false.
- sudo: (string/null/array of string/null/boolean) - Changed in version 22.2.The value ``false`` is deprecated for this key, use ``null`` instead. 
- uid: (integer/string) The user’s ID. Default value [system default]. - Changed in version 22.3.The use of ``string`` type is deprecated. Use an ``integer`` instead. 
 
Example 1: Add the default_user from /etc/cloud/cloud.cfg. This is also the default behavior of cloud-init when no users key is provided.
#cloud-config
users: [default]
Example 2: Add the admingroup with members root and sys, and an empty group cloud-users.
#cloud-config
groups:
- admingroup: [root, sys]
- cloud-users
Example 3: Skip creation of the default user and only create newsuper. Password-based login is rejected, but the GitHub user TheRealFalcon and the Launchpad user falcojr can SSH as newsuper. The default shell for newsuper is bash instead of system default.
#cloud-config
users:
- name: newsuper
  shell: /bin/bash
Example 4: Skip creation of the default user and only create newsuper. Password-based login is rejected, but the GitHub user TheRealFalcon and the Launchpad user falcojr can SSH as newsuper. doas/opendoas is configured to permit this user to run commands as other users (without being prompted for a password) except not as root.
#cloud-config
users:
- doas: [permit nopass newsuper, deny newsuper as root]
  name: newsuper
Example 5: On a system with SELinux enabled, add youruser and set the SELinux user to staff_u. When omitted on SELinux, the system will select the configured default SELinux user.
#cloud-config
users:
- default
- {name: youruser, selinux_user: staff_u}
Example 6: To redirect a legacy username to the default user for a distribution, ssh_redirect_user will accept an SSH connection and emit a message telling the client to SSH as the default user. SSH clients will get the message;
#cloud-config
users:
- default
- {name: nosshlogins, ssh_redirect_user: true}
Example 7: Override any default_user config in /etc/cloud/cloud.cfg with supplemental config options. This config will make the default user mynewdefault and change the user to not have sudo rights.
#cloud-config
ssh_import_id: [chad.smith]
user: {name: mynewdefault, sudo: null}
Example 8: Avoid creating any default_user.
#cloud-config
users: []
Wireguard¶
Module to configure WireGuard tunnel
The WireGuard module provides a dynamic interface for configuring WireGuard (as a peer or server) in a straightforward way.
This module takes care of;
- writing interface configuration files 
- enabling and starting interfaces 
- installing wireguard-tools package 
- loading WireGuard kernel module 
- executing readiness probes 
What is a readiness probe?
The idea behind readiness probes is to ensure WireGuard connectivity before continuing the cloud-init process. This could be useful if you need access to specific services like an internal APT Repository Server (e.g., Landscape) to install/update packages.
Example
An edge device can’t access the internet but uses cloud-init modules which
will install packages (e.g. landscape, packages,
ubuntu_advantage). Those modules will fail due to missing internet
connection. The wireguard module fixes that problem as it waits until
all readiness probes (which can be arbitrary commands, e.g. checking if a
proxy server is reachable over WireGuard network) are finished, before
continuing the cloud-init config stage.
Note
In order to use DNS with WireGuard you have to install the
resolvconf package or symlink it to systemd’s resolvectl,
otherwise wg-quick commands will throw an error message that
executable resolvconf is missing, which leads the wireguard
module to fail.
Internal name: cc_wireguard
Module frequency: once-per-instance
Supported distros: ubuntu
Activate only on keys: wireguard
- wireguard: (null/object) Each object in wireguard list supports the following keys: - interfaces: (array of object) Each object in interfaces list supports the following keys: - name: (string) Name of the interface. Typically wgx (example: wg0). 
- config_path: (string) Path to configuration file of Wireguard interface. 
- content: (string) Wireguard interface configuration. Contains key, peer, … 
 
- readinessprobe: (array of string) List of shell commands to be executed as probes. 
 
Configure one or more WireGuard interfaces and provide optional readiness probes.
#cloud-config
wireguard:
  interfaces:
    - name: wg0
      config_path: /etc/wireguard/wg0.conf
      content: |
        [Interface]
        PrivateKey = <private_key>
        Address = <address>
        [Peer]
        PublicKey = <public_key>
        Endpoint = <endpoint_ip>:<endpoint_ip_port>
        AllowedIPs = <allowedip1>, <allowedip2>, ...
    - name: wg1
      config_path: /etc/wireguard/wg1.conf
      content: |
        [Interface]
        PrivateKey = <private_key>
        Address = <address>
        [Peer]
        PublicKey = <public_key>
        Endpoint = <endpoint_ip>:<endpoint_ip_port>
        AllowedIPs = <allowedip1>
  readinessprobe:
    - 'systemctl restart service'
    - 'curl https://webhook.endpoint/example'
    - 'nc -zv some-service-fqdn 443'
Write Files¶
Write arbitrary files
Write out arbitrary content to files, optionally setting permissions. Parent folders in the path are created if absent. Content can be specified in plain text or binary. Data encoded with either base64 or binary gzip data can be specified and will be decoded before being written. Data can also be loaded from an arbitrary URI. For empty file creation, content can be omitted.
Note
If multi-line data is provided, care should be taken to ensure it
follows YAML formatting standards. To specify binary data, use the YAML
option !!binary.
Note
Do not write files under /tmp during boot because of a race with
systemd-tmpfiles-clean that can cause temporary files to be cleaned
during the early boot process. Use /run/somedir instead to avoid
a race (LP: #1707222).
Warning
Existing files will be overridden.
Internal name: cc_write_files
Module frequency: once-per-instance
Supported distros: all
Activate only on keys: write_files
- write_files: (array of object) Each object in write_files list supports the following keys: - path: (string) Path of the file to which content is decoded and written. 
- content: (string) Optional content to write to the provided path. When content is present and encoding is not ‘text/plain’, decode the content prior to writing. Default: - ''.
- source: (object) Optional specification for content loading from an arbitrary URI. Each object in source list supports the following keys: - uri: (string) URI from which to load file content. If loading fails repeatedly, content is used instead. 
- headers: (object) Optional HTTP headers to accompany load request, if applicable. 
 
- owner: (string) Optional owner:group to chown on the file and new directories. Default: - root:root.
- permissions: (string) Optional file permissions to set on path represented as an octal string ‘0###’. Default: - 0o644.
- encoding: ( - gz/- gzip/- gz+base64/- gzip+base64/- gz+b64/- gzip+b64/- b64/- base64/- text/plain) Optional encoding type of the content. Default:- text/plain. No decoding is performed by default. Supported encoding types are: gz, gzip, gz+base64, gzip+base64, gz+b64, gzip+b64, b64, base64.
- append: (boolean) Whether to append content to existing file if path exists. Default: - false.
- defer: (boolean) Defer writing the file until ‘final’ stage, after users were created, and packages were installed. Default: - false.
 
Example 1: Write out base64-encoded content to /etc/sysconfig/selinux.
#cloud-config
write_files:
- encoding: b64
  content: CiMgVGhpcyBmaWxlIGNvbnRyb2xzIHRoZSBzdGF0ZSBvZiBTRUxpbnV4...
  owner: root:root
  path: /etc/sysconfig/selinux
  permissions: '0644'
Example 2: Appending content to an existing file.
#cloud-config
write_files:
- content: |
    15 * * * * root ship_logs
  path: /etc/crontab
  append: true
Example 3: Provide gzipped binary content
#cloud-config
write_files:
- encoding: gzip
  content: !!binary |
      H4sIAIDb/U8C/1NW1E/KzNMvzuBKTc7IV8hIzcnJVyjPL8pJ4QIA6N+MVxsAAAA=
  path: /usr/bin/hello
  permissions: '0755'
Example 4: Create an empty file on the system
#cloud-config
write_files:
- path: /root/CLOUD_INIT_WAS_HERE
Example 5: Defer writing the file until after the package (Nginx) is installed and its user is created.
#cloud-config
write_files:
- path: /etc/nginx/conf.d/example.com.conf
  content: |
    server {
        server_name example.com;
        listen 80;
        root /var/www;
        location / {
            try_files $uri $uri/ $uri.html =404;
        }
    }
  owner: 'nginx:nginx'
  permissions: '0640'
  defer: true
Example 6: Retrieve file contents from a URI source, rather than inline. Especially useful with an external config-management repo, or for large binaries.
#cloud-config
write_files:
- source:
    uri: https://gitlab.example.com/some_ci_job/artifacts/hello
    headers:
      Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
      User-Agent: cloud-init on myserver.example.com
  path: /usr/bin/hello
  permissions: '0755'
Yum Add Repo¶
Add yum repository configuration to the system
Add yum repository configuration to /etc/yum.repos.d. Configuration
files are named based on the opaque dictionary key under the yum_repos
they are specified with. If a config file already exists with the same
name as a config entry, the config entry will be skipped.
Internal name: cc_yum_add_repo
Module frequency: once-per-instance
Supported distros: almalinux, azurelinux, centos, cloudlinux, eurolinux, fedora, mariner, openeuler, OpenCloudOS, openmandriva, photon, rhel, rocky, TencentOS, virtuozzo
Activate only on keys: yum_repos
- yum_repo_dir: (string) The repo parts directory where individual yum repo config files will be written. Default: - /etc/yum.repos.d.
- yum_repos: (object) Each object in yum_repos list supports the following keys: - <repo_name>: (object) Object keyed on unique yum repo IDs. The key used will be used to write yum repo config files in - yum_repo_dir/<repo_key_id>.repo. Each object in <repo_name> list supports the following keys:- <yum_config_option>: (integer/boolean/string) Any supported yum repository configuration options will be written to the yum repo config file. See: man yum.conf. 
- baseurl: (string) URL to the directory where the yum repository’s ‘repodata’ directory lives. 
- metalink: (string) Specifies a URL to a metalink file for the repomd.xml. 
- mirrorlist: (string) Specifies a URL to a file containing a baseurls list. 
- name: (string) Optional human-readable name of the yum repo. 
- enabled: (boolean) Whether to enable the repo. Default: - true.
 
 
Example 1:
#cloud-config
yum_repos:
  my_repo:
    baseurl: http://blah.org/pub/epel/testing/5/$basearch/
yum_repo_dir: /store/custom/yum.repos.d
Example 2: Enable cloud-init upstream’s daily testing repo for EPEL 8 to install the latest cloud-init from tip of main for testing.
#cloud-config
yum_repos:
  cloud-init-daily:
    name: Copr repo for cloud-init-dev owned by @cloud-init
    baseurl: https://download.copr.fedorainfracloud.org/results/@cloud-init/cloud-init-dev/epel-8-$basearch/
    type: rpm-md
    skip_if_unavailable: true
    gpgcheck: true
    gpgkey: https://download.copr.fedorainfracloud.org/results/@cloud-init/cloud-init-dev/pubkey.gpg
    enabled_metadata: 1
Example 3: Add the file /etc/yum.repos.d/epel_testing.repo which can then subsequently be used by yum for later operations.
#cloud-config
yum_repos:
# The name of the repository
 epel-testing:
   baseurl: https://download.copr.fedorainfracloud.org/results/@cloud-init/cloud-init-dev/pubkey.gpg
   enabled: false
   failovermethod: priority
   gpgcheck: true
   gpgkey: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL
   name: Extra Packages for Enterprise Linux 5 - Testing
Example 4: Any yum repo configuration can be passed directly into the repository file created. See man yum.conf for supported config keys.
Write /etc/yum.conf.d/my-package-stream.repo with gpgkey checks on the repo data of the repository enabled.
#cloud-config
yum_repos:
  my package stream:
    baseurl: http://blah.org/pub/epel/testing/5/$basearch/
    mirrorlist: http://some-url-to-list-of-baseurls
    repo_gpgcheck: 1
    enable_gpgcheck: true
    gpgkey: https://url.to.ascii-armored-gpg-key
Zypper Add Repo¶
Configure Zypper behavior and add Zypper repositories
Zypper behavior can be configured using the config key, which will
modify /etc/zypp/zypp.conf. The configuration writer will only append
the provided configuration options to the configuration file. Any duplicate
options will be resolved by the way the zypp.conf INI file is parsed.
Note
Setting configdir is not supported and will be skipped.
The repos key may be used to add repositories to the system. Beyond the
required id and baseurl attributions, no validation is performed on
the repos entries.
It is assumed the user is familiar with the Zypper repository file format. This configuration is also applicable for systems with transactional-updates.
Internal name: cc_zypper_add_repo
Module frequency: always
Supported distros: opensuse, opensuse-microos, opensuse-tumbleweed, opensuse-leap, sle_hpc, sle-micro, sles
Activate only on keys: zypper
- zypper: (object) Each object in zypper list supports the following keys: - repos: (array of object) Each object in repos list supports the following keys: - id: (string) The unique id of the repo, used when writing /etc/zypp/repos.d/<id>.repo. 
- baseurl: (string) The base repositoy URL. 
 
- config: (object) Any supported zypo.conf key is written to - /etc/zypp/zypp.conf.
 
Example 1:
#cloud-config
zypper:
  config: {download.use_deltarpm: true, reposdir: /etc/zypp/repos.dir, servicesdir: /etc/zypp/services.d}
  repos:
  - {autorefresh: 1, baseurl: 'http://dl.opensuse.org/dist/leap/v/repo/oss/', enabled: 1,
    id: opensuse-oss, name: os-oss}
  - {baseurl: 'http://dl.opensuse.org/dist/leap/v/update', id: opensuse-oss-update,
    name: os-oss-up}