
Infraestructura como Código con Ansible y Vagrant:
La infraestructura como código (IaC) es un enfoque moderno para gestionar y aprovisionar infraestructuras de TI (tecnologías de la información) a través de archivos de configuración legibles y reutilizables. En lugar de realizar configuraciones manuales y repetitivas en servidores, la IaC permite describir de manera declarativa o imperativa los recursos necesarios.
Algunas de sus ventajas son:
-
Automatización: Elimina la necesidad de configurar manualmente servidores y redes.
-
Control de réplicas: Las mismas configuraciones pueden ser replicadas en múltiples entornos (desarrollo, pruebas, producción).
-
Control de versiones: Al tratarse de código, es fácil comprobar lso cambios en configuraciones y revertirlos si es necesario.
-
Reducción de errores humanos: Minimiza la posibilidad de errores manuales al automatizar procesos complejos.
Ansible:

Ansible es una herramienta de automatización de TI que permite la configuración de sistemas, el despliegue de aplicaciones y la orquestación de tareas complejas.
Utiliza archivos YAML llamados “Playbooks” para definir el estado deseado de la infraestructura, ya sea número de equipos, configuraciónes, paqueteria instalada, etc.
Inventario en Ansible:
El inventario es el archivo donde se definen los equipos que vamos a configurar, en este caso, se llama hosts
. Los equipos se agrupan de la siguiente manera:
- Grupo all: Incluye todos los equipos definidos.
- Grupo servidores: En este ejemplo, hemos creado este grupo y añadido nuestra máquina, denominada
nodo1
(que luego se modificará de nombre).
Información del nodo:
ansible_ssh_host
: Dirección IP del equipo a configurar.ansible_ssh_user
: Usuario sin privilegios para acceder por SSH.ansible_ssh_private_key_file
: Ruta del archivo con la clave privada para el acceso.
Configuración en ansible.cfg:
- Especifica el archivo de inventario en el parámetro
inventory
. - Desactiva la comprobación de claves de los hosts con
host_key_checking = False
para evitar verificaciones en cada conexión SSH.
Por otro lado, ansible puede trabajar con variables que obtiene de distinta manera:
-
A nivel de nodo: definimos variables para cada nodo en el inventario, por ejemplo: ansible_ssh_host, ansible_ssh_user, …
-
A nivel de grupo de nodos : Hemos creado un directorio que se tiene que llamar group_vars, dentro de este directorio podemos crear ficheros con las variables que creamos a nivel del grupo. En este ejemplo hemos creado un fichero all, por lo que las variables serán conocidas para todos los nodos. Hemos definido 3 variables para todos los nodos:bd_name, bd_user y bd_pass.
-
Gathering Facts: Variables que obtiene ansible de los nodos que está configurando. La primera tarea que ejecuta el play es obtener información del nodo que va a configurar. Toda esa información se puede usar al definir las tareas, por ejemplo: ansible_hostname, ansible_distribution, etc. Para ver esa información podemos ejecutar:
ansible nodo1 -m setup
.
La instalación y configuración la realizaremos más abajo, en el Taller 1.
Vagrant:

Vagrant es una herramienta que permite crear y gestionar entornos de desarrollo virtualizados. Utiliza en este caso QEMU/KVM, aunque es compatible con otras plataformas para automatizar la creación de máquinas virtuales.
Se integra fácilmente con Ansible, permitiendo el aprovisionamiento automático de las máquinas virtuales creadas.
Ansible se centra en la automatización y gestión de la configuración, Vagrant facilita la creación y manejo de entornos de desarrollo, es decir, con Vagrant creo las máquinas que necesite, y con Ansible, las configuro automáticamente.
Instalación:
Para poder instalar vagrant, primero debemos tener instalado QEMU/KVM, como lo explico aquí .
Para poder instalar vagrant:
sudo apt install vagrant
Al instalarse, se instala también el paquete vagrant-libvirt, que contiene un plugin para que vagrant sea compatible con libvirt + QEMU/KVM.
Si ocurriese algún error, y no se instalase, para hacerlo manualmente:
sudo vagrant plugin install vagrant-libvirt
Para poder obtener la imagen de Debian12, mediante box que son las imágenes, que utiliza vagrant para las máquinas, es decir, las imágenes base (plantillas) con clonación enlazada o vinculada.
Para su uso, es siempre desde un usuario sin privilegios, ya que cada usuario tiene sus propias boxes. (Hay que elegir libvirt cuando pregunte mientras se instala):
vagrant box add debian/bookworm64
vagrant box list
- Cada usuario tiene sus propias imagenes de box.

