在 Ansible 中使用 Jinja 模板需要帮助

Need help using Jinja Templates with Ansible

有没有一种方法可以根据差异在模板中不添加任何命令,而不对要在单独文件中删除的任何变量进行硬编码?例如:

将 运行-config 与文件中的配置进行比较后的差异 Ansible 任务:

- name: Capture the Existing Config
  set_fact:
    existing_config: "{{ post_output['stdout'][0] | regex_findall('interface \S+|ip dhcp relay address \S+') }}"

- name: View the Existing Config
  debug:
    var: existing_config

- name: Required Config Based on Vars
  set_fact:
    required_config: "{{ lookup('file', './Config/{{ inventory_hostname }}.cfg') | regex_findall('interface \S+|ip dhcp relay address \S+') }}"

- name: View Required Config
  debug:
    var: required_config

- name: Compare Existing and Required to Remove Unwanted Config
  set_fact:
    config_to_remove: "{{ existing_config | difference(required_config) }}"

- name: View the Difference Against Existing and Required Configs
  debug:
    var: config_to_remove
TASK [Capture the Existing Config] ***********************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [nxos-1]

TASK [View the Existing Config] ***************************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [nxos-1] => {
    "existing_config": [
        "interface Vlan1",
        "ip dhcp relay address 10.1.1.2",
        "ip dhcp relay address 10.5.5.98",
        "ip dhcp relay address 10.5.5.99",
        "interface Ethernet1/49",
        "ip dhcp relay address 10.1.1.2",
        "ip dhcp relay address 10.5.5.98",
        "ip dhcp relay address 10.5.5.99",
        "interface Ethernet1/50",
        "ip dhcp relay address 10.1.1.2"
        "ip dhcp relay address 10.5.5.98",
        "ip dhcp relay address 10.5.5.99",
    ]
}

TASK [Desired Config Based on Vars] ************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [nxos-1]

TASK [View Required Config] *******************************************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [nxos-1] => {
    "reuired_config": [
        "interface Vlan1",
        "ip dhcp relay address 10.1.1.2",
        "interface Ethernet1/49",
        "ip dhcp relay address 10.1.1.2",
        "interface Ethernet1/50",
        "ip dhcp relay address 10.1.1.2"
    ]
}

TASK [Compare Existing and Required Configs to Remove Unwanted Config] ***************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [nxos-1]

TASK [View the Difference Against Existing and Required Configs] *************************************************************************************************************************************************************************************************************************************************************************************************************
ok: [nxos-1] => {
    "config_to_remove": [
        "ip dhcp relay address 10.5.5.98",
        "ip dhcp relay address 10.5.5.99",
    ]
}

j2 文件构建配置:

{% for ip in config %}
interface Vlan1
  ip dhcp relay address {{ ip }} 
interface Ethernet1/49
  ip dhcp relay address {{ ip }} 
interface Ethernet1/50
  ip dhcp relay address {{ ip }} 
{% endfor %}
vars:
  config:
    10.1.1.2

注意:没有命令来自基于差异的列表

我可以使用 if 语句根据剧本中列表中的项目不使用命令吗?

{% if <ip is not in vars> %}
  no ip dhcp relay address <ip to be removed>
{% endif %}

因此最终的配置文件将类似于以下内容,然后将其推送到设备是单独的任务:

interface Vlan1
  ip dhcp relay address 10.1.1.2 
  no ip dhcp relay address 10.5.5.98 
  no ip dhcp relay address 10.5.5.99 
interface Ethernet1/49
  ip dhcp relay address 10.1.1.2 
  no ip dhcp relay address 10.5.5.98 
  no ip dhcp relay address 10.5.5.99 
interface Ethernet1/50
  ip dhcp relay address 10.1.1.2 
  no ip dhcp relay address 10.5.5.98 
  no ip dhcp relay address 10.5.5.99 

对于这种任务,由于 Ansible/Jinja 是 Python,您甚至可以使用美妙的 for ... if 结构。

鉴于剧本:

- hosts: all
  gather_facts: no

  tasks:
    - debug:
        msg: |-
          #jinja2: trim_blocks:False
          {% for ip in config %}
          interface Vlan1
            ip dhcp relay address {{ ip }}
            {%- for to_remove in config_to_remove if ip not in to_remove %}
            no {{ to_remove }}
            {%- endfor %}
          interface Ethernet1/49
            ip dhcp relay address {{ ip }}
            {%- for to_remove in config_to_remove if ip not in to_remove %}
            no {{ to_remove }}
            {%- endfor %} 
          interface Ethernet1/50
            ip dhcp relay address {{ ip }} 
            {%- for to_remove in config_to_remove if ip not in to_remove %}
            no {{ to_remove }}
            {%- endfor %}
          {% endfor %}
      vars:
        guess_on_existing_config:
          - interface Vlan1
          - ip dhcp relay address 10.1.1.2
          - ip dhcp relay address 10.5.5.98
          - ip dhcp relay address 10.5.5.99
          - interface Ethernet1/49
          - ip dhcp relay address 10.1.1.2
          - ip dhcp relay address 10.5.5.98
          - ip dhcp relay address 10.5.5.99
          - interface Ethernet1/50
          - ip dhcp relay address 10.1.1.2
          - ip dhcp relay address 10.5.5.98
          - ip dhcp relay address 10.5.5.99
        guess_on_required_config:
          - interface Vlan1
          - ip dhcp relay address 10.1.1.2
          - interface Ethernet1/49
          - ip dhcp relay address 10.1.1.2
          - interface Ethernet1/50
          - ip dhcp relay address 10.1.1.2
        config:
          - 10.1.1.2
        config_to_remove: "{{ guess_on_existing_config | difference(guess_on_required_config) }}"

这产生:

$ ansible-playbook play.yml -i inventory.yml | sed 's/\n/\n/g'

PLAY [all] *********************************************************************

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "
interface Vlan1
  ip dhcp relay address 10.1.1.2
  no ip dhcp relay address 10.5.5.98
  no ip dhcp relay address 10.5.5.99
interface Ethernet1/49
  ip dhcp relay address 10.1.1.2
  no ip dhcp relay address 10.5.5.98
  no ip dhcp relay address 10.5.5.99 
interface Ethernet1/50
  ip dhcp relay address 10.1.1.2
  no ip dhcp relay address 10.5.5.98
  no ip dhcp relay address 10.5.5.99
"
}

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0