如何在Ansible中集中定义任务选项并在多任务中复用?
我目前正在使用多个community.postgresql模块,例如postgresql_db、postgresql_user和postgresql_privs。每次都必须定义login_host、port、login_user、login_password选项,但这些选项在整个执行过程中完全相同,因此我希望集中定义一次并在各任务中引用。
目前我的任务代码如下:
- name: Create database community.postgresql.postgresql_db: name: "{{ pg_db_name }}" login_host: "{{ pg_host }}" port: "{{ pg_port }}" login_user: "{{ pg_admin.username }}" login_password: "{{ pg_admin.password }}" - name: Create database user community.postgresql.postgresql_user: name: "{{ pg_user.username }}" password: "{{ pg_user.password }}" login_host: "{{ pg_host }}" port: "{{ pg_port }}" login_user: "{{ pg_admin.username }}" login_password: "{{ pg_admin.password }}" - name: Set user privileges on database community.postgresql.postgresql_privs: database: "{{ pg_db_name }}" roles: "{{ pg_user.username }}" privs: ALL type: database login_host: "{{ pg_host }}" port: "{{ pg_port }}" login_user: "{{ pg_admin.username }}" login_password: "{{ pg_admin.password }}"
我原本想通过YAML Merge实现,但似乎不可行,总是出现以下错误:
ERROR! conflicting action statements: login_host, login_user
我使用YAML Merge的尝试代码如下:
- &pg_connect { login_host: "{{ pg_host }}", port: "{{ pg_port }}", login_user: "{{ pg_admin.username }}", login_password: "{{ pg_admin.password }}" } - name: Create database community.postgresql.postgresql_db: << : *pg_connect name: "{{ pg_db_name }}" - name: Create database user community.postgresql.postgresql_user: << : *pg_connect name: "{{ pg_user.username }}" password: "{{ pg_user.password }}" - name: Set user privileges on database community.postgresql.postgresql_privs: << : *pg_connect database: "{{ pg_db_name }}" roles: "{{ pg_user.username }}" privs: ALL type: database
在Ansible中是否有简单的方案可以省去这些重复代码?
我随后尝试了module_defaults方案,但遇到了以下问题:
我使用最简playbook测试以避免副作用:
pg_connect_modules曾在playbook的vars区域静态定义(如下例),也通过set_fact在运行时定义。pg_connect在所有测试场景中均通过set_fact在运行时定义。- 任务Create database No 1的
module_defaults定义可正常工作。 - 任务Create database No 2的
module_defaults定义总是触发以下错误,导致playbook根本无法启动:ansible-playbook -i inventory play.yml
ERROR! The field 'module_defaults' is supposed to be a dictionary or list of dictionaries, the keys of which must be static action, module, or group names. Only the values may contain templates. For example: {'ping': "{{ ping_defaults }}"} - 只有注释掉任务Create database No 2或至少其
module_defaults行,才能启动playbook执行。 - 若将数据库任务放在任务文件中并通过
include_tasks引入,引入操作会失败,playbook执行到该步骤时触发相同错误。
我的playbook代码如下:
play.yml --- - hosts: testserver become: yes vars: pg_connect_modules: community.postgresql.postgresql_db: login_host: "localhost" port: "5432" login_user: "postgres_admin" login_password: "myPass" tasks: - set_fact: pg_connect: "{{ common_defaults }}" vars: common_defaults: login_host: "localhost" port: "5432" login_user: "postgres_admin" login_password: "myPass" - name: Create database No 1 community.postgresql.postgresql_db: name: "test1" module_defaults: community.postgresql.postgresql_db: "{{ pg_connect }}" - name: Create database No 2 community.postgresql.postgresql_db: name: "test1" module_defaults: "{{ pg_connect_modules }}"
内容的提问来源于stack exchange,提问作者phanaz

