Chapter 4. Configuring cloud-init
By using cloud-init
, you can perform a variety of configuration tasks.
Your cloud-init
configuration can require that you add directives to the cloud.cfg
file and the cloud.cfg.d
directory. Alternatively, your specific data source might require that you add directives to files, such as a user data file and a metadata file. A data source might require that you upload your directives to an HTTP server. Check the requirements of your data source and add directives accordingly.
4.1. Creating a virtual machine that includes cloud-init for a NoCloud datasource
To create a new virtual machine (VM) that includes cloud-init
, create a meta-data
file and a user-data
file.
-
The
meta-data
file includes instance details. -
The
user-data
file includes information to create a user and grant access.
Include these files in a new ISO image, and attach the ISO file to a new VM created from a KVM Guest Image. In this scenario, the datasource is NoCloud.
Procedure
Create a directory named
cloudinitiso
and set is as your working directory:$ mkdir cloudinitiso $ cd cloudinitiso
Create the
meta-data
file and add the following information:instance-id: citest local-hostname: citest-1
Create the
user-data
file and add the following information:#cloud-config password: cilogon chpasswd: {expire: False} ssh_pwauth: True ssh_authorized_keys: - ssh-rsa AAA...fhHQ== sample@redhat.com
NoteThe last line of the
user-data
file references an SSH public key. Find your SSH public keys in~/.ssh/id_rsa.pub
. When trying this sample procedure, modify the line to include one of your public keys.Use the
genisoimage
command to create an ISO image that includesuser-data
andmeta-data
:# genisoimage -output ciiso.iso -volid cidata -joliet -rock user-data meta-data I: -input-charset not specified, using utf-8 (detected in locale settings) Total translation table size: 0 Total rockridge attributes bytes: 331 Total directory bytes: 0 Path table size(bytes): 10 Max brk space used 0 183 extents written (0 MB)
-
Download a KVM Guest Image from the Red Hat Customer Portal to the
/var/lib/libvirt/images
directory. Create a new VM from the KVM Guest Image using the
virt-install
utility and attach the downloaded image to the existing image:# virt-install \ --memory 4096 \ --vcpus 4 \ --name mytestcivm \ --disk /var/lib/libvirt/images/rhel-8.1-x86_64-kvm.qcow2,device=disk,bus=virtio,format=qcow2 \ --disk /home/sample/cloudinitiso/ciiso.iso,device=cdrom \ --os-type Linux \ --os-variant rhel8.0 \ --virt-type kvm \ --graphics none \ --import
Log on to your image with username
cloud-user
and passwordcilogon
:citest-1 login: cloud-user Password: [cloud-user@citest-1 ~]$
Verification
Check the
cloud-init
status to confirm that the utility has completed its defined tasks:[cloud-user@citest-1 instance]$ cloud-init status status: done
The
cloud-init
utility creates thecloud-init
directory layout under/var/lib/cloud
when it runs, and it updates or changes certain directory contents based upon the directives you have specified.For example, you can confirm that the datasource is
NoCloud
by checking the datasource file.$ cd /var/lib/cloud/instance $ cat datasource DataSourceNoCloud: DataSourceNoCloud [seed=/dev/sr0][dsmode=net]
cloud-init
copies user-data into/var/lib/cloud/instance/user-data.txt
:$ cat user-data.txt #cloud-config password: cilogon chpasswd: {expire: False} ssh_pwauth: True ssh_authorized_keys: - ssh-rsa AAA...fhHQ== sample@redhat.com
For OpenStack, the Creating and managing instances includes information for configuring an instance using cloud-init
. See Creating a customized instance for specific procedures.
Additional resources
4.2. Expiring a cloud user password with cloud-init
To force cloud-user
to change the cloud-user
password at the first login, you can set their password as expired.
Procedure
Depending on the requirements of your datasource, edit the
user-data
file or add the following directive to thecloud.cfg.d
directory:NoteAll user directives include
#cloud-config
at the top of the file so thatcloud-init
recognizes the file as containing user directives. When you include directives in thecloud.cfg.d
directory, name the file*.cfg
, and always include#cloud-config
at the top of the file.Change the line
chpasswd: {expire: False}
tochpasswd: {expire: True}
:#cloud-config password: mypassword chpasswd: {expire: True} ssh_pwauth: True ssh_authorized_keys: - ssh-rsa AAA...SDvz user1@yourdomain.com - ssh-rsa AAB...QTuo user2@yourdomain.com
This works to expire the password because
password
andchpasswd
operate on the default user unless you indicate otherwise.NoteThis is a global setting. When you set
chpasswd
toTrue
, all users you create need to change their passwords when they log in.
4.3. Changing a default user name with cloud-init
You can change the default user name to something other than cloud-user
.
Procedure
Depending on the requirements of your datasource, edit the
user-data
file or add the following directive to thecloud.cfg.d
directory:NoteAll user directives include
#cloud-config
at the top of the file so thatcloud-init
recognizes the file as containing user directives. When you include directives in thecloud.cfg.d
directory, name the file*.cfg
, and always include#cloud-config
at the top of the file.Add the line
user: <username>
, replacing <username> with the new default user name:#cloud-config user: username password: mypassword chpasswd: {expire: False} ssh_pwauth: True ssh_authorized_keys: - ssh-rsa AAA...SDvz user1@yourdomain.com - ssh-rsa AAB...QTuo user2@yourdomain.com
4.4. Setting a root password with cloud-init
To set the root password, create a user list.
Procedure
Depending on the requirements of your datasource, edit the
user-data
file or add the following directive to thecloud.cfg.d
directory:NoteAll user directives include
#cloud-config
at the top of the file so thatcloud-init
recognizes the file as containing user directives. When you include directives in thecloud.cfg.d
directory, name the file*.cfg
, and always include#cloud-config
at the top of the file.Create a user list in the
chpasswd
section of the file:NoteWhite space is significant. Do not include white space before or after the colon in your user list. If you include white space, the password is set with a space in it.
#cloud-config ssh_pwauth: True ssh_authorized_keys: - ssh-rsa AAA...SDvz user1@yourdomain.com - ssh-rsa AAB...QTuo user2@yourdomain.com chpasswd: list: | root:myrootpassword cloud-user:mypassword expire: False
NoteIf you use this method to set the user password, you must set all passwords in this section.
4.5. Managing Red Hat subscriptions with cloud-init
You can use the rh_subscription
directive to register your system. For each subscription, you need to edit user data.
Example 1
You can use the
auto-attach
andservice-level
options:Under
rh_subscription
, add yourusername
andpassword
, setauto-attach
toTrue
, and setservice-level
toself-support
.rh_subscription: username: sample@redhat.com password: 'mypassword' auto-attach: True service-level: self-support
NoteThe
service-level
option requires that you use theauto-attach
option.
Example 2
You can use the
activation-key
andorg
options:Under
rh_subscription
, add youractivation key
andorg
number and setauto-attach
toTrue
.rh_subscription: activation-key: example_key org: 12345 auto-attach: True
Example 3
You can add a subscription pool:
Under
rh_subscription
, add yourusername
,password
, and pool number.rh_subscription: username: sample@redhat.com password: 'password' add-pool: XYZ01234567
NoteThis sample is the equivalent of the
subscription-manager attach --pool=XYZ01234567
command.
Example 4
You can set a server host name in the
/etc/rhsm/rhsm.conf
file:Under
rh_subscription
, add yourusername
,password
,server-hostname
, and setauto-attach
toTrue
.rh_subscription: username: sample@redhat.com password: 'password' server-hostname: test.example.com auto-attach: True
4.6. Adding users and user options with cloud-init
You create and describe users in a users
section. You can modify the section to add more users to your initial system configuration, and you can set additional user options.
If you add the users
section, you must also set the default user options in this section.
Procedure
Depending on the requirements of your datasource, edit the
user-data
file or add the following directive to thecloud.cfg.d
directory:NoteAll user directives include
#cloud-config
at the top of the file so thatcloud-init
recognizes the file as containing user directives. When you include directives in thecloud.cfg.d
directory, name the file*.cfg
, and always include#cloud-config
at the top of the file.Add or modify the
users
section to add users.-
If you want
cloud-user
to be the default user created along with the other users you specify, ensure that you adddefault
as the first entry in the section. If it is not the first entry,cloud-user
is not created. By default, users are labeled as
unconfined_u
if there is not anselinux-user
value.#cloud-config users: - default - name: user2 gecos: User N. Ame selinux-user: staff_u groups: users,wheel ssh_pwauth: True ssh_authorized_keys: - ssh-rsa AA..vz user@domain.com chpasswd: list: | root:password cloud-user:mypassword user2:mypassword2 expire: False
Note-
The example places the user
user2
into two groups,users
andwheel
.
-
The example places the user
-
If you want
4.7. Running first boot commands with cloud-init
You can use the runcmd
and bootcmd
sections to execute commands during startup and initialization.
The bootcmd
section executes early in the initialization process and by default runs on every boot. The runcmd
section executes near the end of the process and is only executed during the first boot and initialization.
Procedure
Depending on the requirements of your datasource, edit the
user-data
file or add the following directive to thecloud.cfg.d
directory:NoteAll user directives include
#cloud-config
at the top of the file so thatcloud-init
recognizes the file as containing user directives. When you include directives in thecloud.cfg.d
directory, name the file*.cfg
, and always include#cloud-config
at the top of the file.Add the sections for
bootcmd
andruncmd
; include commands you wantcloud-init
to execute.#cloud-config users: - default - name: user2 gecos: User N. Ame groups: users chpasswd: list: | root:password fedora:myfedpassword user2:mypassword2 expire: False bootcmd: - echo New MOTD >> /etc/motd runcmd: - echo New MOTD2 >> /etc/motd
4.8. Adding additional sudoers with cloud-init
You can configure a user as a sudoer by adding a sudo
and groups
entry to the users
section.
Procedure
Depending on the requirements of your datasource, edit the
user-data
file or add the following directive to thecloud.cfg.d
directory:NoteAll user directives include
#cloud-config
at the top of the file so thatcloud-init
recognizes the file as containing user directives. When you include directives in thecloud.cfg.d
directory, name the file*.cfg
, and always include#cloud-config
at the top of the file.-
Add a
sudo
entry and specify the user access. For example,sudo: ALL=(ALL) NOPASSWD:ALL
allows a user unrestricted user access. Add a
groups
entry and specify the groups that include the user:#cloud-config users: - default - name: user2 gecos: User D. Two sudo: ["ALL=(ALL) NOPASSWD:ALL"] groups: wheel,adm,systemd-journal ssh_pwauth: True ssh_authorized_keys: - ssh-rsa AA...vz user@domain.com chpasswd: list: | root:password cloud-user:mypassword user2:mypassword2 expire: False
4.9. Setting up a static networking configuration with cloud-init
You can set up network configuration with cloud-init
by adding a network-interfaces
section to the metadata.
Red Hat Enterprise Linux provides its default networking service through NetworkManager
, a dynamic network control and configuration daemon that keeps network devices and connections up and active when they are available.
Your datasource might provide a network configuration. For details, see the cloud-init
section Network Configuration Sources.
If you do not specify network configuration for cloud-init
and have not disabled network configuration, cloud-init
tries to determine if any attached devices have a connection. If it finds a connected device, it generates a network configuration that issues a DHCP request on the interface. Refer to the cloud-init
documentation section Fallback Network Configuration for more information.
Procedure
The following example adds a static networking configuration.
Depending on the requirements of your datasource, edit the
user-data
file or add the following directive to thecloud.cfg.d
directory:NoteAll user directives include
#cloud-config
at the top of the file so thatcloud-init
recognizes the file as containing user directives. When you include directives in thecloud.cfg.d
directory, name the file*.cfg
, and always include#cloud-config
at the top of the file.Add a
network-interfaces
section.network: version: 1 config: - type: physical name: eth0 subnets: - type: static address: 192.0.2.1/24 gateway: 192.0.2.254
You can disable a network configuration by adding the following information to your metadata.
network: config: disabled
Additional resources
4.10. Configuring only a root user with cloud-init
You can configure your user data so that you have a root user and no other users.
Procedure
Depending on the requirements of your datasource, edit the
user-data
file or add the following directive to thecloud.cfg.d
directory:NoteAll user directives include
#cloud-config
at the top of the file so thatcloud-init
recognizes the file as containing user directives. When you include directives in thecloud.cfg.d
directory, name the file*.cfg
, and always include#cloud-config
at the top of the file.Create an entry for the user
root
in theusers
section.The simple example that follows includes a
users
section with only thename
option.users: - name: root chpasswd: list: | root:password expire: False
Optionally, set up SSH keys for the root user.
users: - name: root ssh_pwauth: True ssh_authorized_keys: - ssh-rsa AA..vz user@domain.com
4.11. Setting up storage with container-storage-setup in cloud-init
You can set up storage by referencing the container-storage-setup
utility within the write_files
module.
Procedure
Depending on the requirements of your datasource, edit the
user-data
file or add the following directive to thecloud.cfg.d
directory:NoteAll user directives include
#cloud-config
at the top of the file so thatcloud-init
recognizes the file as containing user directives. When you include directives in thecloud.cfg.d
directory, name the file*.cfg
, and always include#cloud-config
at the top of the file.Add or modify the
write_files
module to include the path to thecontainer-storage-setup
utility.The following example sets the size of the root logical volume to 6 GB rather than the default 3 GB.
write_files: - path: /etc/sysconfig/docker-storage-setup permissions: 0644 owner: root content: | ROOT_SIZE=6G
NotePrior to RHEL 7.4, container-storage-setup was called docker-storage-setup. If you are using OverlayFS for storage, as of RHEL 7.4 you can now use that type of file system with SELinux in enforcing mode.
4.12. Changing the system locale with cloud-init
You can configure the system location with the locale
module.
Procedure
-
Depending on the requirements of your datasource, edit the
meta-data
file. You can also add the following directive to thecloud.cfg
file or thecloud.cfg.d
directory: -
Add the
locale
directive, specifying the location. The following sample sets thelocale
toja_JP
(Japan) withUTF-8
encoding.
#cloud-config locale: ja_JP.UTF-8
Additional resources
4.13. cloud-init and shell scripts
You can add list values or string values to bootcmd
or runcmd
. You can also provide a shell script within userdata.
-
If you use a list value for
bootcmd
orruncmd
, each list item runs in turn usingexecve
. - If you use a string value, then the entire string runs as a shell script.
-
If you want to use
cloud-init
to run a shell script, you can provide a shell script (complete with shebang (#!) ) instead of providingcloud-init
with a.yaml
file.
Refer to Run commands on first boot for examples of how to put shell scripts in bootcmd
and runcmd
.
4.14. Preventing cloud-init from updating config files
When you create or restore an instance from a backup image, the instance ID changes. With the change in the instance ID, the cloud-init
utility updates configuration files. However, you can ensure that cloud-init
does not update certain configuration files when you create or restore from backup.
Procedure
Edit the
/etc/cloud/cloud.cfg
file, for example:# vi /etc/cloud/cloud.cfg
Comment out or remove the configuration that you do not want
cloud-init
to update when you restore your instance. For example, to avoid updating the SSH key file, remove-ssh
from thecloud_init_modules
section.cloud_init_modules: - disk_setup - migrator - bootcmd - write-files - growpart - resizefs - set_hostname - update_hostname - update_etc_hosts - rsyslog - users-groups # - ssh
Verification
To check the configuration files updated by
cloud-init
, examine the/var/log/cloud/cloud-init.log
file. Updated files are logged during instance startup with messages beginning withWriting to
. For example:2019-09-03 00:16:07,XXX - util.py[DEBUG]: Writing to /root/.ssh/authorized_keys - wb: [XXX] 554 bytes 2019-09-03 00:16:08,XXX - util.py[DEBUG]: Writing to /etc/ssh/sshd_config - wb: [XXX] 3905 bytes
4.15. Modifying a VM created from a KVM Guest Image after cloud-init has run
You can modify your cloud-init
configuration before rerunning the cloud-init
utility. When you launch a VM with the cloud-init
package installed and enabled, cloud-init
runs in its default state on the initial boot of the VM.
Procedure
- Log in to your VM.
-
Add or change directives, for example, modify the
cloud.cfg
file in the/etc/cloud
directory or add directives to the/etc/cloud/cloud.cfg.d
directory. Run the
cloud-init clean
command to clean directories so thatcloud-init
can rerun. You can also run the following commands as root to clean the VM:rm -Rf /var/lib/cloud/instances/ rm -Rf /var/lib/cloud/instance rm -Rf /var/lib/cloud/data/
NoteYou can save the cleaned image as a new image and use that image for multiple VMs. The new VMs will use updated
cloud-init
configuration to runcloud-init
.Rerun
cloud-init
or reboot the VM.cloud-init
reruns, implementing the configuration changes you made.
4.16. Modifying a VM for a specific datasource after cloud-init has run
You can modify your cloud-init
configuration before rerunning cloud-init
. This procedure uses OpenStack as an example datasource. Note that the exact steps you need to perform vary based on your datasource.
Procedure
-
Create and launch an instance for the OpenStack Platform. For information about creating instances for OpenStack, see Creating an instance. In this example, the virtual machine (VM) includes
cloud-init
, which runs upon boot of the VM. -
Add or change directives. For example, modify the
user-data.file
file that is stored on the OpenStack HTTP server. Clean the virtual machine. Run the following commands as root.
# rm -rf /etc/resolv.conf /run/cloud-init # userdel -rf cloud-user # hostnamectl set-hostname localhost.localdomain # rm /etc/NetworkManager/conf.d/99-cloud-init.conf
NoteYou can save the cleaned image as a new image and use that image for multiple virtual machines. The new virtual machines run
cloud-init
, using your updatedcloud-init
configuration.Rerun
cloud-init
or reboot the virtual machine.Cloud-init
reruns, implementing the configuration changes you made.
4.17. Troubleshooting cloud-init
After running the cloud-init
utility, you can troubleshoot the instance by examining the configuration and log files. After identifying the issue, rerun cloud-init
on your instance. You can run cloud-init
from the command line. For details, run the cloud-init --help
command.
Procedure
Review the
cloud-init
configuration files:-
Examine the
/etc/cloud/cloud.cfg
configuration file. Check which modules are included undercloud_init_modules
,cloud_config_modules
, andcloud_final_modules
. -
Check directives (
*.cfg
files) in the/etc/cloud/cloud.cfg.d
directory.
-
Examine the
Review the
/var/log/cloud-init.log
and/var/log/cloud-init-output.log
files for details on a specific issue. For example, if the root partition was not automatically extended, check log messages for thegrowpart
utility. If the file system was not extended, check log messages forresizefs
. For example:# grep resizefs /var/log/cloud-init.log
Notegrowpart
does not support LVM. If your root partition is based in LVM, the root partition is not automatically extended upon first boot.Rerun
cloud-init
commands as root:Rerun
cloud-init
with only the init modules:# /usr/bin/cloud-init -d init
Rerun
cloud-init
with all modules in the configuration:# /usr/bin/cloud-init -d modules
Delete the
cloud-init
cache and forcecloud-init
to run after boot:# rm -rf /var/lib/cloud/ && /usr/bin/cloud-init -d init
Clean directories and simulate a clean instance:
# rm -rf /var/lib/cloud/instances/ # rm -rf /var/lib/cloud/instance # rm -rf /var/lib/cloud/data/ # reboot
Rerun the
cloud-init
utility:# cloud-init init --local # cloud-init init
Additional resources