You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 03:25:26