我使用Ansible对一小群计算机执行一些简单的用户管理任务。目前,我把我的剧本设置为hosts: all和我的hosts文件只是一个单独的组,列出了所有的机器:

# file: hosts
[office]
imac-1.local
imac-2.local
imac-3.local

我发现自己经常不得不以一台机器为目标。ansible-playbook命令可以这样限制播放:

ansible-playbook --limit imac-2.local user.yml

但这似乎有点脆弱,尤其是对于一个潜在的破坏性剧本来说。省略限制标志意味着剧本将在任何地方运行。因为这些工具只是偶尔被使用,所以似乎有必要采取措施进行万无一失的回放,这样我们就不会在几个月后意外地破坏一些东西。 是否有将剧本运行限制在一台机器上的最佳实践?理想情况下,如果遗漏了一些重要的细节,剧本应该是无害的。


当前回答

这显示了如何在目标服务器上运行剧本。

如果您想使用本地连接,这就有点棘手了。但是,如果您使用一个变量进行主机设置,并在hosts文件中为localhost创建一个特殊的条目,这应该是OK的。

在(所有)剧本中,hosts: line设置为:

- hosts: "{{ target | default('no_hosts')}}"

在目录hosts文件中为localhost添加一个条目,将连接设置为本地:

[localhost]
127.0.0.1  ansible_connection=local

然后在命令行上运行显式设置目标的命令-例如:

$ ansible-playbook --extra-vars "target=localhost" test.yml

这也将工作时使用ansible-pull:

$ ansible-pull -U <git-repo-here> -d ~/ansible --extra-vars "target=localhost" test.yml

如果你忘记在命令行上设置这个变量,这个命令将安全错误(只要你没有创建一个名为“no_hosts”的主机组!),并警告:

skipping: no hosts matched

如上所述,你可以针对一台机器(只要它在你的hosts文件中):

$ ansible-playbook --extra-vars "target=server.domain" test.yml

或者像这样的团体:

$ ansible-playbook --extra-vars "target=web-servers" test.yml

其他回答

一个稍微不同的解决方案是使用特殊变量ansible_limit,这是——limit CLI选项的内容,用于当前Ansible的执行。

- hosts: "{{ ansible_limit | default(omit) }}"

这里不需要定义额外的变量,只需使用——limit标志运行剧本。

ansible-playbook --limit imac-2.local user.yml

还有一个可爱的小技巧,可以让你在命令行上指定单个主机(或者多个主机,我猜),而不需要中间库存:

ansible-playbook -i "imac1-local," user.yml

注意结尾的逗号(,);这表明它是一个列表,而不是一个文件。

现在,如果您不小心传递了一个真实的库存文件,这将无法保护您,因此它可能不是这个特定问题的好解决方案。但这是一个很好用的技巧!

恕我直言,有一个更方便的方法。 你可以通过使用vars_prompt来交互式地提示用户他想要申请的机器:

---
- hosts: "{{ setupHosts }}"
  vars_prompt:
    - name: "setupHosts"
      prompt: "Which hosts would you like to setup?"
        private: false
   tasks:
     - shell: echo

这显示了如何在目标服务器上运行剧本。

如果您想使用本地连接,这就有点棘手了。但是,如果您使用一个变量进行主机设置,并在hosts文件中为localhost创建一个特殊的条目,这应该是OK的。

在(所有)剧本中,hosts: line设置为:

- hosts: "{{ target | default('no_hosts')}}"

在目录hosts文件中为localhost添加一个条目,将连接设置为本地:

[localhost]
127.0.0.1  ansible_connection=local

然后在命令行上运行显式设置目标的命令-例如:

$ ansible-playbook --extra-vars "target=localhost" test.yml

这也将工作时使用ansible-pull:

$ ansible-pull -U <git-repo-here> -d ~/ansible --extra-vars "target=localhost" test.yml

如果你忘记在命令行上设置这个变量,这个命令将安全错误(只要你没有创建一个名为“no_hosts”的主机组!),并警告:

skipping: no hosts matched

如上所述,你可以针对一台机器(只要它在你的hosts文件中):

$ ansible-playbook --extra-vars "target=server.domain" test.yml

或者像这样的团体:

$ ansible-playbook --extra-vars "target=web-servers" test.yml

为了扩展joemailer的回答,如果你想拥有模式匹配能力来匹配远程机器的任何子集(就像ansible命令所做的那样),但仍然想让它非常难以意外地在所有机器上运行playbook,这是我提出的:

和另一个答案一样:

# file: user.yml  (playbook)
---
- hosts: '{{ target }}'
  user: ...

有请以下主持人:

imac-10.local
imac-11.local
imac-22.local

现在,要在所有设备上运行该命令,必须显式地将目标变量设置为“all”

ansible-playbook user.yml --extra-vars "target=all"

要将其限制为特定的模式,可以设置target=pattern_here

或者,你可以保留target=all,并附加——limit参数,例如:

--limit imac-1*

ie。 ansible-playbook用户。Yml——extra-vars "target=all"——limit imac-1*——list-hosts

结果是:

playbook: user.yml

  play #1 (office): host count=2
    imac-10.local
    imac-11.local