如何用Ansible的mysql_users模块批量创建多主机MySQL用户
Ansible 批量创建MySQL用户:解析applications字典方案
问题背景
现有如下变量结构:
applications: app1: app_user: app1 db_user: db_app1 db_pass: abc123 hosts: - 10.0.0.25 - localhost - 127.0.0.1 app2: app_user: app2 db_user: db_app2 db_pass: abc345 hosts: - 10.0.0.26 - localhost - 127.0.0.1
需要基于每个应用的db_user、db_pass和hosts列表,用mysql_user模块批量创建用户,最终生成如下格式的用户条目:
- { user: "db_app1", password: "abc123" , host: "10.0.0.25" } - { user: "db_app1", password: "abc123" , host: "localhost" } - { user: "db_app1", password: "abc123" , host: "127.0.0.1" } - { user: "db_app2", password: "abc345" , host: "10.0.0.26" } - { user: "db_app2", password: "abc345" , host: "localhost" } - { user: "db_app2", password: "abc345" , host: "127.0.0.1" }
解决方案
方法一:直接用with_subelements循环处理
这是最直接的方式,无需提前构造列表,直接在任务中关联应用数据和主机列表:
- name: 批量创建MySQL用户 mysql_user: name: "{{ item.0.db_user }}" password: "{{ item.0.db_pass }}" host: "{{ item.1 }}" state: present # 按需添加权限等其他参数,比如 priv: '*.*:ALL' with_subelements: - "{{ applications.values() }}" - hosts
逻辑说明:
applications.values()提取所有应用的配置字典(比如app1、app2对应的完整数据)with_subelements会把每个应用的字典和它的hosts列表做关联遍历,item.0代表当前应用的配置,item.1代表当前遍历到的主机地址
方法二:先构造目标用户列表再循环
如果需要先预先生成完整的用户列表(方便后续复用或调试),可以用set_fact结合过滤器实现:
- name: 生成标准化MySQL用户列表 set_fact: mysql_users_list: "{{ applications.values() | json_query('[].{user: db_user, password: db_pass, host: hosts}') | subelements('host') | map('combine') | list }}" - name: 批量创建MySQL用户 mysql_user: name: "{{ item.user }}" password: "{{ item.password }}" host: "{{ item.host }}" state: present loop: "{{ mysql_users_list }}"
逻辑说明:
json_query:把每个应用的配置转换成包含user、password、hosts的结构subelements('host'):将每个应用的主机列表拆分成单个条目,得到[{user:..., password:...}, 主机地址]的结构map('combine'):把拆分后的两部分合并成一个完整的用户字典,也就是你需要的目标格式- 最后通过
loop遍历列表完成用户创建
内容的提问来源于stack exchange,提问作者zwerg82
相关产品推荐
相关产品推荐

