To ensure that you can use the user data injection function to inject initial custom information into ECSs created from a private image (such as setting the ECS login password), install Cloud-Init on the ECS used to create the image.
Cloud-Init is open-source software. If the installed version has security vulnerabilities, you are advised to upgrade it to the latest version.
For details, see Check Whether Cloud-Init Has Been Installed.
You can install Cloud-Init using either of the following methods: (Recommended) Install Cloud-Init Using the Official Installation Package and Install Cloud-Init Using the Official Source Code Package and pip.
Perform the operations provided here to check whether Cloud-Init has been installed. The methods of checking whether Cloud-Init is installed vary depending on the OSs.
which cloud-init
/usr/bin/cloud-init
/usr/bin/which: no cloud-init in (/usr/local/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin)
which cloud-init
cloud-init-0.7.5-10.el6.centos.2.x86_64
To confirm Cloud-Init is really not installed, you are advised to run rpm -qa |grep cloud-init to check again. If either of which cloud-init and rpm -qa |grep cloud-init shows that Cloud-Init has been installed, Cloud-Init is installed.
If Cloud-Init has been installed, perform the following operations:
cd /root/.ssh
rm authorized_keys
cd /home/centos/.ssh
rm authorized_keys
sudo rm -rf /var/lib/cloud/*
After the operations are complete, do not restart the ECS. Otherwise, you need to perform these operations again.
The method of installing Cloud-Init on an ECS varies depending on the OS. Perform the installation operations as user root.
The following describes how to install Cloud-Init on an ECS running SUSE Linux, CentOS, Fedora, Debian, and Ubuntu. For other OS types, install the required type of Cloud-Init. For example, you need to install coreos-cloudinit on ECSs running CoreOS.
Paths for obtaining the Cloud-Init installation package for SUSE Linux
Select the required repo installation package in the provided paths.
Take SUSE Enterprise Linux Server 12 as an example. Perform the following steps to install Cloud-Init:
zypper ar https://ftp5.gwdg.de/pub/opensuse/repositories/Cloud:/Tools/SLE_12_SP3/Cloud:Tools.repo
zypper refresh
zypper install cloud-init
chkconfig cloud-init-local on; chkconfig cloud-init on; chkconfig cloud-config on; chkconfig cloud-final on
service cloud-init-local status; service cloud-init status; service cloud-config status; service cloud-final status
systemctl enable cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service
systemctl status cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service
For SUSE and openSUSE, perform the following steps to prevent DHCP from changing the hostname:
vi etc/sysconfig/network/dhcp
Table 1 lists the Cloud-Init installation paths for CentOS. Select an epel-release installation package matching your OS.
OS Type | Version | How to Obtain |
|---|---|---|
CentOS | 6 32-bit | |
6 64-bit | ||
7 64-bit |
yum install Cloud-Init installation package address/epel-release-x-y.noarch.rpm
yum install cloud-init
Cloud-Init installation package address indicates the address of the Cloud-Init epel-release installation package, and x-y indicates the version of the Cloud-Init epel-release required by the current OS. Replace them with the actual values according to Table 1.
yum install https://archives.fedoraproject.org/pub/archive/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum install https://archives.fedoraproject.org/pub/archive/epel/7/x86_64/Packages/e/epel-release-7-14.noarch.rpm
systemctl enable cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service
systemctl status cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service
Before installing Cloud-Init, ensure that the network installation source has been configured for the OS by checking whether the /etc/yum.repo.d/fedora.repo file contains the installation source address of the software package. If the file does not contain the address, configure the address by following the instructions on the Fedora official website.
yum install cloud-init
systemctl enable cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service
systemctl status cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service
Before installing Cloud-Init, ensure that the network installation source has been configured for the OS by checking whether the /etc/apt/sources.list file contains the installation source address of the software package. If the file does not contain the address, configure the address by following the instructions on the Debian or Ubuntu official website.
apt-get update
apt-get install cloud-init
systemctl enable cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service
systemctl status cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service
The following operations use Cloud-Init 0.7.9 as an example to describe how to install Cloud-Init.
Download cloud-init-0.7.9.tar.gz from the following path:
If the ~/.pip/ directory does not exist, run the mkdir ~/.pip command to create it.
[global]index-url = https://<$mirror>/simple/trusted-host = <$mirror>
Replace <$mirror> with a public network PyPI source.
Public network PyPI source: https://pypi.python.org/
pip install [--upgrade] /home/cloud-init-0.7.9.tar.gz
For details about how to install a Cloud-Init source code package, see Cloud-Init Documentation.
cloud-init 0.7.9
chkconfig --add cloud-init-local; chkconfig --add cloud-init; chkconfig --add cloud-config; chkconfig --add cloud-final
chkconfig cloud-init-local on; chkconfig cloud-init on; chkconfig cloud-config on; chkconfig cloud-final on
service cloud-init-local status; service cloud-init status; service cloud-config status; service cloud-final status
systemctl enable cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service
systemctl status cloud-init-local.service cloud-init.service cloud-config.service cloud-final.service
If you install Cloud-Init using the official source code package and pip, note that:
useradd syslog
groupadd adm
usermod -g adm syslog
Run the following command to open the sshd_config file using the vi editor:
vi /etc/ssh/sshd_config
For SUSE and openSUSE, change the values of the following parameters in the sshd_config file to no:
vi /etc/cloud/cloud.cfg
This step is only for Cloud-Init 18.3 or later.
Figure 1 Example configuration

For Ubuntu and Debian, set the value of manage_etc_hosts in the /etc/cloud/cloud.cfg file to localhost. Otherwise, switching to user root may time out. For details about how to change the hostname of a cloud server, configure the SSH key, use Cloud-Init to add a user, and configure swap partitions, see Cloud-Init Configuration FAQ.
Take Ubuntu as an example.
cat /etc/cloud/set_linux_random_password.sh
The file content is as follows:
#!/bin/bashpassword=$(cat /dev/urandom | tr -dc 'A-Za-z0-9!@#$%&+=' | head -c 9)echo "linux:$password" | chpasswdsed -i -e '/^Login/d' /etc/issuesed -i -e '/^Initial/d' /etc/issuesed -i -c -e '/^$/d' /etc/issueecho -e "\nInitial login with linux:$password\n" >> /etc/issue
You can run the chmod +x /etc/cloud/set_linux_random_password.sh command to add execute permissions of set_linux_random_password.sh.
echo -e '\e[1;31m#################################\\e[0m' > /etc/motd
echo -e '\e[1;31m# Important !!! #\e[0m' >> /etc/motd
echo -e '\e[1;31m# Please change password for user linux after first login. #\e[0m' >> /etc/motd
echo -e '\e[1;31m#################################\e[0m' >> /etc/motd
echo -e '' >> /etc/motd
Ensure that the configuration file format (such as alignment and spaces) is consistent with the provided example.
system_info:# This will affect which distro class gets useddistro: rhel# Default user name + that default users groups (if added/used)default_user:name: linux #Username for loginlock_passwd: False #Login using a password is enabled. Note that some OSs use value 0 to enable the password login.gecos: Cloud Usergroups: users #Optional. Add users to other groups that have been configured in /etc/group.passwd: $6$I63DBVKK$Zh4lchiJR7NuZvtJHsYBQJIg5RoQCRLS1X2Hsgj2s5JwXI7KUO1we8WYcwbzeaS2VNpRmNo28vmxxCyU6LwoD0sudo: ["ALL=(ALL) NOPASSWD:ALL"] # Assign the root rights to the user.shell: /bin/bash # Execute shell in bash mode.# Other config here will be given to the distro class and/or path classespaths:cloud_dir: /var/lib/cloud/templates_dir: /etc/cloud/templates/ssh_svcname: sshdbootcmd:- [cloud-init-per, instance, password, bash,/etc/cloud/set_linux_random_password.sh]
The value of passwd is encrypted using SHA512 (which is used as an example). For more details, see https://cloudinit.readthedocs.io/en/latest/topics/examples.html.
For details about how to encrypt a password and generate ciphertext, see the following (encrypting password cloud.1234 is used as an example):
[root@** ~]# python -c "import crypt, getpass, pwd; print crypt.mksalt()"$6$I63DBVKK[root@** ~]# python -c "import crypt, getpass, pwd; print crypt.crypt('cloud.1234', '\$6\$I63DBVKK')"$6$I63DBVKK$Zh4lchiJR7NuZvtJHsYBQJIg5RoQCRLS1X2Hsgj2s5JwXI7KUO1we8WYcwbzeaS2VNpRmNo28vmxxCyU6LwoD0
Add the following information to the last line of /etc/cloud/cloud.cfg:
datasource_list: [ OpenStack ]datasource:OpenStack:metadata_urls: ['http://169.254.169.254']max_wait: 120timeout: 5
echo "NOZEROCONF=yes" >> /etc/sysconfig/network
If the Cloud-Init version is 0.7.9 or later, add the following content to /etc/cloud/cloud.cfg:
network:config: disabled
The added content must be in the YAML format.
Figure 2 Disabling Cloud-Init's network configuration capability

Move ssh from the bottom to the top to speed up the SSH login.
Figure 3 Speeding up the SSH login to the ECS

vi /usr/lib/python2.7/site-packages/cloudinit/sources/__init__.py
Press i to enter editing mode. Modify the file content as follows based on the keyword toks:
if toks:toks = str(toks).split('.')else:#toks = ["ip-%s" % lhost.replace(".", "-")] # Comment out this line.toks = lhost.split(".novalocal") # Add this line.if len(toks) > 1:hostname = toks[0]#domain = '.'.join(toks[1:]) # Comment out this line.else:hostname = toks[0]if fqdn and domain != defdomain:return hostname#return "%s.%s" % (hostname, domain) # Comment out this line.else:return hostname
After the modification is complete, press Esc to exit the editing mode and enter :wq! to save the settings and exit.
Figure 4 Modifying the __init__.py file

cd /usr/lib/python2.7/site-packages/cloudinit/sources/
rm -rf __init__.pyc
rm -rf __init__.pyo
rm -rf /var/lib/cloud/*
rm -rf /var/log/cloud-init*
vim /etc/cloud/cloud.cfg.d/05_logging.cfg
Figure 5 Setting the parameter value to cloudLogHandler

Run the following command to check whether Cloud-Init has been properly configured:
cloud-init init --local
If Cloud-Init has been properly installed, the version information is displayed and no error occurs. For example, messages indicating lack of files will not be displayed.
(Optional) Run the following command to set the password validity period to the maximum:
chage -M 99999 $user_name
user_name is a system user, such as user root.
You are advised to set the password validity period to 99999.