Vagrant: entornos de desarrollo portables, reproducibles y livianos

Publicado el Viernes, 20 de diciembre de 2013
Vagrant

Vagrant

Si no conocen y usan Vagrant, déjenme recomendárselo. Vagrant es una herramienta que nos facilita enormemente la gestión de distintos ambientes de desarrollo. Mediante "boxes", podemos configurar un sistema desde cero para un entorno de desarrollo específico y transportarlo con nuestro proyecto con un solo archivo de configuración: Vagrantfile.

El lema en su sitio web: Crea y configura ambientes de desarrollo livianos, reproducibles y portables, y cumple con lo que promete. Está escrito en Ruby y es Software Libre. Las máquinas son provistas por VirtualBox (por defecto), pero puede usarse también VMware, AWS o cualquier otro proveedor.

Para desarrolladores y administradores de sistemas, elimina el conocido tema "funciona en mi máquina". Una vez creado el Vagrantfile, la misma configuración puede ser usada en una box en cualquier computadora con GNU/Linux, Mac OS X o Windows. Esto nos permite instalar cualquier herramienta necesaria para cada proyecto particular, sin afectar en lo más mínimo nuestro sistema operativo.

La persona que ingresa al proyecto a trabajar, sea un nuevo programador, un diseñador, o un administrador de sistemas, tiene su ambiente de desarrollo pronto con un sólo comando y sin tener que configurar nada a mano.

También es ideal para el programador políglota. Si programamos en varios lenguajes, es muy cómodo tener el ambiente adecuado para cada uno y no llenar nuestra máquina con distintos servidores web (conflictos de puertos, ¡emocionante!), gemas, máquinas virtuales Java, distintas versiones de cada compilador/intérprete, etc. Cada proyecto tiene su ambiente y es cuestión de usar vagrant up y tenemos todo corriendo en una máquina virtual.

Vagrant

Usando Vagrant

Tras instalar Vagrant (en Debian con apt-get install vagrant ya alcanza, se encarga de instalar VirtualBox y demás dependencias) es muy fácil inicializarlo. En el directorio de nuestro proyecto hacemos:

$ vagrant init precise32 http://files.vagrantup.precise32.box
$ vagrant up

Esto nos descarga una versión de Ubuntu 12.04 LTS (Precise Pangolin) y nos crea la box "precise32". Las boxes son archivos tar que difieren según el proveedor de las máquinas. Además de la máquina virtual exportada del proveedor, el tar debe tener un archivo "metadata.json" con información del box y un campo requerido "provider" con el nombre del proveedor para el que está hecha la box. En Vagrantbox.es hay un montón de boxes base para descargar de varios sistemas operativos distintos.

Tras tener levantada la máquina, podemos acceder a ella con el comando vagrant ssh. Pero no hay que editar el código de nuestro proyecto mediante SSH (al menos no necesariamente 😀 ). Vagrant incluye la funcionalidad de compartir directorios. Por defecto, Vagrant comparte el directorio de nuestro proyecto, donde creamos el Vagrantfile (cuando dimos vagrant init). Este se comparte en la máquina virtual en /vagrant.

Si queremos compartir más directorios, es cuestión de agregarlos a nuestro Vagrantfile:

Vagrant.configure("2") do |config|
  # configuraciones...
  config.vm.synced_folder "/home/fernando/workspace/php", "/code/php"
  ...
end

El primer parámetro es el directorio de nuestra computadora y el segundo el de la máquina virtual desde donde vamos a acceder a él. Si no existe, Vagrant crea ese directorio.

Networking

Generalmente vamos a tener un servidor corriendo en la máquina virtual, pero no es lo ideal estar probando nuestro código por ssh. Una de las opciones de networking de Vagrant es port forwarding (redirección de puertos). De esa manera podemos acceder a puertos de la máquina virtual desde nuestra computadora. También hay que agregar esta configuración en el Vagrantfile:

Vagrant.configure("2") do |config|
  ... # más configuraciones
  config.vm.network :forwarded_port, host: 5000, guest: 80
end

Esto va a hacer que al visitar http://localhost:5000 en nuestra computadora, obtengamos lo que se está sirviendo en el puerto 80 de la máquina virtual. Esta configuración se levanta al ejecutar vagrant up o vagrant reload si la máquina ya estaba funcionando.

Aprovisionamiento

Acá es donde viene lo mágico de Vagrant. El aprovisionamiento nos permite instalar paquetes y configurar ajustes en la máquina virtual en un proceso automatizado y repetible. Por lo tanto podemos levantar la misma máquina con un ambiente exactamente igual en cualquier lugar. Si han usado Travis CI, es similar a cuando configuramos el archivo .travis.yml y le decimos qué paquetes instalar o qué archivos de configuración editar.

Hay varias opciones para provisionamiento, la más sencilla (para arrancar) es usar scripts de shell. Se pueden escribir los scrips en el Vagrantfile mismo con bash + Ruby pero para ser un poco más prolijos podemos crear un archivo sh aparte y escribir nuestro aprovisionamiento ahí. Después en el Vagrantfile decimos qué archivo sh usar para esto:

config.vm.provision :shell, path: "bootstrap.sh"

Y así al hacer vagrant up, se ejecutará este script. Podemos ver la salida de los comandos en nuestra terminal al levantar la máquina. Si la máquina ya está "prendida", podemos reiniciarla y aprovisionarla con vagrant reload --provision. Un ejemplo de uno de mis Vagrant file en la vida real: https://github.com/picandocodigo/List-Category-Posts/blob/master/bootstrap.sh

Experiencias

Esto es apenas la punta del iceberg, de todas las funcionalidades y características nombrada hay mucho más para profundizar y conocer. Vagrant Docs incluye documentación muy completa para arrancar desde cero hasta toparse con problemas más avanzados.

