Pourquoi vagrant m’aide dans mon quotidien ? + Vagrantfile complet

Print Friendly, PDF & Email

Si vous me suivez depuis quelques temps et que vous avez suivi quelques live, vous le savez peut être j’utilise souvent vagrant et j’ai plusieurs raisons à cela.

Dans notre domaine, il est important de pouvoir mettre en place facilement certaines stack techniques : kubernetes, prometheus/grafana, elk, couchbase, infra couplée à un pipeline… Pouvoir avoir faiclement ce type d’infrastructure permet d’engager facilement une démarche de tests ou d’apprentissage. En effet plus besoin de passer du temps à réinstaller x ou y paquets et refaire des configurations et de laisser son laptop envahit de machines virtuelles dont on ne sait plus bien dans quel état on les a laissé.

Vagrant permet de mettre noir sur blanc une infrastructure avec des scripts plus ou moins poussés.

Et ce n’est pas tout, car bien sûr nous allons le versionner avec un bon dépôt git pour suivre son évolution voir on peut pousser plus loin avec la mise en place de tags suivant la composition ou les options de la stack en question (malynx le lynx).

Et au-delà de ça c’est important de rentrer dans une démarche d’itération dans l’apprentissage. Ce mode de provisionning et de re-provisionning va permettre de vous libérer une partie de l’esprit pour tenter et retenter des choses de très nombreuses fois.

Enfin et bien sûr quand on fait des démos (talks, tutoriels…), c’est extrêmement pratique pour partager avec votre auditoire la stack en question. Mais également très pratique pour l’expliquer, expliquer également son installation.

Alors j’ai également fait le choix de vagrant couplé à virtualbox (alors que j’aurais pu le coupler à libvirt) pour permettre de rendre accessible cela au plus grand nombre, virtualbox étant bien plus courrant. De la même manière j’utilise un provisionner interne à base de scripts bash plutôt que ansible. Bash va permettre à l’aides commentaires et de la manière donc on va le faire d’expliquer une installation.

Mon évolution avec Vagrant

Finalement, au fur et à mesure des années, je suis partie d’un Vagrantfile assez limité avec de nombreuses boucles à un nombre de boucles plus limités, une meilleure description des machines virtuelles déployés et une interaction avec l’utilisateur qui aurra lancé le vagrant up. Enfin cela n’est que mon avis.

Toutes les stacks que j’utilise ou que j’ai utilisé son souvent dans ce dépôt git.

C’est à dire que j’essaie pour toutes les technos que j’apprends de rapidement cerner le cas d’école pour pratiquer de la pédagogie et je le monte sur vagrant.

Mon vagrantfile le plus avancé est certainement celui intégrant ce que j’appelle le cluster kubernetes pédagogique à savoir :

  • k8s installé avec kubespray (ansible)
  • du nfs
  • le déploiement d’un worpress et persistence de la donnée sur du NFS
  • la mise en place d’une stack de monitoring
  • quelques outils de tooling liés à kubernetes (kubectx, kubens, flux, helm, mes alias…)
  • déploiement de consul et de consulsync et mise à jour des routes pour kube-router + un petit dnsmasq pour tester le dns consul

Quelques points que je trouve sortir de l’ordinaire dans ce que j’ai appris

Vagrant, je me suis rendu compte que souvent on le retrouve sous sa forme la plus simple et efficace mais pas forcément la plus pratique. J’y ai donc appris et développé quelques pratiques avec le temps comme je vous disais.

Ainsi par exemple, je préfère maintenant prévoir différents use-case suivant les besoin d’une stack plus ou moins épurées ou avec différentes mises en situation.

Pour cela j’utilise des interactions avec l’utilisateur avec un prompt (c’est juste des bouts de ruby) :

ingressNginx = ""
wordpress = ""
wordpressUrl = "wordpress.kub"
etcHosts = ""

	# Check ingress controller
	case ARGV[0]
		when "provision", "up"
  	print "Do you want nginx as ingress controller (y/n) ?\n"
  	ingressNginx = STDIN.gets.chomp
  	print "\n"

  if ingressNginx == "y"
	  print "Do you want a wordpress in your kubernetes cluster (y/n) ?\n"
  	wordpress = STDIN.gets.chomp
  	print "\n"

		# check if wordpress
  	if wordpress == "y"
 			print "Which url for your wordpress ?"
  		wordpressUrl = STDIN.gets.chomp
     	unless wordpressUrl.empty? then wordpressUrl else 'wordpress.url' end
		end

    print "Do you want a monitoring in your kubernetes cluster (y/n) ?\n"
    monitoring = STDIN.gets.chomp
    print "\n"

		# check if monitoring
  	if monitoring == "y"

			# prometheus url
 			print "Which url for your prometheus ?"
  		prometheusUrl = STDIN.gets.chomp
     	unless prometheusUrl.empty? then prometheusUrl else 'prometheus.url' end

			# grafana url
 			print "Which url for your grafana ?"
  		grafanaUrl = STDIN.gets.chomp
     	unless grafanaUrl.empty? then grafanaUrl else 'grafana.url' end
		end

	end
	else
  	# do nothing
	end

