Automatizar instalación Moodle con Ansible es una forma práctica de convertir una tarea técnica repetitiva en un proceso reproducible, documentado y menos propenso a errores. Cuando una organización necesita desplegar Moodle en varios servidores, repetir la instalación manual deja de ser eficiente y empieza a convertirse en un riesgo operativo.
Por qué automatizar instalación Moodle con Ansible
Automatizar instalación Moodle con Ansible no consiste únicamente en ahorrar tiempo. También permite reducir diferencias entre servidores, documentar decisiones técnicas y repetir el despliegue con más garantías cuando trabajas con desarrollo, preproducción y producción.
La automatización no es solo una herramienta; es una forma de trabajar. En primer lugar, permite declarar cómo debe quedar el servidor, qué paquetes deben instalarse, qué servicios deben estar activos, qué permisos deben aplicarse y qué configuración necesita Moodle para funcionar correctamente.
En este artículo se muestra cómo preparar un despliegue de Moodle con Ansible sobre Ubuntu, utilizando Apache2, PHP-FPM, MariaDB, Redis y certificados SSL con Let’s Encrypt. La idea es partir de una guía práctica, pero con criterio de producción: seguridad, variables sensibles, estructura del playbook y verificación final.
Si deseas explorar otra alternativa para la instalación de Moodle, puedes consultar mi guía paso a paso sobre cómo instalar Moodle 4.5 con Docker, Apache, PHP-FPM y MySQL.
Además, conviene revisar la documentación oficial de Ansible para entender inventarios, playbooks, módulos e idempotencia antes de llevar esta automatización a producción.
¿Te has encontrado alguna vez instalando Moodle manualmente en múltiples servidores? ¿Y si pudieras automatizar todo el proceso con un playbook versionado, revisable y reutilizable?
Resumen rápido
En esta guía vas a ver cómo automatizar instalación Moodle con Ansible sobre Ubuntu, Apache2, PHP-FPM, MariaDB, Redis y certificados SSL con Let’s Encrypt.
La idea no es solo instalar más rápido, sino conseguir instalaciones repetibles, documentadas y menos propensas a errores cuando trabajas con varios servidores o entornos de cliente.

Tabla de contenidos
- Por qué automatizar instalación Moodle con Ansible
- Paso 1: Preparativos iniciales
- Paso 2: Arquitectura del sistema a desplegar
- Paso 3: Playbook de Ansible paso a paso
- Paso 4: Seguridad con ansible-vault
- Paso 5: Plantillas de configuración de Moodle
- Paso 6: Ejecutar el playbook
- Paso 7: Verificación del sistema
- Conclusión
Paso 1: Preparativos para automatizar instalación Moodle con Ansible
Antes de automatizar la instalación de Moodle, conviene preparar correctamente el entorno de control, el acceso SSH y el inventario de servidores. Estos pasos parecen básicos, pero son los que determinan si el despliegue será fluido o si el playbook fallará por problemas de conectividad, permisos o variables mal definidas.
Antes de empezar
Ejecuta estas pruebas primero en un entorno de desarrollo o preproducción. Un playbook de Ansible puede crear usuarios, modificar permisos, reiniciar servicios y cambiar configuración de Apache, PHP o MariaDB.
La automatización reduce intervención manual. Por eso conviene versionar el playbook, revisar variables sensibles y validar cada cambio antes de aplicarlo en producción.
1.1. Instalación de Ansible
Ansible debe estar instalado en tu máquina local o en un servidor de control. Desde ahí se ejecutarán los playbooks contra los servidores donde quieras instalar Moodle.
# Ubuntu / Debian
sudo apt update
sudo apt install -y software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install -y ansible python3-pymysql
# CentOS / RHEL / Fedora
sudo yum install -y ansible
# macOS con Homebrew
brew install ansible1.2. Acceso SSH a los servidores objetivo
Ansible utiliza SSH para comunicarse con los servidores remotos. Por eso el primer requisito operativo es poder acceder al servidor sin depender de una sesión manual interactiva.
Genera una clave SSH para el usuario desde el que ejecutarás los despliegues:
ssh-keygen -t ed25519 -C "moodle-ansible-admin"Después, copia la clave pública al servidor objetivo. Puedes hacerlo con ssh-copy-id o pegándola manualmente en ~/.ssh/authorized_keys.
ssh-copy-id usuario@servidor
# Alternativa manual: copiar la clave pública
cat ~/.ssh/id_ed25519.pub
# Pegar el contenido en el servidor remoto
vim ~/.ssh/authorized_keysComprueba que puedes conectarte correctamente:
ssh usuario@servidorSi puedes entrar sin introducir la contraseña del usuario remoto, o únicamente usando la contraseña de tu clave privada, estás listo para ejecutar Ansible.
1.3. Inventario de Ansible
El inventario de Ansible define qué servidores se gestionan, cómo se conectan y qué variables de conexión se aplican a cada grupo. En instalaciones Moodle es habitual separar entornos de preproducción, producción o nodos web.
[moodle_servers]
moodle-prod ansible_host=192.168.1.10
moodle-pre ansible_host=192.168.1.11
[moodle_servers:vars]
ansible_user=root
ansible_ssh_private_key_file=~/.ssh/id_ed25519
ansible_python_interpreter=/usr/bin/python3- Grupos: los servidores se agrupan bajo
[moodle_servers]. Puedes crear otros grupos como[dbservers]o[staging]. - Variables: las variables de conexión se declaran bajo
[moodle_servers:vars], incluyendo usuario SSH, clave privada e intérprete de Python.

