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

使用Jinja2 dict作为Ansible模块选项的一部分,ansible,yaml,jinja2,Ansible,Yaml,Jinja2,我有以下意见: endpoint: esxi_hostname: servername.domain.com 我正试图通过jinja2将其作为vmware_来宾的一个选项,但没有成功。我之所以尝试这样做,是因为dict是动态的……它可以是cluster:clustername或esxi_hostname:hostname,两者在vmware_来宾模块中都是互斥的 下面是我如何向模块演示它的: - name: Create VM pysphere vmware_guest: h

我有以下意见:

endpoint:
    esxi_hostname: servername.domain.com
我正试图通过jinja2将其作为vmware_来宾的一个选项,但没有成功。我之所以尝试这样做,是因为dict是动态的……它可以是cluster:clustername或esxi_hostname:hostname,两者在vmware_来宾模块中都是互斥的

下面是我如何向模块演示它的:

- 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"}
任务[准备:包括虚拟机任务]***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
致命:[10.10.10.10]:失败!=>{“原因”:“加载YAML时出现语法错误。
错误似乎出现在“/data01/home/hit/tools/ansible/playbooks/roles/Preparation/tasks/prepareVM.yml”中:第36行第4列,但可能是
根据确切的语法问题,在文件中的其他位置。
令人不快的一行似乎是:
“{{endpoint}}”
主机名:“{vcenter_hostname}”
^这里
我们可能错了,但这一个看起来可能是一个问题
缺少引号。当模板表达式括号中有引号时,请始终使用引号
启动一个值。例如:
有以下项目:
-{{foo}}
应写为:
有以下项目:
-“{{foo}}”
异常类型:
异常:在分析块映射时
在“”中,第33行第3列
未找到所需的密钥
在“”中,第36行第4列“}

因此,总而言之,我不确定该如何格式化,或者它是否可行。

您不可能使用您在问题中尝试过的语法,因为首先,最重要的是Ansible需要一个有效的YAML文件

最接近的解决方法是使用a,尽管它仅适用于文字:

# ...

  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
#。。。
变量:
端点:&端点
esxi_主机名:servername.domain.com
任务:
-名称:创建VM pysphere
vmware_来宾:
主机名:“{vcenter_hostname}”
用户名:“{{username}}”
密码:{{password}}
验证证书:否
数据中心:“{{ansible\u host\u datacenter}”
文件夹:“/DCC/{{ansible\u host\u datacenter}}/vm”
总结了您的问题,但对于可能的解决方案,在文档中,特别是关于,有以下几点:

省略参数

从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=参数将不会 发送到文件模块,而最终文件将接收 模式=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
只有一个选择集。

谢谢@guy!您的和@techraf解决方案都有效。我最终还是和你一起去了,因为感觉更干净了。