Skip to content

feat(roles/valkey)!: add a role to install and configure Valkey - #334

Merged
NavidSassan merged 9 commits into
mainfrom
feat/valkey
Sep 4, 2026
Merged

feat(roles/valkey)!: add a role to install and configure Valkey#334
NavidSassan merged 9 commits into
mainfrom
feat/valkey

Conversation

@NavidSassan

Copy link
Copy Markdown
Member

What

Valkey gets its own role and playbook instead of being installed under the Redis name.

Why

On RHEL 10 the redis role pointed at /etc/valkey while hardcoding the redis group, so
deploying the configuration aborted:

TASK [linuxfabrik.lfops.redis : Deploy /etc/valkey/valkey.conf (v8.0)]
fatal: [<host>]: FAILED! => {"msg": "chgrp failed: failed to look up group redis", ...}

Red Hat ships no Redis on RHEL 10 at all, so the redis role drops that platform instead of
carrying a workaround.

Changes

  • New valkey role. Valkey comes from the distribution repositories, and the configuration
    template matching the installed version is deployed; the role asserts up front that a template
    for that version exists. Templates for 7.2, 8.0, 8.1 and 9.0 are taken verbatim from the
    packages of the respective distributions.
  • New playbooks/valkey.yml, wired into playbooks/all.yml.
  • New molecule scenario extensions/molecule/valkey.
  • redis: vars/RedHat10.yml removed, README points RHEL 10 users at the valkey role.
  • CHANGELOG.md and COMPATIBILITY.md updated.

Breaking change

The redis role no longer supports RHEL 10. Move those hosts to the valkey role: put them into
the lfops_valkey inventory group and rename their redis__* variables to valkey__*.

Testing

molecule test --scenario-name valkey passes on Debian 13, RHEL 8, RHEL 9, RHEL 10, Ubuntu 24.04
and Ubuntu 26.04: converge, verify, idempotence (changed=0) and a second verify, on every
target. Debian 12 and Ubuntu 22.04 ship no Valkey and are not supported.

Valkey gets its own role instead of being installed under the Redis
name. On RHEL 10 the redis role pointed at /etc/valkey while hardcoding
the 'redis' group, so deploying the configuration aborted with "chgrp
failed: failed to look up group redis". Red Hat ships no Redis on RHEL
10 at all, so the redis role drops that platform instead of carrying a
workaround.

The role installs Valkey from the distribution repositories and deploys
the configuration template matching the installed version, asserting up
front that a template for that version exists. The templates for 7.2,
8.0, 8.1 and 9.0 are taken verbatim from the packages of the respective
distributions.

Verified with the new molecule scenario on Debian 13, RHEL 8, RHEL 9,
RHEL 10, Ubuntu 24.04 and Ubuntu 26.04: converge, verify, idempotence
and a second verify pass on every target. Debian 12 and Ubuntu 22.04
ship no Valkey and are not supported.

BREAKING CHANGE: The redis role no longer supports RHEL 10. Move those
hosts to the valkey role: put them into the lfops_valkey inventory
group and rename their redis__* variables to valkey__*.
setup_icinga2_master, setup_mastodon, setup_moodle and setup_nextcloud
could not be deployed on RHEL 10, because the redis role they pull in
has no support for that platform. They now select the server by OS:
Valkey on RHEL 10, Redis everywhere else, which is what the two
platforms ship. Both speak the same protocol on the same port, so the
applications themselves are configured identically either way.

The choice is exposed as a pair of skip variables per playbook, so a
host can be pinned to a specific server or opt out of both. Enabling
both is not prevented; that is left to the admin.

repo_redis is now tied to the redis role, so a Debian host on Valkey
does not get the redis.io repository it has no use for.
maxmemory, service_limit_nofile and service_timeout_stop_sec differ from what
the packages ship. Record the upstream value next to each default and the
reasoning in the README, per "Deviating from an Upstream Default" in
CONTRIBUTING.md.

Read off a clean package installation on every supported platform (the shipped
valkey.conf, the shipped unit, and CONFIG GET on a running server), not from
the Valkey documentation: valkey 8.0.10 (RHEL 8 / EPEL), 8.0.9 (RHEL 9 and 10 /
AppStream), 8.1.1 (Debian 13), 7.2.13 (Ubuntu 24.04), 9.0.4 (Ubuntu 26.04).
The default dropped ::1 entirely to avoid "Failed listening on port 6379 (tcp),
aborting." on a host without an IPv6 loopback, such as a RHEL minimal
installation. Upstream solves the same problem with the '-' prefix, which makes
an address optional: the server warns and carries on where it does not exist.
Clients connecting over ::1 were refused before.

