如何在 Ansible 控制主机(localhost)上执行命令或任务

在日常使用 Ansible 时,你可能希望在本地机器上自动化一些任务。Ansible 提供了多种方式在控制主机上执行命令,以下是三种常见的方法:

  1. 使用 connection: local 插件 这是最推荐的方式,通过在 Play 级别设置 connection: local,并调整一些 Ansible 内部变量(如 Python 解释器路径)来实现。
  2. 使用 delegate_to: localhost 在任务级别将任务委托到 localhost。这种方式的优点是可以只将单个任务委托到本地,但仍然需要使用隐式的 localhost 方案。
  3. 使用 local_action 这是另一种在任务级别执行本地操作的方式,但个人不太推荐,因为它在功能上与 delegate_to 类似。

示例:使用 connection: local 方法在 Ansible 控制主机上执行命令

Playbook 文件:localhost.yml

---
- name: localhost demo
  hosts: localhost
  vars:
    ansible_connection: local
    ansible_python_interpreter: "{{ ansible_playbook_python }}"
  tasks:
    - name: print hostname
      ansible.builtin.debug:
        msg: "{{ inventory_hostname }}"

执行命令

$ ansible-playbook ansible\ statements/localhost.yml

执行结果

[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [localhost demo] ***********************************
TASK [Gathering Facts] **********************************
ok: [localhost]
TASK [print hostname] ***********************************
ok: [localhost] => {
    "msg": "localhost"
}
PLAY RECAP **********************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

解释

  1. ansible_connection: local
    • 通过设置 ansible_connection: local,Ansible 会在控制主机上直接执行任务,而不是通过 SSH 连接到远程主机。
  2. ansible_python_interpreter
    • 默认情况下,Ansible 使用远程主机上的 Python 解释器执行任务。在本地执行时,需要指定控制主机上的 Python 解释器路径。
    • ansible_playbook_python 是 Ansible 提供的内部变量,表示控制主机上用于执行 Playbook 的 Python 解释器路径。
  3. 隐式的 localhost
    • 如果没有指定主机清单文件,Ansible 默认会使用隐式的 localhost。这意味着任务会在控制主机上执行。

其他方法

使用 delegate_to: localhost

---
- name: delegate to localhost demo
  hosts: all
  tasks:
    - name: print hostname
      ansible.builtin.debug:
        msg: "{{ inventory_hostname }}"
      delegate_to: localhost

使用 local_action

---
- name: local action demo
  hosts: all
  tasks:
    - name: print hostname
      ansible.builtin.debug:
        msg: "{{ inventory_hostname }}"
      local_action: ansible.builtin.debug msg="{{ inventory_hostname }}"

总结

  • 推荐方法:使用 connection: local,因为它在 Play 级别设置,适用于整个 Playbook,且更清晰。
  • 适用场景:当你需要在控制主机上执行任务时,例如安装本地依赖、运行本地脚本等。
  • 注意事项:
    • 如果使用隐式的 localhost,可能会看到警告信息,因为 Ansible 未解析主机清单文件。
    • 确保正确设置 ansible_python_interpreter,以避免 Python 解释器路径不匹配的问题。

通过这些方法,你可以在 Ansible 控制主机上灵活地执行任务,满足本地自动化的需求。