首页 > 解决方案 > 如何在 Ansible uri 模块中使用正确的循环

问题描述

我正在使用Ansible uri 模块来触发pfSense API。现在我想在任务中创建防火墙规则(代码被截断)。

---
# tasks file for creating firewall rules

- name: "Create firewall rules"
  uri:
    url: "https://{{ pf_hostname }}/api/v1/firewall/rule"
    method: "POST"
    body: "{ \
          \"client-id\": \"{{ pf_user }}\", 
            \"client-token\": \"{{ pf_password }}\",
            \"type\": \"{{ pf_fw_type_01 }}\",
            \"interface\": \"{{ pf_fw_interface_01 }}\",
          }"

vars 文件如下所示。

---
# vars file for creating firewall rules

# Authentication
pf_hostname: "pfsense.local"
pf_user: "admin"
pf_password: "pfsense"

# Rule 01
pf_fw_type_01: "pass"
pf_fw_interface_01: "wan"

我现在如何在没有不必要的冗余(例如循环)的情况下重复任务?我只提出了以下想法,但对我来说似乎并不理想。

  loop: 
    - "{{ item.client-id: {{ pf_user }}, item.type: {{ pf_fw_type_01 }} }}"
    - "{{ item.client-id: {{ pf_user }}, item.type: {{ pf_fw_type_02 }} }}"

标签: loopsansiblepfsense

解决方案


将规则作为动态参数放在列表中怎么样?
例如,这里是这样的。

变量.yml

---
# vars file for creating firewall rules

# Authentication
pf_hostname: "pfsense.local"
pf_user: "admin"
pf_password: "pfsense"

rules:
  - num: 01
    type: "pass"
    pf_fw_interface: "wan"

  - num: 02
    type: "pass"
    pf_fw_interface: "wan"

剧本

---
- hosts: localhost
  gather_facts: false
  vars_files:
    - vars.yml
  tasks:
    - debug:
        msg: |
          {
            "client-id": "{{ pf_user }}",
            "client-token": "{{ pf_password }}",
            "type": "{{ item.type }}",
            "interface": "{{ item.pf_fw_interface }}"
          }
      loop: "{{ rules }}"

结果

$ ansible-playbook main.yml
(snip)

PLAY [localhost] *********************************************************************************************************************************************************************

TASK [debug] *************************************************************************************************************************************************************************
ok: [localhost] => (item={'type': 'pass', 'pf_fw_interface': 'wan'}) => {
    "msg": {
        "client-id": "admin",
        "client-token": "pfsense",
        "interface": "wan",
        "type": "pass"
    }
}
ok: [localhost] => (item={'type': 'pass', 'pf_fw_interface': 'wan'}) => {
    "msg": {
        "client-id": "admin",
        "client-token": "pfsense",
        "interface": "wan",
        "type": "pass"
    }
}
(snip)

推荐阅读