Lorsque vous installez un serveur sous Linux vous avez tendance à répéter toujours les mêmes actions ? Vous cherchez à déployer une infrastructure de manière automatisée ? Il existe de nombreux outils open source et très complets pour cela. On commence aujourd'hui par Cloud-init.
« Fais une chose une fois. Fais une chose deux fois, automatise-la », une citation qui est un peu le mantra de tout bidouilleur en herbe, au cœur de l'informatique moderne. C'est le plus souvent pour la mettre en application que l'on se met à la programmation en créant tout d'abord de petits scripts, mais cela peut aller beaucoup plus loin.
Du preseed à l'Infrastructure-as-code
C'est notamment le cas pour les serveurs et l'hébergement. Au départ, on avait tendance à automatiser la configuration d'une distribution Linux ou de Windows à la main, d'utiliser PXE pour le déploiement sur des machines « bare metal ». Puis des solutions (utiles mais complexes) sont nées il y a une dizaine d'années comme Chef, Puppet ou Tinkerbell pour organiser tout cela. Mais désormais, le cloud est à portée de main.
Et avec lui des instances qui coûtent quelques portions de centime de l'heure, sans parler des hyperviseurs tels que Proxmox VE que l'on peut utiliser sur un serveur local, dans son « Home Lab ». N'importe qui peut facilement lancer un serveur prêt à l'emploi en quelques secondes et l'utiliser chez différents fournisseurs de services (CSP).
Pour les utilisateurs, le besoin d'automatisation s'est donc déporté et il a fallu mettre en place des solutions pour unifier la configuration ou la mise en place d'infrastructures complètes, parfois en « multi-cloud ».
On est désormais entré dans l'ère des API, où une requête HTTPS permet de lancer un serveur. De Cloud-init qui permet de gérer la post-installation. D'Ansible ou de Terraform pour aller un peu plus loin. Sans parler de la gestion des services sous la forme de conteneurs, avec des déploiements via Kubernetes (K8s).
Après plusieurs mois à « jouer » avec tout cela, nous ouvrons aujourd'hui un dossier dans lequel nous évoquerons ces différentes solutions, ce qu'elles permettent et leurs limites. Et la manière dont elles permettent à ceux qui gèrent des infrastructures de ne plus forcément dépendre d'un fournisseur de service en particulier.
Une manière d'améliorer sa résilience lorsque de grosses pannes surviennent et de limiter sa dépendance technologique. Un sujet que nous explorons dans notre magazine #3, actuellement en cours de financement.
Qu'est-ce que Cloud-init ?
Cloud-Init était au départ un projet propre à Ubuntu. Comme on peut le voir dans l'historique de sa documentation, les premières versions datent de 2010, où il était présenté comme un paquet intégré aux images Enterprise Cloud (UEC) et celles proposées par AWS sur son service EC2. Il permettait à l'époque de configurer certains paramètres par défaut comme la langue, le nom d'hôte, les clés SSH, les points de montage, etc.
Désormais, il s'agit d'un véritable standard de l'industrie du cloud. Le paquet est intégré aux images Ubuntu Server, Cloud ainsi qu'EC2, mais aussi par bon nombre de cloud publics et surtout bien d'autres distributions : Alpine, Arch, Debian, Fedora, Gentoo, openSUSE, Red Hat et ses dérivés ainsi que tous les grands xBSD.
L'outil, toujours open source (double licence Apache 2.0 et GPLv3), est aussi bien plus complet comme le montre sa documentation. Il s'agit toujours de créer un fichier de configuration (user-data) indiquant des paramètres à prendre en compte au premier démarrage (mais pas que). Il peut être accompagné de métadonnées d'instance.
Comme le montrent ses exemples de documentation, il est d'ailleurs pensé pour fonctionner en complément avec des outils comme Chef et Puppet. N'hésitez donc pas à explorer ses différentes possibilités.
Comment ça fonctionne ?
Il existe de nombreuses façons de transmettre les user-data. La plus classique, que nous étudierons dans ce premier exemple est celle du fichier cloud-config, utilisant le langage de balisage YAML. Il s'agit donc d'un fichier texte contenant des paramètres respectant un formatage particulier, plutôt classique.
Passons à un petit cas d'école avec un fichier de configuration assez simple que nous utilisons pour des machines et instances de test. Il consiste à les mettre à jour avant de créer un utilisateur, installer différentes applications, télécharger des fichiers, les décompresser, créer des alias, etc. Son contenu est le suivant :
#cloud-config
# On met à jour le système
package_update: true
package_upgrade: true
# On créé l'utilisateur avec droits sudo en précisant sa clé SSH publique
users:
- default
- name: davlgd
groups: [ wheel , sudo ]
shell: /bin/bash
homedir: /home/davlgd
sudo: ['ALL=(ALL) NOPASSWD:ALL']
ssh_authorized_keys:
- collez ici le contenu de votre clé publique
# On installe les applications nécessaires
packages:
- blender
- curl
- fio
- git
- htop
- ioping
- neofetch
- nload
- p7zip-full
runcmd:
# On se place dans le dossier de l'utilisateur
- cd /home/davlgd
# On ajoute un alias pour mettre à jour facilement le système
- echo "alias fup='sudo apt update && sudo apt full-upgrade -y && sudo apt autoremove -y'" >> .bashrc
# On coupe l'accès au compte root pour la connexion SSH
- sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/g' /etc/ssh/sshd_config
- systemctl restart sshd.service
# On télécharge les fichiers de travail
- wget http://ftp.nluug.nl/pub/graphics/blender/demo/movies/ToS/tearsofsteel_4k.mov
- wget https://download.blender.org/demo/test/BMW27_2.blend.zip
- wget https://download.blender.org/demo/test/benchmark.zip
# On décompresse les archives et on nettoie
- 7z x BMW27_2.blend.zip && rm BMW27_2.blend.zip
- 7z x benchmark.zip && rm benchmark.zip
- mv bmw27/*.blend . && rm -r bmw27
- mv benchmark/*.blend . && rm -r benchmark
# Les fichiers étant créés par le compte utilisateur, on change le propriétaire
- chown davlgd:davlgd *
final_message: "Le système est configuré. Délai nécessaire : $UPTIME secondes"
Si vous le souhaitez, vous pouvez également ajouter un redémarrage automatique :
power_state:
delay: "now"
mode: reboot
message: Redémarrage du système
timeout: 30
condition: True
Dans les paramètres ci-dessus, vous pouvez modifier le délai timeout
(en secondes) ou delay
qui peut être indiqué sous la forme "+5"
pour 5 minutes par exemple. L'arrêt de la machine peut être demandé via le mode halt
.
Création d'une VM ou d'une instance avec Cloud-init
Vous pouvez l'utiliser lors de la création d'une machine virtuelle (VM) avec Multipass dans le cas d'Ubuntu. La Freebox Delta utilise également un champ Cloud-init pour configurer ses VM installées depuis les images cloud de différentes distributions. Vous pouvez le modifier et l'adapter à votre besoin.
Certains hyperviseurs gèrent nativement Cloud-init, comme Proxmox VE. Cela prend la forme d'une section dans les paramètres de vos VM, permettant de déclarer le contenu du script. Il suffit donc de la remplir avant le premier démarrage pour que la configuration d'initialisation soit prise en compte.
Comme évoqué plus haut, plusieurs hébergeurs gèrent Cloud-init comme Gandi, OVHcloud et Scaleway en France ou Infomaniak en Suisse qui vient de lancer son IaaS OpenStack. On peut ainsi déclarer la configuration dans l'interface de gestion à la création d'une machine virtuelle. Chez Scaleway, ça passe par les options avancées :

Sur la voie de l'automatisation, l'exemple de la CLI de Scaleway...
Mais on peut également créer des instances de manière automatisée, avec la CLI maison open source (licence Apache 2.0), scw. Elle s'installe via différents gestionnaires de paquets, dont chocolatey (mais pas encore winget). Elle est aussi distribuée sous la forme de binaires qu'il suffit de télécharger et d'exécuter.
Vous devrez vous identifier via votre email et votre mot de passe ou une clé API. Vous pourrez également ajouter une clé SSH à votre compte facilement dans la phase d'initialisation qui démarre de la sorte :
scw init
Vous pouvez ensuite créer une instance simplement en une commande :
scw instance server create type=DEV1-S image=ubuntu_focal zone=fr-par-1
La documentation précise que la liste des instances s'obtient de la sorte :
scw instance server list
Pour viser un projet particulier, ajoutez son identifiant :
scw instance server list project-id=identifiant
Pour avoir le détail sur une commande il suffit de rajouter --help :
scw instance server --help
... avec quelques ajustements nécessaires
Il est également possible de fournir un fichier de configuration Cloud-init. Le client nous a initialement posé problème mais il nous a été confirmé que c'était un bug connu, corrigé dans la version 2.4.0. Tout comme la documentation pour laquelle nous avions proposé des modifications puisqu'elle est en CC-BY-NC-SA-4.0.
Il suffit donc de lancer la création de l'instance de la sorte :
scw instance server create type=DEV1-S image=ubuntu_focal zone=fr-par-1 cloud-init=@cloudconfig.yml
L'ancienne méthode consistait à créer une instance qui ne sera pas démarrée par défaut :
scw instance server create type=DEV1-S image=ubuntu_focal zone=fr-par-1 stopped=true
Ses paramètres sont affichés, récupérez alors son identifiant (ID). Placez votre fichier de configuration YAML dans un fichier (cloudconfig.yml
dans notre cas). Et tapez la commande suivante :
scw instance user-data set key=cloud-init server-id=identifiant content=@cloudconfig.yml
Si vous vous rendez dans l'interface de Scaleway, vous verrez dans les paramètres avancés de l'instance que le fichier de configuration lui a bien été transmis. Il suffit donc de lancer l'instance :
scw instance server start identifiant
Vous trouverez des fonctionnalités similaires dans les CLI proposées par d'autres CSP.