Aller au contenu

Maîtriser Cloud Init

Mise à jour :

cloud-init est un outil largement utilisé pour automatiser la configuration initiale des instances de VM dans le cloud lors de leur premier démarrage. Il permet de définir des utilisateurs, configurer le réseau, installer des paquets et exécuter des scripts dès l’initialisation, tout cela sans intervention manuelle.

Les fonctionnalités principales de cloud-init

cloud-init propose une large gamme de modules pour automatiser les premières étapes de configuration des instances cloud. Il permet notamment :

  • La création des utilisateurs et des groupes : Vous pouvez ajouter des utilisateurs, définir des mots de passe, et générer des clés SSH automatiquement.
  • La configuration du réseau : Configuration automatique des interfaces réseau, des adresses IP et des routes.
  • L’installation des paquets : cloud-init peut installer les logiciels et dépendances nécessaires via les gestionnaires de paquets comme apt ou yum.
  • L’exécution de scripts de démarrage : Vous pouvez inclure des scripts personnalisés qui seront exécutés à la fin de l’initialisation pour finaliser la configuration de l’instance.

Ces fonctionnalités permettent de déployer des machines prêtes à l’emploi sans intervention manuelle, ce qui facilite grandement la gestion de l’infrastructure en cloud.

Fonctionnement de cloud-init

cloud-init divise l’initialisation des instances cloud en plusieurs phases distinctes, ce qui permet d’organiser efficacement les différentes étapes de configuration. Chaque phase a un rôle spécifique, que ce soit pour configurer le réseau, installer des logiciels ou exécuter des scripts. Voici une liste des principales phases, accompagnée d’une explication de leur rôle et des actions typiques effectuées lors de chacune d’elles.

Voici les différentes phases de cloud-init sous forme de liste :

  1. Phase locale (local stage)

    • Objectif : Collecter les informations locales nécessaires avant la configuration réseau.
    • Actions : Recherche des sources de données locales et initialisation basique.
  2. Phase réseau (network stage)

    • Objectif : Configurer les interfaces réseau de l’instance.
    • Actions : Configuration des interfaces, attribution des adresses IP, et activation des DNS.
  3. Phase de configuration (config stage)

    • Objectif : Appliquer les configurations système, installer des paquets et configurer les utilisateurs.
    • Actions : Création d’utilisateurs, configuration SSH, installation de logiciels et gestion des services.
  4. Phase finale (final stage)

    • Objectif : Exécuter les derniers scripts et finaliser la configuration.
    • Actions : Exécution des commandes finales, démarrage des services, envoi de notifications.
  5. Redémarrage optionnel

    • Objectif : Redémarrer l’instance si nécessaire.
    • Actions : Redémarrage selon la configuration, si cela est requis pour appliquer certaines modifications.

Ces phases permettent de structurer et de gérer l’initialisation des instances cloud en garantissant que chaque étape soit exécutée correctement avant de passer à la suivante.

Créer un fichier de configuration cloud-init

Pour utiliser cloud-init, vous devez créer un fichier de configuration appelé cloud-config, généralement écrit en YAML. Ce fichier contient les directives qui seront exécutées lors du premier démarrage de l’instance. Voici un exemple basique d’un fichier cloud-config :

#cloud-config
users:
- name: ansible
groups: sudo
shell: /bin/bash
ssh_authorized_keys:
- ssh-rsa AAAAB3Nz...
sudo: ALL=(ALL) NOPASSWD:ALL
package_update: true
package_upgrade: true
packages:
- nginx
- git
- openssh-server

Ce fichier de configuration exécute plusieurs tâches lors du démarrage de l’instance :

  • Création d’utilisateurs : Dans cet exemple, un utilisateur ansible est ajouté avec des droits sudo et une clé SSH autorisée. Cela permet une connexion sécurisée à l’instance sans avoir à configurer manuellement chaque utilisateur.

  • Mise à jour et installation des paquets : Le bloc package_update et package_upgrade s’assure que le système est à jour dès le démarrage. Les paquets comme nginx openssh-serveret git sont ensuite installés automatiquement.

Pour valider votre fichier avant de le déployer, vous pouvez utiliser la commande suivante :

Terminal window
sudo cloud-init schema --config-file cloud-config.yaml
Valid schema cloud-config.yaml

