首页 > 技术文章 > Ansible Jinja2 模板

wuqiuyin 2021-09-03 15:28 原文

一、jinja2模板概述

#什么是jinja2模板
jinja2是Python的全功能模板引擎
 
#Jinja2与Ansible啥关系
Ansible通常会使用jinja2模板来修改被管理主机的配置文件等...在saltstack中同样会使用到jinja2
如果在100台主机上安装redis,每台redis的监听地址都不一样,如何解决?
 
#Ansible如何使用Jinja2
使用Ansible的jinja2模板也就是使用template模块,该模块和copy模块一样,都是将文件复制到远端主机上去,但是区别在于,template模块可以获取到文件中的变量,而copy则是原封不动的把文件内容复制过去。之前我们在推送rsync的backup脚本时,想把脚本中的变量名改成主机名,如果使用copy模块则推送过去的就是{{ ansible_fqdn }},不变,如果使用template,则会变成对应的主机名。
 
#Ansible使用Jinja2注意事项
Ansible允许jinja2模板中使用条件判断和循环,但是不允许在playbook中使用。
注意:不是每个管理员都需要这个特性,但是有些时候jinja2模块能大大提高效率。

二、Ansible Jinja2 模板使用

1.变量使用语法

{{ EXPR }} 输出变量值,会输出自定义的变量值或facts
1.playbook文件使用template模块
2.模板文件里面变量使用 {{ 名称 }},比如 {{ PORT }} 或使用facts
例
- hosts: web
      tasks:
        - name: 使用模板
          template:
            src: ./test.conf     # ansible主机上的需要同步的路径
            dest: /root/
# ./tast.conf 写入变量。如主机ip: {{ ansible_eth0.ipv4.address }}

2.Jinja2模板逻辑判断语法

#shell中的判断语法
[root@m01 project]# vim pd.sh 
#!/bin/bash
age=$1
if [ $age -lt 18 ];then
    echo "小姐姐"
else
    echo "大妈"
fi
 
#Jinja2模板判断语法
#条件判断
{% if EXPR %}
{% elif EXPR %}
{% else %}
{% endif %}

例
global_defs {
    router_id {{ ansible_nodename}}
}
vrrp_script check {
    script "/etc/keepalived/check_web.sh"
    interval 5
}
vrrp_instance VI_1 {
{% if ansible_nodename == 'lb01' %}
    state MASTER
{% else %}
    state BACKUP
{% endif %}
    nopreempt
    interface eth0
    virtual_router_id 50
{% if ansible_nodename == 'lb01' %}
    priority 100
{% elif ansible_nodename == 'lb02' %}
    priority 90
{% else %}
    priority 80
{% endif %}
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.214.100
    }
    track_script {
    check
    }  
}

3.Jinja2模板循环语法

#shell中的循环
[root@m01 project]# vim xh.sh
#!/bin/bash
for i in `seq 10`
  do
      echo $i
  done
 
#Jinja2模板循环语法
#循环表达式
{% for i in EXPR %}
{% endfor %}

例
upstream web {
{% for i in range(7,30)  %}
	server 172.16.1.{{ i }};
{% endfor %}
}
server {
	listen 80;
	server_name discuz.test.com;
	location / {
		proxy_pass http://web;
		include proxy_params;
	}
}

4.注释

#shell中的注释
使用 # 写在注释内容最前面
 
#Jinja2模板注释语法
{# COMMENT #}

三、jinja2模板测试

1.实例一

1)配置登陆文件的 jinja2 模板

[root@m01 project]# vim motd.j2
Welcome to {{ ansible_fqdn }}
This system total mem is : {{ ansible_memtotal_mb }} MB
This system free mem is: {{ ansible_memfree_mb }} MB

2)编写剧本

[root@m01 project]# vim motd.yml
- hosts: all
  tasks:
    - name: Config motd
      template:
        src: ./motd.j2
        dest: /etc/motd

3)执行并查看结果

[root@m01 project]# ansible-playbook motd.yml
 
