joeの小窝

Loading...

ansible jinja2模版详解

一、jinja2模版

1、为什么需要这个jinja2模版呢?

之前配置nginx的配置文件的时候,监听自己的ip,如果是多个主机,发送同一份配置文件(监听的ip都是一样的,显然是不合理的),会报错,因为多个主机监听同一个ip

有了jinja2后,写一个jinja2模版,里面的带有变量,发送给被控主机,被控主机会自动的识别出来,转换为自己的ip地址,更加的灵活

更改的配置文件,只需要更改一小部分即可

jinja2模板里面用的是setup变量,也就是事实变量,因此需要收集事实变量

原理:

  • 全部在控制节点上完成,根据控制节点上收集的事实变量,hostvars,自定义变量替换文件的{{}},生成完整文件

  • 目标主机(被管理机器)

    • 只收到渲染完成的静态文件

    • 完全不执行jinja2代码

    • 不出来变量的替换

  • 一定要理解好,在控制节点上的收集的事实变量的信息决定替换文件中的变量

2、template案例

jinja2文件,变量不需要双引号,只需要{{}},就会自动的识别出来

字符串这些需要单引号

# 都是事实变量
# 获取node1的一些信息
[root@master test]# cat node1.j2 
hostname: {{ansible_hostname}} 
ipv4: {{ansible_eth0.ipv4.address}}
os: {{ansible_os_family}}


[root@master test]# cat 1.yml 
- hosts: node1
  tasks:
    - template:
        src: ./node1.j2
        dest: /tmp/node1.txt

# node1主机会自动识别出来
[root@node1 tmp]# cat node1.txt 
hostname: node1
ipv4: 172.26.18.51
os: RedHat

3、jinja2模版语句

1、if判断(条件语句)

如果符合条件的话,就执行,否则不执行

# 1.j2文件

{% if ansible_hostname == 'node1' %}  # 如果主机是node1,则执行
"node1 is ok"
{% elif ansible_hostname == 'node2' %} # 如果主机是node2,则执行
"node2 is ok"
{% endif %}  # endif结尾

2、for循环

常常跟魔法变量配合使用,循环每一个主机

root@master test]# cat 2.j2 
{% for i in groups.all %}

{{hostvars[i].ansible_eth0.ipv4.address}} {{hostvars[i].ansible_fqdn}} {{hostvars[i].ansible_hostname}}

{% endfor %}

[root@master test]# cat 2.yml 
- hosts: all
  tasks:
    - template:
        src: ./2.j2
        dest: /tmp/node.txt

# 控制节点现将变量替换,因为收集了所有主机的变量
# 所以是下面的内容
[root@node1 tmp]# cat node.txt 

172.17.0.148 master master


172.26.18.51 node1 node1


172.17.36.163 node2 node2

4、jinja2过滤器

过滤器就是 | 符号的,前面是变量,对这个变量进行过滤

根据ansible的版本来判断是否支持,大于2.9大部分都支持

{{变量名|jinj2过滤器}}

1、default过滤器

  • 当变量的值没有定义的时候,使用default定义的值
[root@master test]# cat default.yml 
- hosts: all
  tasks:
    - debug:
        msg: "{{qqq|default('none')}}"

2、dict2items过滤器

使用在loop中循环遍历字典

[root@master test]# cat dict2.yml 
- hosts: node1
  vars:
    users:
      user1:
        name: qq
        age: 10
      user2:
        name: www
        age: 100
  tasks:
    - debug:
        msg: "{{item.value.name}}"
      loop: "{{users|dict2items}}"

[root@master test]# ansible-playbook dict2.yml 

PLAY [node1] **********************************************************************************

TASK [Gathering Facts] ************************************************************************
ok: [node1]

TASK [debug] **********************************************************************************
ok: [node1] => (item={'key': 'user1', 'value': {'name': 'qq', 'age': 10}}) => {
    "msg": "qq"
}
ok: [node1] => (item={'key': 'user2', 'value': {'name': 'www', 'age': 100}}) => {
    "msg": "www"
}

PLAY RECAP ************************************************************************************
node1                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


3、password_hash('sha512')过滤器

直接对密码进行加密,以后创建用户的时候可以这样使用

[root@master test]# cat ps.yml 
- hosts: node1
  vars:
    p1: "123"
  tasks:
    - debug:
        msg: "{{p1|password_hash('sha512')}}"

[root@master test]# ansible-playbook ps.yml 

PLAY [node1] **********************************************************************************

TASK [Gathering Facts] ************************************************************************
ok: [node1]

TASK [debug] **********************************************************************************
ok: [node1] => {
    "msg": "$6$Ed76VDH1/Sy8Bw9l$8rw91CWrUGGg3UHI4hNC6OpZgJ/3E6i59XwQ/BiKqdLr6HuYcjgu3kjP1hkrvqTY0KVsNQyQooHNlD1tCS/0D."
}


posted @ 2026-04-11 22:54  乔的港口  阅读(24)  评论(0)    收藏  举报