ansible学习笔记04(最佳实践)

时间:2022-10-18 09:58:58

使用过滤和插件转换数据

1、 使用过滤器处理变量

1.1 ansible filter

ansible应用变量到playbook并且使用jinja2表达式来使用变量。例如下面的J2表达式中的变量使用两个大括号括起来。

J2表达式也支持filter。Filter在playbook或者模板中被用来修改或者处理要替代的变量值。一些filter使用J2语言来使用,其他的一些filter被包含在ansible的插件中。它也可以创建自定义的filter,尽管这超出了本课程的范围。filter在playbook中或者template用于准备使用的数据是非常有用的。

# ansible 表达变量
{{ var }}

1.2 变量类型

ansible将运行时数据存储在变量中,YAML结构或值的内容定义了确切的数据类型,一些值的类型包括:

变量类型 说明
String 字符串
Number 数字
Booleans 布尔值(与或非)
Dates 日期
Null
Lists 或 Arrays 列表或变量矩阵
Dictionaries 字典

1.2.1 String

  • String是一串字符序列,是ansible的默认数据类型,String类型数据不需要使用单引号或者双引号扩起来。
my_string: Those are the contents of the string
  • yaml语言支持使用|或 > 符号对字符串进行格式化输出。
格式化符号 说明
换行输出
> 不换行输出
# 对字符串进行换行输出
string_with_breaks: |
  this string
  has serveral
  line breaks

# 对字符串不换行输出
string_without_breaks: >
  this string will not
  contain any line breaks.
  Separated lines are joined
  by a space character.

1.2.2 Numbers

通过给变量赋值,ansible会自动识别出数字类型,并根据赋值情况确定数字类型。

# 整型Integer
answer: 10

# 浮点型Float
float_answer: 10.5

# 科学计数法整型/浮点型
scientific_answer: 0.4e+2

# 十六进制
hex_answer: 0x2A

# 非数字类型,使用双引号ansible会识别成字符串
string_not_number: "20"

1.2.3 Booleans

布尔值可以作为判断条件

布尔值 含义
yes、y、on、true
no、n、off、false

1.2.4 Date

日期类型准讯ISO-8610标准,ansible变量可以接受日期类型的值

my_date_time: 2019-05-30T21:15:32.42+02:00

my_simple_date: 2019-05-30

1.2.5 Null

可以给变量赋值为空,使用null或者~进行赋值

my_undefined1: null
my_nudefined2: ~

1.2.6 List 或 Arrays

列表或者数组是数据收集和循环的基本结构

# 列表定义方式1,不推荐
my_list: ['xiaoming','xiaohong','xiaobai']

# 列表定义方式2,推荐
my_list:
  - xiaoming
  - xiaohong
  - xiaobai
# 可以通过列表名 + 下标快速索引
- name: confirm that the second list element is "xiaoming"
  assert:
    that:
      - my_list[0] == 'xiaoming'

1.2.7 Dictionaries

字典也称为maps或hashes列,是链接字符串的结构,通常有key:values组成。字典可以写成一行或者多行,也支持通过键访问值。

# 字典定义方式1,不推荐
my_dict: { Douglas: Human, Marvin: Robot, Arthur: Human}

# 字典定义方式2,推荐
my_dict:
  Douglas: Human
  Marvin: Robot
  Arthur: Human
# 可以通过列表名 + 键名快速索引
- name: identiry Marvin
  assert:
    that:
      - my_dict['Marvin'] == 'Robot'

1.3 filter处理数据

filter允许你处理变量中的值以提取信息,转换或使用它来产生一个新的值,要使用filter,需要在变量后加入一个管道符(|),管道符后写filter过滤器名称。你可以一次性使用多个filter对数据进行处理。

1.3.1 过滤器特性

  • capitalize这个filter作用时确保首字母大写,通过Jinja2格式可以通过如下方式定义:
{{ myname | capitalize }}
  • string可以将变量转成字符串,通过Jinja2格式可以通过如下方式定义:
{{ munumber | string }}
  • unique可以去掉重复元素,sort可以对数据进行排序
  • 可以使用连续管道符对变量进行多次处理
- name: test to see if the assertion is true, fail if not
  assert:
    that:
      - "{{ [1,4,2,2] | unique | sort }} is eq( [1,2,4] )"

1.3.2 对过滤器特性进行测试

