我可以更新主机库存并在同一个剧本中使用新主机吗?

时间:2014-06-13 23:45:00

标签: ansible

我通过playbook在主机库存文件中添加了少量主机。现在我在同一个剧本中使用这些新添加的主机。但是那些新添加的主机在相同的运行中看不到同一个剧本,因为我得到了 -

skipping: no hosts matched

当我单独运行它时,即我通过一个剧本更新主机文件并通过另一个剧本使用更新的主机,它可以正常工作。

3 个答案:

答案 0 :(得分:2)

我最近想用ansible 1.8.4这样做。我发现add_host需要使用群组名称,否则将跳过游戏"没有主机匹配"。与此同时,我希望玩#2使用在游戏#1中发现的事实。变量和事实通常仍然限定在每个主机的范围内,因此这需要使用魔术变量hostvarsgroups

这是我想出的。它有效,但它有点难看。我很想看到一个更清洁的选择。

# 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

答案 1 :(得分:1)

目前还不完全清楚你在做什么 - 但从我收集的内容来看,你在游戏中使用add_host模块。

似乎合乎逻辑的是你不能将相同游戏限制在那些主机上,因为它们还不存在 ...所以这永远不会起作用:

- name: Play - add a host
  hosts: new_host

  tasks:
    - name: add new host
      add_host: name=new_host

但是您可以自由地将多个剧本添加到单个电子书文件中(您似乎也已经想到了):

- name: Play 1 - add a host
  hosts: a_single_host

  tasks:
    - name: add new host
      add_host: name=new_host

- name: Play 2 - do stuff
  hosts: new_host

  tasks:
    - name: do stuff

答案 2 :(得分:0)

听起来您正在用剧本修改Ansible广告资源文件,然后想要使用文件的新内容。但是,仅修改磁盘上文件的内容不会导致Ansible正在使用的清单更新。 Ansible的工作方式是,它在首次启动时会读取该文件(以及您拥有的其他清单资源),并将找到的主机名放入内存中。从那时起,它仅与它存储在内存中的清单一起工作,该清单在它第一次开始运行时就存在。它不知道对该文件的任何后续更改。

但是有很多方法可以做你想要的!您可以使用的一种选择是将新主机添加到清单文件中,并使用add_host模块将它们加载到内存中。这是两个独立的步骤:1)将新主机添加到文件的清单中,然后2)使用add_host module将相同的新主机添加到内存清单中:

- name: add a host to in-memory inventory
  add_host:
    name: "{{ new_host_name }}"
    groups: "{{ group_name }}"

第二个选项是告诉Ansible从文件刷新内存清单。但是您必须明确地告诉它这样做。使用此选项,您需要执行两个相关步骤:1)像以前一样将新主机添加到文件清单中,然后2)使用meta module

- name: Refresh inventory to ensure new instances exist in inventory
  meta: refresh_inventory