我使用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

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


当前回答

如果通过检查play_hosts变量提供了多个主机,则该方法将退出。fail模块用于在不满足单主机条件时退出。下面的例子使用一个包含两个主机alice和bob的hosts文件。

用户。yml(剧本)

---
- hosts: all
  tasks:
    - name: Check for single host
      fail: msg="Single host check failed."
      when: "{{ play_hosts|length }} != 1"

    - debug: msg='I got executed!'

不带主机过滤器运行playbook

$ ansible-playbook user.yml
PLAY [all] ****************************************************************
TASK: [Check for single host] *********************************************
failed: [alice] => {"failed": true}
msg: Single host check failed.
failed: [bob] => {"failed": true}
msg: Single host check failed.
FATAL: all hosts have already failed -- aborting

在单台主机上运行剧本

$ ansible-playbook user.yml --limit=alice

PLAY [all] ****************************************************************

TASK: [Check for single host] *********************************************
skipping: [alice]

TASK: [debug msg='I got executed!'] ***************************************
ok: [alice] => {
    "msg": "I got executed!"
}

其他回答

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

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

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

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

我建议使用——limit <hostname或ip>

从1.7版开始ansible就有了run_once选项。本节还讨论了各种其他技术。

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

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

我们有一些通用的战术手册,可供大量团队使用。我们还有特定于环境的目录文件,其中包含多个组声明。

为了迫使调用playbook的人指定一个组来对抗,我们在playbook的顶部播种了一个虚拟条目:

[ansible-dummy-group]
dummy-server

然后,我们将以下检查作为共享剧本的第一步:

- hosts: all
  gather_facts: False
  run_once: true
  tasks:
  - fail:
      msg: "Please specify a group to run this playbook against"
    when: '"dummy-server" in ansible_play_batch'

如果虚拟服务器出现在这个剧本计划运行的主机列表中(ansible_play_batch),那么调用者没有指定一个组,剧本执行将失败。