一、案例目标与目录准备¶
原笔记通过一个 nfs-server 角色,演示如何把 NFS 服务端部署过程整理成标准的 Roles 结构。
首先创建目录和入口文件:
[root@oldboy01 ~]# cd /etc/ansible/roles/
[root@oldboy01 roles]# mkdir roles01
[root@oldboy01 roles]# cd roles01/
[root@oldboy01 roles01]# touch top.yml
[root@oldboy01 roles01]# mkdir -p nfs-server/{files,templates,tasks,handlers} group_vars/all/
[root@oldboy01 roles01]# tree -F
.
├── group_vars/
│ └── all/
├── hosts
├── nfs-server/
│ ├── files/
│ ├── handlers/
│ ├── tasks/
│ └── templates/
└── top.yml
这一步的重点不是命令本身,而是先把角色所需的内容按职责放到固定目录中。
二、编写 tasks/main.yml¶
tasks/main.yml 是角色的核心任务列表。原笔记中给出的内容如下:
- name: 01. 部署nfs-utils, rpcbind
yum:
name: nfs-utils,rpcbind
state: present
tags:
- 01.install
- name: 02. 修改配置文件
template:
src: exports.j2
dest: /etc/exports
backup: yes
notify:
- restart_nfs
tags:
- 02.conf
- name: 03. 创建共享目录并更改所有者
file:
path: "{{ nfs_server_dir }}"
owner: "{{ nfs_user }}"
group: "{{ nfs_user }}"
state: directory
tags:
- 03.dir
- name: 04. 启动服务rpcbind, nfs(注意顺序)
systemd:
name: "{{ item }}"
enabled: yes
state: started
loop:
- rpcbind
- nfs
tags:
- 04.start_service
这个任务文件体现了几个关键点:
- 软件安装放在最前面
- 配置文件通过
template渲染 - 配置变更后用
notify触发handlers - 服务启动通过
loop统一处理多个服务 - 每个阶段都打上
tags,便于后续按步骤执行
三、准备静态文件、模板和 handlers¶
原笔记把配套内容分别放到了 files/、templates/ 和 handlers/ 中。
静态文件示例:
[root@oldboy01 roles01]# cat nfs-server/files/exports
/backup-nfs 192.168.1.0/24(rw,all_squash)
模板文件示例:
#author: {{ author}}
{{ nfs_server_dir }} 192.168.1.0/24(rw,all_squash)
处理器示例:
- name: restart_nfs
systemd:
name: nfs
enabled: yes
state: restarted
这里的组织方式很典型:
- 固定内容可以放到
files/ - 需要变量渲染的内容放到
templates/ - 服务重启这类“只在必要时触发”的动作放到
handlers/
四、补全主机清单与入口剧本¶
角色本身准备好之后,还需要清单文件和顶层入口。
主机清单:
[web]
192.168.1.21
[nfs]
192.168.1.22
[data:children]
web
nfs
入口剧本 top.yml:
- hosts: nfs
roles:
- role: nfs-server
到这里,部署入口已经非常清楚:把具体实现放到角色目录,把调用逻辑放到顶层剧本。
五、用检查模式验证角色¶
原笔记最后使用检查模式做模拟执行:
[root@oldboy01 roles01]# ansible-playbook -C top.yml
这一步适合在正式执行前确认:
- 角色目录是否引用正确
- 模板和任务是否能被正常加载
- 剧本整体结构是否已经连通
对 Roles 场景来说,先用 -C 做验证是很实用的习惯。
六、小结¶
这个 NFS 案例完整展示了 Roles 的典型落地方式:
先按目录规范组织项目,再把任务、模板、静态文件、处理器和入口剧本分开维护。这样写出来的自动化脚本,后续无论是扩展功能、增加变量还是交给别人接手,都会轻松很多。