Paso 2: Arquitectura del sistema a desplegar
El despliegue propuesto instala Moodle sobre una arquitectura clásica, robusta y comprensible: Apache2 como servidor web, PHP-FPM como procesador de PHP, MariaDB como base de datos, Redis como caché y Let’s Encrypt para HTTPS. Además, este enfoque ayuda a automatizar instalación Moodle con Ansible sin perder visibilidad sobre cada servicio implicado.
Esta combinación es adecuada para muchos escenarios: servidores dedicados, VPS, entornos corporativos y plataformas Moodle de tamaño medio. Además, deja abierta la puerta a evoluciones posteriores como balanceo, separación de base de datos, almacenamiento compartido o caché distribuida.

Lectura arquitectónica
El valor de este despliegue no está solo en instalar Moodle, sino en declarar de forma explícita todos los componentes que necesita la plataforma.
Cuando esa arquitectura queda expresada en un playbook, el conocimiento se convierte en un activo reutilizable del proyecto.
Paso 3: Playbook para automatizar instalación Moodle con Ansible
El playbook es el corazón de Ansible. Es el fichero YAML que describe el estado final que queremos conseguir en el servidor: paquetes instalados, servicios activos, directorios creados, permisos aplicados, repositorio de Moodle clonado, base de datos preparada, Apache configurado y certificado SSL emitido.

