Jinja2介绍

什么是jinja2?

jinja2是Python的全功能模板引擎

jinja与Ansible的关系?

Ansible通常会使用jinja2模板来修改被管理主机的配置文件等...在saltstack中同样会使用到jinja2如果在100台主机上安装nginx,每台nginx的端口都不一样,如何解决?

总结:Ansible想要识别配置文件中的变量、判断、循环,只能使用Jinja2语法

Ansible如何使用Jinja2

将原本推送配置文件的copy模块换成template模块即可template模块就是一个能识别Jinja2语法模块

注意事项

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

#ansible playbook:
判断:when
循环:with_items
#Jinja2模板:
判断:if
循环:for while

Jinja2语法

注释和调用变量

# 注释
{# 注释内容 #}
# 调用变量
{{ 变量名 }}

逻辑判断和循环

#循环表达式
{% for i in EXPR %}
{% endfor %}

#条件判断
{% if EXPR %}
{% elif EXPR %}
{% else %}
{% ednif %}

#注释
{# COMMENT #}
-----------------------------------------------------------------------------------------------------
#示例:
{# Jinja2:判断 #}
{% if ansible_hostname == 'web01' %}
  echo 1
{% endif %}
----------------------------------------------
{% if ansible_hostname == 'web01' %}
  echo 1
{% else %}
  echo 2
{% endif %}
----------------------------------------------
{% if ansible_hostname == 'web01' %}-
  echo 1
{% else if ansible_hostname == 'web02' %}
  echo 2
{% else %}
  echo 3
{% endif %}
#shell判断
if [ ansible_hostname == 'web01' ];then
echo 1
echo 2
echo 3
fi
------------------------------------------------------
#单分支判断
if [];then
    echo 1
else
    echo 2
fi
#多分支判断
if [ 条件 ];then
    echo 1
elif [ 条件 ];then
    echo 2
else
fi

循环

{# 循环 #}
{% for n in range(1,11) %}
循环体
{% endfor %}
------------------------------------------------------
#shell: 循环
for xxx in xxx;do
    循环体
done
#示例:
for ip in 5 6 7 8;do
    echo 172.16.1.$ip
done

for num in `seq 10`;do
    echo $num
done

Jinja2实战keepalived

## if判断
#准备配置文件
global_defs {                   
    router_id {{ ansible_hostname }}          
}

vrrp_instance VI_1 {
{% if ansible_hostname == 'web01' %}
    state MASTER
    priority 150
{% else %}
    state BACKUP
    priorty 100
{% endif %}
    interface eth0              
    virtual_router_id 50                 
    advert_int 1                
    authentication {            
        auth_type PASS          
        auth_pass 1111          
    }
    virtual_ipaddress {         
        10.0.0.3                
    }
}
#编写playbook
- hosts: all
  tasks:
  - name: 推送keepalived master配置文件
    template:
      src: /opt/ansible/keepalived/keepalived.conf
      dest: /usr/keepalived.conf
## 直接调用变量(使用变量进行计算,然后使用int转成整型)  //以mysql配置文件为例
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
skip_name_resolve
symbolic-links=0
innodb_buffer_pool_size={{ (ansible_memtotal_mb * 0.8)|int }}

[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
!includedir /etc/my.cnf.d
-----------------------------------------------------------------------------------------------------
# 直接调用变量(字符串切片)
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
skip_name_resolve
symbolic-links=0
server_id={{ ansible_hostname[-1] }}      #//取主机名后面的最后一位数字
innodb_buffer_pool_size={{ (ansible_memtotal_mb * 0.8)|int }}

[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
!includedir /etc/my.cnf.d

Jinja2实战循环负载均衡配置文件

#准备配置文件
upstream {{ lb_name }} {
{% for num in range(7,10) %}
    server 10.0.0.{{ num }}
{% endfor %}
}
server{
    listen 80;
    server_name {{ wordpress_domain }};
    location / {
    proxy_pass http://{{ lb_name }}
    }
}
----------------------------------------------------------------------------------------------------
- hosts: all
  tasks:
  - name: 推送keepalived master配置文件
    template:
    src: /opt/ansible/nginx_php/lb.conf
    dest: /opt/lb.conf