Si le message Valid schema cloud-config.yaml s’affiche, cela signifie que votre fichier est valide. Sinon des informations supplémentaires vous seront fournies pour vous aider à corriger les erreurs.

Tester votre config cloud-init avec des instances Incus

Les conteneurs INCUS prennent en charge cloud-init !

Pour configurer des instances Incus avec cloud-init, vous devez utiliser des images qui incluent cloud-init. Ces images peuvent être obtenues via le serveur d’images d’Incus en utilisant celles dont le nom se termine par /cloud.

Terminal window
incus image list images: architecture=x86_64 /cloud -c lat
+------------------------------------+--------------+-----------------+
| ALIAS | ARCHITECTURE | TYPE |
+------------------------------------+--------------+-----------------+
| almalinux/8/cloud (1 more) | x86_64 | CONTAINER |
+------------------------------------+--------------+-----------------+
| almalinux/8/cloud (1 more) | x86_64 | VIRTUAL-MACHINE |
+------------------------------------+--------------+-----------------+
| almalinux/9/cloud (1 more) | x86_64 | CONTAINER |
+------------------------------------+--------------+-----------------+
...
+------------------------------------+--------------+-----------------+
| ubuntu/jammy/cloud (3 more) | x86_64 | CONTAINER |
+------------------------------------+--------------+-----------------+
| ubuntu/jammy/cloud (3 more) | x86_64 | VIRTUAL-MACHINE |
+------------------------------------+--------------+-----------------+
| ubuntu/noble/cloud (3 more) | x86_64 | CONTAINER |
+------------------------------------+--------------+-----------------+
| ubuntu/noble/cloud (3 more) | x86_64 | VIRTUAL-MACHINE |
+------------------------------------+--------------+-----------------+

Lors de la création d’un container, vous pouvez ajouter un fichier de configuration cloud-init avec des paramètres comme la mise à jour des paquets, l’ajout d’utilisateurs ou la configuration réseau.

Exemple de commande pour appliquer un fichier cloud-init lors du lancement d’une VM :

Terminal window
incus launch images:ubuntu/24.04/cloud test --config=cloud-init.user-data="$(cat cloud-config.yaml)"

Utilisation d’un profil Incus

L’utilisation des profils Incus permet de standardiser et simplifier la configuration de vos containers et machines virtuelles, notamment lorsqu’il s’agit d’appliquer des configurations cloud-init. En configurant un profil, vous pouvez centraliser les paramètres et appliquer les mêmes configurations à plusieurs instances, ce qui est particulièrement utile pour des configurations répétitives.

Création d’un profil Incus pour cloud-init

Pour commencer, vous pouvez créer un profil dédié à cloud-init dans lequel vous spécifierez toutes les options de configuration de démarrage. Voici un exemple de création de profil :

Terminal window
incus profile create cloud-init-profile

Ensuite, vous pouvez éditer ce profil pour inclure les directives cloud-init nécessaires. Utilisez la commande suivante pour modifier le profil :

Terminal window
incus profile edit cloud-init-profile

Dans l’éditeur YAML, ajoutez les options de cloud-init comme suit :

config:
cloud-init.user-data: |
package_update: true
package_upgrade: true
packages:
- nginx
- git
runcmd:
- [touch, /tmp/cloud-init-complete]

Ce fichier cloud-config configure les instances pour mettre à jour et installer des paquets comme nginx et git au démarrage, et exécute une commande pour créer un fichier de suivi une fois les scripts terminés.

Application du profil à une instance

Une fois le profil configuré, vous pouvez l’appliquer à une instance lors de sa création. Par exemple :

Terminal window
incus launch images:ubuntu/24.04/cloud mon-instance--profile default --profile cloud-init-profile

Cela permet de créer une instance basée sur une image Ubuntu avec cloud-init activé, tout en appliquant les configurations définies dans le profil.

Vérification de l’exécution de cloud-init

Après la création de l’instance, vous pouvez vérifier si cloud-init a bien terminé son exécution avec la commande suivante dans le container ou la VM :

Terminal window
incus shell mon-instance
cloud-init status --wait
status: done

Cela vous permettra de savoir si cloud-init a fini d’exécuter toutes les tâches configurées dans le fichier cloud-config.

