2016-05-23 98 views
2

我有几个ansible剧本,有时在本地环境中有意义,否则它们是远程执行的。为了做到这一点我用delegate_to指令,但是这也意味着我不得不把所有的任务,例如: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 

Exec的本地翻番:

$ 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 

Exec的遥控器

$ 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

回答

6

不应在任务中定义任务应执行的位置。如果任务总是必须在本地或在相关机器(例如数据库主机或路由器)上运行,而剧本本身以及大多数任务运行在剧本级别上定义的主机,则委派是有意义的。

但是,如果您的目标是在本地或在一组远程主机上运行整个手册,则应该使用不同的库存文件或组。

如果你有两个不同的清单文件,在一个定义本地主机,在其他所有的远程主机,然后应用调用ansible,-i inv.d/local-i inv.d/remote当你想要的清单。

或者将它全部放入一个清单并动态传递组。在清单中定义两个组:

[local] 
127.0.0.1 

[remote] 
host-1 
host-2 
host-N 

,然后再通过组作为一个额外的VAR到ansible:-e "run=local"-e "run=remote"

在你的剧本设置了hosts动态:

--- 
- hosts: "{{ run | mandatory }}" 
    gather_facts: no 
    tasks: 
    ... 

在您的示例中,您似乎只能使用根据vhost extra-var定义的单个远程主机。在这种情况下,最好的选择似乎是在主机部分重新使用这个变量,默认为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忽略的选择,因为如果它不会被定义。

+0

会起作用:'connection:“{{'ansible_host'| default('local')}}”'? [Docs](http://docs.ansible.com/ansible/intro_inventory.html#non-ssh-connection-types)似乎不明确,'ansible_host'被定义为'要连接到的Docker容器的名称'。我愿意这只是文档中的错误。 –

+0

我会在清单文件中设置连接,如本节底部所述:http://docs.ansible.com/ansible/intro_inventory.html#hosts-and-groups – udondan

+0

'localhost ansible_connection = local' – udondan