gpt4 book ai didi

ansible - 集中定义冗余任务选项并在不同任务中重复使用它们

转载 作者:行者123 更新时间:2023-12-02 17:57:42 27 4
gpt4 key购买 nike

是否可以集中定义任务选项以在不同的任务中重用它们?

我目前正在与几个 community.postgresql 合作模块,如 postgresql_dbpostgresql_userpostgresql_privs。我总是必须定义选项 login_hostportlogin_userlogin_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 变体测试了一段时间,但遇到了以下问题。

我使用最小的剧本进行了测试,以尽可能避免副作用。

  • pg_connect_modules 定义在 playbook 的 vars 区域(如示例)和运行时通过 set_fact 测试为静态定义。<
  • pg_connect 在所有测试场景中通过 set_fact 在运行时定义。
  • 任务 Create database No 1module_defaults 定义没有问题。
  • 任务Create database No 2module_defaults 定义总是导致以下错误- 剧本执行根本无法开始,直接出现错误。

    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 行,我才能开始执行剧本。
  • 如果我在任务文件中有数据库任务并通过include_tasks 包含它们,则包含失败;剧本执行到那个点,然后包含失败并出现相同的错误。

我的剧本是这样的:

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 }}"

最佳答案

在任何level (play, role, block, task) 你可以使用module_defaults .例如,在一个 block 中

- block:

- name: Create database
community.postgresql.postgresql_db:
name: "{{ pg_db_name }}"

- name: Create database user
community.postgresql.postgresql_user:
name: "{{ pg_user.username }}"
password: "{{ pg_user.password }}"

- name: Set user privileges on database
community.postgresql.postgresql_privs:
database: "{{ pg_db_name }}"
roles: "{{ pg_user.username }}"
privs: ALL
type: database

module_defaults:
community.postgresql.postgresql_db:
login_host: "{{ pg_host }}"
port: "{{ pg_port }}"
login_user: "{{ pg_admin.username }}"
login_password: "{{ pg_admin.password }}"
community.postgresql.postgresql_user:
login_host: "{{ pg_host }}"
port: "{{ pg_port }}"
login_user: "{{ pg_admin.username }}"
login_password: "{{ pg_admin.password }}"
community.postgresql.postgresql_privs:
login_host: "{{ pg_host }}"
port: "{{ pg_port }}"
login_user: "{{ pg_admin.username }}"
login_password: "{{ pg_admin.password }}"

在代码之外组合和声明字典 module_defaults 是实用的。例如,在 group_vars

shell> cat group_vars/all/my_defaults.yml
my_module_defaults_list:
- modules:
- community.postgresql.postgresql_db
- community.postgresql.postgresql_user
- community.postgresql.postgresql_privs
defaults:
login_host: "{{ pg_host }}"
port: "{{ pg_port }}"
login_user: "{{ pg_admin.username }}"
login_password: "{{ pg_admin.password }}"

my_module_defaults_str: |
{% for i in my_module_defaults_list %}
{{ dict(i.modules|product([i.defaults])) }}
{% endfor %}
my_module_defaults: "{{ my_module_defaults_str|from_yaml }}"

给定以下变量

  pg_host: pb.example.com
pg_port: 5432
pg_admin:
username: admin
password: admin_passwd

字典给出

  my_module_defaults:
community.postgresql.postgresql_db:
login_host: pb.example.com
login_password: admin_passwd
login_user: admin
port: 5432
community.postgresql.postgresql_privs:
login_host: pb.example.com
login_password: admin_passwd
login_user: admin
port: 5432
community.postgresql.postgresql_user:
login_host: pb.example.com
login_password: admin_passwd
login_user: admin
port: 5432

不幸的是,不能直接在游戏中使用它。由于某些原因,字典的键必须是静态的

- block:

- name: Create database
community.postgresql.postgresql_db:
name: "{{ pg_db_name }}"

- name: Create database user
community.postgresql.postgresql_user:
name: "{{ pg_user.username }}"
password: "{{ pg_user.password }}"

- name: Set user privileges on database
community.postgresql.postgresql_privs:
database: "{{ pg_db_name }}"
roles: "{{ pg_user.username }}"
privs: ALL
type: database

