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

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


当前回答

使用EC2外部目录脚本的AWS用户可以简单地通过实例id进行过滤:

ansible-playbook sample-playbook.yml --limit i-c98d5a71 --list-hosts

这是因为目录脚本创建了默认组。

其他回答

事实证明,可以直接在剧本中输入主机名,因此使用主机运行剧本:imac-2。本地就可以了。但它有点笨拙。

更好的解决方案可能是使用变量定义剧本的主机,然后通过——extra-vars传入特定的主机地址:

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

运行剧本:

ansible-playbook user.yml --extra-vars "target=imac-2.local"

如果{{target}}没有定义,playbook什么也不做。如果需要,还可以传递来自hosts文件的组。总的来说,这似乎是一种更安全的方式来构建一个潜在的破坏性剧本。

针对单个主机的攻略:

$ ansible-playbook user.yml --extra-vars "target=imac-2.local" --list-hosts

playbook: user.yml

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

一群主持人的剧本:

$ ansible-playbook user.yml --extra-vars "target=office" --list-hosts

playbook: user.yml

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

忘记定义主机是安全的!

$ ansible-playbook user.yml --list-hosts

playbook: user.yml

  play #1 ({{target}}): host count=0

如果通过检查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!"
}

使用EC2外部目录脚本的AWS用户可以简单地通过实例id进行过滤:

ansible-playbook sample-playbook.yml --limit i-c98d5a71 --list-hosts

这是因为目录脚本创建了默认组。

我真的不明白为什么所有的答案都这么复杂,方法很简单:

ansible-playbook user.yml -i hosts/hosts --limit imac-2.local --check

检查模式允许您在不做任何更改的情况下以干运行模式运行。

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

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

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

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