Cloud-init

Cloud-Init : La Pierre Angulaire de l'Automatisation Cloud Moderne

cloud-init logo

TL;DR

Cloud-init (github) est l'outil standard open source pour l'initialisation automatisée des instances cloud.

Il transforme une image OS générique en instance configurée (réseau, stockage, sécurité etc.) dès le premier démarrage dans un environnement Cloud (OpenStack, Proxmox, Incus, VMWare, AWS, Azure, GCP).

Introduction

Dans l'écosystème cloud contemporain, cloud-init s'est imposé comme le standard de facto pour l'initialisation automatisée des instances virtuelles (cloud ou VM).

Développé initialement par Canonical pour Ubuntu, cet outil open source résout une problématique fondamentale : transformer une image générique (officielle ou custom) de système d'exploitation en une instance parfaitement configurée dès le premier démarrage, s'avérant crucial pour la scalabilité et la reproductibilité des déploiements cloud.

Domaines d'Application et Cas d'Usage

Automatisation à l'initialisation d'une VM

L'outil permet l'implémentation de politiques de sécurité dès l'amorçage (réseau, pare-feu, clés SSH, durcissement, etc.).

Il permet également d'installer et configurer des applications/services mais aussi d'effectuer des actions d'intégration dans l'infrastructure tel que l'enregistrement d'instances auprès de load balancers ou la configuration de clusters pour la haute disponibilité.

Intégration avec les outils d'IaC

cloud-init s'intègre nativement aux outils IaC comme OpenTofu et Terraform, formant une chaîne d'automatisation complète :

  • OpenTofu/Terraform déploie l'infrastructure (création de VM, réseaux, stockage)
  • Cloud-init configure dynamiquement les instances au premier démarrage (utilisateurs, sécurité, packages)

Cette synergie permet :

  • 🚀 Déploiements reproductibles : Une même configuration cloud-init s'applique sur AWS, Proxmox, Azure via Terraform
  • ⚙️ Personnalisation contextuelle : Injection de variables Terraform (IPs, secrets) dans les scripts cloud-init
  • 🔁 Workflows idempotents : cloud-init ne s'exécute qu'au premier boot, préservant l'état géré par Terraform

Concepts, architecture et mécanique interne

Datasources

Les datasources de cloud-init sont les mécanismes par lesquels cloud-init récupère les données de configuration nécessaires à l’initialisation d’une instance.

Le datasource détermine et comment cloud-init va chercher les fichiers de configuration (user-data, meta-data, vendor-data).
Selon l’environnement (AWS, Azure, Proxmox, OpenStack, etc.), ces données peuvent être injectées via un service HTTP, un CD-ROM virtuel (NoCloud), un disque attaché, ou d’autres moyens.

Configuration

L'utilisateur de cloud-init va pouvoir configurer sa VM (ou instance cloud) grâce à différents fichiers de configuration yaml que l'on regroupe en 3 types :

  • meta-data : Informations concernant la VM (hostname, instance ID, clés SSH publiques)
  • user-data (doc): Configurations au format cloud-config (exemples) définies par l'utilisateur, incluant les scripts d'initialisation, les configurations système et les manifestes d'applications. D'autres formats sont supportés.
  • vendor-data (doc): Données injectées par le fournisseur cloud pour des configurations spécifiques à la plateforme mais cette config peut être écrasée dans par le user-data.

Modules cloud-init

Les fichiers de configuration précédent reposent sur des modules, qui sont des unités fonctionnelles autonomes qui exécutent des tâches spécifiques pendant le processus d'initialisation.

