Virtualización en entornos de desarrollo – Parte 2

En esta segunda parte de nuestro artículo sobre las ventajas de la virtualización aplicada a los entornos de desarrollo vamos a completar la introducción a este concepto con un ejemplo práctico de cómo ponerlo en marcha.

Basándonos en la filosofía de que nuestro entorno sea lo más parecido posible al de producción, vamos a suponer un entorno virtualizado basado en Linux. Así, tanto si tenemos un entorno creado y lo queremos virtualizar o si empezamos desde cero con un nuevo entorno, estos son los pasos que deberemos seguir

Paso 1: Instalar las herramientas de virtualización

Las herramientas que vamos a utilizar y que deberemos instalar son:

Paso 2: Identificar el software y la configuración

Ahora debemos determinar cuáles son las herramientas que vamos a necesitar para desarrollar, ejecutar y desplegar. Un ejemplo de las mismas puede ser:

  • Lenguajes de programación, librerías externas
  • Herramientas de gestión del desarrollo: ant, Maven, git
  • Editores / IDEs: Vim, emacs, Eclipse, IDEA, PyCharm, etc.
  • Base de datos local: Oracle, SQLite, MySQL, PostgreSQL
  • Ficheros de configuración del entorno y del software de desarrollo
Paso 3: Configuración de Vagrant

Por último debemos crear una configuración de Vagrant para nuestro entorno, para ello debemos:

  • Determinar una distribución base (Ubuntu, CentOS, etc.)
  • Crear el script de Vagrant a partir de la base
  • Crear y referenciar los scripts de aprovisionamiento del entorno desde el script de Vagrant con la información del paso 2

Aunque lo hayamos ordenado cronológicamente, lo cierto es que los pasos anteriores no deben verse como un conjunto de tareas a ejecutar estrictamente en ese orden. Normalmente los pasos 2 y 3 los iremos ejecutando en paralelo y de forma iterativa hasta llegar al resultado final, sobre todo si estamos virtualizando un entorno existente.

Imagen base y arranque

Una vez instalado todo el software de virtualización, creamos un directorio para nuestro entorno y configuramos la imagen base de Vagrant que queramos utilizar así como algunos ficheros. En este ejemplo usamos Ubuntu 14.04 y asumimos host Unix o similar:


gt; mkdir -p entorno_prueba/scripts && cd entorno_prueba/scripts

gt; touch provision_prod.sh && chmod +x provision_prod.sh

gt; echo "#\!/bin/bash" > provision_prod.sh

gt; cp provision_prod.sh provision_dev.sh

gt; cp provision_prod.sh provision_user.sh

gt; cd .. && vagrant init -m ubuntu/trusty64

Estos comandos darán como resultado la siguiente estructura:

Los tres scripts van a ser ejecutados por Vagrant dentro de nuestro entorno y es donde vamos a insertar los comandos necesarios para aprovisionarlo:

  • prod: todo lo necesario para que nuestro entorno sea lo más parecido posible al de producción
  • dev: todo lo necesario para desarrollar y desplegar nuestro proyecto
  • user: otras configuraciones y ajustes necesarios que iremos viendo más adelante

La filosofía es que si ya tenemos una política de aprovisionamiento para servidores de producción, debe ir en nuestro script prod, así posiblemente nos ahorramos algo de trabajo y seguimos nuestra máxima de reducir diferencias entre plataformas. Si no existe tal política de aprovisionamiento, después de este paso ya existirá, y nuestro script prod puede ser usado en futuros entornos de producción al aprovisionar entornos cloud, por ejemplo.

Todo lo que no sea relativo al entorno de producción y requiera permisos de root, como instalación de software de desarrollo o cambios en ficheros de configuración, servicios, etc. irá en el script dev.

El resto de cambios irá en el script user, que puede ser usado para definir configuraciones específicas, descargar el proyecto del control de versiones, copiar ficheros de usuario, etc. Normalmente se ejecutará sin privilegios de root.

