How to grant MySQL server administration privileges (SUPER, RELOAD...) with ansible?
Found out the elegant solution after all! First of all the privileges should be defined somewhere as a list:
$ cat group_vars/dbservers
mysql_privileges:
- 'somedatabase.*:ALL'
- 'someotherdatabase.*:ALL'
- '*.*:SUPER,RELOAD,SHOW\ DATABASES'
then the mysql_user
plugin does not need to append the privileges, simply use the privileges string mentioned in the documentation in following format: mydb.*:INSERT,UPDATE/anotherdb.*:SELECT/yetanotherdb.*:ALL
.
The only trick is how to convert list to the string:
- name: Set user privileges
mysql_user:
user={{ mysql_user }}
password={{ mysql_password }}
state=present
priv={{ mysql_privileges|join('/') }}
The repeatable run of the task does not say changed anymore:
TASK: [db | Set user privileges]
**********************************************
ok: [dbuser]
Found out that when switched the order of the privileges I am able to grant mentioned admin. privileges:
- name: Set user privileges
mysql_user:
user={{ mysql_user }}
password={{ mysql_password }}
state=present
append_privs=yes
priv={{ item }}
with_items:
- 'somedatabase.*:ALL'
- 'someotherdatabase.*:ALL'
- '*.*:SUPER,RELOAD,SHOW\ DATABASES'
privileges are set as expected:
mysql> show grants for 'dbuser'@'localhost';
+---------------------------------------------------------------------------------------------------------------------------------------+
| Grants for dbuser@localhost |
+---------------------------------------------------------------------------------------------------------------------------------------+
| GRANT RELOAD, SHOW DATABASES, SUPER ON *.* TO 'dbuser'@'localhost' IDENTIFIED BY PASSWORD '*2046D2DDAE359F311435E8B4D3776EFE13FB584C' |
| GRANT ALL PRIVILEGES ON `somedatabase`.* TO 'dbuser'@'localhost' |
| GRANT ALL PRIVILEGES ON `someotherdatabase`.* TO 'dbuser'@'localhost' |
+---------------------------------------------------------------------------------------------------------------------------------------+
though the task is still not idempotent. Every run gives me:
TASK: [db | Set user privileges]
**********************************************
changed: [dbuser] => (item=somedatabase.*:ALL)
ok: [dbuser] => (item=someotherdatabase.*:ALL)
changed: [dbuser] => (item=*.*:SUPER,RELOAD,SHOW\ DATABASES)
There's no need for tricks with lists, you can set multiple privileges separated by a slash:
- name: Set user privileges
mysql_user:
user: {{ mysql_user }}
password: {{ mysql_password }}
state: present
priv: 'somedatabase.*:ALL/someotherdatabase.*:ALL/*.*:SUPER,RELOAD,SHOW DATABASES'
or shorter:
- name: Set user privileges
mysql_user: user={{ mysql_user }}
password={{ mysql_password }}
state=present
priv='somedatabase.*:ALL/someotherdatabase.*:ALL/*.*:SUPER,RELOAD,SHOW DATABASES'