Mis primeras experiencias con Vagrant no fueron del todo buenas. Estuve en un proyecto cuya configuración estaba rota, tenía que levantar la máquina y no había forma de hacerlo. El proyecto era bastante caótico, la organización del cliente era inexistente, y pasé más tiempo debuggeando problemas con la máquina virtual que desarrollando. Esto seguramente me alejó un poco a Vagrant.

Cuando reinstalé Debian en mi máquina, y me puse a programar en PHP, tuve que instalar y configurar Apache, PHP, y MySQL. Apache no estaba siguiendo los enlaces simbólicos, tenía alguna configuración de permisos que no funcionaba, etc. Este tipo de problemas me habían pasado alguna vez ya, y no tenía ganas de volver a pasar por esto. Fue ahí cuando decidí ponerme las pilas con Vagrant. Así me aseguraba de tener que hacer este trabajo solo una vez. Como agregado: no necesité instalar todo lo mencionado en mi sistema operativo, y además puedo compartir el ambiente de desarrollo con otras personas.

Al escribir el script de aprovisionamiento de cero y probarlo en otra computadora y que funciona mágicamente simplemente haciendo vagrant up, vi la luz. Es una de esas cosas que tras ser descubiertas, es difícil volver atrás. Desde entonces cada vez que empiezo un proyecto nuevo, considero armar una máquina en Vagrant para el ambiente de desarrollo. El tiempo que requiere aprender a usar Vagrant es mínimo comparado con la cantidad de tiempo que nos va a ahorrar a futuro.

Digamos que aprendí lo básico para empezar a sacarle provecho. Pero tras usarlo en un proyecto laboral, me di cuenta que todavía me falta un poco en cuanto a provisionamiento. Si bien se puede hacer de todo con shell scripts, no los veo tan mantenibles (aunque me encanta usar sed, awk y demás en scripts 😀 ). Vagrant acepta para aprovisionamiento otras herramientas como Ansible, Chef y Puppet. Está en mis metas a corto plazo aprender al menos uno de estos, cuando lo haga compartiré lo que haya aprendido por acá.

10 comentarios en este post

Feed de comentarios
  1. Avatar

    kernelp4nic 20 diciembre. 2013 - 11:38

    Nosotros usamos hace un montón y es genial. Tenemos todos nuestros ambientes de desarrollo aprovisionados con Chef desde Vagrant. El mismo Chef que usamos en producción.

    Aparte con providers como VMWare se nota una madurez en el proyecto brutal. Antes parecía un juguete, porque estabas atado a VirtualBox y jamás pondrías nada en producción con Vbox, pero ahora, pueden atacar otros mercado que seguramente haga crecer en pila la herramienta.

    • Avatar

      Fernando 23 diciembre. 2013 - 13:25

      Excelente, o sea que tienen exactamente el mismo environment para desarrollo que en producción, ¿no?

      Ya que estamos te hago una pregunta, estoy entre Chef y Puppet. No he mirado *nada* de ninguno de los dos, pero quiero aprender uno. ¿Cuál recomendarías?

      • Avatar

        kernelp4nic 26 diciembre. 2013 - 11:52

        Mirá, nosotros usamos Chef desde un principio y mi experiencia con Puppet no fué más que probándolo un rato y portando algunas recetas que ya tenía. Me gusta particularmente la manera que tiene Chef de ejecutar las cosas, es como más procedural que Puppet, ya que Puppet decide (creo) el orden en que va a ejecutar las cosas y no vos explícitamente.

        Es mucho más facil perseguir un problema de orden cuando vos sabés exactamente cuando se van a correr las cosas.

        Igualmente, creo que la parte de Chef Server es extremadamente más complicada de armar y setupear que un Puppet Master, pero ta, todo depende de el uso que necesites llegar a darle, nosotros por ahora con chef-solo nos es suficiente.

        Creo que lo mejor es que pruebes ambos y decidas 🙂

  2. Avatar

    Casiva Agustin 5 marzo. 2014 - 13:59

    También estoy trabajando a full con Vagrant, algunos tips que fuí descubriendo con el tiempo de uso.

    Montar las particiones con NFS hace que todo sea mas rápido, el shared folder de Virtual box es super lento.

    Usar Chef para el aprovisionamiento es la mejor opción, hace todo mas sencillo.

    El port forwarding es mejor que el Bridget networking.

    La mayoría de las boxes traen re poco espacio en disco, si trabajas con una base de datos medianamente grande, o un proyecto, seguro te quedas corto. Las boxes de Opscode traen varios gbs mas, esta trae 40gb http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_debian-7.2.0-i386_chef-provisionerless.box.

    Espero que estos tips les aporten algo.

  3. Avatar

    Luis Barragan 18 febrero. 2015 - 03:52

    Tengo instalado una maquina virtual con vagrant

    cuando intento hacer un git clone me aparece el siguiente mensaje:

    fatal: unable to access ‘https://github.com/****/****.git/’: Could not resolve host: github.com; Name or service not known

    esto solo sucede cuando estoy conectado a la red de mi casa con un modem Technicolor TG582n que me acaba de dar mi compañia de internet, sin embargo si me conecto a otra red, puedo hacer el clone sin problemas

    de antemano gracias por su ayuda

  1. Varying Vagrant Vagrants: Configuración desarrollo en WordPress | Picando Código | 3 septiembre. 2014 - 12:30

    […] Vagrant es probablemente la herramienta que me ha ahorrado más horas de configuración de ambientes de desarrollo. Desde que empecé a usar Vagrant, he adelgazado 10 kilos en apenas 2 semanas, se me dejó de caer el pelo, todas mis estimaciones son precisas y no recibo más Spam. […]

Dejar un comentario

Toasty!