Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ansible 我可以更新主机清单并在同一剧本中使用新主机吗?_Ansible - Fatal编程技术网

Ansible 我可以更新主机清单并在同一剧本中使用新主机吗?

Ansible 我可以更新主机清单并在同一剧本中使用新主机吗?,ansible,Ansible,我通过playbook在主机清单文件中添加了几个主机。现在我在同一个剧本中使用这些新添加的主机。但这些新添加的主机似乎不能在同一次运行中被同一个剧本读取,因为我得到了- skipping: no hosts matched 当我单独运行它时,即通过一个剧本更新主机文件,并通过另一个剧本使用其中更新的主机,它工作正常。不完全清楚您在做什么-但从我收集的信息来看,您在剧本中使用的是添加主机模块 似乎合乎逻辑的是,您不能将相同的播放限制在这些主机上,因为它们还不存在。。。所以这永远不会奏效: - n

我通过playbook在主机清单文件中添加了几个主机。现在我在同一个剧本中使用这些新添加的主机。但这些新添加的主机似乎不能在同一次运行中被同一个剧本读取,因为我得到了-

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