目录
[示例一:Nginx 配置](#示例一:Nginx 配置)
[1. 目录结构](#1. 目录结构)
[2. 模板文件:nginx.conf.j2](#2. 模板文件:nginx.conf.j2)
[3. Playbook 文件:deploy_nginx.yml](#3. Playbook 文件:deploy_nginx.yml)
[4. 执行 Playbook](#4. 执行 Playbook)
[示例二:MySQL 配置](#示例二:MySQL 配置)
[1. 目录结构](#1. 目录结构)
[2. 模板文件:my.cnf.j2](#2. 模板文件:my.cnf.j2)
[3. Playbook 文件:deploy_mysql.yml](#3. Playbook 文件:deploy_mysql.yml)
[4. 执行 Playbook](#4. 执行 Playbook)
[示例三:动态生成 hosts 文件](#示例三:动态生成 hosts 文件)
[1. 目录结构](#1. 目录结构)
[2. 模板文件:hosts.j2](#2. 模板文件:hosts.j2)
[3. Playbook 文件:deploy_hosts.yml](#3. Playbook 文件:deploy_hosts.yml)
[4. 执行 Playbook](#4. 执行 Playbook)
Ansible 的 template
模块用于将模板化的文件部署到远程主机。在模板文件中,我们可以使用 Jinja2 模板语言来动态生成配置文件,从而在部署过程中根据变量替换、循环和条件判断生成实际的配置文件。
基本参数
-
src:
- 描述 : 指定模板文件的路径(相对于
templates
目录)。 - 示例 :
src: my_template.j2
- 描述 : 指定模板文件的路径(相对于
-
dest:
- 描述: 指定模板文件复制到远程主机的目标路径。
- 示例 :
dest: /etc/myconfig.conf
选项参数
-
backup:
- 描述: 如果目标文件已存在,则创建一个备份。
- 类型: 布尔值
- 默认值 :
no
- 示例 :
backup: yes
-
force:
- 描述: 如果目标文件已存在且内容相同,是否仍然覆盖它。
- 类型: 布尔值
- 默认值 :
yes
- 示例 :
force: no
-
mode:
- 描述: 设置目标文件的权限模式。
- 类型: 字符串(八进制)
- 示例 :
mode: '0644'
-
owner:
- 描述: 设置目标文件的所有者。
- 类型: 字符串
- 示例 :
owner: root
-
group:
- 描述: 设置目标文件的所有组。
- 类型: 字符串
- 示例 :
group: root
-
validate:
- 描述 : 在将模板复制到目标位置之前运行命令以验证文件的内容。变量
%s
表示临时文件的路径。 - 类型: 字符串
- 示例 :
validate: '/usr/sbin/nginx -t -c %s'
- 描述 : 在将模板复制到目标位置之前运行命令以验证文件的内容。变量
高级参数
-
setype:
- 描述: 设置目标文件的 SELinux 类型。
- 类型: 字符串
- 示例 :
setype: httpd_config_t
-
seuser:
- 描述: 设置目标文件的 SELinux 用户。
- 类型: 字符串
- 示例 :
seuser: system_u
-
serole:
- 描述: 设置目标文件的 SELinux 角色。
- 类型: 字符串
- 示例 :
serole: object_r
-
selevel:
- 描述: 设置目标文件的 SELinux 级别。
- 类型: 字符串
- 示例 :
selevel: s0
基本用法
template
模块的基本语法包括两个主要参数:
src
: 模板文件的路径,一般以.j2
为后缀。dest
: 目标文件的路径,即模板文件渲染后被复制到的远程主机上的路径。
示例:
假设我们有一个 Web 应用服务器组,需要配置不同的服务如 Nginx 和 MySQL。我们将通过 Ansible 的 template
模块来动态生成和分发这些服务的配置文件。
示例一:Nginx 配置
1. 目录结构
现在在ansible机器中去定义了nginx.conf.j2文件和deploy_nginx.yml剧本文件进行举例。
project/
├── templates/
│ └── nginx.conf.j2
└── deploy_nginx.yml
2. 模板文件:nginx.conf.j2
首先,我们需要创建模板文件 nginx.conf.j2
,其内容如下:
bash
server {
# 监听80端口
listen 80;
# 定义服务器名称,这里使用变量 {{ server_name }}
server_name {{ server_name }};
location / {
# 将请求代理到上游服务器,这里使用变量 {{ upstream }}
proxy_pass http://{{ upstream }};
# 设置主机头信息
proxy_set_header Host $host;
# 设置客户端真实IP地址
proxy_set_header X-Real-IP $remote_addr;
# 设置经过的代理服务器列表
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 设置请求的协议(HTTP 或 HTTPS)
proxy_set_header X-Forwarded-Proto $scheme;
}
}
这个文件定义了一个 Nginx 服务器块,其中 server_name
和 upstream
是变量,稍后会在 Playbook 中动态替换。
3. Playbook 文件:deploy_nginx.yml
然后,创建 Playbook 文件 deploy_nginx.yml
,其内容如下:
bash
---
- name: Deploy Nginx configuration # Playbook 名称
hosts: webservers # 目标主机组
vars:
server_name: example.com # 定义服务器名称变量
upstream: 127.0.0.1:8080 # 定义上游服务器地址变量
tasks:
- name: Deploy nginx configuration from template # 任务名称
template:
src: templates/nginx.conf.j2 # 指定模板文件路径(相对于 templates 目录)
dest: /etc/nginx/nginx.conf # 指定模板文件复制到远程主机的目标路径
notify: # 触发处理程序
- reload nginx # 通知 reload nginx 处理程序
handlers:
- name: reload nginx # 处理程序名称
service:
name: nginx # 服务名称
state: reloaded # 重载 Nginx 服务
hosts: webservers
:指定任务将应用到名为webservers
的主机组。vars
:定义模板中使用的变量server_name
和upstream
。tasks
:使用template
模块将模板nginx.conf.j2
渲染并复制到远程主机的/etc/nginx/nginx.conf
位置。notify
:修改配置后通知reload nginx
处理器重新加载 Nginx 服务。handlers
:定义处理器,在接收到通知时执行 Nginx 服务的重载操作。
4. 执行 Playbook
确保主机清单/etc/ansible/hosts已经定义了 webservers
主机组,然后执行以下命令运行 Playbook:
bash
ansible-playbook deploy_nginx.yml
示例二:MySQL 配置
1. 目录结构
创建并编写的my.cnf.j2和deploy_mysql.yml文件在ansible机器中的位置。
project/
├── templates/
│ └── my.cnf.j2
└── deploy_mysql.yml
2. 模板文件:my.cnf.j2
接下来,创建模板文件 my.cnf.j2
,其内容如下:
bash
[mysqld]
# MySQL 服务器的用户
user = mysql
# MySQL 服务器的 PID 文件位置
pid-file = /var/run/mysqld/mysqld.pid
# MySQL 服务器的 Unix 套接字文件位置
socket = /var/run/mysqld/mysqld.sock
# MySQL 服务器的端口
port = 3306
# MySQL 数据库文件的存储目录
datadir = /var/lib/mysql
# MySQL 服务器绑定的地址,可以使用变量 {{ mysql_bind_address }} 替换为实际值
bind-address = {{ mysql_bind_address }}
这个文件定义了 MySQL 的配置,其中 mysql_bind_address
是一个变量,会在 Playbook 中动态替换。
3. Playbook 文件:deploy_mysql.yml
然后创建 Playbook 文件 deploy_mysql.yml
,其内容如下:
bash
---
- name: Deploy MySQL configuration # Playbook 名称
hosts: dbservers # 目标主机组
vars:
mysql_bind_address: 0.0.0.0 # 定义 MySQL 绑定地址变量
tasks:
- name: Deploy my.cnf from template # 任务名称
template:
src: templates/my.cnf.j2 # 指定模板文件路径(相对于 templates 目录)
dest: /etc/mysql/my.cnf # 指定模板文件复制到远程主机的目标路径
notify: # 触发处理程序
- restart mysql # 通知 restart mysql 处理程序
handlers:
- name: restart mysql # 处理程序名称
service:
name: mysql # 服务名称
state: restarted # 重启 MySQL 服务
hosts: dbservers
:指定任务将应用到名为dbservers
的主机组。vars
:定义模板中使用的变量mysql_bind_address
。tasks
:使用template
模块将模板my.cnf.j2
渲染并复制到远程主机的/etc/mysql/my.cnf
位置。notify
:修改配置后通知restart mysql
处理器重新启动 MySQL 服务。handlers
:定义处理器,在接收到通知时执行 MySQL 服务的重启操作。
4. 执行 Playbook
确保在主机清单中已经定义了 dbservers
主机组,然后执行以下命令运行 Playbook:
bash
ansible-playbook deploy_mysql.yml
示例三:动态生成 hosts 文件
动态生成 /etc/hosts
文件有许多实际应用场景,特别是在网络管理和自动化部署中,它能极大地简化运维管理,提高资源利用效率。
1. 目录结构
project/
├── templates/
│ └── hosts.j2
└── deploy_hosts.yml
2. 模板文件:hosts.j2
接下来,创建模板文件 hosts.j2
,其内容如下:
bash
{% for host in hosts %}
{{ host.ip }} {{ host.name }}
{% endfor %}
这个文件定义了 /etc/hosts
文件的模板,使用变量 hosts
动态生成内容。这是一个 Jinja2 for 循环语句,开始循环遍历变量 hosts
。hosts
是一个列表,其中每个元素是一个包含 ip
和 name
键的字典。
3. Playbook 文件:deploy_hosts.yml
然后,创建 Playbook 文件 deploy_hosts.yml
,其内容如下:
bash
---
- name: Deploy /etc/hosts file # Playbook 名称
hosts: all # 目标主机组,指定该 Playbook 应用到所有主机
vars:
hosts: # 定义 hosts 变量,包括主机名称和 IP 地址的列表
- { name: 'host1', ip: '192.168.1.2' } # 定义主机1的信息
- { name: 'host2', ip: '192.168.1.3' } # 定义主机2的信息
- { name: 'host3', ip: '192.168.1.4' } # 定义主机3的信息
tasks:
- name: Deploy /etc/hosts from template # 任务名称
template:
src: templates/hosts.j2 # 指定模板文件路径(相对于 templates 目录)
dest: /etc/hosts # 指定模板文件复制到远程主机的目标路径
hosts: all
:指定任务将应用到所有主机。vars
:定义模板中使用的变量hosts
列表。tasks
:使用template
模块将模板hosts.j2
渲染并复制到远程主机的/etc/hosts
位置。
4. 执行 Playbook
确保主机清单文件里已经定义了相关的主机组,然后执行以下命令运行 Playbook:
bash
ansible-playbook deploy_hosts.yml