Cycle de vie d'un module

  1. Détection :
    cloud-init identifie les modules à exécuter via le fichier /etc/cloud/cloud.cfg
  2. Activation :
    Chaque module est activé par des clés spécifiques dans le user-data (la config yaml
  3. Exécution :
    Les modules s'exécutent selon leur fréquence définie (PER_INSTANCE, PER_BOOT, PER_ONCE)
  4. Journalisation :
    Les résultats sont enregistrés dans /var/log/cloud-init.log

Fréquence d'exécution des modules et sémaphores

Un sémaphore cloud-init est un fichier marqueur créé par cloud-init pour chaque module exécuté, afin de garder une trace de son exécution et d’empêcher qu’il ne soit relancé plus souvent que prévu selon sa fréquence (per-once, per-instance, per-boot).

Sémaphores PER_INSTANCE

Le module s’exécute une fois à chaque nouvelle instance (donc au premier boot d’une VM ou d’un clone), mais pas lors des redémarrages suivants et un instance-id est attribué à cette VM.

Les fichiers sémaphores pour les modules avec fréquence PER_INSTANCE sont stockés dans /var/lib/cloud/instances/<instance-id>/sem/ (noter le dossier instance-id)

Ces fichiers incluent :

  • config_users_groups
  • config_set_hostname
  • config_ssh

Sémaphores PER_ONCE (Globaux)

Le module s’exécute une fois pour toute

Le module s’exécute une seule fois sur la machine, même si elle est clonée ou redémarrée.
Les fichiers sémaphores pour les modules avec fréquence PER_ONCE sont stockés dans /var/lib/cloud/sem/
(chemin différent des sémaphores PER_INSTANCE, sans le dossier instance-id ).

Sémaphores PER_BOOT

Le module s’exécute à chaque démarrage de la machine, donc à chaque reboot.

Les modules avec fréquence PER_BOOT ou ALWAYS ne créent pas de fichiers sémaphores persistants, car ils s'exécutent à chaque démarrage

Configuration des Fréquences d'Exécution

Pour modifier la fréquence d'un module, la méthode recommandée reste la modification du fichier /etc/cloud/cloud.cfg

## exemple de section de /etc/cloud/cloud.cfg
cloud_final_modules:
  - [phone_home, always]    # Force l'exécution à chaque boot
  - [final_message, once]   # Exécution unique
  - scripts_user            # Fréquence par défaut (PER_INSTANCE)

Les bonnes pratiques actuelles privilégient l'utilisation des commandes CLI officielles (cloud-init clean, cloud-init single) plutôt que la manipulation manuelle des fichiers sémaphores.

Configurabilité avancée des modules

Au-delà de la fréquence d'exécution, les modules offrent plusieurs niveaux de configuration :

  1. Paramétrage via user-data
  2. Personnalisation du comportement
  3. Activation conditionnelle (utiliser les cloud-init query pour une activation dynamique)
  4. Override de configuration en créant des fichiers dans /etc/cloud/cloud.cfg.d/ pour désactiver des modules ou modifier l'ordre d'exécution

Lifecycle de cloud-init en 5 phases

L'exécution de cloud-init s'articule autour de 5 phases distinctes (voir le diagramme Boot stages) matérialisé sous forme de sections (⚡) dans le fichier /etc/cloud/cloud.cfg . Il est possible de définir des listes de modules à exécuter dans chacune de ces phases, modules qui peuvent etre configurés dans les fichiers *.yaml.

Voici les 5 phases d'exécution de cloud-init :

  1. Detect
    📜 script /usr/lib/cloud-init/ds-identify
    Détecte la plateforme d'exécution, il est lancé par le generator systemd de cloud-init (cloud-init-generator), qui s’exécute très tôt dans le processus de boot. Cette étape permet à cloud-init de sélectionner la bonne datasource selon l’environnement (cloud public, Proxmox, etc.), ou de s’auto-désactiver s’il n’y a pas de datasource détectée.
  2. Local
    ⚙️ service cloud-init-local
    📁 fichier network-config*.yaml (si disponible)
    Le service est exécutée le plus tot possible, cette phase localise les sources de données locales et applique la configuration réseau de base.
    Elle bloque l'activation du réseau pour éviter les conflits avec d'anciennes configurations.
  3. Network
    ⚙️ service cloud-init-network
    ⚡ section cloud_init_modules
    📁 fichiers network-config*.yaml et meta-data*.yaml (hostname)
    Une fois le réseau opérationnel, ce service exécute les modules (parfois accessible à travers le réseau) définis dans .
    Cette étape exécute aussi les modules disk_setup et mounts qui peuvent partitionner et formater les disques et configurer les points de montage (par exemple dans le fichier /etc/fstab).
  4. Config
    ⚙️ service cloud-config
    ⚡ section cloud_config_modules
    📁 fichiers user-data*.yaml (scripts, packages) et vendor-data*.yaml
    Cette phase traite les modules responsables de la configuration applicative, de la gestion des services et de l'intégration avec les outils de configuration management.
  5. Final
    ⚙️ service cloud-final.service)
    ⚡ section cloud_final_modules
    📁 fichiers user-data (parties finales)
    La dernière phase exécute les modules incluant les tâches de post-configuration, les notifications de fin d'initialisation et les scripts utilisateur finaux.