Et bien sûr derrière cela permet de placer des conditions dans la boucles principales :

        if wordpress == "y"
          cfg.vm.provision :shell, :path => "install_nfs.sh"
          cfg.vm.provision :shell, :path => "install_wordpress.sh", :args => wordpressUrl
	end

Ensuite parfois j’utilise des scripts bash mais également un bloc commun d’éléments installés dans une variable définie directement dans le Vagrantfile. Cela permet d’éviter de chercher partout ce qui est présent sur toutes les machines.

  common = <<-SHELL
  sudo apt update -qq 2>&1 >/dev/null
  sudo apt install -y -qq git vim tree net-tools telnet git python3-pip sshpass nfs-common 2>&1 >/dev/null
  #curl -fsSL https://get.docker.com -o get-docker.sh 2>&1 
  #sudo sh get-docker.sh 2>&1 >/dev/null
  #sudo usermod -aG docker vagrant
  #sudo service docker start
  sudo echo "autocmd filetype yaml setlocal ai ts=2 sw=2 et" > /home/vagrant/.vimrc
  sed -i 's/ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/g' /etc/ssh/sshd_config
  sudo systemctl restart sshd
  SHELL

Je me donne dedans la possiblité de rapidement installer docker sur les VM car assez souvent cela permet d’intégrer des petites choses si nécessaires (exporters…).

Une autre chose que j’aime faire c’est de décrire mes vm dans une variables sous forme de map. Là encore c’est très pratique pour définir les ressources de chacune et définir des type qui permettront de filtrer les scripts à jouer sur chacune.

	NODES = [
  	{ :hostname => "autohaprox", :ip => "192.168.12.10", :cpus => 2, :mem => 512, :type => "haproxy" },
  	{ :hostname => "autokmaster", :ip => "192.168.12.11", :cpus => 6, :mem => 6144, :type => "kub" },
  	#{ :hostname => "autokmaster2", :ip => "192.168.12.12", :cpus => 4, :mem => 2048, :type => "kub" },
  	#{ :hostname => "autokmaster3", :ip => "192.168.12.13", :cpus => 4, :mem => 2048, :type => "kub" },
  	{ :hostname => "autoknode1", :ip => "192.168.12.14", :cpus => 6, :mem => 6144, :type => "kub" },
  	#{ :hostname => "autoknode2", :ip => "192.168.12.15", :cpus => 2, :mem => 2048, :type => "kub" },
  	{ :hostname => "autodep", :ip => "192.168.12.20", :cpus => 2, :mem => 2048, :type => "deploy" }
	]

Et cela permet notamment de réécrire à la volée les /etc/hosts de chaque machine pour disposer d’une résolution par les hostnames de toutes les machines.

  NODES.each do |node|
    if node[:type] != "haproxy"
    	etcHosts += "echo '" + node[:ip] + "   " + node[:hostname] + "' >> /etc/hosts" + "\n"
		else
			etcHosts += "echo '" + node[:ip] + "   " + node[:hostname] + " autoelb.kub ' >> /etc/hosts" + "\n"
		end
  end #end NODES

Enfin un autre truc sympa et simple c’est de passer les variables définies par l’utilisateur dans notre script bash. C’est simple et ça permet de personnaliser certains points.

        if monitoring == "y"
          cfg.vm.provision :shell, :path => "install_monitoring.sh", :args => [prometheusUrl,grafanaUrl]
        end

Là encore ça reste du ruby.

Voilà vous pouvez donc retrouver ce dépôt dans les liens mentionnés ci-dessus. Et vous pouvez vous amuser avec. Personnellement je préfère pas trop en ajouter pour rester encore un peu simple et rendre la chose abordable sans y passer des heures. Mais vous pouvez vous éclater c’est fait pour ça.