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