Ansible 我可以更新主机清单并在同一剧本中使用新主机吗?
我通过playbook在主机清单文件中添加了几个主机。现在我在同一个剧本中使用这些新添加的主机。但这些新添加的主机似乎不能在同一次运行中被同一个剧本读取,因为我得到了-Ansible 我可以更新主机清单并在同一剧本中使用新主机吗?,ansible,Ansible,我通过playbook在主机清单文件中添加了几个主机。现在我在同一个剧本中使用这些新添加的主机。但这些新添加的主机似乎不能在同一次运行中被同一个剧本读取,因为我得到了- skipping: no hosts matched 当我单独运行它时,即通过一个剧本更新主机文件,并通过另一个剧本使用其中更新的主机,它工作正常。不完全清楚您在做什么-但从我收集的信息来看,您在剧本中使用的是添加主机模块 似乎合乎逻辑的是,您不能将相同的播放限制在这些主机上,因为它们还不存在。。。所以这永远不会奏效: - n
skipping: no hosts matched
当我单独运行它时,即通过一个剧本更新主机文件,并通过另一个剧本使用其中更新的主机,它工作正常。不完全清楚您在做什么-但从我收集的信息来看,您在剧本中使用的是
添加主机
模块
似乎合乎逻辑的是,您不能将相同的播放限制在这些主机上,因为它们还不存在。。。所以这永远不会奏效:
- name: Play - add a host
hosts: new_host
tasks:
- name: add new host
add_host: name=new_host
但您可以自由地将多个播放添加到单个plabook文件中(您似乎也已经了解了这一点):
最近我想用ansible 1.8.4做类似的事情。我发现
add\u host
需要使用组名,否则将跳过该剧,并显示“没有匹配的主机”。同时,我想让play#2使用play#1中发现的事实。变量和事实通常对每个主机保持作用域,因此这需要使用神奇变量hostvars
和组
这是我想到的。它能用,但有点难看。我想看看更干净的替代品
# test.yml
#
# The name of the active CFN stack is provided on the command line,
# or is set in the environment variable AWS_STACK_NAME.
# Any host in the active CFN stack can tell us what we need to know.
# In real life the selection is random.
# For a simpler demo, just use the first one.
- hosts:
tag_aws_cloudformation_stack-name_{{ stack
|default(lookup('env','AWS_STACK_NAME')) }}[0]
gather_facts: no
tasks:
# Get some facts about the instance.
- action: ec2_facts
# In real life we might have more facts from various sources.
- set_fact: fubar='baz'
# This could be any hostname.
- set_fact: hostname_next='localhost'
# It's too late for variables set in this play to affect host matching
# in the next play, but we can add a new host to temporary inventory.
# Use a well-known group name, so we can set the hosts for the next play.
# It shouldn't matter if another playbook uses the same name,
# because this entry is exclusive to the running playbook.
- name: add new hostname to temporary inventory
connection: local
add_host: group=temp_inventory name='{{ hostname_next }}'
# Now proceed with the real work on the designated host.
- hosts: temp_inventory
gather_facts: no
tasks:
# The host has changed, so the facts from play #1 are out of scope.
# We can still get to them through hostvars, but it isn't easy.
# In real life we don't know which host ran play #1,
# so we have to check all of them.
- set_fact:
stack='{{ stack|default(lookup("env","AWS_STACK_NAME")) }}'
- set_fact:
group_name='{{ "tag_aws_cloudformation_stack-name_" + stack }}'
- set_fact:
fubar='{% for h in groups[group_name] %} {{
hostvars[h]["fubar"]|default("") }} {% endfor %}'
- set_fact:
instance_id='{% for h in groups[group_name] %} {{
hostvars[h]["ansible_ec2_instance_id"]|default("") }} {% endfor %}'
# Trim extra leading and trailing whitespace.
- set_fact: fubar='{{ fubar|replace(" ", "") }}'
- set_fact: instance_id='{{ instance_id|replace(" ", "") }}'
# Now we can use the variables instance_id and fubar.
- debug: var='{{ fubar }}'
- debug: var='{{ instance_id }}'
# end
听起来好像您正在使用playbook修改Ansible清单文件,然后想要使用该文件的新内容。然而,仅仅修改磁盘上文件的内容不会导致Ansible正在使用的资源清册被更新。Ansible的工作方式是,它在第一次开始时读取该文件(以及您拥有的任何其他资源清册源),并将找到的主机名放入内存中。从那时起,它只对存储在内存中的资源清册起作用,这些资源是它第一次开始运行时就存在的。它不知道文件的任何后续更改 但是有办法做你想做的事!您可以使用的一个选项是将新主机添加到资源清册文件中,并使用add_host模块将其加载到内存中。这是两个独立的步骤:1)将新主机添加到文件的资源清册中,然后2)使用以下命令将相同的新主机添加到内存资源清册中:
-name:将主机添加到内存资源清册中
添加\u主机:
名称:“{{new_host_name}}”
组:“{{group_name}}”
第二个选项是告诉Ansible从文件中刷新内存资源清册。但你必须明确地告诉它这样做。使用此选项,您可以执行两个相关步骤:1)将新主机添加到文件的资源清册中,就像您之前所做的那样,然后2)使用:
-name:刷新资源清册以确保资源清册中存在新实例
meta:刷新库存
是否有办法将“临时库存”提取到变量中?当我将其定义为变量时,主机匹配失败,跳过:没有匹配的主机。当我把它硬编码时,一切正常。我不确定这是出于设计还是一个bug。您可以使用测试用例创建一个新问题,并查看是否有其他人可以回答。在这里发布一个链接,我一定会看一看。仅供参考,这些天我使用terraform进行配置,ansible进行配置。因此,不再需要动态修改ansible库存。相反,我要么使用ec2.py清单脚本,要么从cloudinit userdata脚本运行ansible pull。
# test.yml
#
# The name of the active CFN stack is provided on the command line,
# or is set in the environment variable AWS_STACK_NAME.
# Any host in the active CFN stack can tell us what we need to know.
# In real life the selection is random.
# For a simpler demo, just use the first one.
- hosts:
tag_aws_cloudformation_stack-name_{{ stack
|default(lookup('env','AWS_STACK_NAME')) }}[0]
gather_facts: no
tasks:
# Get some facts about the instance.
- action: ec2_facts
# In real life we might have more facts from various sources.
- set_fact: fubar='baz'
# This could be any hostname.
- set_fact: hostname_next='localhost'
# It's too late for variables set in this play to affect host matching
# in the next play, but we can add a new host to temporary inventory.
# Use a well-known group name, so we can set the hosts for the next play.
# It shouldn't matter if another playbook uses the same name,
# because this entry is exclusive to the running playbook.
- name: add new hostname to temporary inventory
connection: local
add_host: group=temp_inventory name='{{ hostname_next }}'
# Now proceed with the real work on the designated host.
- hosts: temp_inventory
gather_facts: no
tasks:
# The host has changed, so the facts from play #1 are out of scope.
# We can still get to them through hostvars, but it isn't easy.
# In real life we don't know which host ran play #1,
# so we have to check all of them.
- set_fact:
stack='{{ stack|default(lookup("env","AWS_STACK_NAME")) }}'
- set_fact:
group_name='{{ "tag_aws_cloudformation_stack-name_" + stack }}'
- set_fact:
fubar='{% for h in groups[group_name] %} {{
hostvars[h]["fubar"]|default("") }} {% endfor %}'
- set_fact:
instance_id='{% for h in groups[group_name] %} {{
hostvars[h]["ansible_ec2_instance_id"]|default("") }} {% endfor %}'
# Trim extra leading and trailing whitespace.
- set_fact: fubar='{{ fubar|replace(" ", "") }}'
- set_fact: instance_id='{{ instance_id|replace(" ", "") }}'
# Now we can use the variables instance_id and fubar.
- debug: var='{{ fubar }}'
- debug: var='{{ instance_id }}'
# end