【ansible】jinja2语法与项目管理

目录

使用jinja2模板部署自定义文件

一Ansible如何使用jinja2模版

二,jinja2常用语法​​​​​​​

三,jinja2基本语法

1,注释

2,赋值

3,变量

四,条件判断

1,单分支

2,双分支

3,多分支

五,循环语句

六,空白控制

七,jinja2构建文件模板

八,template模块

项目管理

一,并行处理forks serial

1, Aniable运行play机制---forks

2, serial--Ansible运行滚动机制

二,playbook的文件导入

1,管理大型的playbook

2,包含或导入任务文件


使用jinja2模板部署自定义文件

一Ansible如何使用jinja2模版

Ansible使用jinja3模版,也就是template模版,该模块和copy模块一样,都是将文件复制到目标机器上,但是区别在于template模块可以获取要复制文件中的变量的值,而copy则是原封不动的把文件内容复制过去。

实际运用:比如,针对不同的主机定义不同的变量,template会在文件分发前读取变量到jinja2模版,之后分发到不同的被管理主机上。

二,jinja2常用语法

Jinja2是基于python书写的模版引擎,功能比较类似于PHP的smarty模版

1)要想在配置文件中使用jinja2,playbook中的tasks必须使用template模块。

2)模版配置文件里面使用变量,比如{{ port }} 或者{{ facts 变量 }}

三,jinja2基本语法

Jinja2文件以.j2为后缀,也可以不写后缀

