如何用Ansible Playbook识别并自动挂载未挂载磁盘(含新盘初始化)
高阶Ansible磁盘自动挂载方案(适配新旧磁盘)
我来给你梳理一套完全适配你需求的高阶实现思路,不需要硬编码任何磁盘信息,完全依赖Ansible的系统facts和条件判断来自动处理——不管是预格式化好的ext4旧盘,还是空白新盘,都能自动完成识别、分区(仅新盘)、格式化(仅新盘)、挂载到/mnt/{序列号}路径的全流程,同时避开根磁盘、跳过已挂载的磁盘。
核心设计逻辑
首先得明确整个流程的几个核心判断节点,这是实现自动化的关键:
- 排除根磁盘:绝对不能碰系统盘,通过系统挂载信息精准过滤
- 识别未挂载磁盘:只处理当前没有被挂载的磁盘
- 区分新旧磁盘:判断磁盘是否已有ext4分区,决定是否需要执行分区+格式化操作
- 唯一标识磁盘:用磁盘序列号作为挂载点名称,避免设备名(如
/dev/sdb)变动带来的问题
关键模块的高阶运用
你需要组合几个Ansible核心模块,配合facts做动态判断:
- 收集系统磁盘facts:用
ansible.builtin.setup模块获取ansible_devices(所有磁盘设备信息)和ansible_mounts(当前挂载信息),这是整个流程的数据源。- 重点关注字段:
ansible_devices[disk]['serial'](磁盘序列号)、ansible_devices[disk]['partitions'](磁盘分区列表)、ansible_mounts里的device字段(已挂载的设备路径)
- 重点关注字段:
- 分区处理(仅新盘):用
community.general.parted模块创建单分区,设置分区类型为primary,文件系统类型标记为ext4。这里要加条件判断:仅当磁盘没有任何分区时才执行。 - 格式化处理(仅新盘):用
ansible.builtin.filesystem模块创建ext4文件系统,目标是新创建的分区(比如/dev/{{ disk }}1)。条件判断:仅当分区不存在ext4文件系统时执行。 - 挂载点创建:用
ansible.builtin.file模块创建/mnt/{{ disk_serial }}路径,确保目录存在且权限正确。 - 挂载与持久化:用
ansible.builtin.mount模块挂载磁盘分区到指定挂载点,同时写入/etc/fstab,推荐用UUID或者磁盘路径+序列号做标识,挂载选项设置defaults,nofail避免开机挂载失败。
精准条件判断的技巧
这是实现“自适应”的核心,你需要用Jinja2表达式组合多个条件:
- 排除根磁盘:先从
ansible_mounts中筛选出挂载点为/的设备,对应的磁盘(比如/dev/sda)加入排除列表,后续所有操作跳过这个磁盘。when: disk not in root_disk_list - 判断磁盘未挂载:检查磁盘的所有分区是否都不在
ansible_mounts的device列表中:when: ansible_devices[disk]['partitions'] | dict2items | map(attribute='key') | none in ansible_mounts | map(attribute='device') - 判断是否为新盘(需要分区格式化):检查磁盘是否没有任何分区,或者分区的文件系统不是ext4:
when: ansible_devices[disk]['partitions'] | length == 0 or (ansible_devices[disk]['partitions'][partition]['fstype'] is not defined or ansible_devices[disk]['partitions'][partition]['fstype'] != 'ext4')
变量管理与扩展能力
为了方便后续扩展Playbook功能,你需要把关键变量持久化:
- 用
ansible.builtin.set_fact提取磁盘序列号并生成挂载点路径,比如:- set_fact: disk_mount_point: "/mnt/{{ ansible_devices[disk]['serial'] }}" - 可以把这个变量存入主机facts或者自定义的变量文件,后续如果需要扩展(比如配置NFS共享、磁盘监控),直接调用这个变量即可。
避坑指南
- 设备名稳定性:绝对不要依赖
/dev/sdb这种设备名,因为磁盘插拔顺序变化会导致设备名变动,序列号是唯一可靠的标识。 - fstab持久化:挂载时一定要写入
/etc/fstab,否则重启后挂载会丢失,同时加上nofail选项,避免磁盘故障导致系统无法启动。 - 权限控制:创建挂载点时可以设置合适的权限(比如
owner=root,group=root,mode=0755),根据后续使用场景调整。
内容的提问来源于stack exchange,提问作者Bondesen
相关产品推荐
相关产品推荐

