dealing with Redis and it's rewritten configuration files

How do people generally set up Redis through ansible?

Right now we’re using the fairly standard approach of templating the configuration files, and using a notify handler to restart redis whenever the configuration file changes.

The problem with this is that Redis often rewrites its configuration files; for example when a new master is elected.

So if we run a provision again, ansible resets the configuration file to its original value (pointing at the old master), and then restarts Redis. Due to the way Redis and our system is set up, that doesn’t actually appear to be a problem. The new master has a larger epoch value so the restart does not cause the master to change; and our system can tolerate a restarting Redis.

It just seems wrong, so I’m curious to here how other people configure Redis with ansible.

thanks,
Bryan

Excerpts from Bryan Larsen's message of 2014-04-02 08:42:55 -0400:

The problem with this is that Redis often rewrites its configuration files;
for example when a new master is elected.

I haven't actually used Ansible to set up Redis, but I have run into
software that does this, and I would note three things:

1. Ugh tell upstream to not do this. They probably won't listen but
   it's just a terrible thing, in my opinion.

2. The lineinfile module can be made to do some terrifying things, and
   you might finds it useful: if you're a bit clever with your regexes
   and backrefs, you can make almost any change you can perform with it
   idempotent. As an example, this horrifying snippet I use to
   configure ntp.conf:

       - name: Comment out default timeservers.
         lineinfile:
           state: present
           dest: /etc/ntp.conf
           backrefs: yes
           regexp: '^(server (?!{{ ntp_server }}).*)'
           line: '#\\1'
         register: result
         until: not result|changed
         retries: 5
         delay: 1
         notify:
           - restart ntpd

       - name: Set timeserver.
         lineinfile:
           state: present
           dest: /etc/ntp.conf
           insertafter: '^#server .*'
           regexp: '^server .*'
           line: 'server {{ ntp_server }}'
         notify:
           - restart ntpd

   This will comment out any 'server directive beside the one I want, and
   then insert my desired one.

3. Perhaps write some custom facts that get the current state of the
   Redis configuration and incorporate them into the template? You
   might also find Redis' CONFIG GET/SET/REWRITE commands useful.

Thanks for your suggestions.

I think my approach will be to use the template file to create the configuration only if it doesn’t exist, and then use config set/rewrite to set any configuration variables that may change over the project lifetime.

Ansible 1.6 includes some more options to the redis module to make the second part easier, so I may just wait until ansible 1.6 is stable. As I said, my current approach that resets the configuration files and restarts redis on every provision appears to work, it just feels icky.

Bryan

I would use custom fact script on each target that queries locally to see if it ‘is master’, put it in /etc/ansible/facts.d and it will run automatically on gather facts.

I would make sure only 1 master appears when going over the facts, then you can just feed it to the template from the ‘fact’ and it should not change that in the config (nor restart the server if there aren’t any other changes).

Brian Coca