[Ansible系列]ansible JinJia2过滤器

目录

一.  JinJia2简介

二.  JinJia2模板使用 

2.1  在play中使用jinjia2

2.2  template模块使用

2.3   jinjia2条件语句

2.4  jinjia2循环语句

2.5   jinjia2过滤器

2.5.1   default过滤器

2.5.2  字符串操作相关过滤器 

 2.5.3  数字操作相关过滤器

2.5.4  列表操作相关过滤器 

2.5.5   应用于文件的过滤器

2.5.6  应用于注册变量的过滤器 


一.  JinJia2简介

         Jinja2是基于python的模板引擎。那么什么是模板?

假设说现在我们需要一次性在10台主机上安装redis,这个通过playbook现在已经很容易实现。默认 情况下,所有的redis安装完成之后,我们可以统一为其分发配置文件。这个时候就面临一个问题,这 些redis需要监听的地址各不相同,我们也不可能为每一个redis单独写一个配置文件。因为这些配置 文件中,绝大部分的配置其实都是相同的。这个时候最好的方式其实就是用一个通用的配置文件来解 决所有的问题。将所有需要修改的地方使用变量替换。这个通用的配置文件就是模板。

二.  JinJia2模板使用 

2.1  在play中使用jinjia2

         以上面的redis为例,我们创建一个redis的模板,模板如下:

[root@clinet ~]# cat /etc/redis.conf |grep -v ^# |grep -v ^$
bind {{ ansible_eth0.ipv4.address }} 127.0.0.1
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes

现在我们有了一个模板文件,那么在playbook中如何来使用呢? playbook使用template模块来实现模板文件的分发,其用法与copy模块基本相同,唯一的区别是, copy模块会将原文件原封不动的复制到被控端,而template会将原文件复制到被控端,并且使用变 量的值将文件中的变量替换以生成完整的配置文件。

playbook示例:

[root@clinet yum_file]# cat jinjia2/install_redis.yml 
- hosts: test
  
  tasks:
    - name: configure redis max memory
      set_fact:
        redis_mem: "{{ (ansible_memtotal_mb /2) | int }}M"

    - name: debug memeory 
      debug:
        msg: 
          - '{{ redis_mem }}'

    - name: install redis 
      package:
        name: redis
        state: present

    - name: configure redis.conf
      template:
        src: /root/ansible_test/ansible_2/template/redis.conf.j2
        dest: /etc/redis.conf
      notify:
        - restart redis

    - name: start redis
      service:
        name: redis
        state: started
        enabled: yes
  handlers:
    - name: restart redis
      service:
        name: redis
        state: restarted
[root@clinet yum_file]# 

2.2  template模块使用

         template模块会将原文件复制到被控端,并且使用变 量的值将文件中的变量替换以生成完整的配置文件。

关于template模块的更多参数说明:

·  backup:如果原目标文件存在,则先备份目标文件

·  dest:目标文件路径

·  force:是否强制覆盖,默认为yes

·  group:目标文件属组

·  mode:目标文件的权限

·  owner:目标文件属主

·  src:源模板文件路径

·  validate:在复制之前通过命令验证目标文件,如果验证通过则复制

2.3   jinjia2条件语句

         在上面的示例中,我们直接取了被控节点的ens33网卡的ip作为其监听地址。那么假如有些机器的网卡绑定的,那么网络连接时是bond0,这种做法就会报错。这个时候我们就需要在模板文件中定义条件语句如下:

{% if ansbile_bond is defined %}
bind {{ ansible_bond.ipv4.address }} 127.0.0.1
{% elif ansible_bond is defined % }
bind {{ ansible_ens33.ipv4.address }} 127.0.0.1
{% else %}
bind 0.0.0.0
{% endif %}

maxmemory {{ redis_mem }}
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
save 900 1
save 300 10
save 60 10000

利用条件语句进一步配置redis主从模式:

{% if ansbile_bond is defined %}
bind {{ ansible_bond.ipv4.address }} 127.0.0.1
{% elif ansible_ens33 is defined %}
bind {{ ansible_ens33.ipv4.address }} 127.0.0.1
{% else %}
bind 0.0.0.0
{% endif %}

