Jinja2&templates模板

文本文件,嵌套有脚本(使用模板编程语言编写) 借助模板生成真正的文件

Jinja2语言,使用字面量,有下面形式
    字符串:使用单引号或双引号
    数字:整数,浮点数
    列表:[item1, item2, ...]
    元组:(item1, item2, ...)
    字典:{key1:value1, key2:value2, ...}
    布尔型:true/false
    算术运算:+, -, *, /, //, %, **
    比较操作:==, !=, >, >=, <, <=
    逻辑运算:and,or,not
    流表达式:For,If,When

Jinja2相关

字面量

 1> 表达式最简单的形式就是字面量。字面量表示诸如字符串和数值的 Python对象。如“Hello World”

 双引号或单引号中间的一切都是字符串。

 2> 无论何时你需要在模板中使用一个字符串(比如函数调用、过滤器或只是包含或继承一个模板的参数),如4242.23

 3> 数值可以为整数和浮点数。如果有小数点,则为浮点数,否则为整数。在Python 里, 42 和 42.0 是不一样的

Jinja2:算术运算

算术运算
Jinja 允许你用计算值。这在模板中很少用到,但为了完整性允许其存在
支持下面的运算符
    +:把两个对象加到一起。
       通常对象是素质,但是如果两者是字符串或列表,你可以用这 种方式来衔接它们。
       无论如何这不是首选的连接字符串的方式!连接字符串见 ~ 运算符。 {{ 1 + 1 }} 等于 2
    -:用第一个数减去第二个数。 {{ 3 - 2 }} 等于 1
    /:对两个数做除法。返回值会是一个浮点数。 {{ 1 / 2 }} 等于 {{ 0.5 }}
    //:对两个数做除法,返回整数商。 {{ 20 // 7 }} 等于 2
    %:计算整数除法的余数。 {{ 11 % 7 }} 等于 4
    *:用右边的数乘左边的操作数。 {{ 2 * 2 }} 会返回 4 。
       也可以用于重 复一个字符串多次。{{ ‘=’ * 80 }} 会打印 80 个等号的横条
    **:取左操作数的右操作数次幂。 {{ 2**3 }} 会返回 8

template 的使用

template功能:根据模块文件动态生成对应的配置文件
   > template文件必须存放于templates目录下,且命名为 .j2 结尾
   > yaml/yml 文件需和templates目录平级,目录结构如下:
    ./
     ├── temnginx.yml
     └── templates
        └── nginx.conf.j2

template示例

示例:利用template 同步nginx配置文件

前提: 准备templates/nginx.conf.j2文件
#建立templates工作目录
mkdir /home/hjk/ansible/playbook/templates

创建文件nginx.conf.j2 ,定义 worker_processes 的个数 为 cpu的核心数【通过ansible setup 模块获取到 ansible 自带的变量 ansible_processor_vcpus 获取到核心数 ,ansible all -i hosts -m setup -a filter=ansible_processor_vcpus 】

省略部分内容

[hjk@sre playbook]$vim templates/nginx.conf.j2

user nginx;
worker_processes {{ ansible_processor_vcpus }};

error_log  logs/error.log;
error_log  logs/error.log  notice;
error_log  logs/error.log  info;

pid   /run/nginx.pid;

events {
    worker_connections  65535;
}
.............................

[hjk@sre playbook]$ cat nginx-template.yml

---
- hosts: 172.16.10.252
  remote_user: root
  tasks:
    - name: Update sshd configuration safely, avoid locking yourself out
      template:
        src: nginx.conf.j2
        dest: /home/application/nginx/conf/nginx.conf
        owner: root
        group: root
        mode: '0755'
      notify:
        - service restart nginx

  handlers:
    - name: service restart nginx
      service:
        name: nginx
        state: restarted

Playbook中template算术运算

[hjk@sre playbook]$vim templates/nginx.conf.j2

user nginx;
worker_processes {{ ansible_processor_vcpus**2 }};
worker_processes {{ ansible_processor_vcpus*2 }};
worker_processes {{ ansible_processor_vcpus+2 }};
.............

when 实现条件判断

条件测试:如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试,
通过when语句实现,在task中使用,jinja2的语法格式

此外,when语句中还可以使用facts或playbook中定义的变量

when语句

在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法

示例:

tasks:
  - name: shutdown RedHat flavored systems
    command: /sbin/nstat
    when: ansible_os_family == RedHat  当系统属于红帽系列,执行command模块 

when语句中还可以使用Jinja2的大多filter, ansible all -m setup -a filter=XXX

例如要忽略此前某语句的错误并基于其结果(failed或者success)运行后面指定的语句,

可使用类似如下形式:

tasks:
  - command: /bin/false
    register: result
    ignore_errors: True
  - command: /bin/something
    when: result|failed
  - command: /bin/something_else
    when: result|success
  - command: /bin/still/something_else
    when: result|skipped

示例:when条件判断