Outillage et Debuggage Cloud-Init

Commandes d'Analyse et de Diagnostic

Cloud-init fournit plusieurs outils intégrés pour l'analyse et le débogage :

cloud-init status --long # état d'exécution
cloud-init schema --config-file fichier_conf.yaml # validation de la config 

cloud-init analyze show 
cloud-init analyze blame # temps d'exécution des unité d'exécution
cloud-init analyze dump

Voir doc de cloud-init analyze

screenshot cloud-init analyze show

Fichiers de Logs et Configuration

Les fichiers de configuration se trouvent dans :

  • /etc/cloud/cloud.cfg
  • /etc/cloud/cloud.cfg.d/*

Les fichiers de logs principaux sont localisés dans :

  • /var/log/cloud-init.log : Log détaillé avec sortie de débogage
  • /var/log/cloud-init-output.log : Capture la sortie de chaque phase
  • /run/cloud-init/ : Logs d'activation/désactivation et détection de plateforme

Fichiers plus spécifiques :

  • /var/lib/cloud/instance/user-data.txt : Inspection des métadonnées
  • /run/cloud-init/ds-identify.log : Logs d'exécution de ds-identify
  • grep datasource_list /etc/cloud/cloud.cfg.d/* 2>/dev/null : Liste les Datasources configurés

Vérification des services systemd :

  • systemctl status cloud-*

Redémarrage et Nettoyage

Pour forcer une nouvelle exécution de cloud-init :

cloud-init clean --logs --reboot
cloud-init single --name cc_ssh --frequency always
cloud-init init --local --debug
cloud-init modules --mode config --debug

La commande clean supprime les sémaphores stockés dans /var/lib/cloud/instance/sem/ (qui s'ils sont présent, empêchent la ré-exécution des modules).

Suppression de cloud-init

Procédure pour suppression définitive de cloud-Init dans une VM :

sudo apt purge cloud-init cloud-initramfs-dyn-netconf cloud-initramfs-copymods cloud-guest-utils -y
sudo apt autoremove -y

sudo rm -rf /etc/cloud/
sudo rm -rf /var/lib/cloud/

# Vérifier l'absence de paquets cloud-*
dpkg -l | grep cloud-

# Vérifier qu'il n'y a plus de services 
systemctl list-units | grep -i cloud 

Désactivation temporaire

sudo systemctl disable cloud-init
sudo systemctl mask cloud-init

Désactivation définitive de cloud-init

Si le fichier /etc/cloud/cloud-init.disabled existe ou si l’option cloud-init=disabled est présente dans la ligne de commande du noyau, le generator n’active pas cloud-init, et les services ne sont pas lancés.

Intégration Cloud-Init dans Proxmox VE

Mécanisme NoCloud dans Proxmox

Sur Proxmox (datasource NoCloud), un ISO est généré et monté comme CD-ROM virtuel. Cet ISO contient les fichiers user-data, meta-data et éventuellement network-config (tous souvent en YAML). cloud-init lit ces fichiers via le datasource NoCloud et applique la configuration au système invité.

CD-ROM virtuel dans la VM cloné

Cette approche locale évite la dépendance à un service de métadonnées réseau, rendant cloud-init fonctionnel même dans des environnements isolés.

Cas particulier des LXC

Il existe des alternatives pour les LXC comme par exemple lancer cloud-init via un hook Proxmox :

# /etc/pve/lxc/<CTID>.conf
hookscript: local:snippets/cloud-init-hook.sh

Architecture d'Intégration

L'implémentation Proxmox génère dynamiquement un fichier ISO contenant les fichiers user-data, meta-data et network-config. Ce processus s'articule autour de deux mécanismes exclusifs (l'un ou l'autre) :

  • Configuration GUI dans le Template de VM ou la VM : définition des paramètres de base (utilisateur, clés SSH, réseau) dans le menu Cloud-Init.
  • Configuration personnalisée : Fichiers YAML stockés dans /var/lib/vz/snippets/ et injectés via qm set ... --cicustom ... (voir doc Proxmox). Attention cette configuration personnalisée, permet un paramétrage beaucoup plus fin qu'avec la GUI, mais elle la remplace totalement.

Workflow de Déploiement

Le processus de déploiement suit cette séquence :

  1. Téléchargement d'une image cloud-init de référence
  2. Copie de cette image dans un format exploitable par Proxmox
  3. Configuration de cette VM qui servira de template
  4. Création du template depuis cette VM
  5. Configuration du lecteur cloud-init (--ide2)
  6. Personnalisation via l'interface ou fichiers YAML
  7. Puis génération de l'ISO via qm cloudinit update

Équivalent Windows : Cloudbase-Init

Présentation de Cloudbase-Init

cloudbase-init est l'équivalent Windows de cloud-init, développé pour apporter les fonctionnalités d'initialisation cloud aux systèmes Windows. Il supporte Windows Server 2025 à 2012 R2 ainsi que Windows Client 11 à 8.

Architecture et Fonctionnement

Cloudbase-Init fonctionne selon un modèle à deux étapes :

  1. Services : Lecture des métadonnées depuis diverses sources (HTTP, ConfigDrive, EC2, Azure)
  2. Plugins : Exécution des tâches de configuration basées sur ces métadonnées

Intégration avec Sysprep

L'écosystème Windows utilise une approche combinée :

  • sysprep : Généralise l'image Windows en supprimant les identifiants uniques
  • cloudbase-init : Applique la configuration personnalisée au premier démarrage
  • unattend.xml : Fichier de réponse pour l'installation automatisée

Différences Clés de Cloudbase-Init avec Cloud-Init

AspectCloud-Init (Linux)Cloudbase-Init (Windows)
InstallationIntégré dans les images cloudInstallation manuelle requise
ConfigurationYAML cloud-configPowerShell, CMD, Bash
ArchitectureModules Python natifsService Windows avec plugins
Démarragesystemd servicesService Windows + Task Scheduler
MétadonnéesSupport natif multi-cloudAdapté via services spécialisés

Support Multi-OS de Cloud-Init

Distributions Unix/Linux Supportées

Cloud-init offre un support étendu pour difféerents systèmes (liste sur docs.openstack.org) :

  • Linux : Ubuntu, Debian, RHEL/CentOS, SLES/openSUSE, Arch Linux, Alpine Linux
  • BSD : FreeBSD, NetBSD, OpenBSD, DragonFlyBSD
  • macOS n'est pas officiellement supporté par cloud-init, cependant, des projets communautaires proposent des alternatives : macos-init

Considérations Opérationnelles et Limitations

Défis et Limitations

Malgré sa robustesse, cloud-init présente certaines limitations :

  • Sensibilité au format YAML : Les erreurs de syntaxe ou d'indentation peuvent provoquer des échecs silencieux
  • Dépendance réseau : Certains datasources nécessitent une connectivité réseau fonctionnelle
  • Complexité de débogage : L'exécution distribuée sur plusieurs phases complique le diagnostic des problèmes

Conclusion

cloud-init représente bien plus qu'un simple outil d'automatisation : il constitue l'épine dorsale de l'infrastructure cloud moderne.

Pour les architectes et ingénieurs cloud, approfondir la compréhension de ses mécanismes internes constitue un prérequis essentiel à la conception d'infrastructures résilientes et scalables.