在 Ansible 中,如何设置带有列表的字典?
In Ansible, how do I setup dictionaries with lists?
假设我想使用来自 Ansible galaxy 的 FlatKey.firewalld 剧本,它有设置防火墙端口规则的任务
- name: set firewalld port rules
firewalld:
port={{item.value.port}}/{{item.value.protocol|default('tcp')}
permanent={{item.value.permanent|default('true')}
immediate={{item.value.immediate|default('true')}
state={{item.value.state|default('enabled')}
zone={{item.value.zone|default('public')}}
with_dict: "{{firewalld_port_rules|default({})}}"
我有一个 defaults/main.yml 文件是这样设置的
firewalld_port_rules:
key:
port: 123456
protocol: tcp
state: enabled
zone: public
permanent: true
immediate: true
如何在不重复代码的情况下将其用于多个端口? IOW 我真的想要这样的东西,但当然语法不起作用。希望你明白了。
firewalld_port_rules:
key:
port: [123456, 45678, 45679]
protocol: tcp
state: enabled
zone: public
permanent: true
immediate: true
您可以通过 looping over subelements 实现此目的:
Subelements walks a list of hashes (aka dictionaries) and then traverses a list with a given (nested sub-)key inside of those records.
您需要分叉剧本并将任务更改为:
- name: set firewalld port rules
firewalld:
port: "{{item.1}}/{{item.0.protocol|default('tcp')}}"
permanent: "{{item.0.permanent|default('true')}}"
immediate: "{{item.0.immediate|default('true')}}"
state: "{{item.0.state|default('enabled')}}"
zone: "{{item.0.zone|default('public')}}"
with_subelements:
- "{{firewalld_port_rules|default({})}}"
- port
使用with_items
代替with_dict
:
- name: so question 552716
hosts: '{{ target }}'
vars:
firewalld_port_rules:
- { port: 123
, state: enabled
, zone: public
, permanent: true
, immediate: true
, protocol: tcp }
- { port: 222
, state: enabled
, immediate: true
, protocol: udp }
- { port: 333
, state: enabled
, zone: public
, permanent: true
, immediate: true
, protocol: tcp }
tasks:
- name: show debug
debug: msg="port = {{ item.port }} , state = {{ item.state }}, zone = {{ item.zone | default('public') }}, permanent = {{ item.permanent | default(true) }}"
with_items: "{{ firewalld_port_rules }}"
请注意,permanent 始终为 true,zone 通常为 public,因此您可以省略它们并使用默认值(例如,参见端口 222)。
另见 link:Standard Loops
假设我想使用来自 Ansible galaxy 的 FlatKey.firewalld 剧本,它有设置防火墙端口规则的任务
- name: set firewalld port rules
firewalld:
port={{item.value.port}}/{{item.value.protocol|default('tcp')}
permanent={{item.value.permanent|default('true')}
immediate={{item.value.immediate|default('true')}
state={{item.value.state|default('enabled')}
zone={{item.value.zone|default('public')}}
with_dict: "{{firewalld_port_rules|default({})}}"
我有一个 defaults/main.yml 文件是这样设置的
firewalld_port_rules:
key:
port: 123456
protocol: tcp
state: enabled
zone: public
permanent: true
immediate: true
如何在不重复代码的情况下将其用于多个端口? IOW 我真的想要这样的东西,但当然语法不起作用。希望你明白了。
firewalld_port_rules:
key:
port: [123456, 45678, 45679]
protocol: tcp
state: enabled
zone: public
permanent: true
immediate: true
您可以通过 looping over subelements 实现此目的:
Subelements walks a list of hashes (aka dictionaries) and then traverses a list with a given (nested sub-)key inside of those records.
您需要分叉剧本并将任务更改为:
- name: set firewalld port rules
firewalld:
port: "{{item.1}}/{{item.0.protocol|default('tcp')}}"
permanent: "{{item.0.permanent|default('true')}}"
immediate: "{{item.0.immediate|default('true')}}"
state: "{{item.0.state|default('enabled')}}"
zone: "{{item.0.zone|default('public')}}"
with_subelements:
- "{{firewalld_port_rules|default({})}}"
- port
使用with_items
代替with_dict
:
- name: so question 552716
hosts: '{{ target }}'
vars:
firewalld_port_rules:
- { port: 123
, state: enabled
, zone: public
, permanent: true
, immediate: true
, protocol: tcp }
- { port: 222
, state: enabled
, immediate: true
, protocol: udp }
- { port: 333
, state: enabled
, zone: public
, permanent: true
, immediate: true
, protocol: tcp }
tasks:
- name: show debug
debug: msg="port = {{ item.port }} , state = {{ item.state }}, zone = {{ item.zone | default('public') }}, permanent = {{ item.permanent | default(true) }}"
with_items: "{{ firewalld_port_rules }}"
请注意,permanent 始终为 true,zone 通常为 public,因此您可以省略它们并使用默认值(例如,参见端口 222)。
另见 link:Standard Loops