Redis Sentinel configuration pipeline

The default Redis Sentinel installation in Debian Jessie and Debian Stretch supports only 1 instance of Redis per host. The pacakges in Debian Buster and the stretch-backports repository support multiple instances by using a single /etc/redis/sentinel-<instance>.conf configuration file per a systemd instance. However, due to the Redis modifying its own configuration file on the fly, using a single sentinel.conf configuration file does not work well with an Ansible-based approach to configuration.

The solution to this problem implemented in debops.redis_sentinel role is usage of a separate /etc/redis/sentinel-<instance>/ directory for each Redis Sentinel instance. This allows usage of multiple configuration files and even scripts for each Redis Sentinel instance, with configuration applied dynamically at runtime. The sentinel.conf configuration file is generated by Ansible at the instance initialization and not touched after that, since it is modified directly by Redis. This ensures idempotency and allows Ansible and Redis to work together.

Configuration variables

The debops.redis_sentinel Ansible role exposes a set of default variables that can be used to define and modify Redis configuration per instance. Configuration defined in each one is merged together in the redis_sentinel__combined_configuration using a special filter plugin. Multiple configuration entries defined in the format of the redis_sentinel__configuration parameters are merged together, therefore there's no need to copy everything to the Ansible inventory.

The variables are merged in the following order:

  • the redis_sentinel__default_base_options and the redis_sentinel__base_options hold the default parameters applied to all of the Redis Sentinel instances on a particular host. These variables can be used to override options applied to all instances when needed.

  • the redis_sentinel__default_instances and the all/group/host variant of the same variable are used to generate configuration for each instance, which is then put in the configuration pipeline via the redis_sentinel__default_configuration variable. Each instance will include the base options defined for all instances, and per-instance configuration like port, UNIX socket path, optional systemd overrides, etc.

    Additionally, each instance checks the redis_sentinel__default_monitors variable and the all/group/host variant of the same variable to include any monitors defined in them. Monitors that are confined to a particular Redis Sentinel instance are not included in others.

  • the redis_sentinel__default_configuration and the all/group/host variants include the actual configuration used by the role to generate the Redis Sentinel configuration files, systemd service configuration. The variables are joined together in the redis_sentinel__combined_configuration variable which is used in varius role tasks and templates. These variables can be used to override per-instance configuration if needed.

Configuration file structure

The generated configuration file structure contains the following files:

/etc/redis
├── sentinel-main/
│   ├── notify.d/
│   ├── reconfig.d/
│   ├── notify.sh*
│   ├── reconfig.sh*
│   └── sentinel.conf
├── sentinel-second/
│   ├── notify.d/
│   ├── reconfig.d/
│   ├── notify.sh*
│   ├── reconfig.sh*
│   └── sentinel.conf
├── sentinel-third/
│   ├── notify.d/
│   ├── reconfig.d/
│   ├── notify.sh*
│   ├── reconfig.sh*
│   └── sentinel.conf
└── sentinel.conf

The sentinel.conf file in each subdirectory is generated by Ansible at instance initialization. It will not be touched by Ansible later on, because Redis Sentinel modifies it directly.

The reconfig.sh and notify.sh scripts are hooks for the client-reconfig-script and notification-script parameters. They will run all scripts in their corresponding directories via the run-parts command. You can put custom scripts in these subdirectories to perform actions on certain Redis Sentinel events; see the Sentinel documentation for more details.