Creación de máquinas:
Para poder crear las máquinas, tenemos que crear un directorio, por ejemplo /home/usuario/vagrant
y en su interior, creamos un archivo llamado Vagrantfile:
vagrant init
Lo abro y añado lo siguiente:
Vagrant.configure("2") do |config|
config.vm.box = "debian/bullseye64"
config.vm.hostname="prueba"
end

Para iniciar la máquina / crear el escenario (desde el directorio donde esta el archivo Vagrantfile):
vagrant up

Para acceder a la máquina prueba:
vagrant ssh

Para suspender, apagar o destruir:
vagrant suspend
vagrant halt
vagrant destroy
vagrant status
Como último detalle, en el directorio donde esta el archivo Vagrantfile, al crear una máquina, se crea tambien un directorio oculto llamado .vagrant, donde se almacenan los datos de las máquinas de nuestro escenario.
Por ejemplo, si el directorio donde esta todo es /home/usuario/taller3
, entonces vagrant ha creado un directorio oculto llamado .vagrant
, como explico justo arriba. En dicho directorio, se encuentran los archivos de configuración de la máquina, por ejemplo, para la clave ssh /taller3/.vagrant/machines/default/libvirt/private_key
.

En un escenario complejo, donde hay que crear y destruir muchas veces el escenario, es recomendable eliminar este directorio manualmente, para evitar posibles errores.
Taller 1: Ansible - Playbook sencillo:
En este taller, veremos como instalar y configurar ansible, y como crear un playbook sencillo para empezar.
Para instalar ansible en una máquina basada en Debian:
sudo apt install ansible
En mi caso, parto de una máquina Debian 12, la cual es mi host donde tengo instalado ansible, y otra máquina que es la que voy a configurar con ansible.
El usuario de la máquina destino que configura ansible, debe poder ejecutar sudo y sin contraseña, que como ya sabemos, como superusuario:
visudo
Añadiendo:
usuario ALL=(ALL:ALL) NOPASSWD: ALL
Trabajaremos con los archivos de este repositorio , por lo que hacemos un fork, y lo clonamos en nuestra máquina host.
Hay que entrar al directorio del Taller 1 y modificar los siguientes archivos, adaptándolos a nuestra necesidad:
ansible.cfg:
[defaults]
inventory = ./hosts
host_key_checking = False
hosts:
all:
children:
servidores:
hosts:
debiansible:
ansible_ssh_host: 192.168.122.42
ansible_ssh_user: debian
ansible_ssh_private_key_file: /home/debian/.ssh/id_rsa
- Aquí declaro el nombre (debiansible), ip, usuario y ubicación de la clave ssh de la máquina destino que se va a configurar mediante ansible.
Para comprobar que hay conectividad y que funciona bien:
sudo ansible -m ping servidores
sudo ansible -m ping all
sudo ansible -m ping debiansible
- Como explico más arriba, en este ejemplo el grupo se llama servidores, como se ve en el archivo hosts.


Según el esquema de directorios, en el archivo ansible.cfg hay que indicar donde se encuentra el archivo hosts (inventario donde se definen los equipos a configurar), que en este caso esta en el mismo directorio.

En el archivo host hay que especificar el nombre de mi máquina (debiansible), su ip, el usuario para conectarme por ssh y la ruta de la clave privada que usaré.

Para hacer ping a una máquina:
ansible -m ping debiansible
Para configurar el playbook , se realiza mediante el archivo site.yaml , donde he cambiado el nombre del archivo /files/foo.conf
a /files/foo.txt
:
hosts: all
become: true
tasks:
# Actualizamos paquetes
- name: Actualizamos el sistema
apt: update_cache=yes upgrade=yes
# Instalar paquetes
- name: "Instalar paquetes con apt"
apt:
# Aquí tienes que poner lo necesario para instalar git y apache2
name:
- git
- apache2
state: present
# Copia un fichero a la máquina remota
- name: "Copiar fichero a la máquina remota"
copy:
src: files/foo.txt
dest: /etc/
owner: root
group: root
mode: '0644'
# Copia un template a un fichero
- name: "Copiar un template a un fichero de la máquina remota"
template:
src: template/index.j2
dest: /var/www/html/index.html
owner: www-data
group: www-data
mode: 0644
- hosts: all. Significa que las tareas se van a ejecutar en todos los nodos definidos en el inventario. Podríamos haber puesto hosts: servidores o hosts.
- become: true: En las tareas que necesiten ejecutarse como administrador se utilizará sudo.
- tasks: Lista de tareas. Todas las tareas tienen un mensaje en el parámetro name y el uso de un módulo.
Este playbook, lo que hace es:
- Actualiza el sistema.
- Instala los paquetes git y apache2.
- Copia un archivo (foo.txt) a la máquina remota.
- Copia un template (index.j2) a un fichero en la máquina remota.

Para ejecutar el playbook (desde la misma ubicación donde se encuentra el archivo site.yaml):
ansible-playbook site.yaml

El fichero foo.txt en la máquina destino:

El archivo index de la máquina destino, desde el servidor web:

La propiedad que permite que las tareas que ya se han realizado no se vuelvan a ejecutar se denomina idempotence o idempotencia , que sirve para asegurar que se ejecuten las teareas solo si es necesario, y que aunque se repitan no produzcan cambios innecesarios, asegurando que el sistema este exactamente como se le especifica.
El repositorio donde hago esto lo explicado anteriormente se puede ver aquí .
Para poder ver más información de variables del nodo:
ansible nodo1 -m setup
Taller 2: Ansible - Playbook con roles.
En este taller, trabajaremos con dos servidores:
-
Uno será el servidor web.
-
Y el servidor de base de datos.
En lugar de definir tareas específicas para cada nodo, utilizaremos roles.
Los roles permiten organizar tareas para ejecutarlas en nodos específicos o en grupos de nodos, facilitando la reutilización de código.
Por ejemplo, un rol para instalar un servidor web Apache puede reutilizarse en otros proyectos que requieran la misma configuración.
Para este taller, he reutilizado la máquina del taller anterior y otra máquina llamada ansiblebbdd2.
En este taller trabajaremos con los archivos del Taller 2 de este repositorio .
Declaro las 2 máquinas que tengo creadas, en el archivo hosts:
all:
children:
servidores_web:
hosts:
debiansible:
ansible_ssh_host: 192.168.122.42
ansible_ssh_user: debian
ansible_ssh_private_key_file: /home/debian/.ssh/id_rsa
servidores_bd:
hosts:
ansiblebbdd2:
ansible_ssh_host: 192.168.122.97
ansible_ssh_user: debian
ansible_ssh_private_key_file: /home/debian/.ssh/id_rsa
- Esto implica declarar el nombre de las máquinas debiansible y ansiblebbdd2, sus ips, los usuarios, y la ubicación de las claves ssh.
En el fichero site.yaml:
- hosts: all
become: true
roles:
- role: commons
- hosts: servidores_web
become: true
roles:
- role: apache2
- hosts: servidores_bd
become: true
roles:
- role: mariadb
- hosts: nombre del grupo o máquina en la que se van a ejecutar las tareas del rol.
- roles/role: es el nombre del rol que se va a ejecutar. Este nombre debe coincidir con el nombre del directorio que encontramos dentro del directorio roles.
En el fichero site.yaml de arriba, los roles definidos son:
- commons: tareas comunes a todos los nodos, para todos los nodos (grupo all).
- apache2: instalación y configuración de apache2, para todos los nodos del grupo servidores_web.
- mariadb: instalación y configuración de mariadb, para todos los nodos del grupo servidores_bd.
Los roles se definen en el directorio roles, y dentro un subdirectorio por cada rol. Estos nombres de subdirectorios, es lo que se indican más arriba en el archivo site.yaml.
Estos subdirectorios de roles, por ejemplo el de apache, /roles/apache2/
, contiene una serie de directorios como por ejemplo:
-
tasks: Donde se almacena el fichero yaml, con las instrucciones.
-
files: Ficheros para copiar a los nodos con el módulo copy.
-
templates: Plantillas para copiar a los nodos con el módulo template.
-
handlers: Manejadores, qué son las tareas para gestionar los servicios que se han instalado.
En cambio, el rol commons, sólo contiene el directorio tasks, porque son tareas que se ejecutan en todos los nodos.
En el rol commons /roles/common/tasks/main.yaml
, añado lo siguiente:
- name: Actualizamos el sistema
apt: update_cache=yes upgrade=yes
En el rol apache2 /roles/apache2/tasks/main.yaml
:
- name: "ensure apache2 is installed"
apt:
pkg: apache2
- name: copy template index
template:
src: index.j2
dest: /var/www/html/index.html
owner: www-data
group: www-data
mode: 0644
- name: "Copiar fichero al servidor remoto"
copy:
src: fichero.html
dest: /var/www/html/index.html
owner: www-data
group: www-data
mode: '0644'
- name: "Copiar fichero de configuración y reiniciar el servicio"
copy:
src: etc/apache2/ports.conf
dest: /etc/apache2/ports.conf
owner: root
group: root
mode: '0644'
notify:
- restart apache2
Las variables se declaran en /group_vars/all
:
bd_name: wordpress_bd
bd_user: wordpress_user
bd_pass: asdasd
En el rol mariadb /roles/mariadb/tasks/main.yaml
:
- name: ensure mariadb is installed
apt:
pkg:
- mariadb-server
- python3-mysqldb
- name: create database wordpress
mysql_db: name={{bd_name}} state=present
- name: create user mysql wordpress
mysql_user: name={{ bd_user }} host={{ item }} password={{ bd_pass }} priv={{bd_name}}.*:ALL,GRANT
with_items:
- '%'
- name: mariadb listen in all interfaces
lineinfile: dest=/etc/mysql/mariadb.conf.d/50-server.cnf regexp="^bind-address = 127.0.0.1" line="bind-address = 0.0.0.0" state=present
notify:
- restart mariadb
Con los roles ya definidos, procedo a la ejecución del playbook:
ansible-playbook site.yaml


Para comprobar que se sirve bien la página, que se ha enviado al servidor web:

Para comprobar que se puede conectar a la base de datos, demostrando que funciona:
mysql -u wordpress_user -p -h 192.168.122.97 -D wordpress_bd

Si en el archivo de configuración /roles/apache2/files/etc/apache2/ports.conf
, modifico cualquier parámetro, y vuelvo a ejecutar ansible, si se reinicia, hay que añadir al final:
notify: restart apache2

Si da algun error de missing sudo password es porque no se le ha puesto al usuario para que no pida contraseña:
sudo visudo
debian ALL=(ALL:ALL) NOPASSWD: ALL
Si da un error de skipping: no hosts matched, hay que revisar los archivos hosts y site.yaml y comparar que el nombre de servidores sea el mismo, por ejemplo, en bbdd es servidores_bd, pues en ambos debe poner lo mismo.
Para finalizar, el repositorio de este taller ya modificado es este .
Taller 3: Vagrant - Creación de una máquina virtual.
Para este taller crearemos una máquina utilizando vagrant, definiendo su Vagrantfile, y como gestionarla. Para ello, como el resto de talleres, los archivos que modificamos están en este repositorio .
El primer paso es instalar la imagen de Debian 12, si no la tenemos (arriba lo explico, pero lo repetiré):
vagrant box add debian/bookworm64
vagrant box list

Para crear la máquina o iniciarla:
vagrant up

Para acceder a la máquina:
vagrant ssh


Para ver la maquina y la red que se ha creado:
virsh -c qemu:///system list
virsh -c qemu:///system net-list --all


Para ver los discos generados:
virsh -c qemu:///system vol-list default

Para ver la memoria que tiene asignada la máquina y las CPU:
virsh -c qemu:///system dominfo Taller3_default
virsh -c qemu:///system vcpuinfo Taller3_default


Para darle 1GB y 2 CPU y poder modificar la memoria y la CPU de la máquina, hay que modificar el archivo Vagrantfile:
Vagrant.configure("2") do |config|
config.vm.box = "debian/bookworm64"
config.vm.hostname="prueba"
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.provider :libvirt do |libvirt|
libvirt.memory = 1024
libvirt.cpus = 2
end
end
- La línea
config.vm.synced_folder ".", "/vagrant", disabled: true
es para que no se comparta el directorio donde esta el archivo Vagrantfile con la máquina virtual, porque pide privilegios, así que lo mejor es dejarla desactivada.

Para aplicar los cambios a la máquina y ver si ha cambiado la memoria y la cpu:
vagrant reload