{% if master_ip is defined %}
slaveof {{ master_ip }} {{ masterport | default(6379) }}
{% endif %}

{% if masterpass is defined %}
masterauth {{ masterpass }}
{% endif %}

{% if requirepass is defined %}
requirepass {{ requirepass }}
{% endif %}

maxmemory {{ redis_mem }}
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes

注意:

1.  redis主从配置只需要在slave上配置slaveof  ip  port(master节点不需要任何配置)

2.  注意防火墙

2.4  jinjia2循环语句

         以nginx做负载均能,代理到后端httpd的基础实验为例,展示基础的for循环使用。

inventory配置如下:

[proxy]
192.168.194.132

[webserver]
192.168.194.130
192.168.194.131
[root@clinet ansible_2]# 

 playbook如下:

- hosts: proxy:webserver
  gather_facts: yes

  pre_tasks:
    - name: fireword.server
      service:
        name: firewalld
        state: stopped
        enabled: no

  post_tasks:
    - name: message info
      debug:
        msg: 'this playbook finished'

  tasks:
    - name: install & configure ngxin block
      block:
        - name: install nginx
          package:
            name: nginx
            state: present

        - name: configure nginx.conf
          template:
            src: /root/ansible_test/ansible_2/template/nginx.conf.j2
            dest: /etc/nginx/nginx.conf
            backup: yes
          notify: restart nginx

        - name: start ngixn
          service:
            name: nginx
            state: started
            enabled: yes
      when: ansible_ens33.ipv4.address in groups['proxy']

    - name: install & configure httpd block
      block:
        - name: install httpd
          package:
            name: httpd
            state: present

        - name: confgure http.conf
          template:
            src: /root/ansible_test/ansible_2/template/index.html.j2
            dest: /var/www/html/index.html
            backup: yes
          notify: restart httpd

        - name: start httpd
          service:
            name: httpd
            state: started
            enabled: yes
      when: ansible_ens33.ipv4.address in groups['webserver']

  handlers:
    - name: restart nginx
      service:
        name: nginx
        state: restarted

    - name: restart httpd
      service:
        name: httpd
        state: restarted

 总结一:
上述示例中回顾了以下知识点:

1.  pre_tasks 是在tasks之前执行;而 post_tasks 则在tasks和handlers之后执行;

2.  when关键字,playbook中的条件语句

3.  hosts:  proxy:webserver,ansible的主机匹配规则

4.  block和when的配合使用,对整块block语句做判断。等等

总结二:

jinjia2模板中的语法总结:

1.  变量的使用: {{ 变量名 }}  (不需要用引号包裹,与playbook中的变量使用的主要区别)

2.  条件语句:
     {% if %}  ...  {% elif %} ... {% else %} ... {% endif %}

3.  循环语句:
     {% for %}  ... {% endfor %}
(注意:{%%} 是jinjia2模板的语法格式)

2.5   jinjia2过滤器

2.5.1   default过滤器

         当指定的变量不存在时,用于设定默认值

 示例:

‐ hosts: test
  gather_facts: false
  vars:
    ‐ path: /tmp/test
      mode: 0400
    ‐ path: /tmp/foo
    ‐ path: /tmp/bar

  tasks:
    ‐ file:
        path: {{ item.path }}
        state: touch
        mode: {{ item.mode|default(omit)}}
      with_items: "{{ paths }}"

omit表示系统默认的,也可以default(777),当变量不存在的时候,使用777为值。

2.5.2  字符串操作相关过滤器 

·  upper:将所有字符串转换为大写

·  lower:将所有字符串转换为小写

·  capitalize:将字符串的首字母大写,其他字母小写

·  reverse:将字符串倒序排列

·  first:返回字符串的第一个字符

·  last:返回字符串的最后一个字符

·  trim:将字符串开头和结尾的空格去掉

·  center(30):将字符串放在中间,并且字符串两边用空格补齐30位

·  length:返回字符串的长度,与count等价

·  list:将字符串转换为列表

·  shuffle:list将字符串转换为列表,但是顺序排列,shuffle同样将字符串转换为列表,但是会随 机打乱字符串顺序