在jinja2中,存在三种语法:

  • 逻辑表达 {% %}
  • 变量引用 {{ var }}
  • 注释{# 注释内容 #}

1,注释

{#......#}  要把模版中一行或多行注释掉,默认的注释语法

 

2,赋值

为变量赋值,优先级高于playbook中的优先级。

{% set username = 'zhang' % }

{% set navigation = [('index.html','Index'),('about.html','About')] %}

 

3,变量

{{…….}} 把表达式的结果打印到模版上

你可以使用(.)来访问变量的属性,作为替代,也可以使用所谓的下标语法([]),如下示例:

{{ foo.bar }}

{{ foo['bar'] }}

 花括号不是变量的一部分,而是打印语句的重要的一部分

 

 

四,条件判断

1,单分支

{% if 条件表达式 %}

…….

{% endif %}

 

 

2,双分支

{% if 条件表达式 %}

…….

{% else  %}

…….

{% endif %}

 

 

3,多分支

{% if 条件表达式 %}

…….

{% elif 条件表达式 %}

…….

{% else  %}

…….

{% endif %}

 

 

示例:

{% if idc is definded %}

{{ idc }}

{{% else %}}

没有定义

{% endif %}

 

 

 

 

五,循环语句

{% for user in users %}

{{ user }}

{% endfor %}

 列出myhosts中的所有主机

{% for myhost in groups['myhosts'] %}

{{ myhosts }}

{% endfor %}

 案例:列出test中的所有主机

(1)此时的主机清单文件如下:

[root@server var_test]# cat inventory

【ansible】jinja2语法与项目管理_第1张图片

 

(2)编辑ex1.j2文件

[root@server var_test]# vim ex1.j2

{% for myhost in groups.test %}

        {{ myhost }}

{% endfor %}          

【ansible】jinja2语法与项目管理_第2张图片

 

 

(3)编辑ex1.yml文件

---

- name: play1

  hosts: all

  tasks:

  - name: task1

    template:

      src: ./ex1.j2

      dest: /opt/host1

【ansible】jinja2语法与项目管理_第3张图片

 

(4)执行文件ex1.yml

[root@server var_test]# ansible-playbook ex1.yml

【ansible】jinja2语法与项目管理_第4张图片

 

(5)在受控端主机查看结果

[root@node1 ~]# cat /opt/host1

【ansible】jinja2语法与项目管理_第5张图片

 

[root@node2 ~]# cat /opt/host1

【ansible】jinja2语法与项目管理_第6张图片

 

 

 

 

六,空白控制

默认配置中,模版引擎不会对空白做进一步修改,所以每个空白(空格,换行符 等等)都会原封不动返回。

此外,你也可以手动剥离模版中的空白。当你在块(比如一个for标签,一段注释或变量表达式)的开始或结束放置一个减号(-),可以一出块前或块后的空白。

 

案例:

1,没放置空白块前:

(1)编辑文件ex2.j2

{% for item in range(1,9) %}

        {{ item }}

{% endfor %}

【ansible】jinja2语法与项目管理_第7张图片

 

(2)编辑ex2.yml文件

---

- name: play1

  hosts: all

  tasks:

  - name: task1

    template:

      src: ./ex2.j2

      dest: /opt/ex2                       

【ansible】jinja2语法与项目管理_第8张图片

 

(3)执行文件ex2.yml

[root@server var_test]# ansible-playbook ex2.yml

【ansible】jinja2语法与项目管理_第9张图片

 

 

(4)在受控端主机查看结果

[root@node1 ~]# cat /opt/ex2

【ansible】jinja2语法与项目管理_第10张图片

 

 

2,放置空白块后

(1)编辑ex3.j2文件

{% for item in range(1,9) -%}

        {{ item }}

{%- endfor %}          

【ansible】jinja2语法与项目管理_第11张图片

 

(2)编辑ex3.yml文件

---

- name: play1

  hosts: all

  tasks:

  - name: task1

    template:

      src: ./ex3.j2

      dest: /opt/ex3

【ansible】jinja2语法与项目管理_第12张图片

 

(3)执行文件ex3.yml

[root@server var_test]# ansible-playbook ex3.yml

【ansible】jinja2语法与项目管理_第13张图片

  

(4)在受控端主机上查看结果

[root@node1 ~]# cat /opt/ex3

 

 

七,jinja2构建文件模板

 文本文件,嵌套有脚本(使用模板编写语言编写)

 管理文件的一种更强大的方法是为其构建模板。通过此方法,您可以使用ansible变量和事实便捷一个模板配置文件,在部署该文件时自动为受管主机自定义此模板配置文件。这样更容易控制,也更不易出错。

使用分隔符

 变量和逻辑表达式至于标记或分隔符之间。例如,jinja2模板将{% EXPR %}用于表达式或逻辑(如循环),而{{ EXPR }} 则用于向最终用户输出表达式或变量的结果。后一标记在呈现时将被替换为一个或多个值,最终用户可见。使用 {# COMMENT #}语法括起来不应出现在最终文件中的注释。

在下例中第一行中含有不会包含于最终文件中的注释。第二行中引用的变量被替换为所引用的系统事实的值。

{ # /etc/hosts line #}

{{ ansible_facts'default_ipv4'] }} {{ ansible_facts['hostname'] }}

{% for item in all_items %} {{ item }} {% endfor %} {% for finished %} {{ result }} {% endif %}

 

 

八,template模块

template模块

 template使用了Jinjia2格式作为文件模版,进行文档内变量的替换的模块。它的每次使用都会被ansible标记为”changed”状态。

参数名

是否必须

默认值

选项

说明

backup

no

no

yes/no

建立个包括timestamp在内的文件备份,以备不时之需.

dest

yes

远程节点上的绝对路径,用于放置template文件。

group

no

设置远程节点上的的template文件的所属用户组

mode

no

设置远程节点上的template文件权限。类似Linux中chmod的用法

owner

no

设置远程节点上的template文件所属用户

src

yes

本地Jinjia2模版的template文件位置。

案例:制作hosts模板文件

在受控主机中会按照jinja2动态模板文件,生成相对应的主机信息。

(1)编辑文件hosts.j2

[root@server var_test]# vim hosts.j2

{% for host in groups['all'] %}

{{ hostvars[host]['ansible_facts']['default_ipv4']['address'] }} {{ hostvars[host]['ansible_facts']['fqdn'] }} {{ hostvars[host]['ansible_facts']['hostname'] }}

{% endfor %}

(2)编辑hosts.yml 文件

---

- name: play1

  hosts: all

  tasks:

    - name: task1

      template:

        src: ./hosts.j2

        dest: /etc/myhosts                    

【ansible】jinja2语法与项目管理_第14张图片

(3)检查是否有语法错误

[root@server var_test]# ansible-playbook hosts.yml --syntax-check

(4)执行hosts.yml

[root@server var_test]# ansible-playbook hosts.yml

【ansible】jinja2语法与项目管理_第15张图片

(5)在受控端主机node1上查看结果

[root@node1 ~]# cat /etc/myhosts

项目管理

一,并行处理forks serial

1, Aniable运行play机制---forks

1)当Ansible处理playbook时,会按顺序运行每个play。确定play的主机列表之后,Ansible将按

      顺序运行每个任务

2)通常,所有主机必须在任何主机在play中启动下一个任务之前成功完成任务

3) 注意:

      理论上,Ansible可以同时连接到play中的所有主机以执行每项任务。这非常适用于小型主机

      列表。但如果该play以数百台主机为目标,则可能会给控制节点带来沉重负担

