Ansible Playbook - GlusterFS - Apache
Read this first (June 2026): GlusterFS is effectively legacy now. Red Hat ended Gluster Storage and disbanded its engineering team at the end of 2024, upstream commits have slowed to a trickle, and CentOS Stream 10 dropped GlusterFS packages. The community project still exists, but I would not start a new build on it. If you are designing this fresh today, look at CephFS for distributed storage, or for the narrow goal here (keeping
/var/wwwin sync across Apache nodes) a shared NFS mount, object storage with a deploy pipeline, or building artifacts in CI and shipping them to each node. The Ansible patterns below are modernized to FQCN for anyone still maintaining a Gluster deployment, but treat the post as a reference rather than a recommendation.
Background
This is a multi-tier lab build: HAProxy load balancers in front of Apache web servers, MariaDB for data, and a separate GlusterFS cluster. The Apache nodes mount a GlusterFS volume at /var/www so their content stays in sync. The original post collected the playbooks for reference, and this refresh updates the syntax that has drifted since 2015.
Inventory
The site_hosts inventory, with the modern connection variables (ansible_host rather than the deprecated ansible_ssh_host):
ans-test-web01 ansible_host=10.0.110.193 ansible_ssh_private_key_file=.ssh/home
ans-test-web02 ansible_host=10.0.110.222 ansible_ssh_private_key_file=.ssh/home
ans-test-web03 ansible_host=10.0.110.130 ansible_ssh_private_key_file=.ssh/home
ans-test-gs01 ansible_host=10.0.110.132 ansible_ssh_private_key_file=.ssh/home
ans-test-gs02 ansible_host=10.0.110.131 ansible_ssh_private_key_file=.ssh/home
ans-test-gs03 ansible_host=10.0.110.129 ansible_ssh_private_key_file=.ssh/home
[gs-vms]
ans-test-gs[01:03]
[gs-vms:vars]
glusterfs_server=true
glusterfs_client=true
gluster_brick_dir=/mnt/gluster
cluster_hosts=ans-test-gs01,ans-test-gs02,ans-test-gs03
[web-vms]
ans-test-web[01:03]
[web-vms:vars]
glusterfs_client=true
primary_gfs_server=ans-test-gs01
secondary_gfs_server=ans-test-gs02
tertiary_gfs_server=ans-test-gs03
apache_backup_dir=/var/www.backup
apache_home=/var/www
site.yml
The top-level play, with become: true replacing the deprecated sudo: yes:
---
- hosts: all
become: true
roles:
- base
- zabbix-agent
- hosts: web-vms
become: true
roles:
- glusterfs
- apache2
- memcached
- hosts: gs-vms
become: true
roles:
- glusterfs
LVM
The original repeated a full LVM playbook here. That same playbook is covered, modernized, in Ansible Playbook - LVM, so rather than duplicate it, use that version (FQCN, community.general.lvg/lvol, one cross-distro install task) to prepare the /mnt/gluster brick disk.
Installing GlusterFS
The 2015 version added a Launchpad PPA for trusty and imported a key with apt_key. Both are dead: that Ubuntu release and PPA are gone, and apt_key is deprecated in favor of keyrings under /etc/apt/keyrings. On a current distribution, install from the distro packages (or the upstream gluster.org repo for your release). The task itself collapses to a single apt call, since the module takes a list directly instead of a with_items loop:
---
- name: Install GlusterFS prerequisites
ansible.builtin.apt:
name:
- software-properties-common
- xfsprogs
state: present
update_cache: true
- name: Install GlusterFS server
ansible.builtin.apt:
name: glusterfs-server
state: present
when: glusterfs_server
- name: Install GlusterFS client
ansible.builtin.apt:
name: glusterfs-client
state: present
when: glusterfs_client
- name: Enable and start glusterd
ansible.builtin.service:
name: glusterd
state: started
enabled: true
when: glusterfs_server
Building The Volume And Mounting It
The configuration playbook, modernized to FQCN and loop. Note that the dedicated gluster modules were removed from community.general as the project wound down, so volume creation now drives the gluster CLI directly through ansible.builtin.command:
---
- hosts: gs-vms
become: true
tasks:
- name: Probe the gluster peers
ansible.builtin.command: "gluster peer probe {{ item }}"
register: gluster_peer_probe
changed_when: "'already in peer list' not in gluster_peer_probe.stdout"
loop: "{{ groups['gs-vms'] }}"
- name: Create the brick directories
ansible.builtin.file:
path: "{{ gluster_brick_dir }}/{{ item.name }}/"
owner: "{{ item.owner }}"
group: "{{ item.group }}"
state: directory
mode: "0755"
loop:
- {name: webs-test, owner: root, group: www-data}
- {name: loadbalancers-test, owner: root, group: root}
- name: Create the gluster volumes
ansible.builtin.command: >
gluster volume create {{ item }} replica 3
{% for host in groups['gs-vms'] %}{{ host }}:/mnt/gluster/{{ item }}/brick {% endfor %}
force
register: gluster_volume_create
changed_when: "'success' in gluster_volume_create.stdout"
failed_when:
- gluster_volume_create.rc != 0
- "'already exists' not in gluster_volume_create.stderr"
loop:
- webs-test
- loadbalancers-test
run_once: true
- name: Start the gluster volumes
ansible.builtin.command: "gluster volume start {{ item }}"
register: gluster_volume_start
changed_when: "'success' in gluster_volume_start.stdout"
failed_when:
- gluster_volume_start.rc != 0
- "'already started' not in gluster_volume_start.stderr"
loop:
- webs-test
- loadbalancers-test
run_once: true
- hosts: web-vms
become: true
tasks:
- name: Check whether /var/www has already been moved
ansible.builtin.stat:
path: "{{ apache_backup_dir }}"
register: www_backup
- name: Move the existing /var/www aside
ansible.builtin.command: "mv {{ apache_home }} {{ apache_backup_dir }}"
when: not www_backup.stat.exists
- name: Mount the gluster volume at /var/www
ansible.posix.mount:
path: "{{ apache_home }}"
src: "{{ primary_gfs_server }}:/webs-test"
fstype: glusterfs
opts: "defaults,_netdev,backup-volfile-servers={{ secondary_gfs_server }}:{{ tertiary_gfs_server }}"
state: mounted
A couple of correctness notes beyond the syntax: the backup-server mount option is backup-volfile-servers (plural, colon-separated list), not a repeated backupvolfile-server key as the original had it. And moving /var/www aside before the first mount is destructive, so guard it on the backup not already existing, which the when above does.
Conclusion
If you already run GlusterFS, the modernized playbooks above will keep working. If you are building this today, spend your time on a storage layer that is still actively developed. The tiered HAProxy and Apache pattern is fine; it is the Gluster layer underneath that has aged out.
Enjoy!
Comments