# VAGRANT: création d'une box {{INLINETOC}} Les Boxes sont des machines virtuelles préconfigurées (templates) Une box doit pouvoir être utilisée par n'importe qui sur n'importe quelle plate-forme prise en charge par Vagrant afin de créer un environnement de travail identique. Cet article présente une manière de créer une box à partir d'une image de système d'exploitation. # Configurer le système invité Installer n'importe quel système d'exploitation Linux dans libvirt/qvm et se connecter à celui-ci pour la personnalisation ## Editer le fichier /root/.profile $ sudo nano /root/.profile # ~/.profile: exécuté par des shells de connexion compatibles Bourne. if ["$ BASH"]; then if [-f ~/.bashrc]; then .~/.bashrc Fi Fi mesg n # remplace cette ligne par "tty -s && mesg n" Note: Ceci évite un avertissement, au lancement de vagrant plus tard. ## Changer le nom d'hôte $ vi /etc/hostname dgfip-base ## Configurer le nom d'hôte $ vi /etc/hosts 127.0.0.1 dgfip-base localhost #Les lignes suivantes sont souhaitables pour les hôtes compatibles IPv6 :: 1 localhost ip6-localhost ip6-loopback ff02 :: 1 ip6-allnodes ff02 :: 2 ip6-allrouters ## Installer les paquets supplémentaires installer des packages de développement supplémentaires pour les outils pour compiler et installer correctement $ yum install-y gcc build-essentiel kernel-headers kernel-headers-devel automake autoconf openssh-server permettre au service ssh de démarrer au démarrage afin que nous puissions ssh entrer dans la machine dès son démarrage. chkconfig sshd on ## Configuration de l'utilisateur vagrant ### Création de l'utilisateur vagrant avec mot de passe vagrant $ adduser vagrant $ passwd vagrant Changement de mot de passe pour l'utilisateur vagrant. Nouveau mot de passe : MOT DE PASSE INCORRECT : basé sur un mot du dictionnaire MOT DE PASSE INCORRECT : est trop simple Retapez le nouveau mot de passe : passwd : mise à jour réussie de tous les jetons d'authentification. ### Importation de la clé ssh de l'utilisateur vagrant ``` mkdir -p /home/vagrant/.ssh chmod 0700 /home/vagrant/.ssh scp user@xx.xx.xxx.xxx:/opt/vagrant/embedded/gems/gems/vagrant-1.8.1/keys/vagrant.pub /home/vagrant/.ssh/authorized_keys chmod 0600 /home/vagrant/.ssh/authorized_keys $ chown -R vagrant /home/vagrant/.ssh ``` Vagrant utilise la clé privée pour se connecter à l'invité, le problème est que la clé privée doit rester privée. Si on permet à d'autres de le lire, cette condition n'est pas remplie. Afin d'éviter lors de la connection sur l'hôte l'erreur «Les autorisations sont trop ouvertes» on doit restreindre les autorisations sur les fichiers authorized_keys `chmod 600 /home/vagrant/.ssh/authorized\_keys` ## Configuration des droits vagrant exécute des commandes dur les systèmes invités en utilisant une connextion ssh par clé privé, il est donc nécessaire : * d'autoriser l'utilisateur vagrant a exécuter les commandes système via sudo * d'autoriser une connexion par l'utilisateur vagrant sans une authentification par mot de passe ### Configuration les droits sudo de l'utilisateur vagrant L'utilisateur vagrant doit être autorisé à envoyer des commandes distantes à l'aide sans une invite de mot de passe et sans devoir utiliser une console dans /etc/sudoers. Dans `/etc/sudoers` Defaults requiretty interdit l'exécution de la commande sudo à partir d'autre chose qu'une console ou un terminal (les utilisateurs doivent d'abord se connecter, puis passer à un accès privilégié (root) via su / sudo), il faut donc désactiver la condition requiretty dans /etc/sudoers. Si cela n’est pas fait, vagrant ne pourra pas appliquer les modifications au démarrage. La désactivation des connexions directes en root est nécessaire pour que les systèmes se conforment à DISA-STIG, à CIS et à d'autres référentiels de sécurité. Afin de limiter l'entorse à cette règle la désativation de la condition requiretty est limitée au seul utilisateur vagrant. ``` cat < /etc/sudoers.d/vagrant vagrant ALL=(ALL) NOPASSWD: ALL Defaults:vagrant !requiretty EOF ``` ### Configuration de sshd_config Afin de permettre à l'utilisateur de se connecter ssh sans utiliser le couple user/password (utilistaion de l'authentification par clé privée), modifier /etc/ssh/sshd\_config ``` sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/g' /etc/ssh/sshd_config ``` ### Configuration de Polkit L'intégration de systemd dans les nouvelles configurations (RHEL 7, Debian 8, Ubuntu 15.04) impose l'utilisation de ce système pour la gestion de certains services. Polkit (ex PolicyKit) est utilisé en remplacemnt de sudo pour ces services, il est donc nécessaire d'aménager polkit afin de permettre à l'utilisateur vagrant d'agir sur ces services (comme systemd). Rajouter une policy permettant aux utilisateurs du Groupe **Wheel** à exécuter des commandes sans confirmation du mot de passe: ``` cat < /etc/polkit-1/rules.d/49-nopasswd_global.rules /* Allow members of the wheel group to execute any actions * without password authentication, similar to "sudo NOPASSWD:" */ polkit.addRule(function(action, subject) { if (subject.isInGroup("wheel")) { return polkit.Result.YES; } }); EOF ``` Puis intégrer l'utilisateur **vagrant** dans le groupe **wheel**: ``` usermod -aG wheel vagrant ``` ## Configuration du réseau ### Mofitication de l'interface de management vagrant utilise un réseau privé pour effectuer certaines opérations de gestion sur les ordinateurs virtuels. Toutes les machines virtuelles auront une interface connectée à ce réseau et une adresse IP attribuée dynamiquement Lors de l'installation l'interface est créé par MACVTAP avec une adresse MAC. Afin de pouvoir transporter la machine sur d'autres architecture, modifier /etc/sysconfig/network-scripts/ifcfg-eth0 pour utiliser le DEVICE plutôt que l'adresse MAC: ``` DEVICE=eth0 TYPE=Ethernet ONBOOT=yes NM_CONTROLLED=no BOOTPROTO=dhcp ``` ### Activation de NetworkManager Lors de la configuration du réseau par configure_networks.rb si nmcli est installé vagrant tente de relancer NetworkManager, afin d'éviter que celui-ci ne se plante activer le service et l'ajouter pour le reboot: ``` systemctl start NetworkManager.service systemctl enable NetworkManager.service ``` ## Modifier le message de bienvenue Intégrer dans le message d'accueil le numéro de version ``` vi /etc/motd Bienvenue dans la version 0.1.0 de dgfip-base! ``` ## Vérifier les modifications Redémarrer le serveur invité ``` shutdown -r now ``` Se connecter avec le compte vagrant et vérifier que le message du jour (motd) mis en place s'affiche: ``` Last login: Thu Apr 26 10:26:24 2018 from xx.xx.xxx.xx Bienvenue dans la version 0.1.0 de dgfip-base! (jeu. avril 26 10:53:58)--(dgfip-base:~)- ``` ## Nettoyer le système invité Supprimer le fichier de règles réseau persistant udev à l’aide de la commande rm. ``` rm -f /etc/udev/rules.d/70-persistent-net.rules ``` Nettoyer yum en utilisant la commande suivante. ``` yum clean all ``` Nettoyerr le répertoire tmp en supprimant son contenu. ``` rm -rf /tmp/* ``` Nettoyer ensuite les derniers journaux des utilisateurs connectés. ``` rm -f /var/log/wtmp /var/log/btmp ``` Nettoyer l'historique des commandes. ``` history -c ``` ## Arrêter la VM ``` shutdown -h now ``` # Préparation de la box vagrant ## Récupérer l'image du système Sur la machine hôte dans laquelle VM est en cours d'exécution aller dans /var/lib/libvirt/images/ et choisir l'image brute dans laquelle ont été faites les modifications et copier quelque part par exemple /test ``` cp /var/lib/libvirt/images/test.img ~/VagrantBoxes ``` ## Création de la configuration Passer dans le répertoire VagrantBoxes. ``` cd ~/VagrantBoxes ``` créer deux fichiers metadata.json et Vagrantfile ### Créer le fichier metadata.json ``` vi metadata.json { "provider" : "libvirt", "format" : "qcow2", "virtual_size" : 40 } ``` ### Créer le fichier Vagrantfile ``` vi Vagrantfile Vagrant.configure("2") do |config| config.vm.provider :libvirt do |libvirt| libvirt.driver = "kvm" libvirt.host = 'localhost' libvirt.uri = 'qemu:///system' end config.vm.define "new" do |vmbox| vmbox.vm.box = "dgfip-base" vmbox.vm.provider :libvirt do |domain| domain.memory = 1024 domain.cpus = 1 end end end ``` Les noms d'étiquettes entre les pipes ne doivent comporter que des caractères alphabétiques. ## Convertir test.img en format qcow2 ``` sudo qemu-img convert -f raw -O qcow2 test.img invite.qcow2 ``` ## Renommer ubuntu.qcow2 en box.img ``` mv invite.qcow2 box.img ``` # Empaquetage de la box ## Empaqueter la box ``` tar cvzf dgfip-base-0.1.0.box ./metadata.json ./Vagrantfile ./box.img ``` L'empaquetage prendra un certain temps. Note: Afin de pouvoir construire plusieurs versions de la vm dgfip-base, le numéro de version ets ajouter dans le nom du fichier box. ## Tester la nouvelle box ### Passer dans le répertoire VagrantTest ``` cd ~/VagrantTest ``` ### Ajouter la box à vagrant ``` vagrant box add 'dgfip-base' file://~/VagrantBoxes/dgfip-base-0.1.0.box ``` En cas de succès, on doit voir une sortie comme ceci: ``` ==> box: Box file was not detected as metadata. Adding it directly... ==> box: Adding box 'dgfip-base' (v0) for provider: box: Unpacking necessary files from: file:///root/VagrantBoxes/dgfip-base-0.1.0.box ==> box: Successfully added box 'dgfip-base' (v0) for 'libvirt'! ``` On notera le v0. Il n'y a pas encore de version spécifiée. ###Initialiser le projet vagrant ``` vagrant init dgfip-base A `Vagrantfile` has been placed in this directory. You are now ready to `vagrant up` your first virtual environment! Please read the comments in the Vagrantfile as well as documentation on `vagrantup.com` for more information on using Vagrant ``` Maintenant, il y a un fichier Vagrantfile avec les paramètres par défaut dans votre répertoire actuel. Modifier ce fichier Vagrantfile en utilisant un éditeur de texte ``` # Modifier la ligne suivante de config.vm.box = "base" # en config.vm.box = "devops" # enregistrer le fichier ``` **base** est le nom par défaut du vagrant pour une boîte. Mais nous avons dit à la boîte vagabonde ajouter le nom Devops. ## Lancer la VM vagrant ``` vagrant up --provider=libvirt ``` Vagrant passe par les étapes ci-dessous lors de la création d'un nouveau projet: - Se connecte à libvirt via SSH. - Vérifie si l'image de la box est disponible dans le pool de stockage Libvirt. Sinon, télécharge dans le pool de stockage Libvirt distant en tant que nouveau volume. - Crée une image diff de COW de l'image de la box de base pour le nouveau domaine Libvirt. - Crée et démarre un nouveau domaine sur l'hôte Libvirt. - Recherche le bail DHCP dans le serveur Dnsmasq. - Attend que SSH soit disponible. - Synchronise les dossiers et exécute le provisioner Vagrant sur le nouveau domaine si il est configuré dans Vagrantfile. ``` vagrant up Bringing machine 'dgfip-rhel7' up with 'libvirt' provider... ==> dgfip-rhel7: Uploading base box image as volume into libvirt storage... ==> dgfip-rhel7: Creating image (snapshot of base box volume). ==> dgfip-rhel7: Creating domain with the following settings... ==> dgfip-rhel7: Creating shared folders metadata... ==> dgfip-rhel7: Starting domain. ==> dgfip-rhel7: Waiting for domain to get an IP address... ==> dgfip-rhel7: Waiting for SSH to become available... dgfip-rhel7: dgfip-rhel7: Vagrant insecure key detected. Vagrant will automatically replace dgfip-rhel7: this with a newly generated keypair for better security. dgfip-rhel7: dgfip-rhel7: Inserting generated public key within guest... dgfip-rhel7: Removing insecure key from the guest if it's present... dgfip-rhel7: Key inserted! Disconnecting and reconnecting using new SSH key... ==> dgfip-rhel7: Configuring and enabling network interfaces... dgfip-rhel7: SSH address: xxx.xxx.xxx.xxx:22 dgfip-rhel7: SSH username: vagrant dgfip-rhel7: SSH auth method: private key ==> dgfip-rhel7: Installing NFS client... ==> dgfip-rhel7: Exporting NFS shared folders... ==> dgfip-rhel7: Preparing to edit /etc/exports. Administrator privileges will be required... ==> dgfip-rhel7: Mounting NFS shared folders... ```