• Ansible如何使用Filter插件转换数据


    写在前面


    • 今天和小伙伴分享一些Ansible中过滤器
    • 博文内容比较简单
    • 主要介绍的常用过滤器和对应的Demo
    • 使用过滤器如何处理变量
    • 理解不足小伙伴帮忙指正
    • 食用方式:了解Ansible基础语法

    傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。--------王小波


    Ansible 过滤器

    关于Ansible 的过滤器,主要由两部分构成,一部分过滤器通过ansible filter插件提供,包含在 Ansible Engine 中,一部分过滤器通过python模板引擎jinja2提供

    在模板引擎中,Ansible 使用 Jinja2 表达式将变量值应用到Playbook模板Jinja2 表达式也支持过滤器。过滤器用于修改或处理Playbook或模板中放入的变量的值。关于Jinja2,是基于python的模板引擎,类似Java的Freemarker,在Python Web 中也经常使用,比如Flask常常结合Jinja2 实现前后端不分离的小型Web项目

    具体的过滤器列表,小伙伴们可以在下面的路劲看到,当在内网的时候,可以直接查找:

    • jinja2 /usr/lib/python3.6/site-packages/jinja2/filters.py
    • Ansible /usr/lib/python3.6/site-packages/ansible/plugins/filter/core.py

    过滤器具体的说明文档:

    学习之前,简单回顾下 YAML格式数据文件中的变量的定义方式,熟悉小伙伴可以直接跳过

    变量类型

    YAML 结构或值内容定义了确切的数据类型。类型包括:

    • 字符串(字符序列)
    • 数字(数值)
    • 布尔值
    • 日期(ISO-8601 日历日期)
    • Null(将变量设置为未定义的变量)
    • 列表或数组(值的有序集合)
    • 字典(键值对的集合)

    字符串

    字符串是一系列字符,是Ansible中的默认数据类型。字符串不需要使用引导或双引号括起:

    YAML 格式允许定义多行字符,使用竖线(|)保留换行符,或使用大于运算符(>)来取消换行符,(最后一个换行符还是会存在):

    ---
    - name: demo var type
      hosts: servera
      tasks:
         - name: var1
           vars:
             string_var: |
                liruilong
                and
                students
             string_vars: >
                liruilong
                and
                students
           debug:
               msg: "{{ string_var }} ||| {{ string_vars }}"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    测试一下

    $ ansible-playbook  var_type.yaml
    PLAY [demo var type] *********************************************************************************
    TASK [var1] ******************************************************************************************
    ok: [servera] => {
        "msg": "liruilong \nand \nstudents\n ||| liruilong and students   \n"
    }
    PLAY RECAP *******************************************************************************************
    servera                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    数字

    当变量内容是数字时,YAML 会解析字符串,并生成一个数字值,即 IntegerFloat 类型。

    • Integers 包含十进制字符,并且可以选择在前面加上 + 或 - 符号:
    • 如果数值中包含小数点,则将其解析为 Float:
    • 也可以使用科学记数法表示很大的 Integers 或 Floats:
    • 十六进制数字以 0x 开头,后面仅跟十六进制字符:
    • 如果将数字放在引号中,其将被视为 String:
    $ cat var_type.yaml
    ---
    - name: demo var type
      hosts: servera
      tasks:
         - name: var1
           vars:
             string_var: 2.165
             string_vars: 456
           debug:
               msg: "{{ string_var }} ||| {{ string_vars + 3 }}"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    $ ansible-playbook  var_type.yaml
    
    PLAY [demo var type] *********************************************************************************
    TASK [var1] ******************************************************************************************
    ok: [servera] => {
        "msg": "2.165 ||| 459"
    }
    
    PLAY RECAP *******************************************************************************************
    servera                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    $
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    布尔值

    布尔值包含 yes、no、y、n、on、off、true 或 false 字符串。不区分大小写,但是 Jinja2 文档中建议使用小写来保持一致。

    $ cat var_type.yaml
    ---
    - name: demo var type
      hosts: servera
      tasks:
         - name: var1
           vars:
             string_var: 2.165
             string_vars: 456
             boo: yes
           shell:  echo "{{ string_var  }}"
           when: boo
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    $ ansible-playbook var_type.yaml
    
    PLAY [demo var type] *********************************************************************************
    
    TASK [var1] ******************************************************************************************
    changed: [servera]
    
    PLAY RECAP *******************************************************************************************
    servera                    : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
    $
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    日期

    如果字符串符合 ISO-8601 标准,YAML 会将字符串转换为 date 类型的值:

    Null

    特殊的 Null 值将变量声明为 undefined

    $ ansible-playbook  var_demo.yaml
    
    PLAY [var demo] **************************************************************************************
    TASK [var1 demo] *************************************************************************************
    ok: [servera] => {
        "msg": "  \n"
    }
    
    PLAY RECAP *******************************************************************************************
    servera                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
    $
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    列表或数组

    列表(数组)是值的有序集合。列表是数据收集和循环的基本结构。将列表写成以逗号分隔的值序列并用方括号括起,或每行一个元素并加上短划线前缀:可以使用从 0 开始的索引编号来访问列表的特定元素:

    $ ansible-playbook  var_demo.yaml
    
    PLAY [var demo] **************************************************************************************
    
    TASK [var1 demo] *************************************************************************************
    ok: [servera] => {
        "msg": "v1 ['v1', 'v2', 'v3'] \n"
    }
    
    PLAY RECAP *******************************************************************************************
    servera                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
    $ cat var_demo.yaml
    ---
    - name: var demo
      hosts: servera
      vars:
         param:
            - v1
            - v2
            - v3
      tasks:
        - name: var1 demo
          debug:
            msg: >
                  {{ param.0 }} {{ param }}
    $
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    字典

    字典(映射或散列)是将字符串键链接到值以进行直接访问的结构,键括在方括号中来访问字典中的项:

    $ ansible-playbook  var_demo.yaml
    
    PLAY [var demo] **************************************************************************************
    
    TASK [var1 demo] *************************************************************************************
    ok: [servera] => {
        "msg": "{'v1': 10, 'v2': 11, 'v3': 12} 10 \n"
    }
    
    PLAY RECAP *******************************************************************************************
    servera                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
    $ cat var_demo.yaml
    ---
    - name: var demo
      hosts: servera
      vars:
         param_dist:
            v1: 10
            v2: 11
            v3: 12
      tasks:
        - name: var1 demo
          debug:
            msg: >
                  {{ param_dist }} {{ param_dist['v1'] }}
    $
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    使用Jinja2过滤器处理数据

    应用过滤器,需要在变量名称后面加上竖线字符和要应用的过滤器的名称。某些过滤器可能需要将可选参数或选项放在括号中。可以在一个表达式中串联多个过滤器。

    jinja2支持的过滤器:https://jinja.palletsprojects.com/en/3.0.x/templates/#jinja-filters

    在这里插入图片描述

    看几个demo

    使用 Jinja2 过滤器来将首字母进行大写小写转化:

    $ ansible servera -m debug -a 'msg={{ "liruilong" | lower}}'
    servera | SUCCESS => {
        "msg": "liruilong"
    }
    $ ansible servera -m debug -a 'msg={{ "liruilong" | capitalize }}'
    servera | SUCCESS => {
        "msg": "Liruilong"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    将变量转换为另一种类型,如转换为 String 类型:

    $ ansible servera -m debug -a 'msg={{ "liruilong" | string }}'
    servera | SUCCESS => {
        "msg": "liruilong"
    }
    
    • 1
    • 2
    • 3
    • 4

    使用unique过滤器来删除重复数据,使用sort过滤器对其进行排序:

    $ ansible servera -m debug -a 'msg={{ [2,3,4,5,3,1,6] | unique | sort }}'
    servera | SUCCESS => {
        "msg": [
            1,
            2,
            3,
            4,
            5,
            6
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    常用过滤器

    检查变量是否定义

    mandatory:如果变量未定义,则会失败并中止 Ansible Playbook。

    $ ansible servera -m debug -a 'msg={{ name | mandatory }}' -e name=liruilong
    servera | SUCCESS => {
        "msg": "liruilong"
    }
    $ ansible servera -m debug -a 'msg={{ name | mandatory }}'
    servera | FAILED! => {
        "msg": "Mandatory variable 'name'  not defined."
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    可以通过设置未定义变量的处理策略来忽略未定义的变量

    $ ansible-config  dump | grep -i unde
    DEFAULT_UNDEFINED_VAR_BEHAVIOR(default) = True
    $
    
    • 1
    • 2
    • 3

    通过配置文件查看可以看到,可以通过变量的方式,在命令行或者清单文件中定义

    $ ansible-config  list
     env:
      - {name: ANSIBLE_ERROR_ON_UNDEFINED_VARS}
      ini:
      - {key: error_on_undefined_vars, section: defaults}
      name: Jinja2 fail on undefined
      type: boolean
      version_added: '1.3'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ansible.cfg

    error_on_undefined_vars=false
    
    • 1

    default:如果变量未定义,或者为null,则过滤器会将其设置为圆括号中指定的值。

    $ ansible servera -m debug -a 'msg={{ name | default( "liruilong",True) }}'
    servera | SUCCESS => {
        "msg": "liruilong"
    }
    
    • 1
    • 2
    • 3
    • 4

    如果括号中的第二个参数为 True ,那么变量的初始值是空字符串或布尔值 False 时,过滤器也会将变量设置为默认值。

    $ ansible servera -m debug -a 'msg={{ name | default( "liruilong",True) }}' -e name=''
    
    servera | SUCCESS => {
        "msg": "liruilong"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    default 过滤器也可以取特殊值omit,会导致值在没有初始值时保留为未定义状态。如果变量已具有值,则 omit不会更改值。

    $ ansible servera -m debug -a 'msg={{ names | default(omit) }}'
    servera | SUCCESS => {
        "msg": "Hello world!"
    }
    $ ansible servera -m debug -a 'msg={{ names | default(omit) }}' -e names=liruilong
    servera | SUCCESS => {
        "msg": "liruilong"
    }
    $
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    执行数学计算

    Jinja2 提供了多个数学过滤器,可以对数字进行运算。

    算术运算:某写情况下,可能需要首先使用 int 过滤器将值转换为整数,或使用 float 过滤器将值转换为浮点数。还有其它的可用于数学运算的过滤器:root、log、pow、abs 和 round 等。

    $ ansible servera -m debug -a 'msg={{ (12.3 | int) + 1 }}'
    servera | SUCCESS => {
        "msg": "13"
    }
    $ ansible servera -m debug -a 'msg={{ (-12.3 | int) | abs }}'
    servera | SUCCESS => {
        "msg": "12"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    操作列表

    如果列表中包含数字,可以使用max、min 或 sum来查找所有列表项的最大数、最小数和总和:

    $ ansible servera -m debug -a 'msg={{ [2,3,4,5,3,1,6] | max }}'
    servera | SUCCESS => {
        "msg": "6"
    }
    $ ansible servera -m debug -a 'msg={{ [2,3,4,5,3,1,6] | sum }}'
    servera | SUCCESS => {
        "msg": "24"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    提取列表元素

    • 通过first、last、length来获取列表信息:
    $ ansible servera -m debug -a 'msg={{ [2,3,4,5,3,1,6] | first }}'
    servera | SUCCESS => {
        "msg": "2"
    }
    $ ansible servera -m debug -a 'msg={{ [2,3,4,5,3,1,6] | last }}'
    servera | SUCCESS => {
        "msg": "6"
    }
    $ ansible servera -m debug -a 'msg={{ [2,3,4,5,3,1,6] | length }}'
    servera | SUCCESS => {
        "msg": "7"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • random 过滤器从列表中返回一个随机元素:
    $ ansible servera -m debug -a 'msg={{ [2,3,4,5,3,1,6] | random }}'
    servera | SUCCESS => {
        "msg": "1"
    }
    
    • 1
    • 2
    • 3
    • 4

    修改列表元素的顺序

    • sort 过滤器按照元素的自然顺序对列表进行排序。
    $ ansible servera -m debug -a 'msg={{ [2,3,4,5,3,1,6] | sort }}'
    servera | SUCCESS => {
        "msg": [
            1,
            2,
            3,
            3,
            4,
            5,
            6
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • reverse过滤器会返回一个顺序与原始顺序相反的列表。
    $ ansible servera -m debug -a 'msg={{ [2,3,4,5,3,1,6] | sort | reverse | list }}'
    servera | SUCCESS => {
        "msg": [
            6,
            5,
            4,
            3,
            3,
            2,
            1
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • shuffle 过滤器返回一个列表,顺序为随机。
    $ ansible servera -m debug -a 'msg={{ [2,3,4,5,3,1,6] | sort | reverse | shuffle|list }}'
    servera | SUCCESS => {
        "msg": [
            3,
            2,
            4,
            5,
            6,
            1,
            3
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    合并列表

    flatten 过滤器以递归方式取输入列表值中的任何内部列表,并将内部值添加到外部列表中:

    $ ansible servera -m debug -a 'msg={{ [2,3,4,5,3,1,6,[[7,8],9]] | flat
    ten}}'
    servera | SUCCESS => {
        "msg": [
            2,
            3,
            4,
            5,
            3,
            1,
            6,
            7,
            8,
            9
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    以集合形式操作列表

    • unique 过滤器确保列表中没有重复元素。
    • union 并集:过滤器返回一个集合,包含两个集合中的元素。
    • intersect 交集:过滤器返回一个集合,包含两个集合中共有的元素。
    • difference 差集:过滤器返回一个集合,包含存在于第一个集合但不存在第二个集合的元素。

    依次来看一下

    unique 过滤器确保列表中没有重复元素。

    $ ansible servera -m debug -a 'msg={{ [2,3,4,3] | unique }}'
    servera | SUCCESS => {
        "msg": [
            2,
            3,
            4
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    union 过滤器返回一个集合,包含两个集合中的元素。

    $ ansible servera -m debug -a 'msg={{ [2,3,4,3] | union([5]) }}'
    servera | SUCCESS => {
        "msg": [
            2,
            3,
            4,
            5
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    intersect 过滤器返回一个集合,包含两个集合中共有的元素。

    $ ansible servera -m debug -a 'msg={{ [2,3,4,3] | intersect([4]) }}'
    servera | SUCCESS => {
        "msg": [
            4
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    difference 过滤器返回一个集合,包含存在于第一个集合但不存在第二个集合的元素。

    $ ansible servera -m debug -a 'msg={{ [2,3,4,3] | difference([4]) }}'
    servera | SUCCESS => {
        "msg": [
            2,
            3
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    操作字典

    与列表不同,字典不会以任何方式进行排序。它们仅仅是键值对的集合。

    $ ansible servera -m debug -a 'msg={{ { "name":"liruilong"} }}'
    servera | SUCCESS => {
        "msg": {
            "name": "liruilong"
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    连接字典

    通过 combine 过滤器连接多个字典:

    $ ansible servera -m debug -a 'msg={{ { "name":"liruilong"} | combine( { "age": 27 }) }}'                                                                                       servera | SUCCESS => {
        "msg": {
            "age": 27,
            "name": "liruilong"
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    重塑字典

    字典可以通过 dict2items 过滤器重塑为列表

    $ ansible servera -m debug -a 'msg={{ { "name":"liruilong"} | combine( { "age": 27 })| dict2items }}'
    servera | SUCCESS => {
        "msg": [
            {
                "key": "name",
                "value": "liruilong"
            },
            {
                "key": "age",
                "value": 27
            }
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    列表也可通过items2dict过滤器重塑为字典:

    $ ansible servera -m debug -a 'msg={{ { "name":"liruilong"} | combine( { "age": 27 })| dict2items | items2dict }}'
    servera | SUCCESS => {
        "msg": {
            "age": 27,
            "name": "liruilong"
        }
    }
    $
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    散列、编码和操作字符串

    有多个过滤器可用于操作值的文本。可以取各种校验和,创建密码哈希,并将文本和 Base64 编码相互转换。

    散列字符串和密码

    hash 过滤其可以利用提供的哈希算法,返回输入字符串的哈希值:

    $ ansible servera -m debug -a 'msg={{ "liruilong" | hash("sha1") }}'
    servera | SUCCESS => {
        "msg": "bd588e37a86b3f527f61a70bc1ab65129abe4f2c"
    }
    
    • 1
    • 2
    • 3
    • 4
    $ ansible servera -m debug -a 'msg={{ "liruilong" | hash("md5") }}'
    servera | SUCCESS => {
        "msg": "5406f230fe5927a6ea9ac57ba6f4c6cf"
    }
    $
    
    • 1
    • 2
    • 3
    • 4
    • 5
    $ ansible servera -m debug -a 'msg={{ "liruilong" | hash("sha512") }}'
    servera | SUCCESS => {
        "msg": "1ca56023dcbce5b9e85ec6caf3bd721a227ee754afb31171970d19256a24bdbafa0c1f5a0ad66cd93c5b86ea2f7ad5e1d1a63aee7edaaa3533dfd71fcfbe5b06"
    }
    
    • 1
    • 2
    • 3
    • 4

    使用password_hash过滤器来生成密码哈希:

    看下机器上root的密码,

    # cat /etc/shadow | grep root
    root:$6$3kq6I94xqKs0Giut$sEWrjkl8QDpCCb3FECMpOGbVKwJFzxOMzeNJIr6LZjNpjwpU.njmf6bz2JPt6D1OocbCU2fOGchWPfUaI2plq1:18025:0:99999:7:::
    
    • 1
    • 2

    通过密码串我们可以知道,盐为:3kq6I94xqKs0Giut ,加密类型为:$6(sha512),通过Ansilbe的插件生成

    $ ansible servera -m debug -a 'msg={{ "redhat" | password_hash("sha512","3kq6I94xqKs0Giut") }}'                                                                         servera | SUCCESS => {
        "msg": "$6$3kq6I94xqKs0Giut$sEWrjkl8QDpCCb3FECMpOGbVKwJFzxOMzeNJIr6LZjNpjwpU.njmf6bz2JPt6D1OocbCU2fOGchWPfUaI2plq1"
    }
    
    • 1
    • 2
    • 3

    编码字符串
    可以通过b64encode过滤器将二进制数据转换为 base64,并通过 b64decode 过滤器重新转换为二进制:在将字符串发送到 Shell 之前,为了避免解析或代码注入的问题,最好使用quote过滤器清理字符串,这个没有Demo。

    格式化字符串

    使用lower、upper、或 capitalize过滤器来强制字符串的大小写:

    $ ansible servera -m debug -a 'msg={{ "Liruilong" |  lower }}'
    servera | SUCCESS => {
        "msg": "liruilong"
    }
    $ ansible servera -m debug -a 'msg={{ "Liruilong" |  upper }}'
    servera | SUCCESS => {
        "msg": "LIRUILONG"
    }
    $ ansible servera -m debug -a 'msg={{ "liruilong" |  capitalize }}'
    servera | SUCCESS => {
        "msg": "Liruilong"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    替换文本

    • regex_search过滤器,查找所有出现的子字符串,匹配行中第一个项目,并返回一个列表值。
    • regex_findall过滤器,查找所有出现的子字符串,匹配行中所有项目,并返回一个列表值。
    • replace过滤器,换输入字符串中所有出现的子字符串,不支持正则表达式。
    • regex_replace过滤器,换输入字符串中所有出现的子字符串。

    replace 过滤器用于替换字符串:

    $ ansible servera -m debug -a 'msg={{ "liruilong" |  replace("long","bo") }}'
    servera | SUCCESS => {
        "msg": "liruibo"
    }
    
    • 1
    • 2
    • 3
    • 4

    通过使用正则表达式和 regex_search 和 regex_replace 过滤器可以进行更加复杂的搜索替换:

    $ ansible servera -m debug -a 'msg={{ "liruilong up " |  regex_search("up") }}'
    servera | SUCCESS => {
        "msg": "up"
    }
    $ ansible servera -m debug -a 'msg={{ "liruilong up " |  regex_replace("up","and") }}'
    servera | SUCCESS => {
        "msg": "liruilong and "
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    操作 JSON 数据

    Ansible 使用的许多数据结构都采用 JSON 格式。JSON 和 YAML 表示法密切相关,Ansible 数据结构则可作为 JSON 来处理。
    from_json和from_yaml过滤器,从已经格式化好的变量读取数据。

    格式化数组

    $ cat name_list.yaml
    
    users:
      - name: "liruilong"
        job: "dev"
      - name: "sy"
        job: "ops"
    $ ansible-playbook  json.yaml
    
    PLAY [json demo] *************************************************************************************
    
    TASK [debug] *****************************************************************************************
    ok: [servera] => {
        "msg": [
            {
                "job": "dev",
                "name": "liruilong"
            },
            {
                "job": "ops",
                "name": "sy"
            }
        ]
    }
    
    PLAY RECAP *******************************************************************************************
    servera                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    
    $ cat json.yaml
    ---
    - name: json demo
      hosts: servera
      vars_files:
        - name_list.yaml
      tasks:
        - debug:
                msg: "{{ users  | from_yaml }}"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    JSON 查询
    使用 json_query 过滤器从 Ansible 数据结构中提取信息:

    $ cat name_list.yaml
    
    users:
      - name: "liruilong"
        job: "dev"
      - name: "sy"
        job: "ops"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    $ ansible-playbook json.yaml
    
    PLAY [json demo] *************************************************************************************
    
    TASK [debug] *****************************************************************************************
    ok: [servera] => {
        "msg": [
            "liruilong",
            "sy"
        ]
    }
    
    $ cat json.yaml
    ---
    - name: json demo
      hosts: servera
      vars_files:
        - name_list.yaml
      tasks:
        - debug:
                msg: "{{ users  | json_query('[*].name') }}"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    分析和编码数据结构

    数据结构使用to_json 和 to_yaml过滤器序列化为 JSON 或 YAML 格式。哈,这个感谢没啥区别,以后再研究下

    $ ansible servera -m debug -a 'msg={{ file | to_json }}' -e file='[{"name":"bastion","ip":["172.25.250.254","172.25.252.1"]}]'
    servera | SUCCESS => {
        "msg": "\"[{\\\"name\\\":\\\"bastion\\\",\\\"ip\\\":[\\\"172.25.250.254\\\",\\\"172.25.252.1\\\"]}]\""
    }
    $ ansible servera -m debug -a 'msg={{ file | to_yaml }}' -e file='[{"name":"bastion","ip":["172.25.250.254","172.25.252.1"]}]'
    servera | SUCCESS => {
        "msg": "'[{\"name\":\"bastion\",\"ip\":[\"172.25.250.254\",\"172.25.252.1\"]}]'\n"
    }
    $
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    使用 to_nice_json 和 to_nice_yaml 过滤器可以获取人类可读的格式化输出。

    quote过滤器,给字符串添加引号,在shell模块内使用。在将字符串发送到shell之前,为了避免解析或代码注入问题,最好使用quote过滤器对字符串进行处理。

    $ ansible-playbook  quote.yaml
    PLAY [debug play] *******************************************************************************************************************************************
    TASK [shell] ************************************************************************************************************************************************
    changed: [servera]
    TASK [debug] ************************************************************************************************************************************************
    ok: [servera] => {
        "msg": "hello\nworld"
    }
    TASK [shell] ************************************************************************************************************************************************
    changed: [servera]
    TASK [debug] ************************************************************************************************************************************************
    ok: [servera] => {
        "msg": "-e \"hello\\nworld\""
    }
    PLAY RECAP **************************************************************************************************************************************************
    servera                    : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
    $ cat quote.yaml
    ---
    - name: debug play
      hosts: servera
      vars:
        st: -e "hello\nworld"
      tasks:
              - shell: echo {{ st }}
                register: resout
              - debug: msg={{ resout.stdout }}
              - shell: echo {{ st | quote }}
                register: resout
              - debug: msg={{ resout.stdout }}
    $
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    通过这个Demo我们可以看到,没有使用quote过滤器处理的字符串被当作了命令行参数处理

    其他过滤器

    basename过滤器,获取一个文件的绝对路径,例如将foo.txt转换为/etc/asdf/foo.txt。

    $ ansible servera -m debug -a "msg={{ '/etc/sysconfig/network' | basename }}"
    servera | SUCCESS => {
        "msg": "network"
    }
    
    • 1
    • 2
    • 3
    • 4

    dirname过滤器,获取一个文件或目录的上级目录。

    $ ansible servera -m debug -a "msg={{ '/etc/sysconfig/network' | dirname}}"
    servera | SUCCESS => {
        "msg": "/etc/sysconfig"
    }
    $
    
    • 1
    • 2
    • 3
    • 4
    • 5

    to_uuid过滤器,根据一个字符串生成一个UUID。可以看到这里的UUID和时间没有关系,只和种子有关

    $ ansible servera -m debug -a "msg={{ 'liruilong' | to_uuid }}"
    servera | SUCCESS => {
        "msg": "1745726b-5a9a-592e-833b-3a2d9b2f0922"
    }
    $ ansible servera -m debug -a "msg={{ 'liruilong' | to_uuid }}"
    servera | SUCCESS => {
        "msg": "1745726b-5a9a-592e-833b-3a2d9b2f0922"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    comment过滤器,可以实现注释字符串的功能,默认为#注释。

    $ ansible servera -m debug -a "msg={{ 'liruilong' | comment }}"
    servera | SUCCESS => {
        "msg": "#\n# liruilong\n#"
    }
    
    • 1
    • 2
    • 3
    • 4

    关于过滤器就和小伙伴们分享到这里

    博文参考


    《Red Hat Ansible Engine 2.8 DO447》

  • 相关阅读:
    Haddop+Hive 单机hadoop 单机hive
    uniapp中实现H5录音和上传、实时语音识别(兼容App小程序)和波形可视化
    Qt编译MySQL数据库驱动
    quartz框架(六)-ThreadPool
    演讲实录:大模型时代,我们需要什么样的AI算力系统?
    1700. 无法吃午餐的学生数量
    mysql之两段提交
    【Java配置文件】properties文件乱码解决
    Foxmail 服务器的超大附件服务无效的解决方案
    文件恢复软件哪个最好用?数据恢复软件,推荐这几款
  • 原文地址:https://blog.csdn.net/sanhewuyang/article/details/126793714