Ansible内联循环创建列表

huangapple go评论114阅读模式
英文:

Ansible create a list from a loop inline

问题

我有一个操作手册,内容如下:

  1. - name: 安装 PHP 扩展
  2. ansible.builtin.apt:
  3. pkg:
  4. - php{{ php_version }}{{ item.pkg_extension }}
  5. loop:
  6. - { pkg_extension: -mysql }
  7. - { pkg_extension: -bz2 }
  8. - { pkg_extension: -curl }
  9. - { pkg_extension: -gd }
  10. - { pkg_extension: -imap }
  11. - { pkg_extension: -mbstring }
  12. - { pkg_extension: -xml }
  13. - { pkg_extension: -zip }
  14. when: php_key_setup is succeeded and nginx_install is succeeded and php_base_install is succeeded
  15. register: php_install

有时出现我不明白的原因,这个循环中的某个包安装失败。我想将这些包作为列表或字典传递给 apt 模块,就像这样:

  1. - name: 最佳 yum
  2. ansible.builtin.yum:
  3. name: "{{ list_of_packages }}"
  4. state: present

如何从这个循环中创建这个列表,将所有内容连接起来,而不需要额外的步骤来创建这个列表并在之后重复使用它呢?

英文:

I have a playbook that goes like this:

  1. - name: Install php extensions
  2. ansible.builtin.apt:
  3. pkg:
  4. - php{{ php_version }}{{ item.pkg_extension }}
  5. loop:
  6. - { pkg_extension: -mysql }
  7. - { pkg_extension: -bz2 }
  8. - { pkg_extension: -curl }
  9. - { pkg_extension: -gd }
  10. - { pkg_extension: -imap }
  11. - { pkg_extension: -mbstring }
  12. - { pkg_extension: -xml }
  13. - { pkg_extension: -zip }
  14. when: php_key_setup is succeeded and nginx_install is succeeded and php_base_install is succeeded
  15. register: php_install

Sometimes for reasons unknown to me, this fails for one of the packages in the loop. I want to pass these packages as a list or a dictionary to the apt module instead, like in

https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_loops.html#iterating-over-a-simple-list :

  1. - name: Optimal yum
  2. ansible.builtin.yum:
  3. name: "{{ list_of_packages }}"
  4. state: present

How can I create this list from this loop, concatenating everything without adding an extra step to create this list and reuse it afterwards?

答案1

得分: 3