‐ hosts: test
  gather_facts: no
  vars:
    teststr: "abc123ABC"
    teststr1: " abc "
    teststr2: "123456789"
    teststr3: "sfacb1335@#$%"

  tasks:
    ‐ debug:
        msg: "{{ teststr | upper }}"
    ‐ debug:
        msg: "{{ teststr | lower }}"
    ‐ debug:
        msg: "{{ teststr | capitalize }}"
    ‐ debug:
        msg: "{{ teststr | reverse }}"
    ‐ debug:
        msg: "{{ teststr|first }}"
    ‐ debug:
        msg: "{{ teststr|last }}"
    ‐ debug:
        msg: "{{ teststr1 | trim }}"
    ‐ debug:
        msg: "{{ teststr2 | center(30) }}"
    ‐ debug:
        msg: "{{ teststr2 | length }}"
    ‐ debug:
        msg: "{{ teststr3 | list }}"
    ‐ debug:
        msg: "{{ teststr3 | shuffle }}"

 2.5.3  数字操作相关过滤器

·  int: 将对应的值转换为整数

·  float:将对应的值转换为浮点数

·  abs:获取绝对值

·  round:小数点四舍五入

·  random:从一个给定的范围中获取随机值

‐ hosts: test
  gather_facts: no
  vars:
    testnum: ‐1

  tasks:
    ‐ debug:
        msg: "{{ 8+('8'|int) }}"
    ‐ debug:
    # 默认情况下,如果无法完成数字转换则返回0
    # 这里指定如果无法完成数字转换则返回6
        msg: "{{ 'a'|int(default=6) }}"
    ‐ debug:
        msg: "{{ '8'|float }}"
    ‐ debug:
        msg: "{{ 'a'|float(8.88)' }}"
    ‐ debug:
        msg: "{{ testnum|abs }}"
    ‐ debug:
        msg: "{{ 12.5|round }}"
    ‐ debug:
        msg: "{{ 3.1415926 | round(5) }}"
    ‐ debug:
    # 从0到100中随机返回一个数字
        msg: "{{ 100|random }}"
    ‐ debug:
    # 从5到10中随机返回一个数字
        msg: "{{ 10|random(start=5) }}"
    ‐ debug:
    # 从4到15中随机返回一个数字,步长为3
    # 返回的随机数只可能是:4,7,10,13中的一个
        msg: "{{ 15|random(start=4,step=3) }}"
    ‐ debug:
    # 从0到15随机返回一个数字,步长为4
        msg: "{{ 15|random(step=4) }}"

2.5.4  列表操作相关过滤器 

·  length: 返回列表长度

·  first:返回列表的第一个值

·  last:返回列表的最后一个值

·  min:返回列表中最小的值

·  max:返回列表中最大的值

·  sort:重新排列列表,默认为升序排列,sort(reverse=true)为降序

·  sum:返回纯数字非嵌套列表中所有数字的和

·  flatten:如果列表中包含列表,则flatten可拉平嵌套的列表,levels参数可用于指定被拉平的层级

·  join:将列表中的元素合并为一个字符串

·  random:从列表中随机返回一个元素

·  shuffle

·  upper

·  lower

·  union:将两个列表合并,如果元素有重复,则只留下一个

·  intersect:获取两个列表的交集

·  difference:获取存在于第一个列表中,但不存在于第二个列表中的元素 ·  symmetric_difference:取出两个列表中各自独立的元素,如果重复则只留一个

2.5.5   应用于文件的过滤器

·  basename:返回文件路径中的文件名部分

·  dirname:返回文件路径中的目录部分

·  expanduser:将文件路径中的~替换为用户目录

·  realpath:处理符号链接后的文件实际路径

2.5.6  应用于注册变量的过滤器 

         正常情况下,当某个task执行失败的时候,ansible会中止运行。此时我们可以通过 ignore_errors 来 捕获异常以让task继续往下执行。然后调用debug模块打印出出错时的内容,拿来错误结果后,主动 失败。

‐ name: Run myprog
  command: /opt/myprog
  register: result
  ignore_errors: True
‐ debug:
    var: result

