首页 > 解决方案 > 使用字典和循环的 Ansible 剧本中的语法错误

问题描述

我的 vars/ 目录中有以下字典。

vars_dict.yml

---
ruleset:
  rule1:
    rule_name: testrule1
    description: Test Rule number 1
    source_zone: trust
    destination_zone: untrust
    source_ip: 1.2.3.4
    source_user: any
    destination_ip: 4.5.6.7
    action: allow
    disabled: FALSE
    location: top
    log_end: TRUE
    tag_name: superimportant
    vsys: vsys1
    state: present
    commit: TRUE
  rule2:
    rule_name: testrule2
    description: Test Rule number 2
    source_zone: trust
    destination_zone: untrust
    source_ip: 1.2.3.5
    source_user: any
    destination_ip: 4.5.6.8
    action: allow
    disabled: FALSE
    location: bottom
    log_end: TRUE
    tag_name: superimportant
    vsys: vsys1
    state: present
    commit: TRUE
...

我在 vars/ 中也有这些支持变量文件:

凭证.yml

fw_username: test
fw_password: test

和 fw.yml

fw_ip_address: 192.168.1.1

我想循环遍历每组数据以使用此剧本将命令发送到防火墙:

---
- hosts: localhost
  connection: local

  roles:
    - role: PaloAltoNetworks.paloaltonetworks

  tasks:
    - name: include variables
      include_vars:
        dir: vars

    - name: Add superimportant rules to the firewall
      panos_security_rule:
        ip_address: '{{ fw_ip_address }}'
        username: '{{ fw_username }}'
        password: '{{ fw_password }}'
        rule_name: '{{ ruleset.rule_name }}'
        description: '{{ ruleset.description }}'
        source_zone: ['{{ ruleset.source_zone }}']
        destination_zone: ['{{ ruleset.destination_zone }}']
        source_ip: ['{{ ruleset.source_ip }}']
        source_user: ['{{ ruleset.source_user }}']
        destination_ip: ['{{ ruleset.destination_ip }}']
        action: '{{ ruleset.action }}'
        disabled: '{{ ruleset.disabled }}'
        location: '{{ ruleset.location }}'
        log_end: '{{ ruleset.log_end }}'
        tag_name: '{{ ruleset.tag_name }}'
        vsys: '{{ ruleset.vsys }}'
        state: '{{ ruleset.state }}'
        commit: '{{ ruleset.commit }}'
        with_dict:
          - "{{ ruleset }}"
...

我期望 ansible 的输出是循环并为每个数据块生成如下输出:

  panos_security_rule:
    ip_address: '192.168.1.1'
    username: 'test'
    password: 'test'
    rule_name: 'Ansible test 1'
    description: 'An Ansible test rule'
    source_zone: ['trust']
    destination_zone: ['untrust']
    source_ip: ['1.2.3.4']
    source_user: ['any']
    destination_ip: ['any']
    action: 'allow'
    disabled: 'False'
    location: 'top'
    log_end: 'true'
    tag_name: 'superimportant'
    vsys: 'vsys1'
    state: 'present'
    commit: 'True'

我得到的错误是

TASK [include variables] *****************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "Syntax Error while loading YAML.\n  mapping values are not allowed here\n\nThe error appears to have been in '/root/ansible/vars/vars.yml': line 3, column 16, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  rule_name: testrule1\n    description: Test Rule number 1\n               ^ here\n"}
        to retry, use: --limit @/root/ansible/panos_dynamic.retry

我一直在阅读文档和帖子,我尝试重新格式化字典文件并使用 with_items、with_dict、括在“{{}}”中,并且没有括号,我似乎完全被卡住了。

我在这里错过了一些简单的东西吗?

标签: ansibleyaml

解决方案


有一些调整可以解决您的问题。

首先,使用列表而不是字典来定义角色。两者都有效,但列表是更简洁的代码。

其次,with_dict符号需要缩进到与任务相同的级别,而不是任务参数。

最后,您的问题ruleset用作循环变量。默认情况下item,它需要与被迭代的 list/dict 变量不同。

示例:vars_dict.yml

---
ruleset:
  - rule_name: testrule1
    description: Test Rule number 1
    source_zone: trust
    destination_zone: untrust
    source_ip: 1.2.3.4
    source_user: any
    destination_ip: 4.5.6.7
    action: allow
    disabled: FALSE
    location: top
    log_end: TRUE
    tag_name: superimportant
    vsys: vsys1
    state: present
    commit: TRUE

  - rule_name: testrule2
    description: Test Rule number 2
    source_zone: trust
    destination_zone: untrust
    source_ip: 1.2.3.5
    source_user: any
    destination_ip: 4.5.6.8
    action: allow
    disabled: FALSE
    location: bottom
    log_end: TRUE
    tag_name: superimportant
    vsys: vsys1
    state: present
    commit: TRUE

剧本:---主机:本地主机连接:本地

  roles:
    - role: PaloAltoNetworks.paloaltonetworks

  tasks:
    - name: include variables
      include_vars:
        dir: vars

    - name: Add superimportant rules to the firewall
      panos_security_rule:
        ip_address: '{{ fw_ip_address }}'
        username: '{{ fw_username }}'
        password: '{{ fw_password }}'
        rule_name: '{{ item.rule_name }}'
        description: '{{ item.description }}'
        source_zone: ['{{ item.source_zone }}']
        destination_zone: ['{{ item.destination_zone }}']
        source_ip: ['{{ item.source_ip }}']
        source_user: ['{{ item.source_user }}']
        destination_ip: ['{{ item.destination_ip }}']
        action: '{{ item.action }}'
        disabled: '{{ item.disabled }}'
        location: '{{ item.location }}'
        log_end: '{{ item.log_end }}'
        tag_name: '{{ item.tag_name }}'
        vsys: '{{ item.vsys }}'
        state: '{{ item.state }}'
        commit: '{{ item.commit }}'
      with_items:
        - "{{ ruleset }}"  

推荐阅读