module_defaults: "{{ my_module_defaults }}"

上面的代码会导致错误:

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 }}"}

作为解决方法,您可以创建以下模板

shell> cat postgresql.yml.j2
- block:

- name: Create database
community.postgresql.postgresql_db:
name: "{{ pg_db_name }}"

- name: Create database user
community.postgresql.postgresql_user:
name: "{{ pg_user.username }}"
password: "{{ pg_user.password }}"

- name: Set user privileges on database
community.postgresql.postgresql_privs:
database: "{{ pg_db_name }}"
roles: "{{ pg_user.username }}"
privs: ALL
type: database

module_defaults:
{{ my_module_defaults|to_nice_yaml(indent=2)|indent(4, first=true) }}

并将创建的文件包含在播放中

    - template:
src: postgresql.yml.j2
dest: "{{ playbook_dir }}/postgresql.yml"
delegate_to: localhost
run_once: true
- include_tasks: postgresql.yml

<支持>
shell> cat postgresql.yml
- block:

- name: Create database
community.postgresql.postgresql_db:
name: "db_01"

- name: Create database user
community.postgresql.postgresql_user:
name: "user"
password: "user_passwd"

- name: Set user privileges on database
community.postgresql.postgresql_privs:
database: "db_01"
roles: "user"
privs: ALL
type: database

module_defaults:
community.postgresql.postgresql_db:
login_host: pb.example.com
login_password: admin_passwd
login_user: admin
port: 5432
community.postgresql.postgresql_privs:
login_host: pb.example.com
login_password: admin_passwd
login_user: admin
port: 5432
community.postgresql.postgresql_user:
login_host: pb.example.com
login_password: admin_passwd
login_user: admin
port: 5432

正确的解决方案是创建 Module defaults group . source 中没有声明组自动取款机。你可以创造它。例如,找出您的收藏的路径并创建组

shell> cat ~/.local/lib/python3.9/site-packages/ansible_collections/community/postgresql/meta/runtime.yml 
---
requires_ansible: '>=2.9.10'
action_groups:
postgresql:
- postgresql_db
- postgresql_privs
- postgresql_user

然后下面的 block 应该按预期工作

    - block:

- name: Create database
community.postgresql.postgresql_db:
name: "db_01"

- name: Create database user
community.postgresql.postgresql_user:
name: "user"
password: "user_passwd"

- name: Set user privileges on database
community.postgresql.postgresql_privs:
database: "db_01"
roles: "user"
privs: ALL
type: database

module_defaults:
group/community.postgresql.postgresql:
login_host: pb.example.com
login_password: admin_passwd
login_user: admin
port: 5432

你可以打开一个request如果你想。有必要检查所有 postgresql 模块的所有参数的一致性并创建组。


注意事项:

  • 在关键任务环境中,提供有限范围内的login_password。参见 Ansible passing vault password file to playbook .

  • 如果您想在播放级别使用module_defaults,则字典必须在此范围内可用。参见 Ansible, module_defaults and package module (已过时;在 2.12 中损坏)。

  • 引自 CHANGELOG-v2.12.rst 重大变更:“module_defaults 中的操作、模块和组名称必须是静态值。它们的值仍然可以是模板。”

<支持>

用于测试错误和解决方法的完整剧本示例

shell> cat pb3.yml
- hosts: localhost

vars:

my_module_defaults:
debug:
msg: common default

debug_defaults:
msg: common default

tasks:

- name: Work as expected
debug:
module_defaults:
debug: "{{ debug_defaults }}"

# - name: ERROR
# debug:
# module_defaults: "{{ my_module_defaults }}"
#
# 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 }}"}

- name: Workaround
template:
src: my_module.yml.j2
dest: "{{ playbook_dir }}/my_module.yml"
- include_tasks: my_module.yml
shell> cat my_module.yml.j2
- block:

- debug:

module_defaults:
{{ my_module_defaults|to_nice_yaml(indent=2)|indent(4, first=true) }}
shell> cat my_module.yml
- block:

- debug:

module_defaults:
debug:
msg: common default

关于ansible - 集中定义冗余任务选项并在不同任务中重复使用它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75304438/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com