{"id":631,"date":"2025-02-25T10:51:09","date_gmt":"2025-02-25T09:51:09","guid":{"rendered":"https:\/\/tech.fabienletort.com\/?page_id=631"},"modified":"2025-02-25T10:51:09","modified_gmt":"2025-02-25T09:51:09","slug":"cloud-init","status":"publish","type":"page","link":"https:\/\/tech.fabienletort.com\/?page_id=631","title":{"rendered":"cloud-init"},"content":{"rendered":"\n<p><strong>Cloud-init<\/strong> est un logiciel appartenant \u00e0 la cat\u00e9gorie <strong>IaaS (Infrastructure as a Service)<\/strong>, plus pr\u00e9cis\u00e9ment dans le domaine de la <strong>configuration syst\u00e8me<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Pr\u00e9sentation<\/h2>\n\n\n\n<p><strong>Cloud-init<\/strong> est un outil Linux largement utilis\u00e9 sur les<strong> plateformes cloud<\/strong> pour automatiser<strong> l&rsquo;initialisation d&rsquo;une instance<\/strong> lors de son d\u00e9marrage. Bien qu&rsquo;optimis\u00e9 pour les environnements cloud, il est \u00e9galement compatible avec les infrastructures <strong>On-Premise<\/strong>.<\/p>\n\n\n\n<p>Il permet d\u2019ex\u00e9cuter diverses t\u00e2ches li\u00e9es \u00e0 la configuration du syst\u00e8me, telles que :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>La configuration du <strong>nom d&rsquo;h\u00f4te<\/strong><\/li>\n\n\n\n<li>La configuration des <strong>r\u00e9seaux<\/strong><\/li>\n\n\n\n<li>La gestion des <strong>utilisateurs et groupes<\/strong><\/li>\n<\/ul>\n\n\n\n<p>En plus de ces fonctionnalit\u00e9s, <strong>Cloud-init<\/strong> facilite l&rsquo;installation de paquets et l&rsquo;ex\u00e9cution de scripts, permettant ainsi d&rsquo;automatiser l<strong>e d\u00e9ploiement de logiciels<\/strong> d\u00e8s le premier d\u00e9marrage du syst\u00e8me. Cette approche rappelle certaines t\u00e2ches couramment r\u00e9alis\u00e9es avec <strong>Ansible<\/strong>.<\/p>\n\n\n\n<p>Enfin, il est possible de configurer <strong>Cloud-init<\/strong> pour ex\u00e9cuter certaines actions <strong>uniquement au premier d\u00e9marrage<\/strong> ou bien <strong>\u00e0 chaque red\u00e9marrage<\/strong> de l&rsquo;instance, selon les besoins.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fonctionnement<\/h2>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/tech.fabienletort.com\/wp-content\/uploads\/2025\/02\/could-init-Fonctionnement.png\"><img loading=\"lazy\" decoding=\"async\" width=\"660\" height=\"471\" src=\"https:\/\/tech.fabienletort.com\/wp-content\/uploads\/2025\/02\/could-init-Fonctionnement.png\" alt=\"\" class=\"wp-image-661\" style=\"width:514px;height:auto\" srcset=\"https:\/\/tech.fabienletort.com\/wp-content\/uploads\/2025\/02\/could-init-Fonctionnement.png 660w, https:\/\/tech.fabienletort.com\/wp-content\/uploads\/2025\/02\/could-init-Fonctionnement-300x214.png 300w\" sizes=\"auto, (max-width: 660px) 100vw, 660px\" \/><\/a><\/figure>\n\n\n\n<p><strong>Cloud-init<\/strong> fonctionne comme un moteur d&rsquo;initialisation automatis\u00e9 qui adapte la configuration d&rsquo;une instance en fonction de son environnement. Son r\u00f4le peut \u00eatre r\u00e9sum\u00e9 en plusieurs \u00e9tapes :<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>D\u00e9tection du contexte<\/strong> : identification de la plateforme cloud (AWS, OpenStack, etc.) et du syst\u00e8me d\u2019exploitation (Debian, Red Hat, etc.).<\/li>\n\n\n\n<li><strong>R\u00e9cup\u00e9ration des m\u00e9tadonn\u00e9es<\/strong> : collecte des informations sp\u00e9cifiques \u00e0 l\u2019environnement d\u2019ex\u00e9cution.<\/li>\n\n\n\n<li><strong>Application de la configuration utilisateur<\/strong> : prise en compte des param\u00e8tres (agnostique de l&rsquo;os, de l&rsquo;environnement) d\u00e9finis dans le fichier de configuration Cloud-init.<\/li>\n\n\n\n<li><strong>G\u00e9n\u00e9ration des fichiers syst\u00e8me<\/strong> : configuration du r\u00e9seau, des utilisateurs, des param\u00e8tres globaux, etc.<\/li>\n\n\n\n<li><strong>Ex\u00e9cution de t\u00e2ches compl\u00e9mentaires<\/strong> : installation de logiciels et ex\u00e9cution de scripts personnalis\u00e9s.<\/li>\n<\/ol>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>En r\u00e9sum\u00e9, <strong>Cloud-init<\/strong> agit comme un pont entre une configuration g\u00e9n\u00e9rique et les sp\u00e9cificit\u00e9s de l\u2019OS et de la plateforme. Tout ce processus se d\u00e9roule automatiquement lors du d\u00e9marrage de l\u2019instance.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">Phases<\/h3>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/tech.fabienletort.com\/wp-content\/uploads\/2025\/02\/could-init-Etapes.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"429\" src=\"https:\/\/tech.fabienletort.com\/wp-content\/uploads\/2025\/02\/could-init-Etapes-1024x429.png\" alt=\"\" class=\"wp-image-662\" srcset=\"https:\/\/tech.fabienletort.com\/wp-content\/uploads\/2025\/02\/could-init-Etapes-1024x429.png 1024w, https:\/\/tech.fabienletort.com\/wp-content\/uploads\/2025\/02\/could-init-Etapes-300x126.png 300w, https:\/\/tech.fabienletort.com\/wp-content\/uploads\/2025\/02\/could-init-Etapes-768x322.png 768w, https:\/\/tech.fabienletort.com\/wp-content\/uploads\/2025\/02\/could-init-Etapes.png 1101w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p><strong>Cloud-init<\/strong> intervient \u00e0 plusieurs \u00e9tapes du d\u00e9marrage du syst\u00e8me.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Phase locale<\/strong> : D\u00e8s les premiers instants du boot, avant m\u00eame que le r\u00e9seau ne soit compl\u00e8tement initialis\u00e9, <strong>Cloud-init<\/strong> d\u00e9marre sa phase locale. \u00c0 ce stade, il d\u00e9tecte et charge les fichiers de configuration locaux, puis applique une configuration r\u00e9seau minimale.<\/li>\n\n\n\n<li><strong>Phases r\u00e9seau, configuration et finale<\/strong> : Une fois le r\u00e9seau activ\u00e9, <strong>Cloud-init<\/strong> poursuit son ex\u00e9cution en r\u00e9cup\u00e9rant les ressources externes n\u00e9cessaires. La configuration compl\u00e8te du r\u00e9seau s\u2019effectue au cours de la <strong>phase r\u00e9seau<\/strong>, apr\u00e8s quoi l\u2019instance devient accessible pour la connexion.<\/li>\n<\/ul>\n\n\n\n<p>Les diff\u00e9rents modules ex\u00e9cut\u00e9s au cours de ces trois derni\u00e8res phases peuvent \u00eatre personnalis\u00e9s via le fichier de configuration de <strong>Cloud-init<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Phase<\/th><th>Description<\/th><th>Exemple de t\u00e2ches ex\u00e9cut\u00e9es<\/th><\/tr><\/thead><tbody><tr><td>Locale<\/td><td>D\u00e9tecte la source des m\u00e9tadonn\u00e9es et initialise les premi\u00e8res configurations<\/td><td>&#8211; D\u00e9tection du fournisseur Cloud (AWS, OpenStack\u2026)<br>&#8211; Chargement des donn\u00e9es locales (Disque, NoCloud\u2026)<br>&#8211; Configuration des logs<\/td><\/tr><tr><td>R\u00e9seau<\/td><td>Configure l\u2019interface r\u00e9seau avant toute autre configuration<\/td><td>&#8211; Attribution d\u2019une adresse IP via DHCP<br>&#8211; Activation des interfaces r\u00e9seau<br>&#8211; D\u00e9finition du DNS, passerelle et routes<\/td><\/tr><tr><td>Configuration<\/td><td>Applique la configuration syst\u00e8me de base<br>Configure les comptes utilisateurs et SSH<\/td><td>&#8211; Cr\u00e9ation d&rsquo;utilisateurs et SSH<br>&#8211; Installation de packages<br>&#8211; Configuration des d\u00e9p\u00f4ts<\/td><\/tr><tr><td>Finale<\/td><td>Ex\u00e9cute les actions finales apr\u00e8s l&rsquo;initialisation<\/td><td>&#8211; Ex\u00e9cution des scripts User-Data<br>&#8211; D\u00e9marrage des services<br>&#8211; T\u00e2ches post-configuration<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">Description des phases de cloud-init<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">\u00c9volution de la configuration r\u00e9seau \u00e0 travers les phases de Cloud-init<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/tech.fabienletort.com\/wp-content\/uploads\/2025\/02\/could-init-Reseau.png\"><img loading=\"lazy\" decoding=\"async\" width=\"631\" height=\"141\" src=\"https:\/\/tech.fabienletort.com\/wp-content\/uploads\/2025\/02\/could-init-Reseau.png\" alt=\"\" class=\"wp-image-663\" srcset=\"https:\/\/tech.fabienletort.com\/wp-content\/uploads\/2025\/02\/could-init-Reseau.png 631w, https:\/\/tech.fabienletort.com\/wp-content\/uploads\/2025\/02\/could-init-Reseau-300x67.png 300w\" sizes=\"auto, (max-width: 631px) 100vw, 631px\" \/><\/a><\/figure>\n\n\n\n<p>La configuration r\u00e9seau progresse \u00e0 mesure que <strong>Cloud-init<\/strong> suit ses diff\u00e9rentes phases d\u2019ex\u00e9cution.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Phase locale : activation minimale du r\u00e9seau<\/strong><br>Lors de cette premi\u00e8re phase, le r\u00e9seau est <strong>partiellement activ\u00e9<\/strong>, uniquement dans la mesure n\u00e9cessaire pour permettre \u00e0 <strong>Cloud-init<\/strong> d\u2019acc\u00e9der \u00e0 sa source de donn\u00e9es :\n<ul class=\"wp-block-list\">\n<li><strong>Le r\u00e9seau n\u2019est pas encore totalement configur\u00e9<\/strong> (pas d\u2019IP statique, pas de DNS).<\/li>\n\n\n\n<li>Si la <strong>source de donn\u00e9es est locale<\/strong> (CD-ROM, disque dur), aucune connexion r\u00e9seau n\u2019est requise.<\/li>\n\n\n\n<li>Si la <strong>source de donn\u00e9es est externe<\/strong> (ex. AWS Metadata Service, OpenStack Metadata Service), une <strong>connexion minimale<\/strong> doit \u00eatre \u00e9tablie.<\/li>\n\n\n\n<li>Si <strong>DHCP est activ\u00e9<\/strong>, une adresse IP temporaire peut \u00eatre attribu\u00e9e \u00e0 ce stade.<\/li>\n\n\n\n<li>Lors de la phase locale, le r\u00e9seau est activ\u00e9 de mani\u00e8re minimale<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Phase r\u00e9seau : configuration compl\u00e8te du r\u00e9seau<\/strong><br>C\u2019est au cours de cette phase que <strong>Cloud-init applique la configuration r\u00e9seau d\u00e9finitive<\/strong>, en s\u2019appuyant sur des outils comme <strong>Netplan<\/strong> (Ubuntu) ou <strong>ifupdown<\/strong>.\n<ul class=\"wp-block-list\">\n<li><strong>Les param\u00e8tres r\u00e9seau sont enti\u00e8rement configur\u00e9s<\/strong> : attribution d\u2019une IP (statique ou dynamique), configuration DNS, passerelle, etc.<\/li>\n\n\n\n<li><strong>Cloud-init g\u00e9n\u00e8re les fichiers de configuration n\u00e9cessaires<\/strong> :\n<ul class=\"wp-block-list\">\n<li><strong>Sur Ubuntu<\/strong>, un fichier Netplan (<code>\/etc\/netplan\/50-cloud-init.yaml<\/code>) est cr\u00e9\u00e9, puis appliqu\u00e9 via <code>netplan apply<\/code>.<\/li>\n\n\n\n<li><strong>Sur RHEL\/CentOS<\/strong>, un fichier de configuration (<code>\/etc\/sysconfig\/network-scripts\/ifcfg-eth0<\/code>) est g\u00e9n\u00e9r\u00e9 et pris en charge par le service r\u00e9seau.<\/li>\n\n\n\n<li><strong>Sur les syst\u00e8mes utilisant <code>\/etc\/network\/interfaces.d\/<\/code><\/strong>, les interfaces r\u00e9seau sont configur\u00e9es \u00e0 ce moment-l\u00e0.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Les r\u00e8gles de pare-feu sont mises en place<\/strong> (<code>iptables<\/code>, <code>firewalld<\/code>).<\/li>\n\n\n\n<li>Si l\u2019instance requiert une <strong>IP statique<\/strong>, elle est appliqu\u00e9e \u00e0 cette \u00e9tape.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>En r\u00e9sum\u00e9, <strong>la phase locale permet \u00e0 Cloud-init d\u2019amorcer la connexion r\u00e9seau<\/strong>, tandis que <strong>la phase r\u00e9seau finalise la configuration compl\u00e8te du syst\u00e8me<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Sources des donn\u00e9es de configuration en phase locale<\/h3>\n\n\n\n<p>Lors de la <strong>phase locale<\/strong>, <strong>Cloud-init<\/strong> r\u00e9cup\u00e8re ses donn\u00e9es de configuration \u00e0 partir de trois sources principales :<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Les m\u00e9tadonn\u00e9es (Metadata)<\/strong><br>Ces donn\u00e9es fournissent des informations sp\u00e9cifiques \u00e0 l\u2019instance, comme son <strong>nom<\/strong>, son <strong>ID<\/strong> ou d&rsquo;autres attributs syst\u00e8me.\n<ul class=\"wp-block-list\">\n<li>Sur une plateforme cloud, c\u2019est l\u2019infrastructure qui indique \u00e0 <strong>Cloud-init<\/strong> o\u00f9 r\u00e9cup\u00e9rer ces informations.<\/li>\n\n\n\n<li>Elles peuvent \u00eatre utilis\u00e9es dans les fichiers de configuration ou directement dans des scripts.<\/li>\n\n\n\n<li>Pour afficher l\u2019ensemble des m\u00e9tadonn\u00e9es disponibles, utilisez : <code>sudo cloud-init query --all<\/code><\/li>\n\n\n\n<li>Ces m\u00eames valeurs sont \u00e9galement stock\u00e9es dans le fichier : <code>\/run\/cloud-init\/instance-data.json<\/code><\/li>\n\n\n\n<li>Pour une description d\u00e9taill\u00e9e des m\u00e9tadonn\u00e9es, consultez <a href=\"https:\/\/cloudinit.readthedocs.io\/en\/latest\/explanation\/instancedata.html\">la section <strong>Instance-data<\/strong> de la documentation officielle de <strong>Cloud-init<\/strong><\/a>.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Les donn\u00e9es du fournisseur (Vendor Data)<\/strong><br>Ces donn\u00e9es, <strong>optionnelles<\/strong>, sont fournies par le <strong>cloud provider<\/strong> pour adapter l\u2019instance \u00e0 son environnement global.\n<ul class=\"wp-block-list\">\n<li>Leur disponibilit\u00e9 d\u00e9pend du fournisseur, par exemple:\n<ul class=\"wp-block-list\">\n<li><strong>AWS<\/strong> ne fournit <strong>pas<\/strong> de donn\u00e9es de ce type.<\/li>\n\n\n\n<li><strong>OpenStack<\/strong>, en revanche, peut en fournir.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Les donn\u00e9es utilisateur (User Data)<\/strong><br>Ces donn\u00e9es correspondent aux <strong>directives d\u00e9finies par l\u2019utilisateur<\/strong> dans les fichiers de configuration Cloud-init.<br>Elles permettent d\u2019ex\u00e9cuter des commandes personnalis\u00e9es, d\u2019installer des logiciels, ou encore de configurer des services sp\u00e9cifiques au moment du d\u00e9marrage de l\u2019instance.<\/li>\n<\/ol>\n\n\n\n<div class=\"wp-block-esab-accordion esab-g4xipql6\" data-mode=\"global\"><div class=\"esab__container\">\n<div class=\"wp-block-esab-accordion-child\"><div class=\"esab__head\" role=\"button\" aria-expanded=\"false\"><div class=\"esab__heading_txt\"><p class=\"esab__heading_tag\"><strong>Exemple de chargement des m\u00e9tadonn\u00e9es sur AWS<\/strong><\/p><\/div><div class=\"esab__icon\"><div class=\"esab__collapse\"><svg version=\"1.2\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\"><path fill-rule=\"evenodd\" d=\"m3.5 20.5c-4.7-4.7-4.7-12.3 0-17 4.7-4.7 12.3-4.7 17 0 4.6 4.7 4.6 12.3 0 17-4.7 4.6-12.3 4.6-17 0zm0.9-0.9c4.2 4.2 11 4.2 15.2 0 4.2-4.2 4.2-11 0-15.2-4.2-4.3-11-4.3-15.2 0-4.3 4.2-4.3 11 0 15.2z\"><\/path><path d=\"m11.4 15.9v-3.3h-3.3c-0.3 0-0.6-0.3-0.6-0.6 0-0.4 0.3-0.6 0.6-0.6h3.3v-3.3c0-0.3 0.3-0.6 0.6-0.6 0.3 0 0.6 0.3 0.6 0.6v3.3h3.3c0.3 0 0.6 0.2 0.6 0.6q0 0.2-0.2 0.4-0.2 0.2-0.4 0.2h-3.3v3.3q0 0.2-0.2 0.4-0.2 0.2-0.4 0.2c-0.4 0-0.6-0.3-0.6-0.6z\"><\/path><\/svg><\/div><div class=\"esab__expand\"><svg version=\"1.2\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\"><path fill-rule=\"evenodd\" d=\"m12 24c-6.6 0-12-5.4-12-12 0-6.6 5.4-12 12-12 6.6 0 12 5.4 12 12 0 6.6-5.4 12-12 12zm10.6-12c0-5.9-4.7-10.6-10.6-10.6-5.9 0-10.6 4.7-10.6 10.6 0 5.9 4.7 10.6 10.6 10.6 5.9 0 10.6-4.7 10.6-10.6z\"><\/path><path d=\"m5.6 11.3h12.8v1.4h-12.8z\"><\/path><\/svg><\/div><\/div><\/div><div class=\"esab__body\">\n<p>Lorsqu&rsquo;une instance <strong>EC2<\/strong> d\u00e9marre avec <strong>Cloud-init<\/strong>, celui-ci suit plusieurs \u00e9tapes :<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Identification de la source des m\u00e9tadonn\u00e9es<\/strong> : Cloud-init reconna\u00eet qu&rsquo;il s&rsquo;ex\u00e9cute sur <strong>AWS EC2<\/strong>.<\/li>\n\n\n\n<li><strong>R\u00e9cup\u00e9ration des m\u00e9tadonn\u00e9es<\/strong> : Une requ\u00eate HTTP est envoy\u00e9e \u00e0 : <code>http:\/\/169.254.169.254\/latest\/meta-data<\/code><\/li>\n\n\n\n<li><strong>Application de la configuration syst\u00e8me<\/strong> : Les donn\u00e9es r\u00e9cup\u00e9r\u00e9es sont utilis\u00e9es pour configurer le <strong>nom d\u2019h\u00f4te<\/strong>, le <strong>r\u00e9seau<\/strong>, les <strong>cl\u00e9s SSH<\/strong>, etc.<\/li>\n<\/ol>\n\n\n\n<p><strong>Cloud-init est donc responsable du chargement des m\u00e9tadonn\u00e9es, en utilisant le m\u00e9canisme propre \u00e0 chaque plateforme cloud.<\/strong><br>Ici, cloud-init utilise la m\u00e9thode de r\u00e9cup\u00e9ration officielle des m\u00e9tadonn\u00e9es EC2, comme d\u00e9crite par la m\u00e9thode officielle&nbsp;: <a href=\"https:\/\/docs.aws.amazon.com\/fr_fr\/AWSEC2\/latest\/UserGuide\/instancedata-data-retrieval.html\">Acc\u00e9der aux m\u00e9tadonn\u00e9es d&rsquo;une instance EC2<\/a>.<\/p>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">La configuration utilisateur<\/h3>\n\n\n\n<p>La configuration utilisateur (<em>user data<\/em>) peut \u00eatre d\u00e9finie \u00e0 l\u2019aide de trois formats principaux :<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Fichier de configuration cloud-init<\/strong> au format YAML.<\/li>\n\n\n\n<li><strong>Script User-data<\/strong>, qui correspond \u00e0 un script ex\u00e9cut\u00e9 lors de la phase finale (<em>final stage<\/em>).<\/li>\n\n\n\n<li><strong>Cloud boothook<\/strong>, un script ex\u00e9cut\u00e9 tr\u00e8s t\u00f4t dans le processus, durant la phase r\u00e9seau (<em>network stage<\/em>).<\/li>\n<\/ol>\n\n\n\n<p>Ces formats peuvent \u00eatre combin\u00e9s ou enrichis sous des formes plus complexes :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Include file<\/strong> : un fichier contenant une liste d\u2019URL pointant vers des fichiers <em>user data<\/em>. (les 3 formats sont possibles)<\/li>\n\n\n\n<li><strong>Jinja template<\/strong> : les fichiers <em>cloud-config<\/em> et <em>user-data scripts<\/em> peuvent \u00eatre \u00e9crits sous forme de templates Jinja, permettant d\u2019utiliser toutes les variables d\u2019instance. Cette fonctionnalit\u00e9 est couramment utilis\u00e9e pour personnaliser les instances.<\/li>\n\n\n\n<li><strong>MIME multipart file<\/strong> : un fichier unique contenant plusieurs formats diff\u00e9rents.<\/li>\n\n\n\n<li><strong>Cloud-config archive<\/strong> : similaire au fichier pr\u00e9c\u00e9dent, mais les formats sont empaquet\u00e9s en YAML plut\u00f4t que via l&rsquo;astuce du MIME multipart.<\/li>\n\n\n\n<li><strong>Part handler<\/strong> : script python permettant d\u2019ajouter ou de personnaliser les types MIME pris en charge dans un fichier MIME multipart<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Descriptions de Fichiers Utilis\u00e9s<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><code>\/etc\/cloud\/cloud.cfg<\/code><br><code>\/etc\/cloud\/cloud.cfg.d\/<\/code><\/td><td>Configuration de cloud-init<\/td><\/tr><tr><td><code>\/var\/lib\/cloud\/instances\/&lt;id&gt;\/user-data.txt<\/code><\/td><td>Donn\u00e9es de configuration utilisateur<\/td><\/tr><tr><td><code>\/run\/cloud-init\/instance-data.json<\/code><\/td><td>M\u00e9tadonn\u00e9es d&rsquo;instance<\/td><\/tr><tr><td><code>\/var\/log\/cloud-init.log<\/code><br><code>\/var\/log\/cloud-init-output.log<\/code><\/td><td>Logs d&rsquo;ex\u00e9cution<\/td><\/tr><tr><td><code>\/var\/lib\/cloud\/instance\/<\/code><\/td><td>Donn\u00e9es d&rsquo;\u00e9tat li\u00e9es \u00e0 l&rsquo;instance<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Les fichiers dans <strong><code>\/etc\/cloud<\/code><\/strong> sont principalement des fichiers de configuration globale, tandis que les r\u00e9pertoires dans <strong><code>\/var\/lib\/cloud<\/code><\/strong> et <strong><code>\/run\/cloud-init<\/code><\/strong> contiennent des informations relatives \u00e0 l&rsquo;ex\u00e9cution de cloud-init, telles que les m\u00e9tadonn\u00e9es, les donn\u00e9es utilisateurs. Enfin, les logs sont stock\u00e9s dans le classique <strong>\/var\/log<em class=\"diigoHighlight id_e3ff44b7de9f2d5d67029aa3782f944b type_0 yellow\">.<span class=\"diigoHighlightCommentLocator\"><\/span><\/em><\/strong><\/p>\n\n\n\n<p>Plus d&rsquo;information sur les fichiers peuvent \u00eatre trouv\u00e9s sur ces sources :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/docs.redhat.com\/fr\/documentation\/red_hat_enterprise_linux\/9\/html\/configuring_and_managing_cloud-init_for_rhel_9\/red-hat-support-for-cloud-init_cloud-content#red-hat-support-for-cloud-init_cloud-content\">r\u00e9pertoires et fichiers importants de cloud-init&nbsp;sur RedHat<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/docs.redhat.com\/fr\/documentation\/red_hat_enterprise_linux\/9\/html\/configuring_and_managing_cloud-init_for_rhel_9\/cloud-init-var-lib-cloud-directory-layout_red-hat-support-for-cloud-init#cloud-init-var-lib-cloud-directory-layout_red-hat-support-for-cloud-init\">La structure du r\u00e9pertoire cloud-init \/var\/lib\/cloud sur RedHat<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/cloudinit.readthedocs.io\/en\/latest\/topics\/dir_layout.html#directory-layout\">Disposition du r\u00e9pertoire sur le doc de cloud-init<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Premier d\u00e9marrage ?<\/h3>\n\n\n\n<p>Comme mentionn\u00e9 pr\u00e9c\u00e9demment, <strong>cloud-init<\/strong> peut ex\u00e9cuter des op\u00e9rations, soit uniquement au <strong>premier d\u00e9marrage<\/strong> de la machine (op\u00e9rations marqu\u00e9es <strong>\u00ab\u00a0par instance\u00a0\u00bb<\/strong>), soit \u00e0 <strong>chaque d\u00e9marrage<\/strong> (op\u00e9rations marqu\u00e9es <strong>\u00ab\u00a0par d\u00e9marrage\u00a0\u00bb<\/strong>).<\/p>\n\n\n\n<p>Pour d\u00e9terminer son \u00e9tat d&rsquo;ex\u00e9cution, <strong>cloud-init<\/strong> conserve un <strong>cache<\/strong> qui enregistre les \u00e9tapes des d\u00e9marrages successifs. Si ce cache est pr\u00e9sent, <strong>cloud-init<\/strong> reconna\u00eet qu&rsquo;il a d\u00e9j\u00e0 \u00e9t\u00e9 ex\u00e9cut\u00e9 sur le syst\u00e8me. Cela peut poser probl\u00e8me dans deux cas :<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Un <strong>syst\u00e8me de fichiers existant<\/strong> est rattach\u00e9 \u00e0 une <strong>nouvelle instance<\/strong>.<\/li>\n\n\n\n<li>L\u2019instance a \u00e9t\u00e9 cr\u00e9\u00e9e \u00e0 partir d\u2019une <strong>image captur\u00e9e<\/strong> d\u2019une instance d\u00e9j\u00e0 initialis\u00e9e.<\/li>\n<\/ol>\n\n\n\n<p>Pour \u00e9viter ces situations, <strong>cloud-init<\/strong> compare \u00e9galement l\u2019<strong>ID de l\u2019instance en cours<\/strong> avec celui stock\u00e9 dans son cache. Ce comportement, appel\u00e9 <strong>\u00ab\u00a0check\u00a0\u00bb<\/strong>, est activ\u00e9 par d\u00e9faut .<\/p>\n\n\n\n<p>Cependant, cela peut aussi poser probl\u00e8me si :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>L\u2019ID de la nouvelle instance n\u2019est pas disponible.<\/li>\n\n\n\n<li>Une attaque exploite ce m\u00e9canisme pour modifier l\u2019ID d&rsquo;instance stock\u00e9e en cache.<\/li>\n<\/ul>\n\n\n\n<p>Dans ces cas, le mode <strong>\u00ab\u00a0trust\u00a0\u00bb<\/strong> peut \u00eatre utilis\u00e9. Il <strong>ignore la v\u00e9rification de l\u2019ID<\/strong> et consid\u00e8re le cache comme valide. Dans ce mode, la seule fa\u00e7on de r\u00e9initialiser l\u2019\u00e9tat de l\u2019instance est de <strong>supprimer manuellement le cache de cloud-init<\/strong>.<\/p>\n\n\n\n<p>Le choix du mode utilis\u00e9 se fait via le param\u00e8tre <strong><code>manual_cache_clean<\/code><\/strong> :<\/p>\n\n\n\n<p><code>true<\/code> \u2192 mode <strong>\u00ab\u00a0trust\u00a0\u00bb<\/strong> (cloud-init fait toujours confiance au cache).<\/p>\n\n\n\n<p><code>false<\/code> \u2192 mode <strong>\u00ab\u00a0check\u00a0\u00bb<\/strong> (cloud-init v\u00e9rifie l\u2019ID).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Les Modules<\/h2>\n\n\n\n<p>Comme mentionn\u00e9 pr\u00e9c\u00e9demment, le travail effectu\u00e9 par <strong>cloud-init<\/strong> au cours de chaque phase repose sur diff\u00e9rents <strong>modules<\/strong>. Le fichier de configuration principal d\u00e9finit quels modules sont utilis\u00e9s \u00e0 chaque \u00e9tape, et il est possible de les d\u00e9sactiver si n\u00e9cessaire. <br>Tous les modules disponibles sont d\u00e9taill\u00e9s sur <a href=\"https:\/\/cloudinit.readthedocs.io\/en\/latest\/reference\/modules.html\">la page Module de la documentation officielle.<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Modules Principaux<\/h3>\n\n\n\n<p>Voici une liste des principaux modules, class\u00e9s selon leur phase d&rsquo;ex\u00e9cution par d\u00e9faut :<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">1. Phase <code>init<\/code> (Initialisation)<\/h4>\n\n\n\n<p><strong>Objectif<\/strong> : Collecter et traiter les m\u00e9tadonn\u00e9es de l\u2019instance<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Modules principaux :<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>cloud-init-local<\/code><\/strong> : R\u00e9cup\u00e8re les m\u00e9tadonn\u00e9es du fournisseur cloud et configure le r\u00e9seau minimal pour la r\u00e9cup\u00e9ration.<\/li>\n\n\n\n<li><strong><code>seed_random<\/code><\/strong> : Initialise l&rsquo;entropie pour la g\u00e9n\u00e9ration de nombres al\u00e9atoires.<\/li>\n\n\n\n<li><strong><code>bootcmd<\/code><\/strong> : Ex\u00e9cute des commandes au tout d\u00e9but du processus de d\u00e9marrage.<\/li>\n\n\n\n<li><strong><code>write-files<\/code><\/strong> : \u00c9crit des fichiers d\u00e9finis dans la configuration utilisateur.<\/li>\n\n\n\n<li><strong><code>set_hostname<\/code><\/strong> : D\u00e9finit le nom d\u2019h\u00f4te de la machine.<\/li>\n\n\n\n<li><strong><code>update_hostname<\/code><\/strong> : Met \u00e0 jour le fichier <code>\/etc\/hostname<\/code> avec le nouveau nom d\u2019h\u00f4te.<\/li>\n\n\n\n<li><strong><code>update_etc_hosts<\/code><\/strong> : Ajoute le nom d\u2019h\u00f4te et les adresses IP locales au fichier <code>\/etc\/hosts<\/code>.<\/li>\n\n\n\n<li><strong><code>resizefs<\/code><\/strong> : Redimensionne le syst\u00e8me de fichiers principal si n\u00e9cessaire.<\/li>\n\n\n\n<li><strong><code>disk_setup<\/code><\/strong> : Configure les partitions et formate les disques selon la configuration.<\/li>\n\n\n\n<li><strong><code>mounts<\/code><\/strong> : Monte les partitions d\u00e9finies dans la configuration.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">2. Phase <code>config<\/code> (Configuration syst\u00e8me)<\/h4>\n\n\n\n<p><strong>Objectif<\/strong> : Appliquer la configuration de l&rsquo;instance avant que les services utilisateur ne d\u00e9marrent<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Modules principaux :<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>ssh<\/code><\/strong> : Configure le serveur SSH et ajoute les cl\u00e9s SSH.<\/li>\n\n\n\n<li><strong><code>locale<\/code><\/strong> : Configure la langue et le jeu de caract\u00e8res du syst\u00e8me.<\/li>\n\n\n\n<li><strong><code>timezone<\/code><\/strong> : D\u00e9finit le fuseau horaire.<\/li>\n\n\n\n<li><strong><code>users-groups<\/code><\/strong> : Cr\u00e9e des utilisateurs et groupes selon la configuration.<\/li>\n\n\n\n<li><strong><code>ssh-import-id<\/code><\/strong> : T\u00e9l\u00e9charge et ajoute des cl\u00e9s SSH depuis un service comme Launchpad ou GitHub.<\/li>\n\n\n\n<li><strong><code>ca-certs<\/code><\/strong> : Configure les certificats d\u2019autorit\u00e9 de confiance.<\/li>\n\n\n\n<li><strong><code>ntp<\/code><\/strong> : Configure le client de synchronisation de l\u2019heure (NTP).<\/li>\n\n\n\n<li><strong><code>rsyslog<\/code><\/strong> : Configure le service de logs <code>rsyslog<\/code>.<\/li>\n\n\n\n<li><strong><code>sysctl<\/code><\/strong> : Applique les r\u00e9glages syst\u00e8me sp\u00e9cifiques (<code>sysctl.conf<\/code>).<\/li>\n\n\n\n<li><strong><code>apt-update-upgrade<\/code><\/strong> : Met \u00e0 jour la liste des paquets (<code>apt update<\/code>) et met \u00e0 niveau (<code>apt upgrade<\/code>).<\/li>\n\n\n\n<li><strong><code>package-update-upgrade-install<\/code><\/strong> : Installe et met \u00e0 jour les paquets sp\u00e9cifi\u00e9s.<\/li>\n\n\n\n<li><strong><code>snap<\/code><\/strong> : Installe des paquets Snap.<\/li>\n\n\n\n<li><strong><code>runcmd<\/code><\/strong> : Ex\u00e9cute des commandes arbitraires d\u00e9finies par l&rsquo;utilisateur.<\/li>\n\n\n\n<li><strong><code>scripts-vendor<\/code> \/ <code>scripts-per-instance<\/code> \/ <code>scripts-user<\/code><\/strong> : Ex\u00e9cute des scripts personnalis\u00e9s \u00e0 diff\u00e9rents niveaux.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">3. Phase <code>final<\/code> (Finalisation)<\/h4>\n\n\n\n<p><strong>Objectif<\/strong> : Effectuer les derniers ajustements et ex\u00e9cuter les t\u00e2ches utilisateur avant que l&rsquo;instance ne soit pr\u00eate<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Modules principaux :<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><code>phone-home<\/code><\/strong> : Envoie une notification \u00e0 un serveur distant indiquant que l\u2019instance est pr\u00eate.<\/li>\n\n\n\n<li><strong><code>scripts-user<\/code><\/strong> : Ex\u00e9cute les scripts d\u00e9finis par l&rsquo;utilisateur (<code>\/var\/lib\/cloud\/scripts\/per-instance<\/code>).<\/li>\n\n\n\n<li><strong><code>scripts-once<\/code><\/strong> : Ex\u00e9cute un script unique (<code>\/var\/lib\/cloud\/scripts\/per-once<\/code>).<\/li>\n\n\n\n<li><strong><code>power-state-change<\/code><\/strong> : Arr\u00eate ou red\u00e9marre l&rsquo;instance si configur\u00e9.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Autres modules<\/h3>\n\n\n\n<p><code>cloud-init<\/code> propose plusieurs modules optionnels permettant d&rsquo;int\u00e9grer des solutions de gestion de configuration telles qu&rsquo;Ansible et Chef. Voici quelques-uns de ces modules :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>cc_ansible: Ce module installe Ansible lors du d\u00e9marrage de l&rsquo;instance et utilise <code>ansible-pull<\/code> pour ex\u00e9cuter des playbooks depuis un d\u00e9p\u00f4t distant. Il permet d&rsquo;int\u00e9grer la gestion de configuration d&rsquo;Ansible directement dans le processus d&rsquo;initialisation de l&rsquo;instance.<\/li>\n\n\n\n<li>chef: Ce module installe Chef lors du d\u00e9marrage de l&rsquo;instance et utilise <code>chef-client<\/code> pour appliquer des recettes depuis un serveur Chef distant. Il facilite l&rsquo;int\u00e9gration de Chef dans le processus d&rsquo;initialisation de l&rsquo;instance<\/li>\n\n\n\n<li>salt-minion: Ce module permet d&rsquo;int\u00e9grer directement <strong>Salt Minion<\/strong> dans le processus de d\u00e9marrage, facilitant ainsi la gestion de la configuration des instances avec <strong>SaltStack<\/strong>.<\/li>\n<\/ul>\n\n\n\n<p>En int\u00e9grant ces modules, <code>cloud-init<\/code> facilite l&rsquo;automatisation compl\u00e8te de la configuration des instances, en combinant l&rsquo;initialisation de base avec des configurations plus complexes g\u00e9r\u00e9es par des outils sp\u00e9cialis\u00e9s.<\/p>\n\n\n\n<p>Il est \u00e9galement possible de d\u00e9velopper ses <strong>propres modules personalis\u00e9s<\/strong>, pour r\u00e9pondre \u00e0 des<strong> besoins sp\u00e9cifiques<\/strong>. Ce processus est d\u00e9taill\u00e9 dans <a href=\"https:\/\/cloudinit.readthedocs.io\/en\/latest\/reference\/custom_modules.html\">le chapitre Custom Modules de la documentation officielle<\/a>.<\/p>\n\n\n\n<p>Enfin dans un monde Ansible, si vous ne voulez pas d\u00e9ployer Ansible sur chaque machine, bref si vous voulez garder AWX comme chef d&rsquo;orchestre, vous pouvez tr\u00e8s bien \u00e9galement envoyer une notification \u00e0 la fin de votre intialisation cloud-init afin de lancer un playbook c\u00f4t\u00e9 AWX via un webhook.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Contexte de d\u00e9marrage<\/h3>\n\n\n\n<p>Nous avons vu que les modules peuvent \u00eatre ex\u00e9cut\u00e9s soit lors du premier d\u00e9marrage, soit \u00e0 chaque d\u00e9marrage. Voyons maintenant comment ce comportement est d\u00e9fini. Par d\u00e9faut, voici le comportement de chaque phase :<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>Phase \/ Section<\/td><td>Ex\u00e9cution par d\u00e9fault<\/td><\/tr><tr><td><code>cloud_init_modules<\/code><\/td><td>1er d\u00e9marrage uniquement<\/td><\/tr><tr><td><code>cloud_config_modules<\/code><\/td><td>A chaque d\u00e9marrage<\/td><\/tr><tr><td><code>cloud_final_modules<\/code><\/td><td>1er d\u00e9marrage uniquement<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Il est \u00e9galement possible de forcer l&rsquo;ex\u00e9cution des modules \u00e0 chaque d\u00e9marrage en configurant le param\u00e8tre <strong><code>frequency<\/code><\/strong> sur <strong><code>always<\/code><\/strong>. Cette configuration doit \u00eatre appliqu\u00e9e individuellement \u00e0 chaque module. Voici un exemple ci-dessous :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"yaml\" class=\"language-yaml\">cloud_init_modules:\n  - migrator\n  - seed_random\n  - bootcmd:\n      frequency: always\n  - write-files:\n      frequency: always<\/code><\/pre>\n\n\n\n<p>Dans cet exemple, les modules <strong><code>bootcmd<\/code><\/strong> et <strong><code>write-files<\/code><\/strong> seront ex\u00e9cut\u00e9s \u00e0 chaque d\u00e9marrage, malgr\u00e8s qu&rsquo;ils soient list\u00e9s dans la section <code>cloud_init_modules<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Utilisation de cloud-init<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">La ligne de commande<\/h3>\n\n\n\n<p>Les lignes de commande disponibles sont d\u00e9crites <a href=\"https:\/\/cloudinit.readthedocs.io\/en\/latest\/reference\/cli.html#cloud-init\">sur le site officiel<\/a>. Nous allons passer een revue ici les principales commandes de la CLI de <strong>could-init<\/strong> :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>V\u00e9rifier l&rsquo;\u00e9tat de cloud-init: <code>cloud-init status<\/code><br><em>Cette commande affiche l&rsquo;\u00e9tat d&rsquo;\u00e9xecution de cloud-init (en cours, termin\u00e8 avec succ\u00e8s, erreur, &#8230;)<\/em><\/li>\n\n\n\n<li>Voir les logs de cloud-init: <code>cloud-init analyze show<\/code><br><em>Permet d&rsquo;analayser et afficher les journaux de log pour diagnostiquer d&rsquo;\u00e9ventuels probl\u00e8mes<\/em><\/li>\n\n\n\n<li>Forcer une r\u00e9initialisation et red\u00e9marrer cloud init: <code>cloud-init clean --reboot<\/code><br><em>Supprime les anciens fichiers de configuration et red\u00e9marre la machine pour rejouer cloud-init comme si l&rsquo;instance \u00e9tait fra\u00eechement cr\u00e9\u00e9e.<\/em><\/li>\n\n\n\n<li>Voir les m\u00e9tadonn\u00e9es appliqu\u00e9s: <code>cloud-init query userdata<\/code><br><em>Permet d&rsquo;afficher les donn\u00e9es utilisateur (<code>user-data<\/code>) fournies \u00e0 l\u2019instance.<\/em><\/li>\n\n\n\n<li>Ex\u00e9cuter un module sp\u00e9cifique: <code>cloud-init single --name set_hostname<\/code><br><em>Cela ex\u00e9cute <strong>uniquement<\/strong> le module <code>set_hostname<\/code>, sans rejouer tout le processus.<\/em><\/li>\n\n\n\n<li>A noter que les anciennes commandes  (<code>cloud-init init<\/code> et <code>cloud-init modules --mode=***<\/code>) permettait d&rsquo;ex\u00e9cuter manuellement les diff\u00e9rentes phases du processus d&rsquo;initialisation. Cependant, elles sont d\u00e9sormais d\u00e9pr\u00e9ci\u00e9s et seront supprim\u00e9es dans les prochaines versions, car leur ex\u00e9cution apr\u00e8s le d\u00e9marrage peut \u00eatre incompl\u00e8te. La seule solution fiable est <strong>de red\u00e9marrer la machine<\/strong> apr\u00e8s un netoyyage avec <code>cloud-init clean --reboot<\/code> comme vu mentionn\u00e9 pr\u00e9c\u00e9demment.<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-esab-accordion esab-0ysj8ndl\" data-mode=\"global\"><div class=\"esab__container\">\n<div class=\"wp-block-esab-accordion-child\"><div class=\"esab__head\" role=\"button\" aria-expanded=\"false\"><div class=\"esab__heading_txt\"><p class=\"esab__heading_tag\">Exemple de r\u00e9ponse sur une instance Debian sur AWS EC2<\/p><\/div><div class=\"esab__icon\"><div class=\"esab__collapse\"><svg version=\"1.2\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\"><path fill-rule=\"evenodd\" d=\"m3.5 20.5c-4.7-4.7-4.7-12.3 0-17 4.7-4.7 12.3-4.7 17 0 4.6 4.7 4.6 12.3 0 17-4.7 4.6-12.3 4.6-17 0zm0.9-0.9c4.2 4.2 11 4.2 15.2 0 4.2-4.2 4.2-11 0-15.2-4.2-4.3-11-4.3-15.2 0-4.3 4.2-4.3 11 0 15.2z\"><\/path><path d=\"m11.4 15.9v-3.3h-3.3c-0.3 0-0.6-0.3-0.6-0.6 0-0.4 0.3-0.6 0.6-0.6h3.3v-3.3c0-0.3 0.3-0.6 0.6-0.6 0.3 0 0.6 0.3 0.6 0.6v3.3h3.3c0.3 0 0.6 0.2 0.6 0.6q0 0.2-0.2 0.4-0.2 0.2-0.4 0.2h-3.3v3.3q0 0.2-0.2 0.4-0.2 0.2-0.4 0.2c-0.4 0-0.6-0.3-0.6-0.6z\"><\/path><\/svg><\/div><div class=\"esab__expand\"><svg version=\"1.2\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\"><path fill-rule=\"evenodd\" d=\"m12 24c-6.6 0-12-5.4-12-12 0-6.6 5.4-12 12-12 6.6 0 12 5.4 12 12 0 6.6-5.4 12-12 12zm10.6-12c0-5.9-4.7-10.6-10.6-10.6-5.9 0-10.6 4.7-10.6 10.6 0 5.9 4.7 10.6 10.6 10.6 5.9 0 10.6-4.7 10.6-10.6z\"><\/path><path d=\"m5.6 11.3h12.8v1.4h-12.8z\"><\/path><\/svg><\/div><\/div><\/div><div class=\"esab__body\">\n<pre class=\"wp-block-code\"><code class=\"\">admin@host$ cloud-init status\nstatus: done\nadmin@host$ cloud-init analyze show\n-- Boot Record 01 --\nThe total time elapsed since completing an event is printed after the \"@\" character.\nThe time the event takes is printed after the \"+\" character.\n\nStarting stage: init-local\n|`-&gt;no cache found @00.00700s +00.00200s\n|`-&gt;found local data from DataSourceEc2Local @00.03200s +00.36500s\nFinished stage: (init-local) 00.88900 seconds\n\nStarting stage: init-network\n|`-&gt;restored from cache with run check: DataSourceEc2Local @02.58500s +00.01700s\n|`-&gt;setting up datasource @02.64400s +00.00000s\n|`-&gt;reading and applying user-data @02.64800s +00.00200s\n|`-&gt;reading and applying vendor-data @02.65000s +00.00000s\n|`-&gt;reading and applying vendor-data2 @02.65000s +00.00000s\n|`-&gt;activating datasource @02.66600s +00.00000s\n|`-&gt;config-migrator ran successfully @02.70200s +00.00100s\n|`-&gt;config-seed_random ran successfully @02.70300s +00.00000s\n|`-&gt;config-growpart ran successfully @02.70300s +00.07700s\n|`-&gt;config-resizefs ran successfully @02.78100s +00.00700s\n|`-&gt;config-mounts ran successfully @02.78800s +00.00100s\n|`-&gt;config-set_hostname ran successfully @02.78900s +00.00100s\n|`-&gt;config-update_hostname ran successfully @02.79000s +00.00000s\n|`-&gt;config-users-groups ran successfully @02.79000s +00.13300s\n|`-&gt;config-ssh ran successfully @02.92300s +00.62000s\nFinished stage: (init-network) 00.97000 seconds\n\nStarting stage: modules-config\n|`-&gt;config-ssh-import-id ran successfully @04.14100s +00.00000s\n|`-&gt;config-locale ran successfully @04.14100s +00.00100s\n|`-&gt;config-set-passwords ran successfully @04.14200s +00.01200s\n|`-&gt;config-grub-dpkg ran successfully @04.15400s +00.26400s\n|`-&gt;config-apt-configure ran successfully @04.41800s +00.03900s\n|`-&gt;config-byobu ran successfully @04.45700s +00.00100s\nFinished stage: (modules-config) 00.35300 seconds\n\nStarting stage: modules-final\n|`-&gt;config-reset_rmc ran successfully @04.84300s +00.00200s\n|`-&gt;config-refresh_rmc_and_interface ran successfully @04.84500s +00.00100s\n|`-&gt;config-rightscale_userdata ran successfully @04.84600s +00.00000s\n|`-&gt;config-scripts-vendor ran successfully @04.84700s +00.00000s\n|`-&gt;config-scripts-per-once ran successfully @04.84700s +00.00100s\n|`-&gt;config-scripts-per-boot ran successfully @04.84800s +00.00000s\n|`-&gt;config-scripts-per-instance ran successfully @04.84800s +00.00000s\n|`-&gt;config-scripts-user ran successfully @04.84800s +00.00000s\n|`-&gt;config-ssh-authkey-fingerprints ran successfully @04.84900s +00.01000s\n|`-&gt;config-keys-to-console ran successfully @04.85900s +00.05600s\n|`-&gt;config-install-hotplug ran successfully @04.91500s +00.00100s\n|`-&gt;config-final-message ran successfully @04.91600s +00.00600s\nFinished stage: (modules-final) 00.13500 seconds\n\nTotal Time: 2.34700 seconds\n\n1 boot records analyzed\nadmin@host$ cloud-init single --name set_hostname\nCloud-init v. 22.4.2 running 'single' at Sat, 01 Feb 2025 10:03:56 +0000. Up 227092.61 seconds.<\/code><\/pre>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Fichier de configuration<\/h3>\n\n\n\n<p>Voici un example de fichier de configuration cloud-config.yml:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"yaml\" class=\"language-yaml\">#cloud-config\nusers:\n  - name: admin\n    sudo: ALL=(ALL) NOPASSWD:ALL\n    groups: sudo\n    ssh-authorized-keys:\n      - ssh-rsa AAAAB3...\npackage_update: true\npackage_upgrade: true\npackages:\n  - nginx\nruncmd:\n  - systemctl start nginx<\/code><\/pre>\n\n\n\n<p>Au premier d\u00e9marrage, ce fichier permet:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>De cr\u00e9er un utilisateur <code>admin<\/code> avec droits sudo et avec acc\u00e8s SSH (la cl\u00e9 publique est fournie)<\/li>\n\n\n\n<li>De <strong>mettre \u00e0 jour le syst\u00e8me \u00e0 son d\u00e9marrage<\/strong>, via l&rsquo;utilisation de  <code>package_update<\/code>&nbsp;et&nbsp;<code>package_upgrade<\/code><\/li>\n\n\n\n<li>D\u2019installer <code>nginx<\/code><\/li>\n\n\n\n<li>De d\u00e9marrer <code>nginx<\/code> apr\u00e8s l\u2019installation (cette commande \u00e9tant dans la section <code>runcmd<\/code>, elle sera effectu\u00e9 \u00e0 chaque d\u00e9marrage)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Idempotence<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Retour sur l&rsquo;exemple du module users-groups<\/h3>\n\n\n\n<p>On m&rsquo;aurait menti ??? Nous venons bien de dire que le user admin allait \u00eatre cr\u00e9e au 1er d\u00e9marrage. Hors <strong>le module users-groups fait parti de la phase config<\/strong> de cloud-init, qui s&rsquo;ex\u00e9cute donc techniquement \u00e0 chaque d\u00e9marrage. <strong>Mais<\/strong> cela ne signifie pas qu&rsquo;il recr\u00e9e ou modifie les utilisateurs \u00e0 chaque reboot. Explication:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Le module <code>users-groups<\/code> s&rsquo;ex\u00e9cute bien \u00e0 chaque d\u00e9marrage, mais&#8230;<\/strong>\n<ul class=\"wp-block-list\">\n<li><code>cloud-init<\/code> <strong>v\u00e9rifie si l&rsquo;utilisateur existe d\u00e9j\u00e0<\/strong> avant d&rsquo;appliquer la configuration.<\/li>\n\n\n\n<li>Si l&rsquo;utilisateur <strong>existe d\u00e9j\u00e0<\/strong>, il <strong>n&rsquo;est pas modifi\u00e9<\/strong> (ni supprim\u00e9, ni recr\u00e9\u00e9).<\/li>\n\n\n\n<li>Si l&rsquo;utilisateur <strong>n&rsquo;existe pas<\/strong>, il est <strong>cr\u00e9\u00e9 avec la configuration d\u00e9finie<\/strong><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Que se passe-t-il \u00e0 chaque d\u00e9marrage ?<\/strong>\n<ul class=\"wp-block-list\">\n<li>\u00c0 chaque boot, <code>cloud-init<\/code> rejoue bien les modules de la phase <code>config<\/code>, y compris <code>users-groups<\/code>, mais :<\/li>\n\n\n\n<li><strong>Si l&rsquo;utilisateur est d\u00e9j\u00e0 pr\u00e9sent dans <code>\/etc\/passwd<\/code> \u2192 rien ne change.<\/strong><\/li>\n\n\n\n<li><strong>Si un utilisateur est supprim\u00e9 manuellement \u2192 il sera recr\u00e9\u00e9<\/strong><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Cons\u00e9quence :<\/strong>\n<ul class=\"wp-block-list\">\n<li><code>cloud-init<\/code> ne \u00ab\u00a0force\u00a0\u00bb pas la modification des utilisateurs existants.<\/li>\n\n\n\n<li>Il ne \u00ab\u00a0remplace\u00a0\u00bb pas les cl\u00e9s SSH ou les permissions si elles ont chang\u00e9.<\/li>\n\n\n\n<li>Il <strong>ajoute<\/strong> les utilisateurs qui manquent.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Idempotence et cloud-init : Pas syst\u00e9matique !<\/h3>\n\n\n\n<p>En principe, <strong>un module est idempotent si<\/strong> :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Il peut \u00eatre ex\u00e9cut\u00e9 plusieurs fois sans effet secondaire.<\/li>\n\n\n\n<li>Il ne refait pas une action inutilement si elle est d\u00e9j\u00e0 appliqu\u00e9e.<\/li>\n<\/ul>\n\n\n\n<p>Mais <strong>dans <code>cloud-init<\/code>, ce n&rsquo;est pas toujours le cas !<\/strong> Certains modules v\u00e9rifient l&rsquo;\u00e9tat actuel avant d&rsquo;agir (<strong>idempotents<\/strong>), d&rsquo;autres non (<strong>non idempotents<\/strong>). Mais on trouve souvent une idempotence partiel : par exemple, si une configuration existe d\u00e9j\u00e0, elle ne sera pas recr\u00e9\u00e9e, mais son contenu ne sera pas v\u00e9rifi\u00e9 ni mis \u00e0 jour.<\/p>\n\n\n\n<p>Voici un tableau pour mieux comprendre le comportement de cerains modules:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>Module Phase config<\/td><td>Idempotance<\/td><td>Explication<\/td><\/tr><tr><td><code>users-groups<\/code><\/td><td>\u274c <em>Non<\/em><\/td><td>Ne modifie pas les utilisateurs existants mais recr\u00e9e ceux supprim\u00e9s<\/td><\/tr><tr><td><code>ssh<\/code><\/td><td>\u274c <em>Non<\/em><\/td><td>Ne recr\u00e9e pas les cl\u00e9s SSH si elles existent d\u00e9j\u00e0, mais  <br>ne met pas \u00e0 jour une cl\u00e9 SSH existante, m\u00eame si elle a \u00e9t\u00e9 modifi\u00e9e.<\/td><\/tr><tr><td><code>write-files<\/code><\/td><td>\u2705 <em>Oui<\/em><\/td><td>\u00c9crit le fichier seulement si son contenu change.<\/td><\/tr><tr><td><code>package-update<br>package-upgrade<\/code><\/td><td>\u274c <em>Non<\/em><\/td><td>Ne s&rsquo;ex\u00e9cute qu&rsquo;une seule fois au premier boot<\/td><\/tr><tr><td><code>runcmd<\/code><\/td><td>\u274c <em>Non<\/em><\/td><td>Ex\u00e9cut\u00e9 une seule fois (sauf si relanc\u00e9 manuellement)<\/td><\/tr><tr><td><code>bootcmd<\/code><\/td><td>\u2705 \u274c<\/td><td>Ex\u00e9cut\u00e9 \u00e0 chaque d\u00e9marrage avant tout autre processus. L&rsquo;idempotence d\u00e9pend des scripts inclus.<\/td><\/tr><tr><td><code>mounts<\/code><\/td><td>\u274c <em>Non<\/em><\/td><td>Ne refait pas un montage s&rsquo;il existe d\u00e9j\u00e0 mais ne met pas \u00e0 jour les options d&rsquo;un montage existant si elles sont diff\u00e9rentes de la configuration.<\/td><\/tr><tr><td><code>apt-configure<\/code><\/td><td>\u274c <em>Non<\/em><\/td><td>Ne modifie que si la config change, mais ne garantit pas une idempotence compl\u00e8te pour la configuration APT.<\/td><\/tr><tr><td><code>locale<\/code><\/td><td>\u2705 <em>Oui<\/em><\/td><td>Ne rechange pas la locale si elle est d\u00e9j\u00e0 correcte<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Examples de configuration<\/h2>\n\n\n\n<p>De nombreux examples de configuration sont disponibles sur le site officielle: <a href=\"https:\/\/cloudinit.readthedocs.io\/en\/latest\/reference\/examples.html#yaml-examples\">All cloud config examples<\/a>. Cetains configurations sont \u00e9galement plus d\u00e9taill\u00e9s, comme la cas de la configuration du r\u00e9seau, sur cette page <a href=\"https:\/\/cloudinit.readthedocs.io\/en\/latest\/reference\/network-config-format-v1.html\">Networking config Version 1<\/a> ou cette autre page <a href=\"https:\/\/cloudinit.readthedocs.io\/en\/latest\/reference\/network-config-format-v2.html\">Networking config Version 2<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Validation et Tests des configurations<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Validation du Sch\u00e9ma<\/h3>\n\n\n\n<p>Vous pouvez valider un fichier de configuration avant de l&rsquo;utiliser en ex\u00e9cutant la commande suivante :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">$ cloud-init schema --config-file cloud-config.yaml<\/code><\/pre>\n\n\n\n<p>Si le fichier est valide, le message suivant s&rsquo;affichera :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">Valid schema cloud-config.yaml<\/code><\/pre>\n\n\n\n<p>Dans le cas contraire, des informations d\u00e9taill\u00e9es vous seront fournies pour vous aider \u00e0 identifier et corriger les erreurs pr\u00e9sentes dans le fichier.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Test des configurations<\/h3>\n\n\n\n<p>Avant de d\u00e9ployer votre configuration sur des instances r\u00e9elles, il est judicieux de la tester localement:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Avec  QEMU vous pouvez  cr\u00e9er une image de machine virtuelle, y int\u00e9grer votre configuration coud-init et la lancer avec QEMU pour observer le comportement<\/li>\n\n\n\n<li>Multipass peut \u00e9galement \u00eatre utilis\u00e9 pour tester des configuration cloud-init, bien que pr\u00e9vu initiallement pour lancer des machines virtuelles Ubuntu en local.<\/li>\n\n\n\n<li>Sur des conteneurs LXD: LXD a un support natif de cloud-init, il permet donc de facilier le processus de test et d&rsquo;it\u00e9ration sur vos scritps de configuration. L&rsquo;utilisation de LXD apporte certains avantages:\n<ul class=\"wp-block-list\">\n<li><strong>Support natif de <code>cloud-init<\/code><\/strong> : De nombreuses images disponibles dans LXD incluent d\u00e9j\u00e0 <code>cloud-init<\/code>, ce qui simplifie la configuration initiale.<\/li>\n\n\n\n<li><strong>Rapidit\u00e9 et l\u00e9g\u00e8ret\u00e9<\/strong> : Les conteneurs LXD sont g\u00e9n\u00e9ralement plus l\u00e9gers et d\u00e9marrent plus rapidement que les machines virtuelles traditionnelles, ce qui acc\u00e9l\u00e8re les cycles de test.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Le test est \u00e9galement possible sur VMs ou conteneurs avec Incus. Ce dernier prend en charge cloud-init, ce qui permet de personaliser et d&rsquo;automatiser l&rsquo;initialisation des instances que ce soit des conteneurs ou des machines virtuelles.<\/li>\n<\/ul>\n\n\n\n<p>Les options QEMU, LXD et Multipass sont document\u00e9s sur la documetation officielle: <a href=\"https:\/\/cloudinit.readthedocs.io\/en\/23.2.1\/howto\/predeploy_testing.html?utm_source=chatgpt.com\">How to test cloud-init locally before deploying<\/a>. Des tutoriaux seront \u00e9galement mis en place dans le futur sur ce blog. Les liens seront ajout\u00e9s ici, le cas \u00e9ch\u00e9ant.<\/p>\n\n\n\n<p><strong>Limitation des tests si l&rsquo;environnement vis\u00e9 est dans le cloud:<\/strong><br>Tester des configurations <code>cloud-init<\/code> qui d\u00e9pendent des m\u00e9tadonn\u00e9es sp\u00e9cifiques comme celles d&rsquo;AWS EC2 peut \u00eatre complexe en environnement local, car cela n\u00e9cessite l&rsquo;\u00e9mulation du service de m\u00e9tadonn\u00e9es d&rsquo;EC2. Cependant, il existe des approches pour simuler cet environnement :<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Utilisation de simulateurs de m\u00e9tadonn\u00e9es EC2<\/strong> :Des outils comme <strong><code>ec2-metadata-mock<\/code><\/strong> peuvent \u00eatre utilis\u00e9s pour \u00e9muler le service de m\u00e9tadonn\u00e9es EC2 en local. Cela permet \u00e0 <code>cloud-init<\/code> de r\u00e9cup\u00e9rer les m\u00e9tadonn\u00e9es comme si l&rsquo;instance s&rsquo;ex\u00e9cutait sur AWS.<\/li>\n\n\n\n<li><strong>Tests dans un environnement AWS r\u00e9el<\/strong> :Pour des tests plus pr\u00e9cis, il est recommand\u00e9 de d\u00e9ployer vos configurations <code>cloud-init<\/code> directement sur des instances EC2. Vous pouvez utiliser des instances de type t2.micro ou t3.micro, qui sont \u00e9ligibles \u00e0 l&rsquo;offre gratuite d&rsquo;AWS, pour effectuer vos tests sans co\u00fbts significatifs.<\/li>\n\n\n\n<li><strong>Utilisation de Multipass<\/strong> :Bien que des outils comme <strong>Multipass<\/strong> soient principalement con\u00e7us pour lancer des machines virtuelles Ubuntu en local, ils peuvent \u00eatre utilis\u00e9s pour tester des configurations <code>cloud-init<\/code>. Cependant, cette approche peut ne pas couvrir toutes les sp\u00e9cificit\u00e9s des m\u00e9tadonn\u00e9es AWS EC2.<\/li>\n<\/ol>\n\n\n\n<p>En r\u00e9sum\u00e9, bien qu&rsquo;il soit possible de simuler les m\u00e9tadonn\u00e9es EC2 en local, la m\u00e9thode la plus fiable pour tester des configurations <code>cloud-init<\/code> d\u00e9pendantes des m\u00e9tadonn\u00e9es AWS est de les d\u00e9ployer directement sur des instances EC2.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Cloud-init est un logiciel appartenant \u00e0 la cat\u00e9gorie IaaS (Infrastructure as a Service), plus pr\u00e9cis\u00e9ment dans le domaine de la configuration syst\u00e8me. Pr\u00e9sentation Cloud-init est un outil Linux largement utilis\u00e9 sur les plateformes cloud pour automatiser l&rsquo;initialisation d&rsquo;une instance lors de son d\u00e9marrage. Bien qu&rsquo;optimis\u00e9 pour les environnements cloud, il est \u00e9galement compatible avec les [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-631","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/tech.fabienletort.com\/index.php?rest_route=\/wp\/v2\/pages\/631","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tech.fabienletort.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/tech.fabienletort.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/tech.fabienletort.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tech.fabienletort.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=631"}],"version-history":[{"count":21,"href":"https:\/\/tech.fabienletort.com\/index.php?rest_route=\/wp\/v2\/pages\/631\/revisions"}],"predecessor-version":[{"id":665,"href":"https:\/\/tech.fabienletort.com\/index.php?rest_route=\/wp\/v2\/pages\/631\/revisions\/665"}],"wp:attachment":[{"href":"https:\/\/tech.fabienletort.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=631"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}