如何用Ansible通过嵌套列表创建PostgreSQL用户及数据库?
Ansible维护PostgreSQL数据库与用户的最佳YAML结构及循环处理方案
两种YAML结构分析
结构一:用户信息内嵌数据库配置
你最初尝试的结构将用户信息直接嵌套在对应数据库的配置下,优点是能直观看到每个数据库关联的用户,但存在用户重复定义的问题(比如user2在两个数据库下都出现),导致创建用户任务可能重复执行。
--- databases: - name: database1 owner: postgres users: - name: user1 pass: secret priv: CONNECT,REPLICATION - name: user2 pass: secret priv: CONNECT - name: database2 owner: postgres users: - name: user3 pass: secret priv: CONNECT - name: user2 pass: secret priv: CONNECT
结构二:用户与数据库配置分离
拆分后的结构将用户信息和数据库配置分开管理,用户信息集中定义,数据库配置仅关联用户名和权限,避免了用户信息重复,更利于维护。
--- postgres_users: - name: user1 pass: secret - name: user2 pass: secret - name: user3 pass: secret postgres_databases: - name: db1 owner: "{{ 'postgres' }}" users: - user: user1 priv: XXX.YYY - user: user2 priv: CONNECT - name: db2 owner: "{{ 'postgres' }}" users: - user: user1 priv: ZZZ - user: user2 priv: XXX
循环提取用户的实现方案
针对结构一:提取唯一用户列表
使用Ansible的json_query和unique过滤器,从所有数据库的users字段中提取去重后的用户列表,确保每个用户只创建一次:
- name: 提取唯一PostgreSQL用户列表 set_fact: unique_postgres_users: "{{ databases | json_query('[*].users[*]') | flatten | unique(attribute='name') }}" - name: 创建PostgreSQL用户 postgresql_user: name: "{{ item.name }}" password: "{{ item.pass }}" loop: "{{ unique_postgres_users }}"
json_query('[*].users[*]'):递归提取所有数据库下的用户数组flatten:将多维数组转为一维数组unique(attribute='name'):基于name字段去重,确保同一用户仅保留一条记录
针对结构二:分离式配置的处理
1. 创建用户
直接循环集中定义的postgres_users列表即可,无需去重:
- name: 创建PostgreSQL用户 postgresql_user: name: "{{ item.name }}" password: "{{ item.pass }}" loop: "{{ postgres_users }}"
2. 为数据库分配权限
使用subelements过滤器,将数据库与其关联的用户权限信息展开,逐个配置权限:
- name: 为数据库分配用户权限 postgresql_privs: database: "{{ db_item.name }}" role: "{{ user_item.user }}" privs: "{{ user_item.priv }}" type: database loop: "{{ postgres_databases | subelements('users') }}" loop_control: loop_var: db_user_pair vars: db_item: "{{ db_user_pair.0 }}" user_item: "{{ db_user_pair.1 }}"
subelements('users'):将每个数据库条目与其下的users数组元素配对,生成包含数据库和用户权限的二维数组- 通过
loop_control和变量拆分,分别获取数据库信息和用户权限信息
方案建议
优先选择结构二(分离式配置),因为:
- 用户信息集中管理,避免重复定义和不一致
- 权限配置与用户信息解耦,修改用户密码时无需更新数据库配置
- 任务逻辑更清晰,减少去重等额外处理
内容的提问来源于stack exchange,提问作者nbari
相关产品推荐
相关产品推荐