- hosts: all
  remote_user: root
  tasks:
    - name: add group nginx
      tags: user
      user: name=nginx state=present

    - name: add user nginx
      user: name=nginx state=present group=nginx

    - name: Install Nginx
      yum: name=nginx state=present

    - name: restart Nginx
      service: name=nginx state=restarted
      when: ansible_distribution_major_version == 6

示例:when条件判断

根据centos的版本,选择不同的配置文件

- hosts: all
  remote_user: root
  tasks:
  - name: install conf file to centos7
    template: src=nginx.conf.c7.j2 dest=/etc/nginx/nginx.conf
    when: ansible_distribution_major_version == 7

  - name: install conf file to centos6
    template: src=nginx.conf.c6.j2 dest=/etc/nginx/nginx.conf
    when: ansible_distribution_major_version == 6

迭代:with_items

迭代:当有需要重复性执行的任务时,可以使用迭代机制
    > 对迭代项的引用,固定变量名为item
    > 要在task中使用with_items给定要迭代的元素列表
    > 列表格式:
         字符串
         字典

示例1:

示例: 创建用户

---
- hosts: all
  remote_user: root
  tasks:
    - name: add several users
      user: name={{ item }} state=present groups=wheel   #{{ item }} 系统自定义变量
      with_items:       # 定义{{ item }} 的值和个数
        - testuser1
        - testuser2

上面语句的功能等同于下面的语句:
---
- hosts: all
  remote_user: root
  tasks:
    - name: add user testuser1
      user: name=testuser1 state=present groups=wheel
    - name: add user testuser2
      user: name=testuser2 state=present groups=wheel

示例2:将多个文件进行copy到被控端

---
- hosts: all
  remote_user: root
  tasks
  - name: Create rsyncd config
    copy: src={{ item }} dest=/etc/{{ item }}
    with_items:
      - rsyncd.secrets
      - rsyncd.conf

示例3:批量安装服务

- hosts:websrvs
  remote_user: root
  tasks
    - name: install some packages
      yum: name={{ item }} state=present
      with_items:
        - nginx
        - memcached
        - php-fpm

示例4:迭代嵌套子变量

---
- hosts: all
  remote_user: root
  tasks:
    - name: add several users
      user: name={{ item.name }} state=present groups={{ item.groups }}
      with_items:
        - { name: 'testuser1', groups: 'wheel' }
        - { name: 'testuser2', groups: 'root' }
---
- hosts:websrvs
  remote_user: root

  tasks:
    - name: add some groups
      group: name={{ item }} state=present
      with_items:
        - group1
        - group2
        - group3
    - name: add some users
      user: name={{ item.name }} group={{ item.group }} state=present
      with_items:
        - { name: 'user1', group: 'group1' }
        - { name: 'user2', group: 'group2' }
        - { name: 'user3', group: 'group3' }
- name: 使用ufw模块来管理哪些端口需要开启
  ufw:
  rule: “{{ item.rule }}”
  port: “{{ item.port }}”
  proto: “{{ item.proto }}”
  with_items:
    - { rule: 'allow', port: 22, proto: 'tcp' }
    - { rule: 'allow', port: 80, proto: 'tcp' }
    - { rule: 'allow', port: 123, proto: 'udp' }

- name: 配置网络进出方向的默认规则
  ufw:
  direction: {{ item.direction }}
  policy: {{ item.policy }}
  state: enabled
  with_items:
    - { direction: outgoing, policy: allow }
    - { direction: incoming, policy: deny }

Playbook中template for if when循环

案例: nginx.conf 中 生成 多个server 配置

[hjk@sre playbook]$ cat nginx-hosts.yml 
---
- hosts: 172.16.10.252
  remote_user: root
  vars:
    nginx_vhosts:
      - web1:
        listen: 8081
        root: /home/application/nginx/html/web1
      - web2:
        listen: 8082
        server_name: web2.test.com
        root: /home/application/nginx/html/web2
      - web3:
        listen: 8083
        server_name: web3.test.com
        root: /home/application/nginx/html/web3
  tasks:
    - name: template config to
      template: src=nginx.conf-hosts.j2 dest=/home/application/nginx/conf/nginx.conf
[hjk@sre playbook]$  cat templates/nginx.conf-hosts.j2 
user  root;
worker_processes  auto;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] $request '
    #                  '$status $body_bytes_sent $http_referer '
    #                  '$http_user_agent $http_x_forwarded_for';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

{% for vhost in nginx_vhosts %}
server {
    listen {{ vhost.listen }};
{% if vhost.server_name is defined %}
    server_name {{ vhost.server_name }};
{% endif %}
    root {{ vhost.root }};
 }
{% endfor %}

}

效果:

[root@test conf]# cat nginx.conf
user  root;
worker_processes  auto;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] $request '
    #                  '$status $body_bytes_sent $http_referer '
    #                  '$http_user_agent $http_x_forwarded_for';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

server {
    listen 8081;
    root /home/application/nginx/html/web1;
 }
server {
    listen 8082;
    server_name web2.test.com;
    root /home/application/nginx/html/web2;
 }
server {
    listen 8083;
    server_name web3.test.com;
    root /home/application/nginx/html/web3;
 }

}
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容