Los ficheros ya modificados de este taller, se pueden obtener de mi repositorio .
Taller 4: Vagrant - Creación de Escenarios.
Para este taller, definiré varias máquinas, redes y almacenamiento mediante el fichero Vagrantfile, el cual, se encuentra al final del mismo taller, como en los anteriores.
El primer paso es levantar el escenario, el cual empieza a descargar la imagen de ubuntu.

Una vez levantado el escenario, este cuenta con dos máquinas, nodo1 (Debian) y nodo2 (Ubuntu). Para poder entrar por ssh a cada uno:
vagrant ssh nodo1
vagrant ssh nodo2


Del mismo modo, para comprobar la puerta de enlace de ambas máquinas:
ip r
La cual es 192.168.121.1, saliendo por la interfaz eth0 en mi caso.

Hecho, esto ahora vamos a añadir una nueva interfaz al nodo1 de forma que utilice DHCP en el direccionamiento 192.168.200.0/24 junto con una red nat llamada red_nat_vagrant, y para ello hay que especificarlo en el mismo archivo Vagrantfile, añadiendo:
config.vm.network :private_network,
:type => "dhcp",
:libvirt__network_name => 'red_nat_vagrant',
:libvirt__network_address => '192.168.200.0',
:libvirt__netmask => '255.255.255.0'

Al volver a crear el escenario, ya aparece la nueva interfaz en el nodo1, siendo esta eth1:

Por otra parte, se verifica como se ha creado también la propia red, mencionada arriba.
virsh -c qemu:///system net-list

Para el siguiente paso, voy a conectar ambas máquinas, a una red muy interna, con IPS estáticas 10.0.0.1 y 10.0.0.2.
Para esto, elimino el escenario actual, y modifico el archivo Vagrantfile de la siguiente manera:
Vagrant.configure("2") do |config|
config.vm.define :nodo1 do |nodo1|
nodo1.vm.box = "debian/bookworm64"
nodo1.vm.hostname = "nodo1"
nodo1.vm.synced_folder ".", "/vagrant", disabled: true
nodo1.vm.network :private_network,
:libvirt__network_name => 'red_muy_aislada',
:libvirt__dhcp_enabled => false,
:ip => "10.0.0.1",
:libvirt__forward_mode => "veryisolated"
end
config.vm.define :nodo2 do |nodo2|
nodo2.vm.box = "generic/ubuntu2204"
nodo2.vm.hostname = "nodo2"
nodo2.vm.synced_folder ".", "/vagrant", disabled: true
nodo2.vm.network :private_network,
:libvirt__network_name => "red_muy_aislada",
:libvirt__dhcp_enabled => false,
:ip => "10.0.0.2",
:libvirt__forward_mode => "veryisolated"
end
end
Una vez desplegado de nuevo el escenario, verifico que efectivamente han tomado dichas IPS:
vagrant ssh nodo1 -c "ip a"

vagrant ssh nodo2 -c "ip a"

Y verifico que haya conectividad entre ambas máquinas mediante ping:
vagrant ssh nodo1 -c "ping 10.0.0.2"
vagrant ssh nodo2 -c "ping 10.0.0.1"

Para terminar con las interfaces, voy a añadirle una nueva interfaz a nodo2, pero que este conectada a una red pública. Para esto hay que tener previamente configurado el bridge Br0 como ya expliqué en su sección, y la conexión debe ser mediante cable, y no por Wifi, o no funcionará.
Para realizar esto, hay que modificar el archivo Vagrantfile, así:
config.vm.define :nodo2 do |nodo2|
nodo2.vm.box = "generic/ubuntu2204"
nodo2.vm.hostname = "nodo2"
nodo2.vm.synced_folder ".", "/vagrant", disabled: true
nodo2.vm.network :private_network,
:libvirt__network_name => "red_muy_aislada",
:libvirt__dhcp_enabled => false,
:ip => "10.0.0.2",
:libvirt__forward_mode => "veryisolated"
nodo2.vm.network :public_network,
:dev => "br0",
:mode => "bridge",
:type => "bridge",
use_dhcp_assigned_default_route: true
end
end
La redirección que ha cogido, depende de la red en la que estemos conectados.

