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
- 2. Entorno
- 3. Host Vars
- 4. Creación de JSON para el Vagrantfile
- 5. Modificación del Inventory
- 6. Desplegando en Vagrant
- 7. Conclusiones
- 8. Referencias
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…)