在Ansible任务中遍历主机时,jinja模板将不使用这些主机的host_vars

时间:2018-10-04 16:19:46

标签: ansible jinja2

在Ansible中,我有一部剧本,其任务可在一台nginx服务器(即nginx.example.com)上运行。目的是根据需要创建尽可能多的反向代理配置文件(或简单地说:每个主机的配置文件)。任务包括模板模块。理想情况下,该模板应可用于许多主机。 任务:

- name: nginx proxied hosts
  template:
    src: proxy-template.j2
    dest: /etc/nginx/sites-enabled/{{ item }}
  with_items: "{{ groups['groupname'] }}"
  when: hostvars[item].nginx_proxy is defined

此任务将遍历组 groupname 中的所有主机,将使用 proxy-template.j2 模板并创建/etc/nginx/sites-enabled/random.example.com配置文件。

假设host_vars / random.example.com具有以下yaml配置:

nginx_proxy:
  target_fqdn: random.example.com
  target_resource: http://10.10.0.65
  server_ip: 10.10.0.10

当ansible为该主机创建配置文件时,我希望它从host_vars / random.example.com中的主机yaml vars文件中获取值

proxy-template.j2中的其中一行: server_name {{ vars.nginx_proxy.target_fqdn }};

问题是,尽管Ansible可以成功检查主机是否具有nginx_proxy属性(在host_vars / random.example.com中),但它不会在Jinja模板中使用该主机的变量。 Ansible要么使该主机的步骤失败,要么在需要在host_vars(在host_vars / nginx.example.com中)中指定的情况下采用nginx的服务器变量。

两个结果:

  1. host_vars / nginx.example.com和host_vars / random.example.com定义了nginx_proxy变量。两者都有不同的值。

    结果:在nginx服务器上创建了/etc/nginx/sites-enabled/nginx.example.com/etc/nginx/sites-enabled/random.example.com文件。但是,两个文件都包含nginx服务器变量。 random的文件包含nginx的文件值。

  2. 仅host_vars / random.example.com定义了nginx_proxy变量。

    结果:Ansible失败并出现

      

    item“:” random.example.com“,” msg“:” AnsibleUndefinedVariable:'dict object'没有属性'nginx_proxy'“

TLDR ansible将检查任何主机的host_vars中是否具有nginx_proxy,但仅使用nginx的主机host_vars进行模板化。如果host_vars / nginx.example.com没有nginx_proxy vars,则失败。

  

{“已更改”:false,“项目”:“ random.example.com”,“ msg”:“ AnsibleUndefinedVariable:'dict object'没有属性'nginx_proxy'“}

1 个答案:

答案 0 :(得分:0)

vars(无论如何,您都不应该使用它,这就是vars lookup的用途)与hostvars[item]不同。您在条件中检查了hostvars,但在模板中使用了vars

您应该在模板中使用server_name {{ hostvars[item].nginx_proxy.target_fqdn }};


说明

Ansible本身实现了主机循环,vars指的是在其上执行任务的主机。

因此,您在每个主机上运行任务两次:

在第一种情况下:

  • random.example.com上,您运行random.example.comnginx.example.com

    Ansible使用nginx_proxy(正在执行主机的主机)中的random.example.com

  • nginx.example.com上,您运行random.example.comnginx.example.com

    Ansible使用nginx_proxy(正在执行主机的主机)中的nginx.example.com


在第二种情况下:

  • random.example.com上,您运行random.example.com(已跳过nginx.example.com

    Ansible使用nginx_proxy(正在执行主机的主机)中定义的random.example.com

  • nginx.example.com上,您运行random.example.com(已跳过nginx.example.com

    Ansible尝试使用nginx_proxy(在其上执行主机)中定义的nginx.example.com值,但是失败。