Liste exhaustive des modules cloud-init

cloud-init est organisé en différents modules qui sont exécutés lors des différentes phases de l’initialisation d’une instance. Ces modules permettent de configurer et personnaliser diverses parties du système, allant de la gestion des utilisateurs à l’installation de logiciels, en passant par la configuration réseau. Voici une liste des principaux modules disponibles dans cloud-init, regroupés par phase.

Modules cloud_init_modules (phase réseau)

Ces modules s’exécutent au tout début du processus, généralement avant que le réseau ne soit configuré. Ils sont responsables de la préparation des fichiers système et de la configuration réseau de base.

  • bootcmd: Exécute les commandes spécifiées avant toute autre configuration.
  • write-files: Crée des fichiers à partir de la configuration fournie.
  • resizefs: Redimensionne les systèmes de fichiers après leur création.

Modules cloud_config_modules (phase configuration)

Cette phase intervient après l’activation du réseau. Ces modules permettent d’appliquer la configuration système, d’ajouter des utilisateurs, de configurer SSH, et d’installer des paquets.

  • ssh: Configure les clés SSH pour les utilisateurs.
  • users-groups: Crée et configure les utilisateurs et les groupes.
  • set_hostname: Définit le nom d’hôte de l’instance.
  • package-update-upgrade-install: Met à jour et installe des paquets spécifiques via le gestionnaire de paquets.
  • runcmd: Exécute des commandes ou des scripts après que le réseau a été configuré.
  • apt-configure: Configure les dépôts APT (pour Ubuntu/Debian).

Modules cloud_final_modules (phase finale)

Ces modules sont exécutés à la toute fin du processus de configuration, une fois que tout est en place. Ils permettent d’ajuster les services système ou d’exécuter des scripts finaux.

  • phone-home: Envoie une notification à un serveur distant une fois la configuration terminée.
  • scripts-per-instance: Exécute des scripts spécifiques à l’instance.
  • scripts-per-once: Exécute des scripts une seule fois au démarrage.

Modules supplémentaires

Certains modules spécifiques peuvent être activés pour des besoins particuliers, comme la gestion des utilisateurs ou l’exécution de Ansible :

  • cc_ansible: Installe et configure Ansible pour exécuter des playbooks via le mode pull.
  • chef: Installe et exécute des recettes Chef.
  • salt-minion: Configure et exécute un minion Salt pour la gestion de la configuration.

Modules personnalisés

Il est également possible de créer et d’ajouter des modules personnalisés à cloud-init en fonction de vos besoins. Cela vous permet d’étendre les capacités de cloud-init pour des cas d’usage spécifiques à votre infrastructure.

Pour plus d’informations, vous pouvez consulter la documentation officielle de cloud-init.

La CLI cloud-init

Voici une liste des commandes les plus utiles de la CLI cloud-init :

  1. cloud-init status : Vérifie l’état de cloud-init (en cours d’exécution ou terminé).
Terminal window
cloud-init status --long
  1. cloud-init init : Réinitialise cloud-init pour simuler un nouveau démarrage.
Terminal window
sudo cloud-init init
  1. cloud-init modules : Exécute les modules de cloud-init pour une phase spécifique (init, config ou final).
Terminal window
sudo cloud-init modules --mode=config
  1. cloud-init clean : Nettoie les caches et réinitialise l’état de cloud-init pour préparer une nouvelle initialisation.
Terminal window
sudo cloud-init clean
  1. cloud-init query : Interroge et renvoie des informations spécifiques issues des métadonnées de l’instance.
Terminal window
cloud-init query --all
  1. cloud-init single : Exécute un module spécifique de cloud-init.
Terminal window
sudo cloud-init single --name cc_ssh
  1. cloud-init analyze : Analyse les performances de cloud-init et identifie les étapes les plus longues.
Terminal window
cloud-init analyze blame

Ces commandes permettent de gérer et diagnostiquer facilement les configurations et les problèmes potentiels sur les instances cloud gérées par cloud-init. Vous pouvez trouver plus de détails sur chaque commande dans la documentation officielle.

Déboguer cloud-init

Le débogage de cloud-init peut s’avérer essentiel lorsque les configurations ne fonctionnent pas comme prévu. Voici plusieurs approches pour vous aider à diagnostiquer et résoudre les problèmes courants.

