Cloud-init can be found on most cloud images provided by an elastic cloud vendor. If you are rolling/baking your own cloud image, you can typically install cloud-init via your distro's package manager.
Cloud-init executes in several key stages.
Stage-1 - Init Local
/etc/init/cloud-init-local.conf (Upstart)
- start on mounted MOUNTPOINT=/
/lib/systemd/system/cloud-init-local.service (Systemd)
- Before=shutdown.target multi-user.target cloud-config.target cloud-init.service
- After=local-fs.target systemd-journald.socket basic.target system.slice
Execute: /usr/bin/cloud-init init --local
Runs prior to network setup. It looks for a NoCloud data source at /var/lib/cloud/seed/nocloud/{meta-data,user-data,network-data,vendor-data}. If present, it will copy to /var/lib/cloud/instances/<instance-id> and execute all Python modules listed in init stage at /etc/cloud/cloud.cfg.
If a data source is not found at the above, it will look for VFAT or ISO device with LABEL="cidata". If present, it will copy to /var/lib/cloud/instances/<instance-id> and excute all Python modules listed in init stage at /etc/cloud/cloud.cfg.
Stage-2 - Init
/etc/init/cloud-init.conf (Upstart)
- start on mounted MOUNTPOINT=/
- stopped cloud-init-nonet (After network is up)
/lib/systemd/system/cloud-init.service (Systemd)
- Before=multi-user.target shutdown.target systemd-user-sessions.service cloud-config.target sshd-keygen.service ssh.service
- After=network-online.target basic.target cloud-init-local.service system.slice systemd-journald.socket local-fs.target
Execute: /usr/bin/cloud-init init
datasource_list: [ NoCloud, ConfigDrive, OpenNebula, Azure, AltCloud, OVF, MAAS, GCE, OpenStack, CloudSigma, Ec2, CloudStack, None ] (/etc/cloud/cloud.cfg.d/90_dpkg.cfg)
By default, first datasource listed is the priority. If metadata is discovered, it is copied to /var/lib/cloud/instances/<instance-id>/.
All Python modules listed in init stage (/etc/cloud/cloud.cfg) will execute.
Stage-3 - Config
/etc/init/cloud-config.conf (Upstart)
- start on (filesystem and started rsyslog)
/lib/systemd/system/cloud-config.service (Systemd)
- Before=cloud-final.service multi-user.target shutdown.target
- After=systemd-journald.socket network-online.target syslog.target system.slice basic.target cloud-config.target
Execute: /usr/bin/cloud-init modules --mode=config
All Python modules listed in config stage (/etc/cloud/cloud.cfg) will execute.
Stage-4 - Final
/etc/init/cloud-final.conf (Upstart)
- start on (stopped rc RUNLEVEL=[2345] (starts after rc.local)
- stopped cloud-config
/lib/systemd/system/cloud-final.service (Systemd)
- Before=multi-user.target shutdown.target
- After=rc-local.service network-online.target cloud-config.service basic.target system.slice systemd-journald.socket syslog.target
Execute: /usr/bin/cloud-init modules --mode=final
All Python modules listed in final stage (/etc/cloud/cloud.cfg) will execute.
Additional Info
- Most cloud-init Python modules have a default run frequency: per_always (run on every boot), per_instance (run only if it has never run with this specific instance-id), per_boot (run only once, regardless of the instance-id).
- Cloud-init keeps track of whether particular modules have been run by using semaphores. These get placed into the /var/lib/cloud/sem and /var/lib/cloud/sem/instances/<instance-id>/sem directories.
- One can specify which specific modules to run at specific stages and override default module frequency:
#cloud-config
cloud_init_modules:
- seed_random
- [bootcmd, once]
- [write-files, instance]
- growpart
- resizefs
- set_hostname
- update_hostname
- rsyslog
- users-groups
- ssh
cloud_config_modules:
- disable-ec2-metadata
- runcmd
- byobu
cloud_final_modules:
- scripts-per-boot
- scripts-per-instance
- [scripts-user, always]
Comments
comments powered by Disqus