Antes de arrancar por primera vez nuestro entorno, vamos a editar el fichero Vagrantfile, a referenciar nuestros scripts (de momento vacíos) y a añadir algunas opciones más:

# -*- mode: ruby -*-

# vi: set ft=ruby :

Vagrant.configure(2) do |config|

  config.vm.box = "ubuntu/trusty64"

  config.vm.hostname = "entorno_prueba"

  config.ssh.forward_x11 = true

  config.vm.provider "virtualbox" do |vb|

    vb.memory = "2048"

    vb.name = "EntornoPrueba"

  end

  config.vm.provision "shell", path: "./scripts/provison_prod.sh"

  config.vm.provision "shell", path: "./scripts/provison_dev.sh"

  config.vm.provision "shell", path: "./scripts/provison_user.sh", privileged: false

end

Aparte del nombre de nuestro entorno y la memoria base que le vamos a dar, hemos indicado que se ejecute con “X11 forwarding” de modo que sea el servidor X11 de nuestro host el que muestre las aplicaciones gráficas que se ejecuten en el entorno virtual. De esta forma evitamos el tener que instalar y arrancar un entorno de escritorio completo dentro de nuestra máquina virtual.

Ya estamos listos para arrancar nuestro entorno virtual y empezar a configurarlo. Desde el directorio base (donde se ubica el Vagrantfile) ejecutamos:


gt; vagrant up

Esperamos a que se descargue la imagen base de Ubuntu (podemos ir a por un café) y si todo va bien, al finalizar nos informará de que está listo el entorno, con lo que podremos ejecutar el siguiente comando para entrar por ssh:


gt; vagrant ssh

El siguiente prompt que tendremos será el de Ubuntu como usuario vagrant en nuestro entorno de desarrollo:

$vagrant@entorno_prueba>

Configuración del entorno

Y ya estamos en nuestro entorno base Ubuntu como el usuario vagrant. A partir de aquí vamos a ir dando forma a nuestros scripts de configuración. Si ya habíamos copiado o adaptado un script existente para producción, verificamos que se haya ejecutado correctamente (ver que se ha instalado todo el software, servicios, etc.)

Lo siguiente será abrir nuestros scripts en un editor de texto e ir ejecutando en el entorno virtual uno a uno los comandos necesarios para configurarlo, copiando cada comando al script correspondiente (prod, dev o user). De esta forma, cuando desechemos el entorno y creemos uno nuevo, se ejecutarán los scripts de aprovisionamiento y tendremos nuestro entorno listo en unos momentos:


gt; vagrant destroy && vagrant up

Normalmente, en dev instalaremos el servidor de base de datos local, si procede (normalmente en entornos de producción estarán en máquinas separadas), y en user descargamos el proyecto de nuestro sistema de control de versiones, copiamos cualquier fichero de configuración que necesitemos y configuramos nuestro editor o IDE. Como guía debemos saber que Vagrant comparte por defecto la carpeta base del entorno automáticamente con la máquina virtual: Este directorio aparecerá dentro de nuestra máquina virtual en el path /vagrant

Compartir el entorno

Una vez que hemos terminado de afinar los detalles en nuestros scripts y fichero Vagrant, podemos subirlo a nuestro repositorio git:


gt; git init

gt; git commit -a -m "Commit inicial de entorno_prueba"

gt; git remote add origin \     git@servidor.remoto:/ruta/a/repo/entorno_prueba.git

gt; git push --all

Una vez hecho esto podemos pasar la URL a nuestros compañeros de trabajo. Siempre que tengan instalado Virtualbox, Vagrant y git, sólo con descargarse el proyecto y ejecutar vagrant up ya tendrán disponible el entorno de desarrollo.

Conclusión

Aunque es un tema bastante amplio y que da para algunos otros artículos, hemos intentado ofrecer algunas recomendaciones interesantes evitando extendernos mucho con los detalles de la implementación los cuales intentaremos ir completando en próximos artículos.