Creación de entornos con múltiples configuraciones en Vagrant con Ansible

0
3419

En este tutorial vamos a ver cómo definir varias configuraciones para los roles de Ansible y cómo desplegarlos en Vagrant. Esto puede ser útil cuando tenemos entornos que utilizan un stack tecnológico similar (por ejemplo dos sitios web de WordPress).

Índice de contenidos

1. Introducción

Aquí nos vamos a centrar en qué modificaciones hay que hacer para poder definir múltiples configuraciones. En este otro tutorial podéis ver una explicación detallada sobre cómo instalar y el funcionamiento de Vagrant y Ansible.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 15′ (2 Ghz Intel Core I7, 8GB DDR3).
  • Sistema Operativo: OS X El Capitan 10.11.6
  • Ansible 2.2.0.0
  • Vagrant 1.8.7

3. Host Vars

En nuestro proyecto de Ansible creamos una carpeta a la que llamaremos «host_vars». En ella vamos a añadir un fichero por cada configuración diferente que queramos tener.

Por ejemplo vamos a ver cómo haríamos para un rol de MySQL.

Configuración 1


mysql_databases:
     - name: baseDeDatos1
       replicate: no

mysql_users:
     - name: usuarioA
       pass: 12345
       priv: "*.*:ALL,GRANT"

Configuración 2


mysql_databases:
     - name: baseDeDatos2
       replicate: no

mysql_users:
     - name: usuarioB
       pass: 546789
       priv: "*.*:ALL,GRANT"

De esta forma ejecutaremos el rol de MySQL cambiando el nombre de los usuarios y de la base de datos según nos interese.


- name: MySQL | Ensure the database's are present
  mysql_db:
    name: "{{ item.name }}"
    collation: "{{ item.collation | default('utf8_general_ci') }}"
    encoding: "{{ item.encoding | default('utf8') }}"
    state: present
  with_items: "{{mysql_databases}}" # Esta variable tomará valores diferentes
  when: mysql_databases|lower() != 'none'

4. Creación de JSON para el Vagrantfile

Una buena forma de añadir y modificar configuraciones de forma clara es crear un archivo JSON para cada configuración donde asignaremos la ip, el mapeo de los puertos, etc.


{
    "nodes" :
    {
        "maquina1" :
        {
            ":node" : "maquina1",
            ":ip" : "192.168.33.10",
            ":host" : "grupoMaquinas.maquina1",
            "ports" : [
                {
                    ":host" : 2222,
                    ":guest" : 22,
                    ":id" : "ssh"
                },
                {
                    ":host" : 33066,
                    ":guest" : 3306,
                    ":id" : "mysql"
                }
            ],
            ":memory" : 2048,
            ":ansible.inventory_path" : "../inventory",
            ":ansible.verbose" : "vvv",
            ":ansible.playbook" : "../playbook.yml"
        },
        "maquina2" :
        {
            ":node" : "maquina2",
            ":ip" : "192.168.33.11",
            ":host" : "grupoMaquinas.maquina2",
            "ports" : [
                {
                    ":host" : 2223,
                    ":guest" : 22,
                    ":id" : "ssh"
                },
                {
                    ":host" : 33067,
                    ":guest" : 3306,
                    ":id" : "mysql"
                }
            ],
            ":memory" : 2048,
            ":ansible.inventory_path" : "../inventory",
            ":ansible.verbose" : "vvv",
            ":ansible.playbook" : "../playbook.yml"
        }
      }
    }

Es importante que los puertos en la máquina anfitriona (host) sean diferentes en cada configuración para evitar conflictos.

Una vez hecho esto, solo es necesario leer el archivo JSON en el Vagrantfile y asignar las variables, iterando sobre cada configuración que hayamos definido.


nodes = (JSON.parse(File.read("nodes.json")))['nodes']

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box     = "ubuntu/trusty64"

  nodes.each do |node|
    name = node[0] # name of node
    node_values = node[1] # content of node

    config.vm.define name do |config|

      # configures all forwarding ports in JSON array
      ports = node_values['ports']
      ports.each do |port|
        config.vm.network :forwarded_port,
          host:  port[':host'],
          guest: port[':guest'],
          id:    port[':id']
      end

      config.vm.hostname = node_values[':node']
      config.vm.network :private_network, ip: node_values[':ip']

      config.vm.provider :virtualbox do |vb|
        vb.customize ["modifyvm", :id, "--memory", node_values[':memory']]
        vb.customize ["modifyvm", :id, "--name", node_values[':node']]
        vb.customize ["modifyvm", :id, "--ioapic", "on"]
        vb.customize ["modifyvm", :id, "--cpus", "2"]
      end

      # Provision config
      config.vm.provision "ansible" do |ansible|
        ansible.inventory_path = node_values[':ansible.inventory_path']
        ansible.verbose = node_values[':ansible.verbose']
        ansible.playbook = node_values[':ansible.playbook']
        #ansible.tags= "vhosts"
      end

    end
  end
end

5. Modificación del Inventory

En este archivo añadimos una entrada por cada configuración que tengamos.


[grupoMaquinas]
maquina1 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222 ansible_ssh_user='vagrant' ansible_ssh_private_key_file='../maquina1/virtualbox/private_key'

maquina2 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2223 ansible_ssh_user='vagrant' ansible_ssh_private_key_file='../maquina2/virtualbox/private_key'

En este ejemplo «[grupoMaquinas]» hace referencia a ambas configuraciones y «maquina1» y «maquina2» a cada una por separado.

Es importante que el Inventory esté en la misma ruta que el directorio «host_vars» y que el nombre que le demos a cada configuración que definamos (en este caso «maquina1» y «maquina2») sea el mismo que el nombre de cada fichero dentro de «host_vars».

6. Desplegando en Vagrant

Ahora es necesario especificar la configuración que queremos usar al introducir los comandos de vagrant. Por ejemplo:


vagrant up maquina1

vagrant provision maquina2

7. Conclusiones

Una vez hayamos modificado estos archivos, podemos seguir añadiendo todas las configuraciones que queramos de forma sencilla.

De esta forma, nos podemos asegurar que sólo cambia la configuración de cada entorno pero que los roles se instalan exactamente igual (mismos paquetes, versión…)

8. Referencias

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad