使用Jinja2 dict作为Ansible模块选项的一部分

时间:2018-02-16 15:29:03

标签: ansible yaml jinja2

我有以下词典:

endpoint:
    esxi_hostname: servername.domain.com

我试图通过jinja2为vmware_guest使用它作为一个选项但是没有成功。我尝试这样做的原因是因为dict是动态的......它可以是cluster:clustername或esxi_hostname:hostname,在vmware_guest模块中都是互斥的。

以下是我如何将其呈现给模块:

- name: Create VM pysphere
  vmware_guest:
   hostname: "{{ vcenter_hostname }}"
   username: "{{ username }}"
   password: "{{ password }}"
   validate_certs: no
   datacenter: "{{ ansible_host_datacenter }}"
   folder: "/DCC/{{ ansible_host_datacenter }}/vm"
   "{{ endpoint }}"
   name: "{{ guest }}"
   state: present
   guest_id: "{{ osid }}"
   disk: "{{ disks }}"
   networks: "{{ niclist }}"
   hardware:
    memory_mb: "{{ memory_gb|int * 1024 }}"
    num_cpus: "{{ num_cpus|int }}"
    scsi: "{{ scsi }}"
   customvalues: "{{ customvalues }}"
   cdrom:
    type: client
  delegate_to: localhost

以下是我在包含任务文件时遇到的错误:

TASK [Preparation : Include VM tasks] *********************************************************************************************************************************************************************************   
fatal: [10.10.10.10]: FAILED! => {"reason": "Syntax Error while loading YAML.


The error appears to have been in '/data01/home/hit/tools/ansible/playbooks/roles/Preparation/tasks/prepareVM.yml': line 36, column 4, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

    "{{ endpoint }}"
   hostname: "{{ vcenter_hostname }}"
   ^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes.  Always quote template expression brackets when they
start a value. For instance:

    with_items:
      - {{ foo }}

Should be written as:

    with_items:
      - "{{ foo }}"

exception type: <class 'yaml.parser.ParserError'>
exception: while parsing a block mapping
  in "<unicode string>", line 33, column 3
did not find expected key
  in "<unicode string>", line 36, column 4"}

总而言之,我不确定如何格式化或甚至是否可能。

2 个答案:

答案 0 :(得分:1)

你无法使用你在问题中尝试的语法,因为首先Ansible需要一个有效的YAML文件。

最接近的解决方法是使用YAML anchor/alias,尽管它只适用于文字:

# ...

  vars:
    endpoint: &endpoint
      esxi_hostname: servername.domain.com

  tasks:
     - name: Create VM pysphere
       vmware_guest:
         hostname: "{{ vcenter_hostname }}"
         username: "{{ username }}"
         password: "{{ password }}"
         validate_certs: no
         datacenter: "{{ ansible_host_datacenter }}"
         folder: "/DCC/{{ ansible_host_datacenter }}/vm"
         <<: *endpoint
         name: "{{ guest }}"
         state: present
         guest_id: "{{ osid }}"
         disk: "{{ disks }}"
         networks: "{{ niclist }}"
         hardware:
           memory_mb: "{{ memory_gb|int * 1024 }}"
           num_cpus: "{{ num_cpus|int }}"
           scsi: "{{ scsi }}"
         customvalues: "{{ customvalues }}"
         cdrom:
           type: client
       delegate_to: localhost

答案 1 :(得分:1)

post from techraf总结了您的问题,但对于可能的解决方案,在文档中,特别是关于Jinja filters,有以下几点:

  

省略参数

     

从Ansible 1.8开始,可以使用默认过滤器来省略   使用特殊省略变量的模块参数:

- name: touch files with an optional mode
  file: dest={{item.path}} state=touch mode={{item.mode|default(omit)}}   >       with_items:
    - path: /tmp/foo
    - path: /tmp/bar
    - path: /tmp/baz
      mode: "0444"
     

对于列表中的前两个文件,默认模式为   由系统的umask决定,因为mode =参数不会   被发送到文件模块,而最终文件将收到   mode = 0444选项。

所以看起来应该尝试的是:

esxi_hostname: "{{ endpoint.esxi_hostname | default(omit) }}"
# however you want the alternative cluster settings done.
# I dont know this module.
cluster: "{{ cluster | default(omit) }}"

这显然依赖于vars只有一个选择集。