Ansible多维数组嵌套循环问题:PHP及扩展安装失败求助
解决Ansible嵌套循环安装多版本PHP及扩展的问题
嘿,刚学Ansible3天就敢折腾多维数组,已经超棒啦!我来帮你搞定这个嵌套循环的问题~
首先先提个小细节:你的YAML配置里扩展项的缩进有点问题,会导致Ansible无法正确解析数组。正确的缩进应该让每个扩展成为对应PHP版本的子元素,像这样:
php: versions: - 7.2: - cli - fpm - curl - mysql - pdo - zip - xml - gd - mbstring - tokenizer - ctype - json - 7.3: - cli - fpm - curl - mysql - pdo - zip - xml - gd - mbstring - tokenizer - ctype - json
接下来解决嵌套循环的问题,你之前的写法错误是因为直接把整个扩展数组拼到了包名里,而没有遍历单个扩展。这里给你两种简单易懂的方案:
方案一:基于现有数组结构,用子任务实现嵌套循环
这种方法不用修改你的数组结构,通过拆分任务来实现外层遍历PHP版本、内层遍历扩展的效果:
- 新建一个子任务文件,比如
install_php_extensions.yml,内容如下:
- name: 安装PHP {{ php_version }} 的扩展 apt: name: "php{{ php_version }}-{{ item }}" state: present loop: "{{ php_extensions }}"
- 在你的主任务文件里,添加外层循环来遍历每个PHP版本,把版本号和对应扩展列表传给子任务:
- name: 遍历所有PHP版本,安装对应扩展 include_tasks: install_php_extensions.yml loop: "{{ php.versions }}" vars: php_version: "{{ item.keys() | first }}" # 提取当前项的PHP版本号 php_extensions: "{{ item.values() | first }}" # 提取当前版本对应的扩展列表
这样外层循环会逐个处理每个PHP版本项,把版本号和扩展列表传给子任务,子任务再循环安装每个扩展,完美实现嵌套遍历~
方案二:调整数组结构,让遍历更直观
如果你觉得keys() | first这种写法有点绕,可以把数组改成更清晰的键值对结构,刚学Ansible的话这种方式更容易理解:
修改你的配置数组为:
php: versions: - version: "7.2" extensions: - cli - fpm - curl - mysql - pdo - zip - xml - gd - mbstring - tokenizer - ctype - json - version: "7.3" extensions: - cli - fpm - curl - mysql - pdo - zip - xml - gd - mbstring - tokenizer - ctype - json
然后主任务可以直接写成:
- name: 遍历PHP版本并安装扩展 include_tasks: install_php_extensions.yml loop: "{{ php.versions }}" vars: php_version: "{{ item.version }}" php_extensions: "{{ item.extensions }}"
子任务install_php_extensions.yml和方案一的一样,这样代码可读性更高,后续维护也更方便。
为什么你之前的写法会失败?
你之前的php{{ item.keys() | first }}-{{ item[item.keys() | first] }}会把整个扩展数组(比如[cli,fpm,...])直接拼到包名里,生成类似php7.2-[cli,fpm,curl]这种完全无效的包名,自然安装失败啦。必须要遍历每个扩展,逐个生成正确的包名才行~
内容的提问来源于stack exchange,提问作者RedoColor
相关产品推荐
相关产品推荐