Por último, voy a añadir a la máquina nodo2, dos discos de 1GB. Para ello, de nuevo, modifico el archivo Vagrantfile:
nodo2.vm.provider :libvirt do |libvirt|
libvirt.storage :file, :size => '1G'
libvirt.storage :file, :size => '1G'
end
Quedando así:
Vagrant.configure("2") do |config|
config.vm.define :nodo1 do |nodo1|
nodo1.vm.box = "debian/bookworm64"
nodo1.vm.hostname = "nodo1"
nodo1.vm.synced_folder ".", "/vagrant", disabled: true
nodo1.vm.network :private_network,
:libvirt__network_name => 'red_muy_aislada',
:libvirt__dhcp_enabled => false,
:ip => "10.0.0.1",
:libvirt__forward_mode => "veryisolated"
end
config.vm.define :nodo2 do |nodo2|
nodo2.vm.box = "generic/ubuntu2204"
nodo2.vm.hostname = "nodo2"
nodo2.vm.synced_folder ".", "/vagrant", disabled: true
nodo2.vm.network :private_network,
:libvirt__network_name => "red_muy_aislada",
:libvirt__dhcp_enabled => false,
:ip => "10.0.0.2",
:libvirt__forward_mode => "veryisolated"
nodo2.vm.network :public_network,
:dev => "br0",
:mode => "bridge",
:type => "bridge",
use_dhcp_assigned_default_route: true
nodo2.vm.provider :libvirt do |libvirt|
libvirt.storage :file, :size => '1G'
libvirt.storage :file, :size => '1G'
end
end
end

Para poder verificar que efectivamente se han añadido los dos discos:
vagrant ssh nodo2 -c "lsblk"

Y con esto estaria realizado el Taller 4. A continuación dejo unas aclaraciones / soluciones de posibles errores:
Para ejecutar comandos desde fuera de algun nodo (ip a de ejemplo):
vagrant ssh nodo1 -c "ip a"
Para utilizar una ruta por defecto alternativa como por ejemplo 192.168.200.1 hay que añadir la linea:(asi sale por eth1, en vez de eth0, se puede comprobar con ip r en la máquina)
use_dhcp_assigned_default_rute: true
Si diera el error de que la red “red_nat_vagrant” existe pero no tiene dhcp desactivado, hay que comprobar que la nueva red que quiero crear tenga otro nombre, o sino, borrarla y hacerlo de nuevo con:
virsh -c qemu:///systemnet-destroy red_nat_vagrant
O sino por último hacer un rm -rf .vagrant para eliminar los archivos residuales, o eliminar el escenario que se hizo antes donde se creo la red nat vagrant primera.
Para saber que la máquina esta en una red aislada es porque tiene la linea:
:libvirt__forward_mode => "none"
Y que si no tiene dhcp por esto:
:libvirt__dhcp_enabled => false,
Para saber que la máquina esta en una red muy aislada es porque contiene:
:libvirt__forward_mode => "veryisolated"
El repositorio donde hago esto lo explicado anteriormente se puede ver aquí .
Taller 5: Vagrant + Ansible:
Para este último taller, cuento con una única máquina, la cual va a crearse utilizando Vagrant y personalizarla utilizando Ansible, y debo poder acceder a ella por ssh, pero sin usar el comando vagrant ssh, ya que esto utiliza la red de mantenimiento que corresponde a eth0.
Se puede realizar una conexión ssh directamente a la máquina destino, pero tenemos que tener claro primero unos conceptos básicos:
-
Vagrant siempre crea un usuario sin privilegios llamado “vagrant”.
-
Averiguar la IP de la máquina destino desde la propia maquina o desde el host con “vagrant ssh nodo1 -c “hostname -I”
-
La clave pública se encuentra en ".vagrant/machines/nodo1/libvirt/private_key”
Para empezar lo primero que hago es averiguar la IP de la máquina (no especifico nodo1 porque es el único):
vagrant ssh -c "hostname -I"

Sabiendo la IP, modifico el fichero Taller5/ansible/hosts para declararla:

Y una vez añadido hay que comprobar que haya conectividad con:
ansible -m ping all

Hecho esto, ejecuto la receta de Ansible que despliega el servidor web, para comprobar que no haya errores durante la configuración:
ansible-playbook site.yaml

Y por último desde el navegador, introduzco la IP de la máquina para comprobar el funcionamiento:

Y con esto estaria realizado el Taller5. El repositorio donde hago esto lo explicado anteriormente se puede ver aquí .