Les journaux de cloud-init fournissent une trace détaillée de chaque action exécutée. Les principaux fichiers de log sont situés ici :

  • /var/log/cloud-init.log : Contient des détails complets sur chaque événement de cloud-init.
  • /var/log/cloud-init-output.log : Capture les sorties de chaque étape de cloud-init.

En analysant ces fichiers, vous pouvez identifier les erreurs et suivre la progression des scripts. Cela peut être particulièrement utile si une configuration ne s’applique pas correctement.

Utilisation de la commande cloud-init status

La commande cloud-init status vous permet de vérifier si cloud-init a terminé ses opérations ou s’il est encore en cours d’exécution. Pour plus de détails, utilisez :

Terminal window
cloud-init status --long
status: done
extended_status: done
boot_status_code: enabled-by-generator
last_update: Thu, 01 Jan 1970 00:00:19 +0000
detail: DataSourceNoCloud [seed=/var/lib/cloud/seed/nocloud-net]
errors: []
recoverable_errors: {}

Cela fournit une vue d’ensemble sur les étapes complétées ou échouées, ainsi que des informations sur les erreurs et les problèmes spécifiques.

Exemples de config cloud-init

Configurer le réseau des instances avec cloud-init

cloud-init permet de configurer facilement le réseau d’une instance lors de son démarrage. Cette configuration inclut la gestion des interfaces réseau, des adresses IP statiques ou dynamiques, des routes, et d’autres options réseau personnalisées. Voici comment vous pouvez configurer le réseau d’une instance avec cloud-init.

Utilisation des directives network

Le fichier cloud-config permet d’utiliser la directive network pour définir la configuration réseau d’une instance. Cela peut inclure plusieurs interfaces réseau, des adresses IP statiques, des passerelles et des DNS. Voici un exemple de configuration simple pour une interface réseau avec une IP statique :

#cloud-config
network:
version: 2
ethernets:
eth0:
dhcp4: false
addresses:
- 192.168.1.100/24
gateway4: 192.168.1.1
nameservers:
addresses:
- 8.8.8.8
- 8.8.4.4

Dans cet exemple, l’interface eth0 est configurée avec une adresse IP statique (192.168.1.100), une passerelle (192.168.1.1), et des serveurs DNS (8.8.8.8 et 8.8.4.4). cloud-init appliquera cette configuration lors du premier démarrage de l’instance.

Configuration DHCP

Si vous préférez que l’instance obtienne son adresse IP via DHCP, il suffit de définir l’interface avec l’option dhcp4: true comme suit :

#cloud-config
network:
version: 2
ethernets:
eth0:
dhcp4: true

Cette configuration est utile lorsque vous avez un serveur DHCP dans votre réseau qui attribue dynamiquement les adresses IP.

Configurer plusieurs interfaces

Dans certains cas, vous pouvez avoir besoin de configurer plusieurs interfaces réseau sur une même instance. Voici un exemple pour deux interfaces, l’une utilisant DHCP et l’autre avec une IP statique :

#cloud-config
network:
version: 2
ethernets:
eth0:
dhcp4: true
eth1:
dhcp4: false
addresses:
- 192.168.2.10/24
gateway4: 192.168.2.1
nameservers:
addresses:
- 1.1.1.1
- 8.8.8.8

Ici, l’interface eth0 est configurée avec DHCP et l’interface eth1 utilise une IP statique.

Vérification de la configuration

Après le démarrage de l’instance, vous pouvez vérifier si la configuration réseau a été correctement appliquée en utilisant des commandes telles que ip a pour afficher les interfaces réseau et leurs adresses IP :

Terminal window
ip a

Cela vous permettra de voir si les adresses IP et les routes ont été correctement configurées sur les interfaces.

Utilisation du module Ansible en mode pull dans cloud-init

