Ansible有条件地委托本地或远程?

时间:2016-05-23 10:34:05

标签: ansible ansible-playbook

我有一些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

1 个答案:

答案 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忽略该选项,就好像它没有被定义一样。