‐ debug:
    msg: "Stop running the playbook if myprog failed"
  failed_when: result|failed

任务返回值过滤器:

·  failed: 如果注册变量的值是任务failed则返回True

·  changed: 如果注册变量的值是任务changed则返回True

·  success:如果注册变量的值是任务succeeded则返回True

·  skipped:如果注册变量的值是任务skipped则返回True


 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: Ansible 过滤器Filter)是一种基于 Jinja2 模板引擎的功能,用于在 Ansible playbook 中对变量进行处理和转换。过滤器可以对变量进行格式化、切分、合并等操作,也可以进行比较、排序、求和等统计计算。 Ansible 过滤器语法为:`{{ variable | filter1 | filter2 | ... }}`,其中 `variable` 是需要处理的变量,`filter1`、`filter2` 等是要应用的过滤器。 例如,可以使用 `| length` 过滤器来获取某个变量的长度: ``` {{ my_var | length }} ``` 还可以使用 `| default` 过滤器来设置默认值: ``` {{ my_var | default('default_value') }} ``` 此外,Ansible 还提供了许多其他过滤器,如 `| upper`、`| lower`、`| join`、`| map` 等等,可以根据不同的需求进行使用。 ### 回答2: Ansible过滤器是一种功能强大的工具,用于在Ansible playbooks和任务中对数据进行处理和转换。过滤器可以用于对变量、注册的变量和模板的输出结果进行修改,以满足特定需求。 过滤器是以“|”字符表示的,紧随其后的是过滤器的名称和参数。过滤器可以用于对数据进行排序、格式化、截取等各种操作。常用的过滤器有grep、match和join等。 grep过滤器用于从列表中选择指定的元素,可以通过正则表达式或通配符来匹配。可以使用该过滤器从主机清单中提取特定的组或主机,或从变量列表中选择某些元素。 match过滤器用于比较字符串,可以根据提供的模式匹配字符串,并返回匹配的结果。这可以用于对变量值进行验证,或在条件判断中使用。 join过滤器用于将列表中的元素连接成一个单独的字符串,可以指定连接符号。这对于生成复杂的命令行参数或组合配置文件路径非常有用。 除了内置的过滤器外,还可以自定义自己的过滤器。自定义过滤器需要使用Python编写,然后将其加载到Ansible中。这样就可以根据自己的需求添加特定的过滤器,对数据执行任何想要的操作。 总之,Ansible过滤器是处理和转换数据的有用工具。它们可以帮助用户快速有效地对变量和其他数据进行操作,以满足特定的要求。无论是在playbooks中还是在任务中使用,使用过滤器都可以提高Ansible的灵活性和功能性。 ### 回答3: Ansible 过滤器是用于修改变量值、格式化输出以及对数据进行处理的工具。它们提供了一种简便的方式来处理变量和数据,帮助用户更灵活地控制剧本的执行和输出结果的格式。 Ansible 过滤器可以在模板和剧本中使用。使用过滤器时,可以对变量值进行各种操作,如截取字符串、转换大小写、格式化日期等。这些过滤器可以通过管道(|)符号与变量名结合使用,添加到模板或剧本的变量中。 例如,我们可以使用过滤器 `upper` 将一个变量的值转换为大写字母,将 `my_variable` 变量的值转换为大写字母后输出: ``` {{ my_variable | upper }} ``` 除了转换大小写,还有很多其他实用的过滤器可供使用。例如,`default` 过滤器可以设置默认值,如果变量不存在或为空,则返回默认值。`length` 过滤器可以用于获取变量的长度,`replace` 过滤器可以替换字符串中的某些部分。 Ansible 过滤器还可以通过参数进行更多的操作。例如,`strftime` 过滤器可以根据指定的格式将日期转换为字符串,参数就是转换的格式。还有一些过滤器需要通过正则表达式来匹配和处理文本。 总的来说,Ansible 过滤器提供了一种强大的机制来处理数据和变量,使我们能够在模板和剧本中更加灵活地操作和处理数据。通过合理地使用过滤器,我们可以提高剧本的可读性和可维护性,并得到我们期望的输出结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小肖同学..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值