问题描述
在使用Ansible playbook时,遇到了一个问题。他有一个名为packages
的变量,其中包含了一个混合了嵌套字典的列表。他想要使用类似下面的指令来安装所有在变量中定义的软件包:
- name: Install a list of packages
become: yes
apt:
name: "{{ packages }}"
但是他不知道应该使用什么过滤器将变量转换为普通的列表,他需要获取嵌套字典中的项目。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
根据用户提供的示例,你可以将变量定义为一个字典,其中值是一个列表。这样可以避免使用嵌套字典。
以下是一个示例:
packages:
- apt-file
- axel
- ibus-rime
- rofi
- i3
- ffmpeg
- xclip
- cargo
- httpie
- ttf-ubuntu-font-family
- tldr-py
- glances
- brave-browser
- chromium
- emacs
然后,你可以使用with_items
循环来遍历列表,并在每次迭代中安装软件包。
以下是一个示例任务:
- name: Install a list of packages
become: yes
apt:
name: "{{ item }}"
with_items: "{{ packages }}"
这将安装变量packages
中定义的所有软件包。
方案2
如果你仍然希望保留嵌套字典的结构,你可以使用json_query
过滤器来提取嵌套字典中的项目。
以下是一个示例任务:
- name: Install a list of packages
become: yes
apt:
name: "{{ packages | json_query('[].*') }}"
在上面的示例中,json_query('[].*')
将提取嵌套字典中的所有项目,并返回一个列表。然后,这个列表将作为apt
模块的name
参数的值,用于安装软件包。
请注意,使用json_query
过滤器需要安装jmespath
库。你可以使用以下命令安装它:
pip install jmespath
方案3
如果你希望在变量中保留嵌套字典的结构,并且不想使用json_query
过滤器,你可以编写一个自定义的Ansible过滤器来提取嵌套字典中的项目。
以下是一个示例自定义过滤器的代码:
# filters/flatten_list.py
def flatten_list(value):
result = []
for item in value:
if isinstance(item, list):
result.extend(item)
else:
result.append(item)
return result
class FilterModule(object):
def filters(self):
return {
'flatten_list': flatten_list
}
将上面的代码保存为flatten_list.py
文件,并将其放置在Ansible playbook的filters
目录中。
然后,你可以在playbook中使用自定义过滤器来提取嵌套字典中的项目。
以下是一个示例任务:
- name: Install a list of packages
become: yes
apt:
name: "{{ packages | flatten_list }}"
这将使用自定义过滤器flatten_list
来提取嵌套字典中的项目,并将其作为apt
模块的name
参数的值,用于安装软件包。
请注意,使用自定义过滤器需要在Ansible playbook中配置filter_plugins
选项,以指定自定义过滤器的路径。例如:
- hosts: localhost
gather_facts: no
vars:
packages:
- apt-file
- axel
- ibus-rime
- rofi
- i3
- ffmpeg
- xclip
- cargo
- httpie
- ttf-ubuntu-font-family
- tldr-py
- glances
- browsers:
- brave-browser
- chromium
- editors:
- emacs
tasks:
- name: Install a list of packages
become: yes
apt:
name: "{{ packages | flatten_list }}"
filter_plugins:
- filters
在上面的示例中,filter_plugins
选项指定了自定义过滤器的路径为filters
目录。
以上是几种解决方案,你可以根据自己的需求选择其中一种来解决问题。希望对你有帮助!