将变量传递给主机的 Ansible playbook:使用双引号
Posted
技术标签:
【中文标题】将变量传递给主机的 Ansible playbook:使用双引号【英文标题】:Issue passing variable to Ansible playbook for hosts: with double quotes 【发布时间】:2018-10-01 22:26:37 【问题描述】:我正在尝试编写一个启动角色剧本并将主机列表传递给它的剧本。 “主”剧本中有一些负载平衡逻辑,我不想在每个角色剧本中重复,也不能放入 site.yml。
inventory.yml
[webservers]
Web1
Web2
Web3
Web4
master.yml
---
- name: Split Inventory into Odd/Even
hosts: all
gather_facts: false
tasks:
- name: Set Group Odd
set_fact:
group_type: "odd"
when: (inventory_hostname.split(".")[0])[-1] | int is odd
- name: Set Group Even
set_fact:
group_type: "even"
when: (inventory_hostname.split(".")[0])[-1] | int is even
- name: Make new groups "odd" or "even"
group_by:
key: " group_type "
- name: Perform Roles on Odd
include: webservers.yml hosts= groups['odd'] | join(' ')
- name: Perform Roles on Even
include: webservers.yml hosts= groups['even'] | join(' ')
webservers.yml
- name: Perform Tasks on Webservers
hosts: webservers:&" hosts | replace('\"','')"
roles:
- pause
join(' ') 将主机列表扁平化为一个字符串,每个主机之间用空格分隔。当我运行 playbook 时,它会将主机列表传递给 webservers.yml,但是它会在开头和结尾添加双引号,导致 webservers.yml 什么都不做,因为没有主机匹配。我假设 replace('\"','') 会删除字符串周围的引号,但似乎并非如此。这是 webservers.yml 的示例输出:
[WARNING]: Could not match supplied host pattern, ignoring: Web4"
[WARNING]: Could not match supplied host pattern, ignoring: "Web2
有什么想法吗? hosts:
处理过滤的方式不同吗?
【问题讨论】:
我认为replace('\"','')
没有任何理由。没有工作完全正常。你从哪里得到"
?您的库存是什么样的?
我不明白。 “负载均衡逻辑”是干什么用的?
@techraf 清单看起来像 [webservers] Web1 Web2 Web3 Web4 ,没有替换传递给 webservers.yml 的额外变量“hosts”打印为“Web2 Web4”,所以当它尝试正如您在警告中看到的那样,为它评估为“Web2 和 Web4”的主机解析该字符串。我尝试替换以删除“Web2 Web4”周围的引号,但它不起作用。
@Jack 负载均衡逻辑是从负载均衡器中删除所有奇数框,在奇数上运行 ansible 任务,将它们放回负载均衡器,对偶数重复。我从上面的剧本中省略了实际的 LB 任务,以使问题更容易识别。
您生成了一个不带引号的字符串,并且不需要删除引号。您在问题中发布的代码可以正常工作(尽管replace('\"','')
是不必要的)。这段代码唯一的事情是:你会收到一个警告,因为你会为变量名hosts
使用保留关键字。或者您正在使用一些带有错误的过时 Ansible 版本。
【参考方案1】:
我觉得你用错了角色和戏剧。当您执行任务时,您不应更改执行此任务或角色的主机列表。基本上,只有 play(带有'hosts:...,tasks:...,roles:...'的东西)可以控制运行的位置。
很少有例外,例如你可以玩代表团等等。但是对于您的情况,任何尝试使用任务或角色来控制主机列表只会带来痛苦和仇恨(对自己,对 ansible 等)。
要做到这一点,只需在您的剧本中添加另一个剧本(剧本是剧本的列表)。
这是您的代码,稍作修改。
---
- name: Split Inventory into Odd/Even
hosts: all
gather_facts: false
tasks:
- name: Set Group Odd
set_fact:
group_type: "odd"
when: (inventory_hostname.split(".")[0])[-1] | int is odd
- name: Set Group Even
set_fact:
group_type: "even"
when: (inventory_hostname.split(".")[0])[-1] | int is even
- name: Make new groups "odd" or "even"
group_by:
key: " group_type "
- name: Doing odd things
hosts: odd
gather_facts: false
tasks:
- name: Perform Roles
include: webservers.yml
- name: Doing even things
hosts: even
gather_facts: false
tasks:
- name: Perform Roles
include: webservers.yml
您可以看到,我刚刚将剧本分配给两个组(“奇数”和“偶数”)。动态组在剧本中保留在剧本之间,在这件事上它们与任何其他组没有什么不同。
附:不要使用 'include',使用 'import_tasks' (包括在新版本的 ansible 中是危险的,如果可以的话,避免使用它们。)。
【讨论】:
以上是关于将变量传递给主机的 Ansible playbook:使用双引号的主要内容,如果未能解决你的问题,请参考以下文章
Ansible playboos 实现上传文件创建crontab