我有一些ansible
个剧本,有时在本地环境中有意义,否则它们是远程执行的。为了做到这一点,我使用delegate_to
指令,但这也意味着我必须加倍我的所有任务,例如:
---
- hosts: all
gather_facts: no
tasks:
- name: Local command
command: hostname
register: target_host
when: vhost is undefined
delegate_to: 127.0.0.1
# ---
- name: Remote command
command: hostname
register: target_host
when: vhost is defined
本地执行 :
$ ansible-playbook -i inv.d/test.ini play.d/delegate.yml
PLAY [all] ********************************************************************
TASK: [Local command] *********************************************************
changed: [new-server -> 127.0.0.1]
TASK: [Remote command] ********************************************************
skipping: [new-server]
PLAY RECAP ********************************************************************
new-server : ok=1 changed=1 unreachable=0 failed=0
远程执行 :
$ ansible-playbook -i inv.d/test.ini play.d/delegate.yml -e vhost=y
PLAY [all] ********************************************************************
TASK: [Local command] *********************************************************
skipping: [new-server]
TASK: [Remote command] ********************************************************
changed: [new-server]
PLAY RECAP ********************************************************************
new-server : ok=1 changed=1 unreachable=0 failed=0
是否有更聪明的方法告诉ansible
何时回退到本地环境?目前我正在使用ansible==1.9.2
。
答案 0 :(得分:7)
不应在任务中定义应执行任务的位置。当任务总是必须在本地或相关机器(例如数据库主机或路由器)上运行时,委派是有意义的,而playbook本身因此大多数任务运行在playbook级别定义的主机。
但如果你的目标是在本地或在一组远程主机上运行整个剧本,你应该使用不同的库存文件或组。
如果您有两个不同的清单文件,您可以在另一个远程主机中定义localhost,然后在调用ansible -i inv.d/local
或-i inv.d/remote
时应用所需的清单。
或者将其全部放在一个库存中并动态传递该组。在您的广告资源中,您可以定义两个组:
[local]
127.0.0.1
[remote]
host-1
host-2
host-N
然后将该组作为extra-var传递给ansible:-e "run=local"
或-e "run=remote"
在您的剧本中,您动态设置hosts
:
---
- hosts: "{{ run | mandatory }}"
gather_facts: no
tasks:
...
在您的示例中,您似乎只使用按vhost
extra-var定义的单个远程主机。在这种情况下,最佳选项似乎是在hosts部分重用此变量,默认为localhost。
---
- hosts: "{{ vhost | default('127.0.0.1') }}"
gather_facts: no
tasks:
...
因此,如果定义vhost
,整个剧本将在该主持人上执行。如果没有定义,则剧本在本地运行。
最后,您仍然可以在单个任务上使用delegate_to
选项,如下所示:
- name: Local AND remote command
command: hostname
delegate_to: "{{ '127.0.0.1' if vhost is undefined else omit }}"
omit
is a special variable使Ansible忽略该选项,就好像它没有被定义一样。