Ansible的template模块

605次阅读
没有评论

共计 11111 个字符,预计需要花费 28 分钟才能阅读完成。

Ansible的template模块

template模块通常用来渲染配置文件,通过使用模板语言的语义在任务执行时自动翻译渲染出自定义格式的配置文件

template模块

使用方式

- name: Copy a new sudoers file into place, after passing validation with visudo
  template:
    src: /mine/sudoers
    dest: /etc/sudoers
    validate: /usr/sbin/visudo -cf %s

- name: Update sshd configuration safely, avoid locking yourself out
  template:
    src: etc/ssh/sshd_config.j2
    dest: /etc/ssh/sshd_config
    owner: root
    group: root
    mode: '0600'
    validate: /usr/sbin/sshd -t -f %s
    backup: yes

模板文件内支持的数据类型和操作

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

nginx模板配置样例

nginx简单样例

目标实现的最终文件为

[root@manager web]# cat test.xadocker.cn.conf
server {
    listen                             80;
    server_name                        test.xadocker.cn;
    index                              index.html;
    root                               /home/wwwroot/test.xadocker.cn/public;
    # logging
    access_log /home/wwwlogs/test.xadocker.cn.access.log combined buffer=512k flush=1m;
}

用模板语言进行提取域名和端口为变量

[root@manager web]# cat web.conf.j2
server {
    listen                             {{ port }};
    server_name                        {{ server_name }};
    index                              index.html;
    root                               /home/wwwroot/{{ server_name }}/public;
    # logging
    access_log /home/wwwlogs/{{ server_name }}.access.log combined buffer=512k flush=1m;
}

playbook则为

[root@manager web]# cat  nginx-template.yaml
---
- name: render nginx web conf
  hosts: web
  vars:
    server_name: "test.xadocker.cn"
    port: "80"
  tasks:
  - name: render nginx web conf
    template:
      src: ./web.conf.j2
      dest: /etc/nginx/conf.d/{{ server_name }}.conf

任务运行并查看

[root@manager web]# ansible-playbook -i hosts nginx-template.yaml
[WARNING]: Found variable using reserved name: port

PLAY [render nginx web conf] *******************************************************************************************

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

TASK [render nginx web conf] *******************************************************************************************
changed: [192.168.44.151]

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

[root@k8s-master web]# cat /etc/nginx/conf.d/test.xadocker.cn.conf
server {
    listen                             80;
    server_name                        test.xadocker.cn;
    index                              index.html;
    root                               /home/wwwroot/test.xadocker.cn/public;
    # logging
    access_log /home/wwwlogs/test.xadocker.cn.access.log combined buffer=512k flush=1m;
}

循环渲染多个配置文件

# 模板文件
[root@manager web]# cat web.conf.j2
server {
    listen                             {{ port }};
    server_name                        {{ item }};
    index                              index.html;
    root                               /home/wwwroot/{{ item }}/public;
    # logging
    access_log /home/wwwlogs/{{ item }}.access.log combined buffer=512k flush=1m;
}

# playbook配置
[root@manager web]# cat nginx-template.yaml
---
- name: render nginx web conf
  hosts: web
  vars:
    server_name:
    - "test1.xadocker.cn"
    - "test2.xadocker.cn"
    port: "80"
  tasks:
  - name: render nginx web conf
    template:
      src: ./web.conf.j2
      dest: /etc/nginx/conf.d/{{ item }}.conf
    with_items:
    - "{{ server_name }}"

# 任务输出
[root@manager web]# ansible-playbook -i hosts nginx-template.yaml
[WARNING]: Found variable using reserved name: port

PLAY [render nginx web conf] *******************************************************************************************

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

TASK [render nginx web conf] *******************************************************************************************
changed: [192.168.44.151] => (item=test1.xadocker.cn)
changed: [192.168.44.151] => (item=test2.xadocker.cn)

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

[root@k8s-master web]# cat /etc/nginx/conf.d/test1.xadocker.cn.conf
server {
    listen                             80;
    server_name                        test1.xadocker.cn;
    index                              index.html;
    root                               /home/wwwroot/test1.xadocker.cn/public;
    # logging
    access_log /home/wwwlogs/test1.xadocker.cn.access.log combined buffer=512k flush=1m;
}
[root@k8s-master web]# cat /etc/nginx/conf.d/test2.xadocker.cn.conf
server {
    listen                             80;
    server_name                        test2.xadocker.cn;
    index                              index.html;
    root                               /home/wwwroot/test2.xadocker.cn/public;
    # logging
    access_log /home/wwwlogs/test2.xadocker.cn.access.log combined buffer=512k flush=1m;
}

模板文件中的判断

判断使用以下语法

{% if condition %}

{% endif %}

{% if condition %}

{% else %}

{% endif %}

{% if condition1 %}

{% elif condition2 %}

