Ansible教程:Jinja2 模板介绍、语法 作者:马育民 • 2026-09-26 22:16 • 阅读:10000 # 介绍 Ansible 的模板基于 **Jinja2** 模板引擎,文件后缀一般为 `.j2`。核心用途:把变量、事实(facts)、循环、判断逻辑注入配置文件,动态生成目标主机上的配置,常用于 Nginx、MySQL、系统配置等文件分发。 ### 模块 `template` 模块(区别于 `copy`:copy直接复制文件;template会渲染jinja2语法后再传到远端) # 应用场景 ### 生成配置文件(最常用) - Nginx/Apache:循环批量生成多个 `server {}` 虚拟主机块;根据环境变量动态开关配置项。 - MySQL:不同主机内存不一样,动态计算 `innodb_buffer_pool_size`;prod 开启慢查询,测试环境关闭。 - Redis:根据主机内存设置 maxmemory;不同集群节点生成不同 redis.conf(不同 port、cluster-node-id)。 ### 生成脚本文件 shell、bash、python 启动脚本,渲染变量后传到远端,再赋予执行权限 ### 生成清单、报告 中控机或远端生成主机巡检报告、hosts 文件、静态 inventory # 语法 ### 1. 三种定界符 ##### 1. 变量输出:{{ 表达式 }} 渲染输出值 ```jinja2 {{ nginx_port }} ``` ###### 2. 逻辑控制 `{% 语句 %}` 不输出内容,用于 `if` / `for` 等 ``` {% if nginx_enable %} listen {{ nginx_port }}; {% endif %} ``` ##### 3. 注释 `{# 注释内容 #}` ,渲染后会被删除,不会出现在目标文件 ``` {# 这是nginx监听端口,不要修改 #} ``` ### 3. 条件判断 if / elif / else ```jinja2 {% if env == "prod" %} worker_processes auto; {% elif env == "test" %} worker_processes 2; {% else %} worker_processes 1; {% endif %} ``` 支持逻辑运算符:`and`、`or`、`not`,比较 `==` `!=` `>` `<` `>=` `<=` ### 4. 循环 for ```jinja2 {# 遍历列表 #} {% for site in sites %} server { server_name {{ site.name }}; root {{ site.root }}; } {% endfor %} ``` 循环内置变量: - `loop.index`:从1开始计数 - `loop.index0`:从0开始计数 - `loop.first`:布尔值,是否第一次循环 - `loop.last`:布尔值,是否最后一次循环 ```jinja2 {% for site in sites %} # {{ loop.index }} 站点 server_name {{ site.name }}; {% endfor %} ``` #### 循环 + if 过滤 ```jinja2 {% for site in sites if site.enable %} server_name {{ site.name }}; {% endfor %} ``` # 模板调试 ### 1. 单独渲染模板(不推送到远端) ```bash ansible localhost -m ansible.builtin.template -a "src=test.j2 dest=/tmp/out" ``` ### 2. debug模块查看变量,排查模板取值问题 ```yaml - name: 打印变量 ansible.builtin.debug: msg: "{{ sites }}" ``` ### 3. 查看渲染完成后的文件 登录目标主机查看 `dest` 指定文件,确认渲染结果。 # 注意事项 & 坑 1. **引号与YAML冲突** playbook里mode权限必须加引号 `mode: '0644'`,否则yaml会把0644当成八进制解析出错。 2. **缩进问题** Jinja2的缩进**不强制**,渲染后输出文本的缩进由模板内写的空格决定。 > Jinja2控制语句 `{% %}` 的缩进和生成的配置文件缩进相互独立,容易出现配置文件错乱。 3. **特殊字符转义** 如 `{{ }}`、`%` 要原样写入配置文件(例如prometheus、grafana配置),需要**raw块** ```jinja2 {% raw %} # 原样输出,不解析jinja语法 {{ metric_name }} {% endraw %} ``` 4. **变量优先级** 模板内变量遵循ansible完整变量优先级(extra vars > host_vars > group_vars > play vars)。 5. **换行控制 `-` 减号** `{%-` 去除前面空白换行;`-%}` 去除后面空白换行,用来清理多余空行 ```jinja2 {%- if env == 'prod' %} worker_processes auto; {%- endif %} ``` # template vs copy vs file |模块|作用| |---|---| |`copy`|直接复制文件,**不渲染jinja2**| |`template`|渲染jinja2模板后传输文件| |`file`|仅创建目录、修改权限,不传输内容| 原文出处:/show_1GW481VDeaCw.html