Le module Ansible dans cloud-init permet d’automatiser l’installation d’Ansible et d’exécuter des playbooks à partir d’un dépôt distant en utilisant la commande ansible-pull. Cela est particulièrement utile pour appliquer des configurations post-déploiement à vos serveurs ou instances cloud sans nécessiter d’installation manuelle.

  1. Installation d’Ansible : Le module permet d’installer Ansible soit via le gestionnaire de paquets de la distribution (distro), soit via pip. Voici un exemple simple où Ansible est installé via pip et un playbook est exécuté depuis un dépôt Git.

  2. Exécution de ansible-pull : La commande ansible-pull permet à Ansible de récupérer et d’exécuter un playbook directement depuis un dépôt Git. Vous pouvez personnaliser l’URL du dépôt, choisir le playbook à exécuter, et même spécifier une clé SSH pour l’authentification sécurisée.

Voici un exemple de configuration pour exécuter un playbook via ansible-pull lors du démarrage d’une instance :

#cloud-config
users:
- name: ansible
groups: sudo
homedir: /home/ansible
shell: /bin/bash
ssh_authorized_keys:
- ssh-rsa AAAAB3Nz...
sudo: ALL=(ALL) NOPASSWD:ALL
write_files:
- path: /home/ansible/.config/pip/pip.conf
content: |
[global]
break-system-packages = true
append: true
package-upgrade: true
package_update: true
packages:
- nginx
- git
ansible:
package_name: ansible
run_user: ansible
install_method: pip
pull:
url: https://github.com/votre-repo/playbooks.git
playbook_name: playbook.yml

Dans cet exemple :

  • package_name définit la version d’Ansible à installer (ici via pip).
  • url est l’URL du dépôt Git contenant les playbooks Ansible.
  • playbook_name spécifie le fichier playbook à exécuter.
  • private_key est la clé privée utilisée pour accéder au dépôt Git en toute sécurité.

Options supplémentaires :

Vous pouvez également ajouter des options comme :

  • timeout : définir un délai maximum pour l’exécution du playbook.
  • tags et skip_tags : exécuter des parties spécifiques du playbook.
  • extra_vars : passer des variables supplémentaires au playbook.

En utilisant cette configuration, cloud-init installe Ansible et récupère les playbooks via Git, garantissant ainsi que vos instances sont configurées de manière cohérente dès leur premier lancement. Et comme le repo est dans le répertoire de l’utilisateur ansible, rien n’empêche de le lancer à volonté voir via un job cron.

Et vendor-data ???

Le vendor-data est une donnée optionnelle fournie par l’entité qui lance une instance, comme un fournisseur de cloud. Cette donnée permet de personnaliser l’image pour mieux l’adapter à l’environnement dans lequel l’instance s’exécute, comme l’installation de packages spécifiques ou la configuration de services en fonction du cloud utilisé.

cloud-init traite le vendor-data de la même manière que le user-data, avec quelques différences :

  1. Exécution contrôlée par l’utilisateur : L’utilisateur final peut désactiver l’exécution du vendor-data ou de parties spécifiques de celui-ci.
  2. Exécution unique : Par défaut, le vendor-data est exécuté uniquement lors du premier démarrage de l’instance.
  3. Fusion avec le user-data : Si l’utilisateur fournit également un fichier user-data, cloud-init fusionnera les deux configurations. Cependant, en cas de conflit (même clé dans les deux fichiers), la configuration utilisateur prendra le dessus.
  4. Sécurisation par les fournisseurs : Il est recommandé aux fournisseurs de cloud de s’assurer que leur vendor-data est sûr, idempotent et ne compromet pas la sécurité des utilisateurs.

Vous pouvez ajouter des directives supplémentaires au vendor-data via un fichier cloud-config, similaire à la manière dont vous configurez le user-data. Par exemple, si vous souhaitez désactiver une partie spécifique du vendor-data, vous pouvez ajouter cette configuration dans le fichier user-data :

#cloud-config
vendordata:
excluded: 'text/part-handler'

Conclusion

En espérant que ce guide vous aura aidé à mieux comprendre et exploiter cloud-init pour l’automatisation des configurations d’instances cloud, nous avons couvert ses fonctionnalités principales, ses limites, et des cas d’usage concrets, notamment la configuration réseau et l’intégration avec Ansible en mode pull. cloud-init est un outil puissant pour automatiser l’initialisation des machines, et lorsqu’il est utilisé avec des outils complémentaires comme Ansible, il permet de gérer efficacement les configurations à grande échelle. Cependant, gardez à l’esprit ses limitations, notamment l’impossibilité de relancer les scripts automatiquement après le démarrage.

Plus d’infos