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

Nar*_*asK 3 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
Run Code Online (Sandbox Code Playgroud)

Exec local:

$ 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
Run Code Online (Sandbox Code Playgroud)

远程执行:

$ 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
Run Code Online (Sandbox Code Playgroud)

有没有更聪明的方法来判断ansible何时回退到当地环境?目前我正在使用ansible==1.9.2.

udo*_*dan 7

应该执行的任务不应该在任务中定义.当任务总是必须在本地或相关机器(例如数据库主机或路由器)上运行时,委派是有意义的,而playbook本身因此大多数任务运行在playbook级别定义的主机.

但是,如果您的目标是在本地或在一组远程主机上运行整个Playbook,则应使用不同的清单文件或组.

如果您有两个不同的清单文件,在一个中定义localhost,在另一个所有远程主机中,则在调用ansible时应用所需的清单,-i inv.d/local-i inv.d/remote.

或者将它全部放在一个库存中并动态传递该组.在您的清单中,您定义了两个组:

[local]
127.0.0.1

[remote]
host-1
host-2
host-N
Run Code Online (Sandbox Code Playgroud)

然后将该组作为extra-var传递给ansible:-e "run=local"-e "run=remote"

在您的剧本中,您hosts可以动态设置:

---
- hosts: "{{ run | mandatory }}"
  gather_facts: no
  tasks:
    ...
Run Code Online (Sandbox Code Playgroud)

在您的示例中,您似乎只使用每个vhostextra-var 定义的单个远程主机.在这种情况下,最佳选项似乎是在hosts部分中重用此变量,默认为localhost.

---
- hosts: "{{ vhost | default('127.0.0.1') }}"
  gather_facts: no
  tasks:
    ...
Run Code Online (Sandbox Code Playgroud)

因此,如果vhost定义了整个剧本将在该主持人上执行.如果没有定义,则剧本在本地运行.

最后,您仍然可以delegate_to在单个任务上使用该选项,如下所示:

- name: Local AND remote command
  command: hostname
  delegate_to: "{{ '127.0.0.1' if vhost is undefined else omit }}"
Run Code Online (Sandbox Code Playgroud)

omit是一个特殊的变量,使Ansible忽略该选项,就好像它不会被定义一样.