Linux jinja2模板的使用(2)

Linux jinja2模板的使用(2)

1.for循环

一个列表中有多个元素,如果需要依次对列表中的每个元素操作,则可以使用for循环来实现,for 循环的语法如下。

{% for i in 列表名 %}
 {{i}}
 {% endfor %}

这里首先把列表中的第一个元素赋值给i,执行中间的操作;然后把第二个元素赋值给i执行中间的操作,以此类推,直到把最后一个元素赋值给i。看下面的例子。

[blab@rh1 templates]$ cat dd.conf.j2 
{% set list1=['aa','bb','cc'] %}
1111
{% for i in list1 %}
{{i}}
{% endfor %}
5555

这里手动在jinja2模板中定义了一个列表(注意定义列表的方式)list1,里面有3个元素,分别为aa、bb、cc。然后对这个列表的内容进行循环。

这里jinja2模板生成的文件有5行内容,第1行和第5行的内容是固定的,为1111和5555。
第2~4行是循环列表list1 中的值,为aa、bb、cc.

写一个 playbook,内容如下。

[blab@rh1 demo4]$ cat 4.yaml 
---
- hosts: rh2
  tasks:
  - name: 拷贝一个文件
    template: src=dd.conf.j2 dest=/opt/dd.conf

运行此playbook,内容如下。

[blab@rh1 demo4]$ ansible-playbook 4.yaml 

PLAY [rh2] ********************************************************************************************

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

TASK [拷贝一个文件] *****************************************************************************************
changed: [rh2]

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

查看rh2 上/opt/dd.conf的内容,命令如下。

[blab@rh1 demo4]$ ansible rh2 -m shell -a "cat /opt/dd.conf"
rh2 | CHANGED | rc=0 >>
1111
aa
bb
cc
5555

除了jinja2模板中手动定义的列表,一般情况下,我们会在playbook中定义列表,然后对列表中的元素进行循环。

写一个变量文件users_list.txt,里面包含一个名称为users的列表,命令如下。

[blab@rh1 demo4]$ cat users_list.txt 
users:
- uname: zhangsan
  age: 20
  sex: man
- uname: lisi
  age: 21
  sex: woman
- uname: wangwu
  age: 23
  sex: man

在 templates目录下写一个ee.j2,里面写一个 for 语句循环users列表,内容如下。

[blab@rh1 templates]$ cat ee.j2 
现在公司中所有员工的姓名是:
{% for i in users %}
{{i.uname}}
{% endfor %}

循环每个元素时,只打印元素中的uname变量。写一个名称为5.yaml的playbook,加载变量文件 users list.txt,命令如下。

[blab@rh1 demo4]$ cat 5.yaml
---
- hosts: rh2
  vars_files:
          - users_list.txt
  tasks:
  - name: 拷贝一个文件
    template: src=ee.j2 dest=/opt/ee.conf  

这里通过 template模块把ee.j2拷贝到被管理主机的/opt 中并命名为ee.conf。查看rh2上/opt/ee.conf的内容,命令如下。

[blab@rh1 demo4]$ ansible-playbook 5.yaml 

PLAY [rh2] *******************************************************************************************

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

TASK [拷贝一个文件] ****************************************************************************************
changed: [rh2]

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

查看被管理主机的/opt/ee.conf,里面包括users列表中所有的用户名。

[blab@rh1 demo4]$ ansible rh2 -m shell -a "cat /opt/ee.conf"
rh2 | CHANGED | rc=0 >>
现在公司中所有员工的姓名是:
zhangsan
lisi
wangwu

2.handlers

前面讲了模板的使用,但是后期我们可能需要修改模板的内容,然后重新拷贝到各个机器,此时需要重启httpd服务才会生效,先看下面的例子。

先获取 httpd.conf的配置文件,获取的httpd.conf中没有任何空白行和注释行。

[blab@rh1 demo4]$ egrep -v '#|^#' /etc/httpd/conf/httpd.conf > httpd.conf.j2

修改此httpd.conf.j2的Listen,把原来Listen后面的端口80换成{{myport}},让
httpd.con.fj2引用myport变量,内容如下。

[blab@rh1 demo4]$ head -5 httpd.conf.j2 

ServerRoot "/etc/httpd"

Listen {{myport}}

为了不让例子变得太复杂,先临时关闭rh2上的 SELinux,命令如下。

[root@rh1 demo4]# setenforce 0
[root@rh1 demo4]# getenforce 0
Permissive
[root@rh1 demo4]# exit
exit
[blab@rh1 demo4]$ 

写一个名称为hand-1.yaml的playbook,命令如下。

[blab@rh1 demo4]$ cat hand-1.yaml 
---
- hosts: rh2
  vars:
   myport: 80
  tasks:
  - name: task1安装httpd
    yum: name=httpd state=installed
  - name: task2拷贝配置文件
    template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
  - name: task3启动httpd服务
    service: name=httpd state=started

第一个task用于安装 htpd,第二个task用于把模板httpd.conf.j2拷贝到被管理机器,第三个 task用于启动httpd服务,第一次是可以正常运行的。

[blab@rh1 demo4]$ ansible-playbook hand-1.yaml 

PLAY [rh2] *******************************************************************************************

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

TASK [task1安装httpd] **********************************************************************************
changed: [rh2]

TASK [task2拷贝配置文件] ***********************************************************************************
changed: [rh2]

TASK [task3启动httpd服务] ********************************************************************************
changed: [rh2]

PLAY RECAP *******************************************************************************************
rh2                        : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

下面修改myport的值为808,内容如下。

[blab@rh1 demo4]$ cat hand-1.yaml 
---
- hosts: rh2
  vars:
   myport: 808
  tasks:
  - name: task1安装httpd
    yum: name=httpd state=installed
  - name: task2拷贝配置文件
    template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
  - name: task3启动httpd服务
    service: name=httpd state=started

再次运行此playbook,因为 httpd已经安装过了,状态并没有发生任何改变,所以这次第一个task不会执行。因为改变了myport的值,httpd.conf.j2中的端口也就发生了变化,第二个task再次把模板文件拷贝到被管理机器。因为httpd已经处于启动状态,所以第三个task也不会执行,从而导致第二个task铂贝过去的新模板文件并不会生效,因为httpd并没有重启。

[blab@rh1 demo4]$ ansible-playbook hand-1.yaml 

PLAY [rh2] *******************************************************************************************

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

TASK [task1安装httpd] **********************************************************************************
ok: [rh2]

TASK [task2拷贝配置文件] ***********************************************************************************
changed: [rh2]

TASK [task3启动httpd服务] ********************************************************************************
ok: [rh2]

PLAY RECAP *******************************************************************************************
rh2                        : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   


修改hand-1.yaml的内容如下。

[blab@rh1 demo4]$ cat hand-1.yaml 
---
- hosts: rh2
  vars:
   myport: 808
  tasks:
  - name: task1安装httpd
    yum: name=httpd state=installed
  - name: task2拷贝配置文件
    template: src=httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
  - name: task3启动httpd服务
    service: name=httpd state=restarted

这里把第三个task中的 started改成了restarted

如果我们修改了myport的值之后运行此playbook,第二个task 会正常执行,因为 httpd.conf,j2中的端口发生了变化。第三个task总是会执行,因为第三个task中state 的值为restarted,这样所做的修改会生效。

你可能感兴趣的:(linux,运维,服务器,ansible)