{% endif %}

我们将nginx的日志提取出来做判断是否开启日志记录

# 模板文件
[root@manager web]# cat web.conf.j2
server {
    listen                             {{ port }};
    server_name                        {{ item }};
    index                              index.html;
    root                               /home/wwwroot/{{ item }}/public;

{% if item == "test1.xadocker.cn" %}
    # logging
    access_log /home/wwwlogs/{{ item }}.access.log combined buffer=512k flush=1m;
{% endif %}
}

# playbook配置
[root@k8s-master web]# cat nginx-template.yaml
---
- name: render nginx web conf
  hosts: web
  vars:
    server_name:
    - "test1.xadocker.cn"
    - "test2.xadocker.cn"
    port: "80"
  tasks:
  - name: render nginx web conf
    template:
      src: ./web.conf.j2
      dest: /etc/nginx/conf.d/{{ item }}.conf
    with_items:
    - "{{ server_name }}"

# 任务输出
[root@manager web]# ansible-playbook -i hosts nginx-template.yaml
[WARNING]: Found variable using reserved name: port

PLAY [render nginx web conf] *******************************************************************************************

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

TASK [render nginx web conf] *******************************************************************************************
changed: [192.168.44.151] => (item=test1.xadocker.cn)
changed: [192.168.44.151] => (item=test2.xadocker.cn)

PLAY RECAP *************************************************************************************************************
192.168.44.151             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
[root@manager web]# cat /etc/nginx/conf.d/test1.xadocker.cn.conf
server {
    listen                             80;
    server_name                        test1.xadocker.cn;
    index                              index.html;
    root                               /home/wwwroot/test1.xadocker.cn/public;

    # logging
    access_log /home/wwwlogs/test1.xadocker.cn.access.log combined buffer=512k flush=1m;
}
[root@manager web]# cat /etc/nginx/conf.d/test2.xadocker.cn.conf
server {
    listen                             80;
    server_name                        test2.xadocker.cn;
    index                              index.html;
    root                               /home/wwwroot/test2.xadocker.cn/public;

}

模板语言循环

循环可以使用以下方法

{% for i in you_vars %}

{% endfor %}

{% for user in users %}
    {%- if loop.index is even %}{% continue %}{% endif %}
    ...
{% endfor %}

{% for user in users %}
    {%- if loop.index >= 10 %}{% break %}{% endif %}
{%- endfor %}

循环中可以使用这些特殊变量

变量 描述
loop.index 当前循环迭代的次数(从 1 开始)
loop.index0 当前循环迭代的次数(从 0 开始)
loop.revindex 到循环结束需要迭代的次数(从 1 开始)
loop.revindex0 到循环结束需要迭代的次数(从 0 开始)
loop.first 如果是第一次迭代,为 True 。
loop.last 如果是最后一次迭代,为 True 。
loop.length 序列中的项目数

循环渲染配置ip百名单

# 模板文件
[root@manager web]# cat web.conf.j2
server {
    listen                             {{ port }};
    server_name                        {{ item }};
    index                              index.html;
    root                               /home/wwwroot/{{ item }}/public;

{% if item == "test1.xadocker.cn" %}
    # logging
    access_log /home/wwwlogs/{{ item }}.access.log combined buffer=512k flush=1m;
{% endif %}

    # check file
    location ~ ^/.*check\.txt$ {
        {% for ip in allow_list %}
        allow  {{ ip }};
        {% endfor %}
        deny all;
    }
}

# playbook配置
[root@manager web]# cat nginx-template.yaml
---
- name: render nginx web conf
  hosts: web
  vars:
    server_name:
    - "test1.xadocker.cn"
    - "test2.xadocker.cn"
    port: "80"
    allow_list:
    - "192.168.1.0/24"
    - "192.168.2.0/24"
    - "192.168.3.0/24"
  tasks:
  - name: render nginx web conf
    template:
      src: ./web.conf.j2
      dest: /etc/nginx/conf.d/{{ item }}.conf
    with_items:
    - "{{ server_name }}"

# 任务输出
[root@manager web]# ansible-playbook -i hosts nginx-template.yaml
[WARNING]: Found variable using reserved name: port

PLAY [render nginx web conf] *******************************************************************************************

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

TASK [render nginx web conf] *******************************************************************************************
changed: [192.168.44.151] => (item=test1.xadocker.cn)
changed: [192.168.44.151] => (item=test2.xadocker.cn)

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

[root@manager web]# cat /etc/nginx/conf.d/test1.xadocker.cn.conf
server {
    listen                             80;
    server_name                        test1.xadocker.cn;
    index                              index.html;
    root                               /home/wwwroot/test1.xadocker.cn/public;

    # logging
    access_log /home/wwwlogs/test1.xadocker.cn.access.log combined buffer=512k flush=1m;

    # check file
    location ~ ^/.*check\.txt$ {
                allow  192.168.1.0/24;
                allow  192.168.2.0/24;
                allow  192.168.3.0/24;
                deny all;
    }
}