#查看结果
Connecting to 10.0.0.51:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
 
Last login: Thu Dec 24 15:29:37 2020 from 10.0.0.61
Welcome to db01
This system total mem is : 972 MB
This system free mem is: 267 MB
[root@db01 ~]# 

2.实例二

1)配置数据库配置文件

[root@m01 project]# vim /etc/my.cnf
innodb_buffer_pool_size = {{ ansible_memtotal_mb * 0.8 }}M

2)编写剧本

[root@m01 project]# cat my.yml 
- hosts: db01
  tasks:
    - name: Config Mariadb
      template:
        src: /etc/my.cnf
        dest: /etc/

3)执行并查看

[root@m01 project]# ansible-playbook my.yml 
 
#检查
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
innodb_buffer_pool_size = 777.6M

4)jinja2模板修改

[root@m01 project]# vim /etc/my.cnf
 
[mysqld]
 
{% if ansible_memtotal_mb == 972 %}
innodb_buffer_pool_size = 800M
{% elif ansible_memtotal_mb == 1980 %}
innodb_buffer_pool_size = 1600M
{% endif %}

5)再次执行查看

#查看服务器
    1.如果服务器内存是 972M,则配置为  innodb_buffer_pool_size = 800M
    2.如果服务器内存是 1980M,则配置为  innodb_buffer_pool_size = 1600M

3.实例三:使用jinja2模板配置nginx负载均衡

0)先给负载均衡安装nginx

1)准备负载均衡配置文件

#正常的配置文件
[root@m01 project]# vim conf/upstream.conf
upstream web {
    server 172.16.1.7;
    server 172.16.1.8;
}
 
server {
    listen 80;
    server_name linux.wp.com;
 
    location / {
        proxy_pass http://web;
        proxy_set_header Host $http_host;
    }
}
 
#不正经的配置文件
[root@m01 project]# vim conf/upstream.j2
upstream {{ server_name }} {
{% for i in range(7,20) %}
    server {{ net_ip }}.{{ i }};
{% endfor %}
}
 
server {
    listen {{ web_port }};
    server_name {{ server_name }};
 
    location / {
        proxy_pass http://{{ server_name }};
        proxy_set_header Host $http_host;
    }
}

2)配置变量文件

[root@m01 project]# vim upstream_vars.yml
server_name: linux.wp.com
web_port: 80
net_ip: 172.16.1

3)编写剧本

[root@m01 project]# vim lb.yml
- hosts: lb_server
  vars_files: ./upstream_vars.yml
  tasks:
    - name: Config Nginx Upstream
      template:
        src: conf/upstream.j2
        dest: /etc/nginx/conf.d/upstream.conf
      notify: restert_upstream
 
    - name: Start Nginx Server
      systemd:
        name: nginx
        state: started
 
  handlers:
    - name: restert_upstream
      systemd:
        name: nginx
        state: restarted

4)执行并测试

[root@m01 project]# ansible-playbook lb.yml

4.实例四:使用jinja2模板配置keepalived

1)准备keepalived配置文件

#正经的配置文件
[root@m01 project]# vim conf/keepalived.conf
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
    }
}
 
#不正经的配置文件
[root@m01 project]# vim conf/keepalived.conf
global_defs {
    router_id {{ ansible_fqdn }}
}
vrrp_instance VI_1 {
{% if ansible_fqdn == "lb01" %}
    state MASTER
    priority 100
{% else %}
    state BACKUP
    priority 90
{% endif %}
    interface eth0
    virtual_router_id 50
    advert_int 1
    authentication {  
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.0.0.3
    }
}

2)配置剧本

[root@m01 project]# cat keepalived.yml 
- hosts: lb_server
  tasks:
    - name: Install keepalived Server
      yum:
        name: keepalived
        state: present
 
    - name: Config keepalived Server
      template:
        src: conf/keepalived.j2
        dest: /etc/keepalived/keepalived.conf
 
    - name: Start keepalived Server
      systemd:
        name: keepalived
        state: started

推荐阅读