Cómo leer el playbook
No conviene verlo como un simple script largo, sino como una descripción declarativa del estado deseado del servidor.
Cada tarea acerca la máquina al estado final: paquetes instalados, servicios activos, directorios creados, repositorio clonado, permisos aplicados, base de datos preparada y VirtualHost listo.
Vamos a crear un fichero llamado playbook.yml con el siguiente contenido. Esta versión permite automatizar instalación Moodle con Ansible evitando publicar contraseñas en claro y utilizando variables cifradas mediante ansible-vault.
---
- name: Instalar Moodle con Apache, PHP-FPM, MariaDB, Redis y SSL
hosts: moodle_servers
become: true
vars_files:
- group_vars/moodle/vault.yml
vars:
moodle_git_repo: "https://github.com/moodle/moodle.git"
moodle_branch: "MOODLE_405_STABLE"
moodle_dir: "/var/www/moodle"
moodle_data_dir: "/var/www/moodledata"
moodle_url: "https://moodle.miempresa.com"
moodle_dns: "moodle.miempresa.com"
db_name: "moodle"
db_user: "moodleuser"
db_host: "localhost"
php_version: "8.3"
tasks:
- name: Actualizar caché de paquetes
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
- name: Actualizar paquetes instalados
ansible.builtin.apt:
upgrade: dist
- name: Agregar repositorio de Ondrej Sury para PHP
ansible.builtin.apt_repository:
repo: "ppa:ondrej/php"
state: present
- name: Instalar dependencias del servidor Moodle
ansible.builtin.apt:
name:
- apache2
- php{{ php_version }}-fpm
- php{{ php_version }}-cli
- php{{ php_version }}-mysql
- php{{ php_version }}-xml
- php{{ php_version }}-mbstring
- php{{ php_version }}-curl
- php{{ php_version }}-zip
- php{{ php_version }}-gd
- php{{ php_version }}-intl
- php{{ php_version }}-soap
- php{{ php_version }}-bcmath
- php{{ php_version }}-redis
- mariadb-server
- mariadb-client
- redis
- git
- unzip
- certbot
- python3-certbot-apache
- python3-pymysql
state: present
- name: Asegurar que PHP-FPM está iniciado y habilitado
ansible.builtin.systemd:
name: php{{ php_version }}-fpm
state: started
enabled: true
- name: Crear directorio de datos de Moodle
ansible.builtin.file:
path: "{{ moodle_data_dir }}"
state: directory
owner: www-data
group: www-data
mode: "0770"
- name: Clonar Moodle desde Git
ansible.builtin.git:
repo: "{{ moodle_git_repo }}"
dest: "{{ moodle_dir }}"
version: "{{ moodle_branch }}"
force: true
notify: Reiniciar PHP-FPM
- name: Configurar el directorio de Moodle como seguro para Git
ansible.builtin.command: git config --global --add safe.directory {{ moodle_dir }}
changed_when: false
- name: Ajustar permisos del código de Moodle
ansible.builtin.file:
path: "{{ moodle_dir }}"
owner: www-data
group: www-data
recurse: true
- name: Crear base de datos de Moodle
community.mysql.mysql_db:
name: "{{ db_name }}"
state: present
login_user: root
login_password: "{{ vault_db_root_password }}"
- name: Crear usuario de base de datos para Moodle
community.mysql.mysql_user:
name: "{{ db_user }}"
password: "{{ vault_db_password }}"
priv: "{{ db_name }}.*:ALL"
host: "localhost"
state: present
login_user: root
login_password: "{{ vault_db_root_password }}"
- name: Configurar VirtualHost de Apache para Moodle con PHP-FPM
ansible.builtin.template:
src: templates/moodle-apache.conf.j2
dest: /etc/apache2/sites-available/moodle.conf
owner: root
group: root
mode: "0644"
notify: Reiniciar Apache
- name: Habilitar módulos necesarios en Apache
ansible.builtin.shell: |
a2enmod ssl
a2enmod rewrite
a2enmod proxy_fcgi
a2enmod setenvif
args:
executable: /bin/bash
notify: Reiniciar Apache
- name: Habilitar VirtualHost de Moodle
ansible.builtin.shell: |
a2ensite moodle.conf
a2dissite 000-default.conf
args:
executable: /bin/bash
notify: Reiniciar Apache
- name: Generar config.php de Moodle
ansible.builtin.template:
src: templates/config.php.j2
dest: "{{ moodle_dir }}/config.php"
owner: www-data
group: www-data
mode: "0640"
notify: Reiniciar PHP-FPM
- name: Ajustar php.ini para Moodle
ansible.builtin.lineinfile:
path: "/etc/php/{{ php_version }}/fpm/php.ini"
regexp: "^{{ item.key }} ="
line: "{{ item.key }} = {{ item.value }}"
loop:
- { key: "max_input_vars", value: "5000" }
- { key: "upload_max_filesize", value: "128M" }
- { key: "post_max_size", value: "128M" }
- { key: "memory_limit", value: "512M" }
notify: Reiniciar PHP-FPM
- name: Obtener certificado SSL con Let's Encrypt
ansible.builtin.command: >
certbot --apache -d {{ moodle_dns }}
--non-interactive --agree-tos
-m {{ vault_certbot_email }}
args:
creates: "/etc/letsencrypt/live/{{ moodle_dns }}/fullchain.pem"
notify: Reiniciar Apache
- name: Reiniciar servicios auxiliares
ansible.builtin.systemd:
name: "{{ item }}"
state: restarted
enabled: true
loop:
- mariadb
- redis
handlers:
- name: Reiniciar Apache
ansible.builtin.service:
name: apache2
state: restarted
- name: Reiniciar PHP-FPM
ansible.builtin.service:
name: php{{ php_version }}-fpm
state: restartedExplicación del playbook
La primera parte define el nombre del playbook, el grupo de servidores sobre el que se ejecutará y el uso de privilegios elevados mediante become: true. También carga un fichero externo de variables cifradas, donde guardaremos contraseñas y correos sensibles.
Después se declaran variables reutilizables: rama de Moodle, rutas de instalación, dominio, datos de base de datos y versión de PHP. Separar estos valores del cuerpo de las tareas hace que el playbook sea más fácil de mantener.
- Actualización del sistema: refresca caché de paquetes y actualiza paquetes instalados.
- Instalación de dependencias: instala Apache2, PHP-FPM, extensiones PHP, MariaDB, Redis, Git, Certbot y PyMySQL.
- Directorios y permisos: crea
moodledatay ajusta propietarios parawww-data. - Repositorio Moodle: clona Moodle desde Git utilizando la rama estable definida.
- Base de datos: crea base de datos y usuario específico para Moodle.
- Servidor web: genera el VirtualHost de Apache desde una plantilla.
- Configuración final: crea
config.php, ajustaphp.iniy solicita el certificado SSL.
Ojo con la idempotencia
Ansible funciona mejor cuando las tareas pueden ejecutarse varias veces sin romper el estado del sistema. Siempre que sea posible, utiliza módulos declarativos en lugar de comandos shell.
En algunos casos se usa command o shell, pero conviene añadir condiciones como creates, changed_when o validaciones explícitas para evitar cambios innecesarios.
Paso 4: Seguridad al automatizar instalación Moodle con Ansible
Punto crítico de seguridad
Evita publicar contraseñas reales dentro del playbook. En un proyecto real las credenciales deben gestionarse con variables cifradas, variables de entorno, un gestor de secretos o ansible-vault.
Esto afecta especialmente a contraseñas de base de datos, claves privadas SSH, tokens de API y cualquier dato que permita acceder al servidor o a Moodle.
Para crear un fichero de variables cifradas, utiliza ansible-vault:
mkdir -p group_vars/moodle
ansible-vault create group_vars/moodle/vault.ymlDentro del fichero cifrado puedes guardar las variables sensibles que usará el playbook:
vault_db_password: "CAMBIAR_PASSWORD_MOODLE"
vault_db_root_password: "CAMBIAR_PASSWORD_ROOT_MARIADB"
vault_certbot_email: "admin@miempresa.com"
Cuando ejecutes el playbook, Ansible te pedirá la contraseña del vault con --ask-vault-pass. También puedes integrar un fichero de password o un gestor de secretos si trabajas en un pipeline CI/CD.
Paso 5: Plantillas de configuración de Moodle
Además del playbook principal, conviene separar los ficheros de configuración en plantillas Jinja2. Así podemos generar un VirtualHost de Apache y un config.php de Moodle a partir de variables.
5.1. Plantilla del VirtualHost de Apache
Crea el fichero templates/moodle-apache.conf.j2:
<VirtualHost *:80>
ServerName {{ moodle_dns }}
DocumentRoot {{ moodle_dir }}
<Directory {{ moodle_dir }}>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php{{ php_version }}-fpm.sock|fcgi://localhost"
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/moodle_error.log
CustomLog ${APACHE_LOG_DIR}/moodle_access.log combined
</VirtualHost>5.2. Plantilla config.php.j2 de Moodle
Crea el fichero templates/config.php.j2. Esta plantilla genera el fichero de configuración principal de Moodle y utiliza las variables definidas en el playbook y en el vault.
<?php
unset($CFG);
global $CFG;
$CFG = new stdClass();
$CFG->dbtype = 'mariadb';
$CFG->dblibrary = 'native';
$CFG->dbhost = '{{ db_host }}';
$CFG->dbname = '{{ db_name }}';
$CFG->dbuser = '{{ db_user }}';
$CFG->dbpass = '{{ vault_db_password }}';
$CFG->prefix = 'mdl_';
$CFG->dboptions = [
'dbpersist' => false,
'dbsocket' => false,
'dbport' => '',
];
$CFG->wwwroot = '{{ moodle_url }}';
$CFG->dataroot = '{{ moodle_data_dir }}';
$CFG->admin = 'admin';
$CFG->directorypermissions = 0770;
$CFG->sslproxy = false;
require_once(__DIR__ . '/lib/setup.php');Permisos recomendados
El fichero config.php contiene credenciales de base de datos. Por eso el playbook lo genera con permisos restrictivos y propietario www-data.
En producción conviene revisar también permisos de moodledata, configuración de backups, acceso a logs y políticas de rotación.
Paso 6: Ejecutar el playbook
Checklist antes de ejecutar
Confirma que el inventario apunta al servidor correcto, que el usuario SSH tiene permisos, que las variables sensibles están protegidas y que el dominio DNS resuelve hacia la máquina donde vas a instalar Moodle.
También conviene lanzar primero el playbook con --check cuando sea posible y revisar qué cambios aplicará antes de modificar el servidor.
Con el inventario, el playbook, las plantillas y el vault preparados, ya puedes ejecutar Ansible:
ansible-playbook -i inventory.ini playbook.yml --ask-vault-pass
# Modo comprobación, cuando las tareas lo permitan
ansible-playbook -i inventory.ini playbook.yml --ask-vault-pass --checkSi el playbook se completa correctamente, el servidor debería quedar con Moodle desplegado, Apache configurado, PHP-FPM funcionando, MariaDB preparada, Redis activo y HTTPS habilitado.
Paso 7: Verificación del sistema
Después de automatizar la instalación, no des por terminado el despliegue sin verificar servicios, configuración y acceso web. Una instalación automatizada debe cerrarse siempre con una comprobación objetiva.

