【问题标题】:How to get IP address from controller's hosts file in Ansible?如何从 Ansible 中控制器的主机文件中获取 IP 地址?
【发布时间】:2020-03-03 20:59:48
【问题描述】:

我很难在我的 Ansible 剧本中设置一个事实,该事实包含我控制器上 /etc/hosts 文件中列出的服务器的 IP 地址。我正在针对需要文件服务器 IP 地址的 Web 服务器运行剧本。我像这样运行命令:

ansible-playbook deploy-webservers.yml -i inventory.ini -l webservers

我的库存文件如下所示:

[fileservers]
prod-fs1.example.com

[webservers]
prod-web1.example.com

[localhost]
127.0.0.1 ansible_connection=local ansible_python_interpreter=/Users/jsmith/.virtualenvs/provision/bin/python

这是剧本:

---
hosts: all
gather_facts: yes
become: yes


pre_tasks:
  - name: get file server's IP address
    command: "grep prod-fs1 /etc/hosts | awk '{ print $1 }'"
    register: fs_ip_addr
    delegate_to: localhost

  - debug: var={{ fs_ip_addr }}

当我运行它时,我得到了这个错误:

TASK [get file server's IP address] ****************************************************************************************
fatal: [prod-web1.example.com -> localhost]: FAILED! => {"changed": true, "cmd": ["grep", "prod-fs1", "/etc/hosts", "|", "awk", "{ print $0 }"], "delta": "0:00:00.010303", "end": "2020-03-03 12:24:36.207656", 
"msg": "non-zero return code", "rc": 2, "start": "2020-03-03 12:24:36.197353", "stderr": "grep: |: No such file or directory\ngrep: awk: No such file or directory\ngrep: { print $0 }: 
No such file or directory", "stderr_lines": ["grep: |: No such file or directory", "grep: awk: No such file or directory", "grep: { print $0 }: No such file or directory"], "stdout": "/etc/hosts:45.79.99.99    prod-fs1.example.com    prod-fs1", "stdout_lines": ["/etc/hosts:45.79.99.99    prod-fs1.example.com    prod-fs1"]}


PLAY RECAP ****************************************************************************************************************
prod-web1.example.com : ok=7    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0;

看起来 Ansible 在到达管道符号时解析命令时出现问题。有没有办法解决这个问题?

【问题讨论】:

  • 试试shell 而不是command
  • 您还需要将var={{ fs_ip_addr }} 更改为var=fs_ip_addr
  • @Jack 你说得对。我经常忘记你不能使用带有“var=”的大括号。谢谢提醒。

标签: ansible


【解决方案1】:

试试这个。无需委托给本地主机。 lookup 始终在控制器上运行

    - set_fact:
        fs_ip_addr: "{{ (lookup('file', '/etc/hosts').splitlines()|
                         list|
                         select('search', search_host)|
                         list|
                         first).split().0 }}"
      vars:
        search_host: "prod-fs1"

【讨论】:

  • 这是一个有趣的解决方案,因为我以前没有使用过“查找”。但它产生了一个错误:“该任务包含一个带有未定义变量的选项。错误是:没有第一项,序列为空。”我将对此进行分解,看看是否能找出导致此错误的原因。
  • 对。尝试逐步显示结果。该任务对我有用(更改了 search_host)。
  • 是的,你是对的。 search_host 不正确。谢谢。
【解决方案2】:

代码可以简化一点。请注意,search_host 是一个 var。

- set_fact:
        fs_ip_addr: "{{ lookup('file', '/etc/hosts').splitlines() |
                      select('search', search_host) |
                      first | split() | first }}"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-20
    • 1970-01-01
    • 2017-11-10
    • 2017-02-10
    • 2014-05-21
    • 2013-06-14
    相关资源
    最近更新 更多