防止Ansible 2中出现重复的密钥警告

防止Ansible 2中出现重复的密钥警告,ansible,ansible-playbook,ansible-2.x,Ansible,Ansible Playbook,Ansible 2.x,我在我的角色中使用了大量YAML锚定和引用,以将逻辑保持在单个位置,而不是在多个任务中重复我自己。下面是一个非常基本的例子 - &sometask name: "Some Task" some_module: with a lot of parameters with_items: list_A - <<: *sometask name: "Some OTHER Task" with_items: list_B Ansible 2现在有一个功能,当一个

我在我的角色中使用了大量YAML锚定和引用,以将逻辑保持在单个位置,而不是在多个任务中重复我自己。下面是一个非常基本的例子

- &sometask
  name: "Some Task"
  some_module: with a lot of parameters
  with_items: list_A

- <<: *sometask
  name: "Some OTHER Task"
  with_items: list_B
Ansible 2现在有一个功能,当一个任务中多次定义了键时,可以抱怨。它仍然有效,但在运行playbook时会产生不必要的噪音:

TASK [Some OTHER Task] *******************************************************
 [WARNING]: While constructing a mapping from /some/file.yml, line 42, column 3, found a duplicate dict key (name).  Using last defined value only.

 [WARNING]: While constructing a mapping from /some/file.yml, line 42, column 3, found a duplicate dict key (with_items).  Using last defined value only.

Ansible配置允许防止和消除故障。是否有办法防止此类警告?

还有一个
系统警告配置选项,但这些选项都不会使您看到的输出静音

下面是从中生成该消息的代码
ansible/lib/ansible/parsing/yaml/constructor.py

if key in mapping:
    display.warning('While constructing a mapping from {1}, line {2}, column {3}, found a duplicate dict key ({0}).  Using last defined value only.'.format(key, *mapping.ansible_pos))
虽然您使用YAML引用非常聪明,但我怀疑这是否会很快改变,因为Ansible的核心租户是剧本和任务的可读性。将有助于任务条件的重复,尽管此时它们似乎仅限于剧本中的任务


您始终可以提交一个请求,添加一个禁用这些警告的选项,并查看它的去向。

要在Ansible中创建任务级别的可重用功能,您应该查看任务包含。Task includes将允许您更自由地做一些事情,如使用_项进行迭代等。在我的雇主,我们自由地使用锚/引用,但仅用于变量。鉴于在Ansible中创建可重用任务的几种现有方法,例如任务包含、剧本包含和角色,我们不需要按照您描述的方式为任务使用锚定/引用

如果您只想在任务之间复制模块参数,可以使用模板路径:

args_for_case_x: arg1='some value' arg2=42 arg3='value3'

- name: a task of case x for a particular scenario
  the_module: "{{ args_for_case_x }}"
  when: condition_a

- name: a different use of case x
  the_module: "{{ args_for_case_x }}"
  when: condition_b

正如您所看到的,这不容易支持基于循环迭代改变参数,如果您使用上述重用功能之一,您可能会得到循环迭代。

稍后我将不同意其他答案,并支持YAML merge。Playbook布局非常主观,什么对您最合适取决于您需要描述的配置

是的,ansible具有与或与\u items/with \u dict合并的功能

我发现YAML merge的用例是任务只有几个异常值,因此可以覆盖的默认值是最紧凑和可读的表示形式。让ansible抱怨完全有效的语法是令人沮丧的

中的评论表明开发人员比用户更清楚

其中大部分来自yaml.constructor.SafeConstructor。我们在这里复制它,以便在用户有重复的dict密钥时警告用户(pyyaml静默地允许覆盖密钥)


PyYAML默默地允许“覆盖”键,因为在中明确处理了键优先级。

从Ansible 2.9.0开始,这可以通过将环境变量
Ansible\u DUPLICATE\u YAML\u DICT\u key
设置为
ignore
来实现。此变量的其他可能值为
warn
,这是默认值并保留原始行为;以及
error
,这会导致playbook执行失败


有关实现的详细信息,请参阅pull request。

有趣的是,我刚刚准备提交一个pull请求,以使这个确切的警告成为致命警告,因为它掩盖了剧本中的实际错误。现在我想知道是否需要某种形式的
——警告是致命的
标志……看起来他们没有正确地修复它。我把这个变量放在我的剧本“ANSIBLE\u DUPLICATE\u YAML\u DICT\u KEY:‘ignore’”的顶层,但仍然收到警告。不过还是谢谢你的链接。我必须使用2个“changed_when”逻辑块,但得到以下警告:“找到重复的dict密钥(changed_when)”@Shtefan:这是一个环境变量。我不是Ansible专家,但不确定是否支持以这种方式填充它。我想你也可以通过ansible.cfg进行设置。看看这里:它不是一个真正的变量。它是可解逻辑的一部分。见官方文件:。当我需要抑制不必要的“changed”标志时,我使用的是“failed_When”块。“我没办法把它改成别的东西了。”“好吧,我想我明白你的意思了。”。为了确保我足够清楚,我的意思是在终端中运行
ANSIBLE\u DUPLICATE\u YAML\u DICT\u KEY=ignore ANSIBLE playbook your\u playbook.YAML
应该设置变量,我不确定ANSIBLE是否允许您像在playbook中那样设置配置变量。在剧本中这样做似乎没有记录在这里:无论如何,如果这不能解决问题,请随时与他们一起打开一个bug。谢谢你,Mihai。我会努力的。
args_for_case_x: arg1='some value' arg2=42 arg3='value3'

- name: a task of case x for a particular scenario
  the_module: "{{ args_for_case_x }}"
  when: condition_a

- name: a different use of case x
  the_module: "{{ args_for_case_x }}"
  when: condition_b