Verificación técnica de un despliegue Moodle automatizado con Ansible, revisando Apache, PHP-FPM, MariaDB, Redis, SSL, permisos de moodledata y acceso desde navegador.Puedes usar comandos como estos para revisar el estado del sistema:
systemctl status apache2
systemctl status php8.3-fpm
systemctl status mariadb
systemctl status redis
apache2ctl -t
php -v
mysql -u moodleuser -p moodle -e "SHOW TABLES;"
curl -I https://moodle.miempresa.com- Apache: debe estar activo y sin errores de sintaxis.
- PHP-FPM: debe estar iniciado y conectado correctamente desde Apache.
- MariaDB: debe aceptar conexión con el usuario de Moodle.
- Redis: debe estar disponible si vas a usarlo para caché o sesiones.
- HTTPS: el dominio debe responder con certificado válido.
- Moodle: debe cargar en navegador y poder completar el asistente o acceder si ya está configurado.
Conclusión: automatizar instalación Moodle con Ansible en entornos reales
Idea clave
Ansible no sustituye el conocimiento de administración de sistemas. Lo ordena, lo documenta y lo convierte en un proceso repetible.
Para equipos que mantienen varias plataformas Moodle, esta diferencia es enorme: menos improvisación, menos pasos manuales y más control sobre cada cambio aplicado en infraestructura.
Automatizar instalación Moodle con Ansible permite transformar una instalación manual, larga y propensa a errores en un proceso controlado. Además, cada servidor puede configurarse de forma coherente, cada cambio queda documentado y cada despliegue puede revisarse, versionarse y repetirse.
La clave está en no limitarse a “hacer que funcione”. Un buen playbook debe ser legible, seguro, idempotente y fácil de adaptar. Debe separar variables, proteger secretos, usar plantillas y permitir que cualquier persona del equipo entienda qué se está instalando y por qué.
En proyectos Moodle reales, esta aproximación ayuda a reducir incidencias, acelerar despliegues, facilitar auditorías técnicas y mejorar la mantenibilidad de la infraestructura. Y, sobre todo, libera tiempo para trabajar en lo importante: mejorar la plataforma, integrarla con otros sistemas y ofrecer una mejor experiencia de aprendizaje.
¿Ya estás usando Ansible para desplegar Moodle o sigues haciendo instalaciones manuales servidor a servidor? Si tu objetivo es automatizar instalación Moodle con Ansible de forma segura, el primer paso es convertir este playbook en una base versionada y adaptable a tus entornos reales.







Deja una respuesta