Ansible 练习题与答案解析
环境说明
基础环境配置
主机类型 |
主机名 / IP |
核心配置 |
控制机(master) |
master.example.com192.168.122.100/24 |
RHEL9 系统;可免密 SSH 登录所有受管机;预设 sudo 用户 student(密码 redhat) |
受管机(node1-5) |
node[1-5].example.com192.168.122.[10-50]/24 |
RHEL9 系统;student 用户可免密登录;已配置主机名映射 |
外部服务支持
- 软件源:提供 3 个 RHEL9 源
http://ansible.example.com/rhel9/BaseOS、http://ansible.example.com/rhel9/AppStream、http://ansible.example.com/ansible-automation-platform
- 辅助服务:DNS 解析(example.com 区域)、NTP 时间同步服务
- 预设密码:所有主机 root 口令为 redhat
一、安装和配置 Ansible 环境
需求
- 安装 Ansible 所需软件包;
- 配置主机清单(/home/student/ansible/inventory),按要求划分主机组;
- 配置 ansible.cfg,指定清单、角色、集合路径等。
操作步骤
1. 创建主机清单(/home/student/ansible/inventory)
# 主机组划分:test01、test02、web、test05;webtest 为 web 组的父组
[test01]
node1
[test02]
node2
[web]
node3
node4
[test05]
node5
[webtest:children] # 父组,包含 web 组所有主机
web
2. 配置 ansible.cfg(/home/student/ansible/ansible.cfg)
# 生成默认配置文件(含注释)
ansible-config init --disabled > /home/student/ansible/ansible.cfg
# 编辑关键配置(去除注释并修改)
vim /home/student/ansible/ansible.cfg
[defaults]
inventory = /home/student/ansible/inventory # 主机清单路径
roles_path = /home/student/ansible/roles # 角色存放路径
collections_paths = /home/student/ansible/collections # 集合存放路径
remote_user = student # 远程连接用户
host_key_checking = False # 关闭主机密钥检查(避免首次连接交互)
become = True
become_method = sudo # 提权方式
become_user = root # 提权目标用户(root)
3. 创建角色和集合目录
# 创建角色和集合目录
mkdir -p /home/student/ansible/{roles,collections}
4. 测试环境(验证所有主机连通性)
# 切换到配置文件所在目录(避免路径问题)
cd /home/student/ansible
# 测试所有主机 ping 连通性
ansible all -m ping
- 成功标志:所有主机返回 SUCCESS。
二、创建和运行 Ansible 任务(配置 YUM 仓库)
需求
编写 yum.yml,为所有受管机配置 2 个 YUM 仓库(BASEOS、APPSTREAM),启用 GPG 签名。
剧本内容(/home/student/ansible/yum.yml)
---
- name: 为所有受管机配置 YUM 仓库
hosts: all # 目标:所有主机
tasks:
# 配置 BASEOS 仓库
- name: 配置 BASEOS 仓库
yum_repository:
name: BASEOS # 仓库 ID(唯一)
description: software base # 仓库描述
baseurl: http://ansible.example.com/rhel9/BaseOS # 仓库 URL
gpgcheck: yes # 启用 GPG 校验
gpgkey: http://ansible.example.com/rhel9/RPM-GPG-KEY-redhat-release # GPG 密钥 URL
enabled: yes # 启用仓库
# 配置 APPSTREAM 仓库
- name: 配置 APPSTREAM 仓库
yum_repository:
name: APPSTREAM
description: software stream
baseurl: http://ansible.example.com/rhel9/AppStream
gpgcheck: yes
gpgkey: http://ansible.example.com/rhel9/RPM-GPG-KEY-redhat-release
enabled: yes
执行与验证
# 执行剧本
cd /home/student/ansible
ansible-playbook yum.yml
# 验证(在任意受管机执行,如 node1)
ansible node1 -m shell -a 'yum repolist'
# 成功标志:列表中包含 BASEOS 和 APPSTREAM 仓库
三、编写剧本远程安装软件(tools.yml)
需求
- 给 test01、test02、web 组安装 php 和 tftp;
- 给 test01 组安装 RPM Development Tools 软件包组;
- 升级 test01 组所有软件到最新版。
剧本内容(/home/student/ansible/tools.yml)
---
# Play 1:给 test01、test02、web 组安装 php 和 tftp
- name: 安装 php 和 tftp 软件
hosts: test01,test02,web # 多主机组用逗号分隔
tasks:
- name: 安装 php 和 tftp
yum:
name: # 需安装的软件列表
- php
- tftp
state: present # 确保软件已安装(不存在则安装)
# Play 2:给 test01 组安装软件包组并升级所有软件
- name: 给 test01 组安装软件包组并升级
hosts: test01
tasks:
# 安装 RPM Development Tools 软件包组(组名需加 @)
- name: 安装 RPM Development Tools 软件包组
yum:
name: "@RPM Development Tools" # @ 表示软件包组
state: present
# 升级所有软件到最新版
- name: 升级所有软件
yum:
name: '*' # 匹配所有软件包
state: latest # 升级到最新版
四、配置计划任务(jihua.yml)
需求
给 test02 组主机的 student 用户配置计划任务:每 5 分钟执行 echo "hello tarena"。
剧本内容(/home/student/ansible/jihua.yml)
---
- name: 给 test02 组配置计划任务
hosts: test02
tasks:
- name: 配置 student 用户的计划任务
cron:
name: aa # 任务名称(唯一,用于后续修改/删除)
user: student # 计划任务所属用户
minute: '*/5' # 分钟:每 5 分钟(*/N 表示每 N 单位)
job: 'echo "hello tarena"' # 需执行的命令(建议用单引号避免转义)
state: present # 确保任务存在(默认,可省略)
执行与验证
# 执行剧本
ansible-playbook jihua.yml
# 验证(查看 student 用户的计划任务)
ansible test02 -m shell -a 'crontab -u student -l'
# 成功标志:输出中包含 "*/5 * * * * echo "hello tarena""
五、安装并使用系统角色(时间同步 timesync)
需求
- 安装 RHEL 系统角色包;
- 给 test01 组配置时间同步,使用 ansible.example.com 作为 NTP 服务器,启用 iburst。
操作步骤
1. 安装系统角色包
# 在控制机执行(需 root 权限)
sudo yum -y install rhel-system-roles
2. 复制 timesync 角色到自定义路径
# 系统角色默认路径:/usr/share/ansible/roles
sudo cp -r /usr/share/ansible/roles/rhel-system-roles.timesync
/home/student/ansible/roles/timesync
3. 剧本内容(/home/student/ansible/timesync.yml)
---
- name: 给 test01 组配置时间同步
hosts: test01
vars:
# 配置 NTP 服务器:启用 iburst(加速首次同步)
timesync_ntp_servers:
- hostname: ansible.example.com # NTP 服务器地址
iburst: yes # 启用 iburst 参数
roles:
- timesync # 引用自定义路径下的 timesync 角色
执行与验证
# 执行剧本
ansible-playbook timesync.yml
# 验证(查看时间同步状态)
ansible test01 -m shell -a 'chronyc sources'
六、通过 Galaxy 安装角色与 Collection
需求 1:安装自定义角色(haproxy、myphp)
1. 创建角色安装配置文件(down.yml)
# /home/student/ansible/roles/down.yml
---
# 角色 1:haproxy
- name: haproxy # 角色名(安装后目录名)
src: http://ansible.example.com/roles/haproxy.tar # 角色下载 URL
# 角色 2:myphp
- name: myphp
src: http://ansible.example.com/roles/myphp.tar
2. 安装角色到指定路径
# 执行安装(-p 指定安装路径,-r 指定配置文件)
cd /home/student/ansible
ansible-galaxy install -r roles/down.yml -p roles/
# 验证(列出本地角色)
ansible-galaxy list
# 成功标志:列表中包含 haproxy 和 myphp
需求 2:安装 Collection(ansible-posix、community-general)
安装命令
# 安装 ansible-posix-1.5.1.tar.gz
ansible-galaxy collection install http://ansible.example.com/materials/ansible-posix-1.5.1.tar.gz -p collections/
# 安装 community-general-6.3.0.tar.gz
ansible-galaxy collection install http://ansible.example.com/materials/community-general-6.3.0.tar.gz -p collections/
# 验证(列出已安装的 Collection)
ansible-galaxy collection list
# 成功标志:列表中包含 ansible.posix 和 community.general
七、创建及使用自定义角色(httpd 角色)
需求
- 角色功能:安装 httpd 并开机自启、配置防火墙允许 http、用模板生成网页;
- 网页内容:Welcome to HOSTNAME on IPADDRESS(HOSTNAME 为 FQDN,IPADDRESS 为 IP);
- 编写 myrole.yml,给 webtest 组启用该角色。
操作步骤
1. 创建 httpd 角色目录
# 进入角色目录
cd /home/student/ansible/roles
# 创建 httpd 角色(自动生成固定目录结构)
ansible-galaxy init httpd
2. 编写模板文件(httpd/templates/index.html.j2)
# 模板中使用 Ansible 内置变量(动态生成内容)
Welcome to {{ ansible_fqdn }} on {{ ansible_default_ipv4.address }}
3. 编写角色任务(httpd/tasks/main.yml)
---
# tasks file for httpd:角色的核心任务逻辑
- name: 安装 httpd 和 firewalld
yum:
name:
- httpd # Web 服务
- firewalld # 防火墙服务
state: present
- name: 用模板生成网页文件
template:
src: index.html.j2 # 引用 templates 目录下的模板(无需写路径)
dest: /var/www/html/index.html # 目标路径(网页根目录)
mode: '0644' # 文件权限(所有者读写,其他读)
- name: 启动并设置 httpd、firewalld 开机自启
service:
name: "{{ item }}" # 循环变量(对应 loop 中的服务名)
state: restarted # 确保服务重启(首次安装后启动)
enabled: yes # 开机自启
loop: # 循环执行(一次处理两个服务)
- httpd
- firewalld
- name: 配置防火墙允许 http 服务
firewalld:
service: http # 预定义服务名(http 对应 80 端口)
state: enabled # 允许访问
permanent: yes # 永久生效(重启防火墙后保留)
immediate: yes # 临时生效(无需重启防火墙)
4. 编写引用角色的剧本(myrole.yml)
# /home/student/ansible/myrole.yml
---
- name: 给 webtest 组启用 httpd 角色
hosts: webtest # 目标主机组(包含 web 组)
roles:
- httpd # 引用 httpd 角色(角色名即目录名)
执行与验证
# 执行剧本
cd /home/student/ansible
ansible-playbook myrole.yml
# 验证(访问任意 webtest 组主机的网页,如 node3)
curl http://node3.example.com
# 成功标志:输出 "Welcome to node3.example.com on 192.168.122.30"
八、使用 Galaxy 下载的角色(web.yml)
需求
- 给 test05 组运行 haproxy 角色(实现负载均衡);
- 给 webtest 组运行 myphp 角色(配置 PHP 页面);
- 访问 node5.example.com 和 node5.example.com/index.php 应显示不同主机的欢迎页。
剧本内容(/home/student/ansible/web.yml)
---
# Play 1:给 webtest 组运行 myphp 角色(先配置后端 PHP 服务)
- name: 给 webtest 组配置 PHP 服务(myphp 角色)
hosts: webtest
roles:
- myphp # 引用 Galaxy 下载的 myphp 角色
# Play 2:给 webtest 组运行 haproxy 角色
- name: 给 test05 配置负载均衡
hosts: test05
roles:
- haproxy # 引用 Galaxy 下载的 haproxy 角色
执行与验证:
# 执行剧本
cd /home/student/ansible
ansible-playbook web.yml
# 验证 1:访问负载均衡地址(node5)的默认页面
curl http://node5.example.com
# 成功标志:多次执行,返回不同 webtest 组主机(node3/node4)的欢迎页
# 验证 2:访问 PHP 页面
curl http://node5.example.com/index.php
# 成功标志:多次执行,返回不同 webtest 组主机的 PHP 欢迎页(负载均衡生效)
九、编写剧本远程管理逻辑卷(lvm.yml)
需求
- 在所有受管机的 search 卷组中创建 mylv 逻辑卷(大小 1000MiB);
- 用 ext4 格式化逻辑卷;
- 若卷组空间不足,显示错误并改为 500MiB;
- 若卷组不存在,显示错误;无需挂载逻辑卷。
剧本内容(/home/student/ansible/lvm.yml)
---
- name: 管理逻辑卷(LVM)配置
hosts: all
tasks:
# 场景 1:卷组 search 存在时,创建逻辑卷
- name: 卷组 search 存在时创建逻辑卷
block: # 代码块:正常执行逻辑
- name: 尝试创建 1000MiB 的 mylv 逻辑卷
lvol:
lv: mylv # 逻辑卷名
vg: search # 卷组名
size: 1000MiB # 目标大小
state: present # 确保逻辑卷存在
rescue: # 代码块:block 执行失败时触发(空间不足)
- name: 输出空间不足错误信息
debug:
msg: "insufficient free space" # 需求指定错误信息
- name: 改为创建 500MiB 的 mylv 逻辑卷
lvol:
lv: mylv
vg: search
size: 500MiB
state: present
always: # 代码块:无论 block/rescue 是否成功,均执行(格式化逻辑卷)
- name: 用 ext4 格式化 mylv 逻辑卷
filesystem:
dev: /dev/search/mylv # 逻辑卷设备路径
fstype: ext4 # 文件系统类型
when: "'search' in ansible_lvm.vgs" # 条件:卷组 search 存在
# 场景 2:卷组 search 不存在时,输出错误
- name: 卷组 search 不存在时输出错误
debug:
msg: "VG not found" # 需求指定错误信息
when: "'search' not in ansible_lvm.vgs" # 条件:卷组 search 不存在
执行与验证
# 执行剧本
ansible-playbook lvm.yml
十、根据模板部署主机文件(newhosts.yml)
需求
- 下载模板 newhosts.j2,生成包含所有主机的 /etc/newhosts 文件;
- 模板需包含本地回环地址和所有受管机的 IP、FQDN、短主机名;
- 仅在 test01 组主机生成该文件。
操作步骤
1. 下载模板文件
# 切换到工作目录
cd /home/student/ansible
# 下载模板
curl -O http://ansible.example.com/materials/newhosts.j2
2. 编辑模板文件(newhosts.j2)
# 本地回环地址(固定内容)
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
# 循环生成所有受管机的主机映射(利用 Ansible 内置变量)
{% for host in groups.all %} # 遍历所有主机组中的主机
{{ hostvars[host].ansible_default_ipv4.address }} {{ hostvars[host].ansible_fqdn }} {{ hostvars[host].ansible_hostname }}
{% endfor %}
- 变量说明:
-
- hostvars[host]:获取指定主机的所有 facts 变量;
-
- ansible_default_ipv4.address:主机默认 IP 地址;
-
- ansible_fqdn:主机完全域名;
-
- ansible_hostname:主机短名。
3. 剧本内容(/home/student/ansible/newhosts.yml)
---
- name: 给 test01 组部署主机文件(newhosts)
hosts: test01
tasks:
- name: 用模板生成 /etc/newhosts 文件
template:
src: /home/student/ansible/newhosts.j2 # 本地模板路径
dest: /etc/newhosts # 目标主机路径
执行与验证
# 执行剧本
ansible-playbook newhosts.yml
# 验证(查看 test01 组主机的 /etc/newhosts 文件)
ansible test01 -m shell -a 'cat /etc/newhosts'
# 成功标志:文件包含回环地址和所有受管机的 IP、FQDN、短主机名(如 192.168.122.10 node1.example.com node1)
十一、编写剧本修改远程文件内容(newissue.yml)
需求
- 在所有受管机修改 /etc/issue 文件(登录欢迎信息);
- test01 组主机内容为 test01;
- test02 组主机内容为 test02;
- web 组主机内容为 Webserver。
剧本内容(/home/student/ansible/newissue.yml)
---
- name: 批量修改 /etc/issue 文件内容
hosts: all
tasks:
- name: 根据主机组动态设置 /etc/issue 内容
copy:
content: | # 多行内容,用 | 保留格式
{% if 'test01' in group_names %} # 条件 1:属于 test01 组
test01
{% elif 'test02' in group_names %} # 条件 2:属于 test02 组
test02
{% elif 'web' in group_names %} # 条件 3:属于 web 组
Webserver
{% endif %}
dest: /etc/issue # 目标文件路径
- 关键说明:group_names 是 Ansible 内置变量,存储当前主机所属的所有主机组列表。
执行与验证
# 执行剧本
ansible-playbook newissue.yml
# 验证 1:test01 组(node1)
ansible node1 -m shell -a 'cat /etc/issue' # 输出:test01
# 验证 2:test02 组(node2)
ansible node2 -m shell -a 'cat /etc/issue' # 输出:test02
# 验证 3:web 组(node3)
ansible node3 -m shell -a 'cat /etc/issue' # 输出:Webserver
十二、编写剧本部署远程 Web 目录(webdev.yml)
需求
- 在 test01 组主机创建 /webdev 目录(属组 webdev,权限 rwxrwxr-x,SetGID 权限);
- 创建符号链接 /var/www/html/webdev 指向 /webdev;
- 在 /webdev 中创建 index.html(内容 It's works!);
- 确保 httpd 和防火墙正常,访问 http://node1/webdev/ 显示内容。
剧本内容(/home/student/ansible/webdev.yml)
---
- name: 部署 Web 目录(webdev)到 test01 组
hosts: test01
tasks:
# 1. 创建 webdev 组
- name: 创建 webdev 组
group:
name: webdev
state: present # 确保组存在
# 2. 创建 /webdev 目录(含 SetGID 权限)
- name: 创建 /webdev 目录并设置权限
file:
path: /webdev
state: directory # 类型:目录
group: webdev # 属组:webdev
mode: '2775' # 权限:rwxrwxr-x + SetGID(2 代表 SetGID)
setype: httpd_sys_content_t # SELinux 上下文(允许 httpd 访问)
# 3. 安装 httpd 和 firewalld(确保服务存在)
- name: 安装 httpd 和 firewalld
yum:
name:
- httpd
- firewalld
state: present
# 4. 创建 /webdev/index.html 文件
- name: 创建 index.html 文件
copy:
content: "It's works!\n" # 内容(换行符 \n 确保格式正确)
dest: /webdev/index.html
mode: '0644'
setype: httpd_sys_content_t # SELinux 上下文(允许 httpd 读取)
# 5. 创建符号链接 /var/www/html/webdev -> /webdev
- name: 创建 Web 目录符号链接
file:
src: /webdev # 源路径(真实目录)
dest: /var/www/html/webdev # 目标路径(符号链接)
state: link # 类型:符号链接
force: yes # 若链接已存在,强制覆盖
# 6. 启动并设置 httpd、firewalld 开机自启
- name: 启动服务并设置开机自启
service:
name: "{{ item }}"
state: restarted
enabled: yes
loop:
- httpd
- firewalld
# 7. 配置防火墙允许 http 服务
- name: 防火墙允许 http 服务
firewalld:
service: http
state: enabled
permanent: yes
immediate: yes
执行与验证
# 执行剧本
ansible-playbook webdev.yml
# 验证 1:检查目录权限和链接
ansible node1 -m shell -a 'ls -ld /webdev /var/www/html/webdev'
# 成功标志:/webdev 权限为 drwxrwxr-x(含 s 标志,SetGID);/var/www/html/webdev 为符号链接
# 验证 2:访问 Web 页面
curl http://node1/webdev/
# 成功标志:输出 "It's works!"
十三、编写剧本为受管机生成硬件报告(hardware.yml)
需求
- 所有受管机从指定 URL 下载 hardware.empty,生成 /root/hardware.txt;
- 报告包含:主机名、总内存(MB)、BIOS 版本、vda/vdb 硬盘大小;
- 若硬件信息不存在,替换为 NONE。
剧本内容(/home/student/ansible/hardware.yml)
---
- name: 生成硬件报告(hardware.txt)
hosts: all
tasks:
# 1. 下载 hardware.empty 并保存为 /root/hardware.txt
- name: 下载硬件报告模板文件
get_url:
url: http://ansible.example.com/materials/hardware.empty # 下载 URL
dest: /root/hardware.txt # 目标路径
# 2. 替换报告中的变量:主机名(inventory_hostname)
- name: 替换主机名变量
replace:
path: /root/hardware.txt
regexp: 'inventoryhostname' # 模板中的占位符(需与 hardware.empty 一致)
replace: "{{ inventory_hostname }}" # Ansible 内置变量(清单主机名)
# 3. 替换总内存(MB)
- name: 替换总内存变量
replace:
path: /root/hardware.txt
regexp: 'memory_in_MB' # 模板占位符
replace: "{{ ansible_memtotal_mb | default('NONE') }}" # 总内存,默认 NONE
# 4. 替换 BIOS 版本
- name: 替换 BIOS 版本变量
replace:
path: /root/hardware.txt
regexp: 'BIOS_version' # 模板占位符
replace: "{{ ansible_bios_version | default('NONE') }}" # BIOS 版本,默认 NONE
# 5. 替换 vda 硬盘大小(不存在则 NONE)
- name: 替换 vda 硬盘大小变量
replace:
path: /root/hardware.txt
regexp: 'disk_vda_size' # 模板占位符
replace: "{{ ansible_devices.vda.size if ansible_devices.vda is defined else 'NONE' }}"
# 6. 替换 vdb 硬盘大小(不存在则 NONE)
- name: 替换 vdb 硬盘大小变量
replace:
path: /root/hardware.txt
regexp: 'disk_vdb_size' # 模板占位符
replace: "{{ ansible_devices.vdb.size if ansible_devices.vdb is defined else 'NONE' }}"
执行与验证
# 执行剧本
ansible-playbook hardware.yml
# 验证(查看任意主机的硬件报告,如 node1)
ansible node1 -m shell -a 'cat /root/hardware.txt'
# 成功标志:报告包含所有字段,不存在的硬件信息显示为 NONE(如无 vdb 则 disk_vdb_size: NONE)
十四、创建保险库文件(passdb.yml)
需求
- 创建加密文件 passdb.yml,包含 2 个变量:pw_dev: ab1234、pw_man: cd5678;
- 加密 / 解密密码为 pwd@1234,密码存储在 secret.txt 中。
操作步骤
1. 创建明文变量文件(passdb.yml)
# /home/student/ansible/passdb.yml
---
pw_dev: ab1234
pw_man: cd5678
2. 创建密码文件(secret.txt)
# 写入加密密码(仅 student 用户可读写,确保安全)
echo "pwd@1234" > /home/student/ansible/secret.txt
chmod 600 /home/student/ansible/secret.txt # 权限:仅所有者可读
3. 加密保险库文件
# 使用密码文件加密 passdb.yml
cd /home/student/ansible
ansible-vault encrypt passdb.yml --vault-id secret.txt
- **参数说明**:
- `--vault-id`:指定密码文件路径,避免手动输入密码;
- 加密成功后,`passdb.yml` 内容会变为乱码(加密状态)。
十五、编写剧本为受管机批量创建用户(users.yml)
需求
- 下载用户列表 name_list.yml;
- dev 职位用户:在 test01/test02 组创建,用 pw_dev 密码,属补充组 devops;
- man 职位用户:在 web 组创建,用 pw_man 密码,属补充组 opsmgr;
- 密码采用 SHA512 哈希,有效期 30 天。
操作步骤
1. 下载用户列表文件
cd /home/student/ansible
curl -O http://ansible.example.com/materials/name_list.yml
- name_list.yml 内容格式(用户列表):
users:
- name: zhangsan
job: dev
- name: lisi
job: man
- name: wangwu
job: dev
2. 剧本内容(/home/student/ansible/users.yml)
---
# Play 1:为 test01/test02 组创建 dev 职位用户
- name: 为 test01/test02 组创建 dev 职位用户
hosts: test01,test02
vars_files:
- /home/student/ansible/passdb.yml # 引入加密的密码变量
- /home/student/ansible/name_list.yml # 引入用户列表
tasks:
# 1. 创建补充组 devops
- name: 创建 devops 补充组
group:
name: devops
state: present
# 2. 循环创建 dev 职位用户
- name: 创建 dev 职位用户(属 devops 组)
user:
name: "{{ item.name }}" # 用户名(取自用户列表)
groups: devops # 补充组(非主组)
password: "{{ pw_dev | password_hash('sha512') }}" # SHA512 哈希加密密码
state: present # 确保用户存在
password_expire_max: 30 # 密码最大有效期 30 天
loop: "{{ users }}" # 遍历用户列表
when: item.job == 'dev' # 仅创建 job 为 dev 的用户
# Play 2:为 web 组创建 man 职位用户
- name: 为 web 组创建 man 职位用户
hosts: web
become: yes
vars_files:
- /home/student/ansible/passdb.yml
- /home/student/ansible/name_list.yml
tasks:
# 1. 创建补充组 opsmgr
- name: 创建 opsmgr 补充组
group:
name: opsmgr
state: present
# 2. 循环创建 man 职位用户
- name: 创建 man 职位用户(属 opsmgr 组)
user:
name: "{{ item.name }}"
groups: opsmgr
password: "{{ pw_man | password_hash('sha512') }}" # 用 pw_man 密码
state: present
password_expire_max: 30
loop: "{{ users }}"
when: item.job == 'man' # 仅创建 job 为 man 的用户
执行与验证
# 用密码文件执行剧本(需指定 --vault-id)
ansible-playbook users.yml --vault-id /home/student/ansible/secret.txt
# 验证 1:查看 test01 组(node1)的 dev 用户(如 zhangsan)
ansible node1 -m shell -a 'id zhangsan'
# 成功标志:输出包含 `groups=...(devops)...`(补充组正确)
# 验证 2:查看 web 组(node3)的 man 用户(如 lisi)
ansible node3 -m shell -a 'id lisi'
# 成功标志:输出包含 `groups=...(opsmgr)...`(补充组正确)
# 验证 3:查看密码有效期(node1 的 zhangsan)
ansible node1 -m shell -a 'chage -l zhangsan | grep "Maximum number of days between password change"'
# 成功标志:输出 `Maximum number of days between password change: 30`
十六、重设保险库密码(topsec.yml)
需求
- 下载加密文件 topsec.yml(原密码 banana);
- 将密码改为 big_banana。
操作步骤
1. 下载加密文件
cd /home/student/ansible
curl -O http://ansible.example.com/materials/topsec.yml
2. 重设保险库密码
# 执行重设命令(需先输入原密码,再输入新密码)
ansible-vault rekey topsec.yml
- 执行过程交互:
Vault password: # 输入原密码 banana
New Vault password: # 输入新密码 big_banana
Confirm New Vault password: # 再次输入新密码 big_banana
Rekey successful
3. 验证密码修改
# 用新密码查看文件内容(确认解密成功)
ansible-vault view topsec.yml
# 输入新密码 big_banana 后,成功显示文件内容(`I love banana`)
总结
本实战文档覆盖 Ansible 核心场景:
- 环境配置:清单、配置文件、权限基础;
- 基础任务:YUM 仓库、软件安装、计划任务;
- 角色管理:自定义角色、系统角色、Galaxy 角色;
- 进阶功能:LVM 管理、模板部署、保险库加密、用户批量创建;
- 验证逻辑:每个步骤均包含明确的验证命令,确保任务落地生效。
所有操作均基于 RHEL9 环境,符合企业级 Ansible 自动化规范,可直接复用或根据实际需求调整。