自动化运维工具-Ansible之6-Jinja2模板

时间:2021-04-29 20:32:52

自动化运维工具-Ansible之6-Jinja2模板

Ansible Jinja2模板概述

Jinja2是基于python的模板引擎,功能比较类似于PHP的smarty,J2ee的Freemarker和velocity。它能完全支持unicode,并具有集成的沙箱执行环境,应用广泛。jinja2使用BSD授权。

Ansible通常会使用jinja2模板来修改被管理主机的配置文件等。在saltstack中同样会使用到jinja2。


使用Ansible的jinja2模板也就是使用template模块。

template模块和copy模块一样,都是将文件复制到远端主机上去,但是区别在于,template模块可以获取到文件中的变量,而copy则是原封不动的把文件内容复制过去。列如我们在推送rsync的backup脚本时,想把脚本中的变量{{ ansible_fqdn }}改成主机名,如果使用copy模块则推送过去的就是{{ ansible_fqdn }},不变,如果使用template,则会变成对应的主机名。

注意:Ansible允许jinja2模板中使用条件判断和循环,但是不允许在playbook中使用。不是每个管理员都需要这个特性,但是有些时候jinja2模块能大大提高效率。

Ansible Jinja2模板使用

Jinja2的语法是由variables(变量)和statement(语句)组成,如下

  1. variables:输出自定义或facts的变量值

{{ custom_variables | facts_variables }}

  1. statements: 可以用来创建条件和循环等
# 循环表达式
{% for i in EXPR %}
{% endfor %} # 条件判断
{% if EXPR %}
{% elif EXPR %}
{% else %}
{% ednif %} # 注释
{# COMMENT #}

Jinja2使用方法

  1. playbook文件,使用template模块
  2. 模板文件,使用变量{{名称}},比如{{PORT}}或使用facts

Ansible使用jinja2模板使用facts变量渲染出登录欢迎词配置文件,并推送到主机

  1. 编辑playbook
[root@m01 ~]# cat > /root/test/jinja2.yml <<EOF
- hosts: web_group
tasks:
- name: Copy Template File
template:
src: ./motd.j2
dest: /etc/motd
EOF
  1. 准备motd.j2文件
[root@m01 ~]# cat > /root/test/motd.j2 <<EOF
Welcome to {{ ansible_fqdn }}
This system total mem is : {{ ansible_memtotal_mb }} MB
This system free mem is: {{ ansible_memfree_mb }} MB
EOF
  1. 执行playbook
[root@m01 ~]# ansible-playbook test/jinja2.yml

PLAY [web_group] *****************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [web02]
ok: [web01] TASK [Copy Template File] ********************************************************************************************************************************************************************************************************************
changed: [web01]
changed: [web02] PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
web01 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
web02 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
  1. 查看结果
[root@m01 ~]# ansible web_group -a 'cat /etc/motd'
web01 | CHANGED | rc=0 >>
Welcome to web01
This system total mem is : 1982 MB
This system free mem is: 1106 MB web02 | CHANGED | rc=0 >>
Welcome to web02
This system total mem is : 1982 MB
This system free mem is: 1096 MB

Ansible Jinja2管理nginx

Ansible使用jinja2的for循环表达式渲染出nginx作负载均衡的配置文件,并推送到lb主机上。


准备nginx配置文件

[root@m01 ~]# cat > /root/test/www.oldboy.com.conf.j2 <<EOF
upstream {{ server_name }} {
{% for n in range(5,6) %}
server 172.16.1.{{ n }}:{{ upstream_port }};
{% endfor %}
} server {
listen 80;
server_name {{ server_name }}; location / {
root /code;
index index.html;
proxy_pass http://{{ server_name }};
proxy_set_header Host $http_host;
}
}
EOF

编辑playbook推送文件并重载nginx

[root@m01 ~]# cat > /root/test/lb.yml <<EOF
- hosts: lb_group
vars:
upstream_port: 80
server_name: www.oldboy.com
tasks:
- name: copy
template:
src: ./www.oldboy.com.conf.j2
dest: /etc/nginx/conf.d/www.oldboy.com.conf
notify: reload nginx handlers:
- name: reload nginx
systemd:
name: nginx
state: reloaded
EOF

Ansible Jinja2管理keepalived

ansible使用jinja2模板的if判断表达式渲染出keepalived高可用配置文件,并推送到lb主机上。


根据keepalived原配置文件

# keepalived master 配置文件
global_defs {
router_id lb01
} vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 50
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
} # keepalived backup配置文件
global_defs {
router_id lb02
} vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 50
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
}

准备keepalived配置文件

[root@m01 ~]# cat > /root/test/keepalived.j2 <<EOF
global_defs {
router_id {{ ansible_fqdn }}
} vrrp_instance VI_1 {
{% if ansible_fqdn == "lb01" %}
state MASTER
priority 150
{% else %}
state BACKUP
priority 100
{% endif %} interface eth0
virtual_router_id 50
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.3
}
}
EOF

编辑playbook推送keepalived配置文件并重启restarted

[root@m01 ~]# cat > /root/test/keepalived.yml <<EOF
- hosts: lb_group
tasks:
- name: copy file
template:
src: ./keepalived.j2
dest: /etc/keepalived/keepalived.conf
notify: restart keepalived handlers:
- name: restart keepalived
systemd:
name: keepalived
state: restarted
EOF