繁体   English   中英

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

[英]Use Jinja2 dict as part of an Ansible modules options

我有以下字典:

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"}

所以总而言之,我不确定如何格式化这个或者是否可能。

您永远无法使用您在问题中尝试过的语法,因为首先也是最重要的是 Ansible 需要一个有效的 YAML 文件。

最接近的解决方法是使用YAML 锚点/别名,尽管它仅适用于文字:

# ...

  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

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

省略参数

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

 - 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只有一个选择集。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM