【问题标题】:ansible-playbook command raising undefined variable error while variable is set in inventory file在库存文件中设置变量时,ansible-playbook 命令引发未定义变量错误
【发布时间】:2021-05-06 15:44:11
【问题描述】:

我正面临一种神秘的 ansible 行为。

我已经在我的清单文件中设置了组、主机和组变量,但是 ansible-playbook 命令正在为我的所有组变量提升 Undefined Variable,同时使用 ansible debug 模块显示变量嗯。

这是我的 inventory.ini 文件:

 [windows]
ad_server ansible_host=mrspw00550.mydomain.com
[windows:vars]
ansible_connection=winrm
ansible_winrm_transport=ntlm
ansible_port=5985
ansible_become_method=runas
dns_zone=mydomain.com
ptr_zone=10.in-addr.arpa
dns_server=10.0.100.100

[linux]
web_server ansible_host=10.0.101.129
[linux:vars]
ansible_connection=ssh
ansible_become=yes
ansible_become_method=sudo
dns_zone=mydomain.com
ptr_zone=10.in-addr.arpa
dns_server=10.0.100.100
linux_home_dir=/home/ldaphome

剧本文件(set-hostname-and-dns.yml):

- name: Debug vars
  debug: var=hostvars[inventory_hostname]['dns_zone']
  delegate_to: ad_server

- name: Set  hostname and make DNS registrations
  block:
    - name: Set  hostname
      hostname:
        name: "web.{{ dns_zone }}"
      delegate_to: web_server
    - name: Create a DNS registration of type A 
      win_dns_record:
        name: "web"
        type: "A"
        value: "{{ inventory_hostname }}"
        zone: "{{ dns_zone }}"
        computer_name: "{{ dns_server }}"
      delegate_to: "{{ ad_server }}"
    - name: Create a DNS registration of type PTR 
      win_dns_record:
        name: "{{ inventory_hostname }}"
        type: "PTR"
        value: "web"
        zone: "{{ ptr_zone }}"
        computer_name: "{{ dns_server }}"
      delegate_to: "{{ ad_server }}"

运行ansible-playbook 命令给出:

$ ansible-playbook playbook.yml  -i inventory-files/inventory.ini
PLAY [localhost] *********************************************************************************************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************************************************************************************
ok: [localhost]
TASK [create-linux-vm : Debug vars] **************************************************************************************************************************************************************************
ok: [localhost -> mrspw00550.mydomain.com] => {
    "hostvars[inventory_hostname]['dns_zone']": "VARIABLE IS NOT DEFINED!"
}
TASK [create-linux-vm : Set web_server hostname] **************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dns_zone' is undefined\n\nThe error appears to be in 'set-hostname-and-dns.yml': line 14, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  block:\n    - name: Set {{ vm_name }} hostname\n      ^ here\nWe could be wrong, but this one looks like it might be an issue with\nmissing quotes. Always quote template expression brackets when they\nstart a value. For instance:\n\n    with_items:\n      - {{ foo }}\n\nShould be written as:\n\n    with_items:\n      - \"{{ foo }}\"\n"}
PLAY RECAP ***************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

运行debug 模块:

$ ansible -m debug -i inventory-files/inventory.ini -a "var=hostvars[inventory_hostname]['dns_zone']" all
ad_server | SUCCESS => {
    "hostvars[inventory_hostname]['dns_zone']": "mydomain.com"
}
web_server | SUCCESS => {
    "hostvars[inventory_hostname]['dns_zone']": "mydomain.com"
}
$

如您所见,ansible-playbook 命令无法检索我的主机变量,而ansible debug 模块可以。

即使我在inventory-files/group_vars/linux.ymlinventory-files/group_vars/windows.yml 中定义了这些变量,结果也是一样的,该变量仍然与ansible 中的未定义一样。如果尝试从运行 ansible-playbook 的库存中访问除特殊变量之外的任何其他变量,问题也是一样的

那里可能有什么问题?

【问题讨论】:

  • 我认为你的剧本的输出显示它正在为“localhost”而不是“ad_server”或“web_server”运行。
  • @SipSeb 但如您所见,我指定了库存文件,并将任务委派到库存中托管
  • 你运行的是什么 ansible 版本?从去年年中开始有一个Bug report 和一个merge request,显然它被向后移植到了 Ansible 2.10。在此之前,似乎在使用“delegate_to”时,您仍然只能从inventory_name 访问主机变量,而不是delegate_to 目标的主机变量。
  • delegate_to 仅代表执行,而非事实和 varr。如果您想从其他主机(即在 localhost 上运行的 Windows 主机)获取 var/fact,则必须专门要求它。您的示例库存中的一个示例:{{ hostvars['ad_server'].ptr_zone }}

标签: ansible ansible-2.x


【解决方案1】:

我尝试将delegate_facts 设置为 true,但没有成功。

然后在包含localhost 的库存中定义一个local 组,并在那里定义我的本地组变量,如下所示:

[local]
localhost

[local:vars]
ansible_connection=local
dns_zone=mydomain.com
ptr_zone=10.in-addr.arpa
dns_server=10.0.100.100
linux_home_dir=/home/ldaphome

并从远程主机事实中删除这些 var,因为我实际上并没有这些变量。我的所有任务都在本地主机上执行,并根据操作委托给远程主机。

我还想在他的评论中明确要求像上面提到的@Zeitounator ({{ hostvars['ad_server'].ptr_zone }}) 这样的 var/fact 也有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-04
    • 2022-01-23
    • 1970-01-01
    • 2015-08-20
    • 2020-04-22
    • 1970-01-01
    相关资源
    最近更新 更多