Introduction à Vagrant
Vagrant est un un outil de la chaine DevOps pour la création et la configuration d'environnements virtualisés. Il peut être considéré comme une couche au dessus de logiciels de virtualisation comme VirtualBox, VMware, voire Amazon EC2... afin de fournir la configuration, le provisioning et le déploiement d'une VM. Depuis la version 1.6, Vagrant fournit un support pour l'exécution de conteneurs Docker.
Vagrant s'utilise via une interface en ligne de commande. Le concept central est la box qu'il faut voir comme une machine virtuelle préconfigurée (template). Vagrant Cloud sert de plateforme d'échange pour trouver des boîtes et y déposer ses propres boîtes.
Ensuite, Vagrant s'utilise à travers un cycle de vie qui se résume en trois étapes :
- Configuration (il faut détailler ici le rôle du fichier Vagrantfile).
- Provisioning : c'est en gros l'importation de données dans la VM. Avec Vagrant il est possible d'utiliser les outils de provisioning suivants : File, Shell, Ansible, CFEngine, Chef Solo, Chef Client, Docker, Puppet Apply, Puppet Agent et Salt.
- Déploiement : il vise à transférer votre image de VM sur un noeud (serveur). Le déploiement se réalise en utilisant la commande vagrant push par Heroku, SFTP et FTP, en écrivant vos propres scripts de ligne de commande.
Comme vous le voyez, l'ensemble de l'architecture Vagrant repose sur la notion de recettes (receipes en Anglais), c'est à dire la description d'étapes à réaliser pour atteindre un but. Il ne s'agit pas à proprement parler de programmation (il n'y a pas de boucle ici).
Pour aller encore plus loin, par rapport à notre travail de TP, dans l'utilisation de Vagrant, vous pouvez aussi, par vous même, réaliser le TP en ligne suivant. C'est un travail en plus !
Énoncé du TP
Partie facile
Veuillez suivre les étapes décrites dans le texte ci-dessous. Nous suposons que vous avez lancé une VM à partir de RosettaHub. Cela signifie que toutes les manipulations proposées ou à faire le sont à partir d'une VM AWS/RosettaHub.
# Installer vagrant et autres outils $ sudo apt-get install vagrant \ > golang-github-hashicorp-atlas-go-dev # Ajouter une image/box ubuntu de votre choix # Pour cela remplacez XXX par une distribution. $ vagrant box add ubuntu/XXX # Lister les images/box de votre machine virtuelle $ vagrant box list # Le fichier Vagrantfile contient la specification du type # de machine virtuelle et comment elle est configurée # et provisionnée. Commencez par créer un fichier Vagrantfile : $ vagrant init # La partie interessante du Vagrantfile doit ressembler à Vagrant.configure(2) do |config| config.vm.box = "base" end Editer le fichier Vagrantfile pour remplacer "base" par config.vm.box = "ubuntu/XXX" # Lancez la machine virtuelle/box : $ vagrant up # Connectez vous en SSH dans la machine virtuelle : $ vagrant ssh # Tapez une commande Linux une fois connecté, par exemple : ubuntu@ubuntu-xenial:˜$ uname -nor ubuntu-xenial 4.4.0-87-generic GNU/Linux # Sortez de la VM ubuntu@ubuntu-xenial:˜$ exit logout Connection to 127.0.0.1 closed. $ # N'oubliez pas d'arréter la machine virtuelle : $ vagrant halt
Intermède
Voici un exemple complet de déploiement, avec les logs, à partir d'un Macbook Pro, de Ansible/tower. Je mentionne également les versions de Vagrant et Virtualbox utilisées.
christophe:~ christophecerin$ mkdir vagrant-project christophe:~ christophecerin$ cd vagrant-project/ christophe:vagrant-project christophecerin$ vagrant --version Vagrant 2.2.3 christophe:vagrant-project christophecerin$ VBoxManage --version 6.0.4r128413 christophe:vagrant-project christophecerin$ vagrant init ansible/tower 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. christophe:vagrant-project christophecerin$ vagrant up --provider virtualbox Bringing machine 'default' up with 'virtualbox' provider... ==> default: Box 'ansible/tower' could not be found. Attempting to find and install... default: Box Provider: virtualbox default: Box Version: >= 0 ==> default: Loading metadata for box 'ansible/tower' default: URL: https://vagrantcloud.com/ansible/tower ==> default: Adding box 'ansible/tower' (v3.4.1) for provider: virtualbox default: Downloading: https://vagrantcloud.com/ansible/boxes/tower/versions/3.4.1/providers/virtualbox.box default: Download redirected to host: vagrantcloud-files-production.s3.amazonaws.com ==> default: Successfully added box 'ansible/tower' (v3.4.1) for 'virtualbox'! ==> default: Importing base box 'ansible/tower'... ==> default: Matching MAC address for NAT networking... ==> default: Checking if box 'ansible/tower' version '3.4.1' is up to date... ==> default: Setting the name of the VM: vagrant-project_default_1550261517485_18390 Vagrant is currently configured to create VirtualBox synced folders with the `SharedFoldersEnableSymlinksCreate` option enabled. If the Vagrant guest is not trusted, you may want to disable this option. For more information on this option, please refer to the VirtualBox manual: https://www.virtualbox.org/manual/ch04.html#sharedfolders This option can be disabled globally with an environment variable: VAGRANT_DISABLE_VBOXSYMLINKCREATE=1 or on a per folder basis within the Vagrantfile: config.vm.synced_folder '/host/path', '/guest/path', SharedFoldersEnableSymlinksCreate: false ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat default: Adapter 2: hostonly ==> default: Forwarding ports... default: 22 (guest) => 2222 (host) (adapter 1) ==> default: Running 'pre-boot' VM customizations... ==> default: Booting VM... ==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 127.0.0.1:2222 default: SSH username: vagrant default: SSH auth method: private key default: Warning: Connection reset. Retrying... default: Warning: Remote connection disconnect. Retrying... default: Warning: Connection reset. Retrying... default: Warning: Remote connection disconnect. Retrying... default: Warning: Connection reset. Retrying... default: Warning: Remote connection disconnect. Retrying... default: default: Vagrant insecure key detected. Vagrant will automatically replace default: this with a newly generated keypair for better security. default: default: Inserting generated public key within guest... default: Removing insecure key from the guest if it's present... default: Key inserted! Disconnecting and reconnecting using new SSH key... ==> default: Machine booted and ready! ==> default: Checking for guest additions in VM... default: The guest additions on this VM do not match the installed version of default: VirtualBox! In most cases this is fine, but in rare cases it can default: prevent things such as shared folders from working properly. If you see default: shared folder errors, please make sure the guest additions within the default: virtual machine match the version of VirtualBox you have installed on default: your host and reload your VM. default: default: Guest Additions Version: 5.2.22 default: VirtualBox Version: 6.0 ==> default: Setting hostname... ==> default: Configuring and enabling network interfaces... ==> default: Mounting shared folders... default: /vagrant => /Users/christophecerin/vagrant-project christophe:vagrant-project christophecerin$ vagrant ssh Welcome to Ansible Tower! Log into the web interface here: https://10.42.0.42/ Username: admin Password: FYQRPYCeeVSe The documentation for Ansible Tower is available here: http://www.ansible.com/tower/ For help, visit http://support.ansible.com/ [vagrant@ansible-tower ~]$ ls [vagrant@ansible-tower ~]$ pwd /home/vagrant [vagrant@ansible-tower ~]$ cd / [vagrant@ansible-tower /]$ ls bin dev home lib64 mnt proc run srv tmp vagrant boot etc lib media opt root sbin sys usr var [vagrant@ansible-tower /]$ exit déconnexion Connection to 127.0.0.1 closed. christophe:vagrant-project christophecerin$
Il vous reste à ouvrir un navigateur et à vous connecter à l'adresse qui sera donnée, ainsi qu'avec le loggin et le mot de passe fournis. Vous pourrez alors découvrir Ansible / tower : Red Hat® Ansible® Tower helps you scale IT automation, manage complex deployments and speed productivity. Centralize and control your IT infrastructure with a visual dashboard, role-based access control, job scheduling, integrated notifications and graphical inventory management. And Ansible Tower's REST API and CLI make it easy to embed Ansible Tower into existing tools and processes.
Si vous voulez faire un peu de ménage avant de repartir sur une autre image/box (ici une ubuntu/trusty32) vous pouvez procéder en suivant le cycle vagrant halt; vagrant destroy; vagrant init <...>; vagrant up; vagrant ssh, comme suit :
christophe:vagrant-project christophecerin$ vagrant halt ==> default: Attempting graceful shutdown of VM... christophe:vagrant-project christophecerin$ vagrant destroy default: Are you sure you want to destroy the 'default' VM? [y/N] y ==> default: Destroying VM and associated drives... Il faut modifier ici votre Vagrantfile ou refaire un vagrant init ubuntu/trusty32 pour recréer un nouveau Vagrantfile christophe:vagrant-project christophecerin$ vagrant up Bringing machine 'default' up with 'virtualbox' provider... ==> default: Importing base box 'ubuntu/trusty32'... ==> default: Matching MAC address for NAT networking... ==> default: Checking if box 'ubuntu/trusty32' version '20190206.0.0' is up to date... ==> default: Setting the name of the VM: vagrant-project_default_1550315983820_82799 ==> default: Clearing any previously set forwarded ports... ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat ==> default: Forwarding ports... default: 22 (guest) => 2222 (host) (adapter 1) ==> default: Booting VM... ==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 127.0.0.1:2222 default: SSH username: vagrant default: SSH auth method: private key default: default: Vagrant insecure key detected. Vagrant will automatically replace default: this with a newly generated keypair for better security. default: default: Inserting generated public key within guest... default: Removing insecure key from the guest if it's present... default: Key inserted! Disconnecting and reconnecting using new SSH key... ==> default: Machine booted and ready! ==> default: Checking for guest additions in VM... default: The guest additions on this VM do not match the installed version of default: VirtualBox! In most cases this is fine, but in rare cases it can default: prevent things such as shared folders from working properly. If you see default: shared folder errors, please make sure the guest additions within the default: virtual machine match the version of VirtualBox you have installed on default: your host and reload your VM. default: default: Guest Additions Version: 4.3.36 default: VirtualBox Version: 6.0 ==> default: Mounting shared folders... default: /vagrant => /Users/christophecerin/vagrant-project christophe:vagrant-project christophecerin$ vagrant ssh Welcome to Ubuntu 14.04.5 LTS (GNU/Linux 3.13.0-165-generic i686) * Documentation: https://help.ubuntu.com/ System information as of Sat Feb 16 11:20:06 UTC 2019 System load: 0.9 Processes: 79 Usage of /: 3.4% of 39.34GB Users logged in: 0 Memory usage: 15% IP address for eth0: 10.0.2.15 Swap usage: 0% Graph this data and manage this system at: https://landscape.canonical.com/ Get cloud support with Ubuntu Advantage Cloud Guest: http://www.ubuntu.com/business/services/cloud 0 packages can be updated. 0 updates are security updates. New release '16.04.5 LTS' available. Run 'do-release-upgrade' to upgrade to it. vagrant@vagrant-ubuntu-trusty-32:~$ pwd /home/vagrant vagrant@vagrant-ubuntu-trusty-32:~$ ls / bin dev home lib media opt root sbin sys usr var boot etc initrd.img lost+found mnt proc run srv tmp vagrant vmlinuz vagrant@vagrant-ubuntu-trusty-32:~$ exit logout Connection to 127.0.0.1 closed. christophe:vagrant-project christophecerin$ christophe:vagrant-project christophecerin$ vagrant halt ==> default: Attempting graceful shutdown of VM... christophe:vagrant-project christophecerin$
ATTENTION : si votre noyau est en 32 bits, vous ne pouvez pas lancer une box 64 bits. Veuillez également vérifier si Virbualbox est un executable 32 bits ou 64 bits. Il pourrait y avoir des incompatibilités entre le/les provisionners et les box.
Partie un peu plus dure : provisionner avec le shell
Commencer par modifier votre Vagrantfile précédent pour créer un script qui sera lancé par la méthode inline. Le script installera un paquet de votre choix.
$script = <<-SCRIPT echo I am provisioning... apt get install "paquet_de_votre_choix" date > /etc/vagrant_provisioned_at SCRIPT Vagrant.configure("2") do |config| config.vm.provision "shell", inline: $script end
Modifiez maintenant le Vagrantfile de sorte que le script d'installation du paquet se télécharge automatiquement depuis Internet et s'exécute.
Vagrant.configure("2") do |config| config.vm.provision "shell", path: "https://example.com/provisioner.sh" end
Modifier encore une fois comme suit votre fichier Vagrantfile de sorte que le script soit paramétré par le nom de deux paquets à installer automatiquement paquet1, paquet2 :
Vagrant.configure("2") do |config| config.vm.provision "shell" do |s| s.inline = "echo $1 $2;apt get install $1; apt get install $2" s.args = ["paquet1, paquet2"] end end
Pour terminer, on voudrait que le nom des deux paquets précédents à installer soient en paramètre de la commande vagrant up. Inspirez vous du code suivant pour réaliser cette demande :
# Vagrantfile should be similar to: require 'getoptlong' opts = GetoptLong.new( [ '--custom-option', GetoptLong::OPTIONAL_ARGUMENT ] ) customParameter='' opts.each do |opt, arg| case opt when '--custom-option' customParameter=arg end end Vagrant.configure("2") do |config| ... config.vm.provision :shell do |s| ... s.args = "#{customParameter}" end end # Then, you can run: $ vagrant --custom-option="paquet1 paquet2" up $ vagrant --custom-option="paquet1 paquet2" provision
Pour aller plus loin
Supposons maintenant que nous avons un PC/Mac à la maison sur lequel nous avons installé Vagrant. Pour utiliser de la ressource disponible chez RosettaHub/AWS, nous devons installer le plugin AWS de vagrant sur le PC/Mac, puis il s'agit de créer une instance à distance au-lieu d'utiliser le web console de AWS. Tous les détails de cette technique visant à piloter une prise de resource chez AWS à distance, de manière automatique, se trouvent ici : https://github.com/mitchellh/vagrant-aws.