如果您有一个扩展名列表,您可以使用map来对每个项目应用regex_replace过滤器,就像这样:

  1. - hosts: localhost
  2. gather_facts: false
  3. vars:
  4. php_version: 8.3
  5. php_pkg_extensions:
  6. - mysql
  7. - bz2
  8. - curl
  9. - gd
  10. - imap
  11. - mbstring
  12. - xml
  13. - zip
  14. tasks:
  15. - name: 安装 PHP 扩展
  16. ansible.builtin.apt:
  17. pkg: "{{ packages }}"
  18. vars:
  19. packages: >-
  20. {{
  21. php_pkg_extensions |
  22. map('regex_replace', '^(.*)$', 'php%s-\' % (php_version,))
  23. }}

不需要php_pkg_extensions变量,但它会使事情更清晰。您可以改为这样编写:

  1. - hosts: localhost
  2. gather_facts: false
  3. vars:
  4. php_version: 8.3
  5. tasks:
  6. - name: 安装 PHP 扩展
  7. ansible.builtin.apt:
  8. pkg: "{{ packages }}"
  9. vars:
  10. packages: >-
  11. {{
  12. ["mysql", "bz2", "curl", "gd", "imap", "mbstring", "xml", "zip"] |
  13. map('regex_replace', '^(.*)$', 'php%s-\' % (php_version,))
  14. }}
英文:

If you have the list of extensions in a list, you can use map to apply the regex_replace filter to each item, like this:

  1. - hosts: localhost
  2. gather_facts: false
  3. vars:
  4. php_version: 8.3
  5. php_pkg_extensions:
  6. - mysql
  7. - bz2
  8. - curl
  9. - gd
  10. - imap
  11. - mbstring
  12. - xml
  13. - zip
  14. tasks:
  15. - name: Install php extensions
  16. ansible.builtin.apt:
  17. pkg: "{{ packages }}"
  18. vars:
  19. packages: >-
  20. {{
  21. php_pkg_extensions |
  22. map('regex_replace', '^(.*)$', 'php%s-' % (php_version,))
  23. }}

You don't need the php_pkg_extensions variable, but it makes things much cleaner. You could instead write:

  1. - hosts: localhost
  2. gather_facts: false
  3. vars:
  4. php_version: 8.3
  5. tasks:
  6. - name: Install php extensions
  7. ansible.builtin.apt:
  8. pkg: "{{ packages }}"
  9. vars:
  10. packages: >-
  11. {{
  12. ["mysql", "bz2", "curl", "gd", "imap", "mbstring", "xml", "zip"] |
  13. map('regex_replace', '^(.*)$', 'php%s-' % (php_version,))
  14. }}

答案2

得分: 2

  1. 给定以下变量
  2. ```yaml
  3. php_version: 8.3
  4. php_pkg_extensions:
  5. - mysql
  6. - bz2
  7. - curl
  8. - gd
  9. - imap
  10. - mbstring
  11. - xml
  12. - zip

声明列表

  1. packages: "{{ ['php' ~ php_version]|
  2. product(php_pkg_extensions)|
  3. map('join', '-') }}"

将得到

  1. packages:
  2. - php8.3-mysql
  3. - php8.3-bz2
  4. - php8.3-curl
  5. - php8.3-gd
  6. - php8.3-imap
  7. - php8.3-mbstring
  8. - php8.3-xml
  9. - php8.3-zip

<hr>

<sup>

用于测试的完整playbook示例

  1. - hosts: localhost
  2. vars:
  3. php_version: 8.3
  4. php_pkg_extensions:
  5. - mysql
  6. - bz2
  7. - curl
  8. - gd
  9. - imap
  10. - mbstring
  11. - xml
  12. - zip
  13. packages: "{{ ['php' ~ php_version]|
  14. product(php_pkg_extensions)|
  15. map('join', '-') }}"
  16. tasks:
  17. - debug:
  18. var: packages
  19. - name: 安装php扩展
  20. ansible.builtin.apt:
  21. pkg: "{{ packages }}"
  22. when: install_php_extensions|d(false)|bool

</sup>

  1. <details>
  2. <summary>英文:</summary>
  3. Given the variables
  4. ```yaml
  5. php_version: 8.3
  6. php_pkg_extensions:
  7. - mysql
  8. - bz2
  9. - curl
  10. - gd
  11. - imap
  12. - mbstring
  13. - xml
  14. - zip

Declare the list

  1. packages: &quot;{{ [&#39;php&#39; ~ php_version]|
  2. product(php_pkg_extensions)|
  3. map(&#39;join&#39;, &#39;-&#39;) }}&quot;

gives what you want

  1. packages:
  2. - php8.3-mysql
  3. - php8.3-bz2
  4. - php8.3-curl
  5. - php8.3-gd
  6. - php8.3-imap
  7. - php8.3-mbstring
  8. - php8.3-xml
  9. - php8.3-zip

<hr>

<sup>

Example of a complete playbook for testing

  1. - hosts: localhost
  2. vars:
  3. php_version: 8.3
  4. php_pkg_extensions:
  5. - mysql
  6. - bz2
  7. - curl
  8. - gd
  9. - imap
  10. - mbstring
  11. - xml
  12. - zip
  13. packages: &quot;{{ [&#39;php&#39; ~ php_version]|
  14. product(php_pkg_extensions)|
  15. map(&#39;join&#39;, &#39;-&#39;) }}&quot;
  16. tasks:
  17. - debug:
  18. var: packages
  19. - name: Install php extensions
  20. ansible.builtin.apt:
  21. pkg: &quot;{{ packages }}&quot;
  22. when: install_php_extensions|d(false)|bool

</sup>

huangapple
  • 本文由 发表于 2023年7月10日 23:08:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/76655082.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定