I’m trying to write an Ansible role that configures Redis cluster.
The shell command that creates the cluster is:
$ /usr/bin/redis-cli --user admin --pass mypass --cluster create 10.226.2.194:6379 10.226.2.196:6379 10.226.2.195:6379 --cluster-replicas 1 --cluster-yes
I pass username, password, IP addresses of Redis servers and number of replicas as extra-vars
in shell script
#!/bin/sh
ansible-playbook /etc/ansible/playbook-redis.yml -vv
--extra-vars='redis_admin_user=admin redis_admin_password=mypass'
--extra-vars='redis_cluster_members="10.226.2.194:6379 10.226.2.196:6379 10.226.2.195:6379" redis_cluster_replicas=1'
After reading the documentation for the command module I wrote the following task:
- name: Create Redis cluster
ansible.builtin.command:
argv:
- /usr/bin/redis-cli
- "--user {{ redis_admin_user }}"
- "--pass {{ redis_admin_password }}"
- "--cluster create {{ redis_cluster_members }}"
- "--cluster-replicas {{ redis_cluster_replicas }}"
- --cluster-yes
But when I run it I get the following error:
"Unrecognized option or bad number of args for: '--user admin'"
which seems to be error of redis-cli that it doesn’t recognize the argument.
I was able to get around the username and password by changing the task as following:
- name: Create Redis cluster
ansible.builtin.command:
argv:
- /usr/bin/redis-cli
- --user
- "{{ redis_admin_user }}"
- --pass
- "{{ redis_admin_password }}"
- --cluster create
- "{{ redis_cluster_members }}"
- --cluster-replicas
- "{{ redis_cluster_replicas }}"
- --cluster-yes
This is not exactly nice looking, but at least it passes the username and the password, because the following task works:
- name: Get server info
ansible.builtin.command:
argv:
- /usr/bin/redis-cli
- --user
- "{{ redis_admin_user }}"
- --pass
- "{{ redis_admin_password }}"
- info
But now it can’t get past the --cluster create
argument:
"Unrecognized option or bad number of args for: '--cluster create'"
I also tried - --cluster create "{{ redis_cluster_members }}"
and
- --cluster
- create
- "{{ redis_cluster_members }}"
to no avail.
What is the correct syntax to run this command?
P.S.
The following task works correctly:
- name: Get Redis version
ansible.builtin.command:
argv:
- /usr/bin/redis-cli
- --version
and returns the version.
P.P.S
The following also works
- name: Create Redis cluster
ansible.builtin.command:
cmd: "/usr/bin/redis-cli --user {{ redis_admin_user }} --pass {{ redis_admin_password }} --cluster create {{ redis_cluster_members }} --cluster-replicas {{ redis_cluster_replicas }} --cluster-yes"
2
Answers
Got help from Ansible devs at GitHub. The reason for this behavior is how command module and redis-cli utility work with arguments.
argv
adds delimiters when passing the command to the command line. So this:turns to (mind the single quotation marks)
If you enter the above command directly you'll get the same error when running the task -
"Unrecognized option or bad number of args for: '--user admin'"
This is because how redis-cli delimits arguments. From redis-cli documentation:
So, the correct command should be (note the single quotation marks)
But for the Ansible task there is a problem -
redis_cluster_members
variable. The solution suggested to me at GitHub:It works, but I decided to use a workaround. In
vars/main.yml
I defined a variableFor the explanation about
>
please read this article, particularly the second part. Thequote
filter is for, as suggested in command module's documentation, "to avoid injection issues". Note that it's missing fromredis_cluster_members
line because it too breaks the arguments.The task itself:
I can’t test but I’m pretty sure you need to separate each cluster member in its own item in the
argv
list. The following is a bit ugly but should work.