4) Ansible所进行的最大同时连接数由Ansible配置文件中的forks参数控制,默认情况下设为

       5(forks:分叉)

      通过以下方式之一来验证:[root@localhost ~]# grep forks /etc/ansible/ansible.cfg #forks = 5

5) 例如,假设Ansible控制节点配置了5个forks的默认值,并且play具有10个受管主机。

       Ansible将在前5个受管主机上执行play中的第一个任务,然后在其他5个受管主机上对第一个

       任务执行第二轮。

       在所有受管主机上执行第一个任务后,Ansible将继续一次在5受管主机的组中的所有受管主

       机上执行下一个任务。Ansible将依次对每个任务执行此操作,直到play结束。

6)forks的默认值设置得非常保守。如果你的控制节点正在管理Linux主机,则大多数任务将在受

      管主机上运行,并且控制节点的负载较少。在这种情况下,通常可以将forks的值设置得更高

      , 可能接近100,然后性能就会提高

7)如果playbook在控制节点上运行很多代码,则应明智地提高forks限值。如果使用Ansible管理

     网络路由器和交换机,则大多数模块在控制节点上运行而不是在网络设备上运行。

      由于这会增加控制节点上的负载,因此其支持forks数量增加的能力将显著低于仅管理Linux

      主机的控制节点

8)可以从命令行覆盖Ansible配置文件中forks的默认设置。ansible和ansible-playbook命令均提

      供-f或--forks选项以指定要使用的forks数量

 

 

2, serial--Ansible运行滚动机制

 

滚动更新:

方法一: 设置固定批量大小

Serial:2

方法二: 设置批量大小为百分比

Serial:20%

方法三: 将批量大小设置为可更改

Serial:

  - 1

  - 10%

  - 100 %

(如果第一台机器失败,就停止;若成功,则继续后面的10%)

 

 

1)通常,当Ansible运行play时,它会确保所有受管主机在启动任何主机进行下一个任务之前已

      完成每个任务。在所有受管主机完成所有任务后,将运行任何通知的处理程序

2)但是,在所有主机上运行所有任务可能会导致意外行为。

      例如,如果play更新负载均衡Web服务器集群,则可能需要在进行更新时让每个Web服务器

      停止服务。如果所有服务器都在同一个play中更新,则它们可能全部同时停止服务

3)避免此问题的一种方法是使用serial关键字,通过play批量运行主机。在下一批次启动之前,

     每批主机将在整个play中运行

4)演示实例:

    [root@localhost project]# cat playbook.yml

    ---

    - hosts: all

      serial: 2

      tasks:

        - name: install httpd

          yum:        

             name: httpd

               state: present

          notify:

              - start httpd

     

      handlers:

          - name: start httpd

            service:

               name: httpd

               state: started

在上面的示例中,Ansible一次在两个受管主机上执行play,直至所有受管主机都已更新

5)更新机制:

  • Ansible首先在前两个受管主机上执行play中的任务。如果这两个主机中的任何一个或两个都通知了处理程序,则Ansible将根据这两个主机的需要运行处理程序。
  • 在这两个受管主机上执行完play时,Ansible会在接下来的两个受管主机上重复该过程。Ansible继续以这种方式运行play,直到所有受管主机都已更新

