Installs and manages Moodle (4.5+) on Debian, Ubuntu, and Rocky Linux 10 hosts. Tested with Ansible 13 / ansible-core 2.20.
Use a supported host with PHP 8.1+, Apache 2.4, Git, and either PostgreSQL or MariaDB/MySQL available. This role manages Moodle itself; the surrounding web and database stack should be prepared separately.
On Debian-based systems, php-fpm can also be blocked by AppArmor depending on
the target path you use for moodle_src_path and the Moodle data directories.
If you deploy outside the default /srv/moodle/... layout, make sure the local
AppArmor policy allows PHP-FPM to read and write the target directories.
Available variables are listed below, along with default values (see defaults/main.yml):
moodle_version: "MOODLE_405_STABLE"
moodle_src_path: "/srv/moodle/src"
moodle_domain_name: "moodle.test"
moodle_is_https: false
moodle_database:
dbtype: "pgsql"
dbhost: "localhost"
dbname: "moodle"
dbuser: "username"
dbpass: "password"
dbprefix: "mdl_"
moodle_run_config: true
moodle_manage_config: true
moodle_overwrite_config: false
moodle_fetch_source: true
moodle_reset_admin_password: false
php_set_default_cli: falseImportant behavior:
moodle_fetch_source: fetch or update the Moodle git checkout.moodle_run_config: run installation and upgrade orchestration.moodle_manage_config: createconfig.phpwhen missing.moodle_overwrite_config: update an existingconfig.php. Keep thisfalseunless you explicitly want the role to rewrite a live site's configuration.moodle_reset_admin_password: reset the admin password on an existing installation.moodle_webroot_path: derived from the source tree. When{{ moodle_src_path }}/publicexists, the role uses that as the web root; otherwise it usesmoodle_src_path.php_set_default_cli: opt in to making the selectedphp_versionthe host defaultphpcommand on Debian/Ubuntu. Use this only after PHP packages are installed, and setphp_versionexplicitly.
When you import tasks/phpsql-setup.yml, the role exposes helper facts that other playbooks can consume directly:
php_packages
If you want to switch the host default php command after installation, call the dedicated task file explicitly:
- import_role:
name: call_learning.moodle
tasks_from: phpsql-setup
- role: geerlingguy.php
- import_role:
name: call_learning.moodle
tasks_from: php-default-cli
when: php_set_default_cli | boolNo hard role dependencies are declared. If you want Ansible to provision the full stack, pair this role with infrastructure roles such as:
geerlingguy.apachegeerlingguy.phpgeerlingguy.postgresqlgeerlingguy.mysql
- hosts: moodle
become: true
roles:
- role: call_learning.moodle
vars:
moodle_domain_name: "moodle.example.com"
moodle_is_https: true
moodle_version: "MOODLE_405_STABLE"
moodle_database:
dbtype: "pgsql"
dbhost: "127.0.0.1"
dbname: "moodle"
dbuser: "moodle"
dbpass: "{{ vault_moodle_dbpass }}"
dbprefix: "mdl_"MIT / BSD
This role was created in 2017 by Laurent David, from Jeff Geerling roles templates author of Ansible for DevOps.
You must have the following installed:
ansiblemolecule
If you prefer uv instead of a system Python for local tooling, you can create a dedicated environment and install the test dependencies with it:
uv venv
source .venv/bin/activate
uv pip install ansible moleculeThe test suite is built around Molecule.
GitHub Actions runs linting and Molecule scenarios through the ci.yml workflow on pull requests, scheduled runs, and pushes to master.
That workflow runs the full Molecule scenario set on the supported LTS baseline, and the monthly/manual module-moodle-edge.yml workflow checks the edge Moodle branch controlled by the MOODLE_EDGE_VERSION repository variable (default 502).
Both workflows install tooling through uv sync --frozen, so CI uses the same locked dependency set as local uv runs.
Run the default scenario with:
molecule testRun a specific scenario with:
molecule test -s default