模板语言移除空白

{%- for item in seq -%}
    {{ item }}
{%- endfor -%}

这会产出中间不带空白的所有元素。如果 seq 是 1 到 9 的数字的列表, 输出会是 123456789

给nginx配置增加静态文件缓存时间

# 模板文件
[root@manager web]# cat web.conf.j2
server {
    listen                             {{ port }};
    server_name                        {{ item }};
    index                              index.html;
    root                               /home/wwwroot/{{ item }}/public;

{% if item == "test1.xadocker.cn" %}
    # logging
    access_log /home/wwwlogs/{{ item }}.access.log combined buffer=512k flush=1m;
{% endif %}

    # check file
    location ~ ^/.*check\.txt$ {
        {% for ip in allow_list %}
        allow  {{ ip }};
        {% endfor %}
        deny all;
    }
    location ~* \.(
        {%- for i in static_file_ext -%}
            {%- if loop.last -%}
                {{ i }}
            {%- else -%}
                {{ i }}|
            {%- endif -%}
        {%- endfor -%}
    )$ {
        expires 7d;
    }
}

# playbook配置
[root@manager web]# cat nginx-template.yaml
---
- name: render nginx web conf
  hosts: web
  vars:
    server_name:
    - "test1.xadocker.cn"
    - "test2.xadocker.cn"
    port: "80"
    allow_list:
    - "192.168.1.0/24"
    - "192.168.2.0/24"
    - "192.168.3.0/24"
    static_file_ext:
    - "js"
    - "css"
    - "jpg"
    - "jpeg"
    - "png"
  tasks:
  - name: render nginx web conf
    template:
      src: ./web.conf.j2
      dest: /etc/nginx/conf.d/{{ item }}.conf
    with_items:
    - "{{ server_name }}"

# 任务输出
[root@manager web]# ansible-playbook -i hosts nginx-template.yaml
[WARNING]: Found variable using reserved name: port

PLAY [render nginx web conf] *******************************************************************************************

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

TASK [render nginx web conf] *******************************************************************************************
changed: [192.168.44.151] => (item=test1.xadocker.cn)
changed: [192.168.44.151] => (item=test2.xadocker.cn)

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

[root@manager web]# cat /etc/nginx/conf.d/test1.xadocker.cn.conf
server {
    listen                             80;
    server_name                        test1.xadocker.cn;
    index                              index.html;
    root                               /home/wwwroot/test1.xadocker.cn/public;

    # logging
    access_log /home/wwwlogs/test1.xadocker.cn.access.log combined buffer=512k flush=1m;

    # check file
    location ~ ^/.*check\.txt$ {
                allow  192.168.1.0/24;
                allow  192.168.2.0/24;
                allow  192.168.3.0/24;
                deny all;
    }
    location ~* \.(js|css|jpg|jpeg|png)$ {
        expires 7d;
    }
}

另外一种更简便的行内列表拼接方式就是使用过滤器join

{{ [1, 2, 3]|join('|') }}
    -> 1|2|3

{{ [1, 2, 3]|join }}
    -> 123

之前的例子可以改写为

[root@manager web]# cat web.conf.j2
server {
    listen                             {{ port }};
    server_name                        {{ item }};
    index                              index.html;
    root                               /home/wwwroot/{{ item }}/public;

{% if item == "test1.xadocker.cn" %}
    # logging
    access_log /home/wwwlogs/{{ item }}.access.log combined buffer=512k flush=1m;
{% endif %}

    # check file
    location ~ ^/.*check\.txt$ {
        {% for ip in allow_list %}
        allow  {{ ip }};
        {% endfor %}
        deny all;
    }
    location ~* \.({{ static_file_ext|join('|') }})$ {
        expires 7d;
    }
}

模板语言注释

要把模板中一行的部分注释掉,默认使用 {# ... #} 注释语法。这在调试或 添加给你自己或其它模板设计者的信息时是有用的

{# note: disabled template because we no longer use this
    {% for user in users %}
        ...
    {% endfor %}
#}

模板语言自动转义

可以在模版中开启或者关闭自动转义,例如用template渲染为模板文件,而不是渲染成最钟的配置文件

{% autoescape true %}
自动转义在这块文本中是开启的。
{% endautoescape %}

{% autoescape false %}
自动转义在这块文本中是关闭的。
{% endautoescape %}

模板语言的各种方法还有很多,此处就举例一些博主层级常用的方式。若读者有其他需求可以查看jinja2的官方文档学习:http://doc.yonyoucloud.com/doc/jinja2-docs-cn/index.html

正文完
 
xadocker
版权声明:本站原创文章,由 xadocker 2019-04-19发表,共计11111字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)