首页 > 解决方案 > 有没有办法根据条件过滤 ansible vars

问题描述

我在剧本和多个任务中有这个变量,我只想根据提示输入从变量列表中过滤项目。现在我必须使用 when 从多个任务中排除该项目。请看下面的例子:

vars_prompt:
    - name: rmetcd
      prompt: "remove etcd: YES OR NO?"
      private: no

vars:
    containers:
      - "etcd"
      - "mysql"
      - "postgres"

    folders:
      - "etcd"
      - "mysql"
      - "postgres"
tasks:
    - name: remove container
         shell: "docker rm -f {{ item }}"
         with_items: "{{ containers }}"
         when: 
           - '"etcd" not in item' 

    - name: remove folder
         file:
           path: "{{ item }}"
           state: absent
         with_items: "{{ folders }}"
         when: 
           - '"etcd" not in item' 

 when: rmetcd == "NO"

标签: ansible

解决方案


我会以相反的顺序处理问题:我不会为每个任务过滤我的列表以潜在地取出一个元素,而是使用默认元素定义我的列表,如果用户回答是,则添加额外的元素。

注意:你的两个列表是相同的,我在下面的例子中只保留了一个:

---
- hosts: localhost
  gather_facts: false

  vars_prompt:
    - name: rmetcd
      prompt: "Remove etcd [yes/no]?"
      private: no

  vars:
    _default_services:
      - mysql
      - postgres

    services: "{{ _default_services + (rmetcd | bool | ternary(['etcd'], [])) }}"

  tasks:
    - name: task1
      debug:
        msg: "remove container {{ item }}"
      loop: "{{ services }}"

    - name: taks2
      debug:
        msg: "remove folder {{ item }}"
      loop: "{{ services }}"

要点:

  • 我定义了一个“私有”变量_default_services。这是将始终包含的服务列表。
  • 我计算了services两个列表相加的变量:_default_services以及根据用户输入添加的附加值。对于最后一个:
    • 我使用rmetcd了包含值(应该是“是”或“否”)
    • 我应用bool过滤器将值转换为布尔值
    • 如果为真() ,我使用ternary过滤器选择单个元素列表,['etcd']如果为假(),则选择一个空列表[]

推荐阅读