# 将3个特性写在一个playbook中进行测试
[workstation task-review (master *)]# cat test_fileter.yml 
---
- name: test filter
  hosts: servera.lab.example.com
  vars:
    var1: test1
    var2: 123
  tasks:
    - name: test capitalize
      debug:
        msg: "{{ var1 | capitalize }}"

    - name: test string filter
      debug:
        msg: "{{ var2 | string }}"

    - name: test unique and sort filter
      debug:
        msg: "{{ [1,4,2,2] | unique | sort }}"
[workstation task-review (master *)]# ansible-playbook test_fileter.yml 

PLAY [test filter] *************************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************************
ok: [servera.lab.example.com]

TASK [test capitalize] *********************************************************************************************************************************
ok: [servera.lab.example.com] => {
    "msg": "Test1"
}

TASK [test string filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
    "msg": "123"
}

TASK [test unique and sort filter] *********************************************************************************************************************
ok: [servera.lab.example.com] => {
    "msg": [
        1,
        2,
        4
    ]
}

PLAY RECAP *********************************************************************************************************************************************
servera.lab.example.com    : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

1.4 filter描述

ansible存在大量的filter过滤器,包括在Jinja2和RHEL提供的额外的过滤器。如果要查询这些过滤器,请参考:

  • http://jinja.pocoo.org/docs/2.10/templates/#builtinfilters
  • https://jinja.palletsprojects.com/en/3.0.x/templates/

ansible学习笔记04(最佳实践)

1.4.1 检查变量是否定义

通过使用两个Ansible-specific filter过滤器,可以检查变量是否定义

  • mandatory

判断变量是否被赋值,如果变量没被赋值,则失败或终止

# 定义格式
{{ my_value | mandatory }}
# 提示:在生产环境中,一定要使用mandatory指定特定的版本,不要使用缺省值!!!
# 如果变量未被定义,报错如下
fatal: [servera.lab.example.com]: FAILED! => {"msg": "Mandatory variable 'var2'  not defined."}
  • default

判断变量是否被赋值,如果变量没有赋值,则赋予一个缺省的值

# 定义格式
# 如果my_value未被赋值,则使用缺省值“my_default”
{{ my_value | default(my_default, True )}}

default filter也可以使用omit作为缺省值,如果使用了该缺省值,一旦变量未赋值,将会用“hello world”作为替代

# default filter参数使用omit作为赋值参数
"{{ var2 | default(omit) }}"

1.4.2 mandatory和default测试

[workstation task-tagging (master *)]# cat useful_filter1.yml 
---
- name: check if the var exist
  hosts: servera.lab.example.com
  vars:
    var1: test
  tasks: 
    - name: use default filter
      debug:
        msg: "{{ var1 | mandatory }}"
        
    - name: use defualt filter
      debug:
        msg: "{{ var2 | mandatory }}"
      tags:
        - mandatory
          
    - name: use default filter
      debug:
        msg: "{{ var1 | default('var1 is not exist') }}"
              
    - name: use default filter
      debug:
        msg: "{{ var1 | default('var1 is not exist', true)}}"
              
    - name: use default filter
      debug:
        msg: "{{ var2 | default('var1 is not exist') }}"
              
    - name: use default filter
      debug:
        msg: "{{ var2 | default('var1 is not exist', true)}}"
              
    - name: use default filter
      debug:
        msg: "{{ var1 | default(omit) }}"
              
    - name: use default filter
      debug:
        msg: "{{ var2 | default(omit) }}"
[workstation task-tagging (master *)]# ansible-playbook useful_filter1.yml 

PLAY [check if the var exist] **************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************************
ok: [servera.lab.example.com]

TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
    "msg": "test"
}

TASK [use defualt filter] ******************************************************************************************************************************
fatal: [servera.lab.example.com]: FAILED! => {"msg": "Mandatory variable 'var2'  not defined."}

PLAY RECAP *********************************************************************************************************************************************
servera.lab.example.com    : ok=2    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

[workstation task-tagging (master *)]# ansible-playbook useful_filter1.yml --skip-tags mandatory

PLAY [check if the var exist] **************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************************
ok: [servera.lab.example.com]

TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
    "msg": "test"
}

TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
    "msg": "test"
}

TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
    "msg": "test"
}

TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
    "msg": "var1 is not exist"
}

TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
    "msg": "var1 is not exist"
}

TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
    "msg": "test"
}

TASK [use default filter] ******************************************************************************************************************************
ok: [servera.lab.example.com] => {
    "msg": "Hello world!"
}

PLAY RECAP *********************************************************************************************************************************************
servera.lab.example.com    : ok=8    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

1.5 执行数学计算