6)假设上一示例中的webservers组包含5个Web服务器,它们位于负载均衡器后面。将serial参

      数设置为2后,play一次将运行两台Web服务器。因此,5台Web服务器中的大多数服务器将

      始终可用

  • 相反,如果不使用serial关键字,将同时在5台Web服务器上执行play和生成的处理程序。这可能会导致服务中断,因为Web服务将在所有Web服务器上同时重新启动

7)重要:

      在设置了serial: 2 的上一个场景中,如果出现问题并且处理的前2个主机的play失败,

      则 playbook将中止,其余3个主机将不会通过play运行。这是一个有用的功能,因为只有

       一部分服务器会不可用,使服务降级而不是中断    

      serial关键字也可以指定为百分比。此百分比应用于play中的主机总数,以确定滚动更新批

      处理大小。无论百分比为何,每一工序的主机数始终为1或以上      

 

二,playbook的文件导入

1,管理大型的playbook

1)   如果playbook很长很复杂,我们可以将其分成较小的文件以便于管理

2)可采用模块化方式将多个playbook组合为一个主要playbook,或者将文件中的任务列表

      插入play import_playbook

2,包含或导入任务文件

1Import_playbook示例:安装bind并启动

(1)创建目录

[root@server ~]# mkdir /day06/playbook -pv

【ansible】jinja2语法与项目管理_第16张图片

(2)创建inventory文件与ansible.cfg文件

[root@server playbook]# cp /day05/var_test/inventory inventory
[root@server playbook]# cp /day05/var_test/ansible.cfg ansible.cfg

(3)创查看nventory文件与ansible.cfg文件

[root@server playbook]# cat inventory
[root@server playbook]# cat ansible.cfg

【ansible】jinja2语法与项目管理_第17张图片

(4)此时的node1主机上没有bind软件包

[root@node1 ~]# rpm -q bind

【ansible】jinja2语法与项目管理_第18张图片

(5)编辑文件import_playbook.yml文件,安装bind服务

---

- name: play1

  hosts: node1

  tasks:

    - name: task1

      yum:

        name: bind

        state: present

【ansible】jinja2语法与项目管理_第19张图片

(6)检测有无语法问题

[root@server playbook]# ansible-playbook import_playbook.yml --syntax-check

(7)编辑playbook.yml文件,开启上面安装的bind服务

---

- name: import

  import_playbook: ./import_playbook.yml

 

- name: play1

  hosts: node1

  tasks:

    - name: task1

      service:

        name: named

        state: started

【ansible】jinja2语法与项目管理_第20张图片

(8)检测有无语法问题:

[root@server playbook]# ansible-playbook playbook.yml --syntax-check

(8)执行文件playbook.yml

[root@server playbook]# ansible-playbook playbook.yml

【ansible】jinja2语法与项目管理_第21张图片

(9)在node1主机上查看结果

[root@node1 ~]# rpm -q bind
[root@node1 ~]# systemctl status named

【ansible】jinja2语法与项目管理_第22张图片

2Import_tasks示例:停止bind并卸载

(1)编辑文件tasks.yml,把停止bind并卸载bind写入次文件中

---

- name: stop  

  service:

    name: named

    state: stopped

- name: absent    

  yum:

    name: named

    state: absent

【ansible】jinja2语法与项目管理_第23张图片

(2)检查是否有无语法错误

[root@server playbook]# ansible-playbook tasks.yml --syntax-check

(3)编辑playbook2.yml文件,将上述任务导入并执行

---

- hosts: node1

  tasks:

    - name:

      import_tasks: ./tasks.yml

【ansible】jinja2语法与项目管理_第24张图片

(4)检查是否有无语法错误

[root@server playbook]# ansible-playbook playbook2.yml --syntax-check

(5)执行playbook2.yml文件

[root@server playbook]# ansible-playbook playbook2.yml

【ansible】jinja2语法与项目管理_第25张图片

 

(6)在node1主机上查看结果

[root@node1 ~]# systemctl status named

你可能感兴趣的:(RHCE,linux,ansible,开发语言)