代码之家  ›  专栏  ›  技术社区  ›  Mike Klebolt

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

  •  2
  • Mike Klebolt  · 技术社区  · 7 年前

    我有以下意见:

    endpoint:
        esxi_hostname: servername.domain.com
    

    我正试图通过jinja2将其作为vmware\u来宾的一个选项,但没有成功。我之所以这样做是因为口述是动态的。。。它可以是cluster:clustername或esxi\u hostname:hostname,两者在vmware\u来宾模块中都是互斥的。

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

    - 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 回复  |  直到 7 年前
        1
  •  1
  •   Guy    7 年前

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

        2
  •  1
  •   techraf    7 年前

    您不可能使用您在问题中尝试过的语法,因为首先和最前面的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