Verified on Rocky 9 (valkey 8.0.9), Debian 13 (8.1.1) and Ubuntu 24.04 (7.2.13),
each with and without an IPv6 loopback in the network namespace: '127.0.0.1 ::1'
aborts where it is absent, '127.0.0.1 -::1' starts in both cases and answers on
::1 where one exists.
Every packaged unit starts the server with "--daemonize no --supervised systemd"
on its ExecStart line, and the command line wins over the configuration file, so
neither variable ever reached the running service. Pin both to the values the
units enforce and stop offering a knob that does nothing.

Verified that the command line wins by starting valkey 8.0.9 with the opposite
values in valkey.conf: CONFIG GET reports the command-line ones. Verified the
ExecStart override on all six supported platforms (RHEL 8 / 9 / 10, Debian 13,
Ubuntu 24.04 / 26.04).

No breaking-change marker and no CHANGELOG entry: the role has not shipped yet,
so no inventory can carry either variable. The rendered valkey.conf is unchanged
("daemonize no", "supervised auto"), so the template header timestamps stay.

Note that roles/redis is NOT the same case and keeps both variables: the
packages.redis.io unit used on Debian and Ubuntu has a bare ExecStart with
Type=notify, so "supervised" in the configuration file is what makes the service
report readiness. Setting it to "no" there makes the unit fail to start.
Neither value could change the running service. A Redis supervised by systemd
never daemonizes, whatever daemonize says, and every packaged unit either passes
"--daemonize no --supervised systemd" on its ExecStart line or, for
packages.redis.io on Debian and Ubuntu, relies on the "supervised auto" this
role deploys. There "no" is the only other reachable value and it leaves the
unit failed, so no setting an administrator could pick was useful.

Measured across 54 runs, six daemonize/supervised combinations against each
package: redis from Remi (EL8 7.2.16, EL9 8.0.6), AppStream (EL8 5.0.3, EL9
6.2.22), packages.redis.io (Debian 12/13, Ubuntu 24.04, 8.10.1) and the distro
packages (Debian 13 8.0.2, Ubuntu 24.04 7.0.15). Only one combination was ever
not "active": packages.redis.io with "supervised no". EL8 AppStream is the
clearest evidence for daemonize, since its unit passes --supervised systemd but
not --daemonize no, and "daemonize yes" still came up.

The rendered redis.conf is unchanged ("daemonize no", "supervised auto"), so the
template header timestamps stay. Verified the role end to end afterwards on
Debian 13 with redis.io 8.8.2 (bare ExecStart) and Rocky 9 with Remi 7.2.16:
service active, PONG, second run idempotent.
The default dropped ::1 entirely to avoid "Failed listening on port 6379 (tcp),
aborting." on a host without an IPv6 loopback, such as a RHEL minimal
installation, so a client resolving localhost to ::1 was refused. Upstream
solves the same problem with the '-' prefix, which makes an address optional:
the server warns and carries on where it does not exist.

Verified with Remi redis 7.2.16 on Rocky 9 and packages.redis.io redis 8.8.2 on
Debian 13, each with and without an IPv6 loopback in the network namespace:
'127.0.0.1 ::1' aborts where it is absent, '127.0.0.1 -::1' starts in both cases.
Running the role end to end on both kinds of host leaves the service active and
answering, on ::1 as well where one exists, and is idempotent.

Same change as the one made for roles/valkey.
The guard read ansible_facts["all_ipv6_addresses"], which lists the real
addresses only and never contains ::1, so both tasks skipped on every target.
The scenario reported success while the bind default this branch changed went
unverified. Gate on the loopback interface facts instead.

Before: the verify play was ok=14 skipped=2 on all six targets, and the two
IPv6 tasks skipped everywhere. After: ok=16 skipped=0, and the assertion passes
on all six in both verify runs.
@NavidSassan
NavidSassan merged commit 3271161 into main Sep 4, 2026
12 checks passed
@NavidSassan
NavidSassan deleted the feat/valkey branch September 4, 2026 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant