Ansible 练习题与答案解析

发布于:2025-09-10 ⋅ 阅读:(24) ⋅ 点赞:(0)

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/BaseOShttp://ansible.example.com/rhel9/AppStreamhttp://ansible.example.com/ansible-automation-platform

  • 辅助服务:DNS 解析(example.com 区域)、NTP 时间同步服务
  • 预设密码:所有主机 root 口令为 redhat

一、安装和配置 Ansible 环境

需求

  1. 安装 Ansible 所需软件包;
  2. 配置主机清单(/home/student/ansible/inventory),按要求划分主机组;
  3. 配置 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)

需求

  1. 给 test01、test02、web 组安装 php 和 tftp;
  2. 给 test01 组安装 RPM Development Tools 软件包组;
  3. 升级 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)

需求

  1. 安装 RHEL 系统角色包;
  2. 给 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 角色)

需求

  1. 角色功能:安装 httpd 并开机自启、配置防火墙允许 http、用模板生成网页;
  2. 网页内容:Welcome to HOSTNAME on IPADDRESS(HOSTNAME 为 FQDN,IPADDRESS 为 IP);
  3. 编写 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)

需求

  1. 给 test05 组运行 haproxy 角色(实现负载均衡);
  2. 给 webtest 组运行 myphp 角色(配置 PHP 页面);
  3. 访问 node5.example.comnode5.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)

需求

  1. 在所有受管机的 search 卷组中创建 mylv 逻辑卷(大小 1000MiB);
  2. 用 ext4 格式化逻辑卷;
  3. 若卷组空间不足,显示错误并改为 500MiB;
  4. 若卷组不存在,显示错误;无需挂载逻辑卷。

剧本内容(/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)

需求

  1. 下载模板 newhosts.j2,生成包含所有主机的 /etc/newhosts 文件;
  2. 模板需包含本地回环地址和所有受管机的 IP、FQDN、短主机名;
  3. 仅在 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)

需求

  1. 在所有受管机修改 /etc/issue 文件(登录欢迎信息);
  2. test01 组主机内容为 test01;
  3. test02 组主机内容为 test02;
  4. 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)

需求

  1. 在 test01 组主机创建 /webdev 目录(属组 webdev,权限 rwxrwxr-x,SetGID 权限);
  2. 创建符号链接 /var/www/html/webdev 指向 /webdev;
  3. 在 /webdev 中创建 index.html(内容 It's works!);
  4. 确保 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)

需求

  1. 所有受管机从指定 URL 下载 hardware.empty,生成 /root/hardware.txt;
  2. 报告包含:主机名、总内存(MB)、BIOS 版本、vda/vdb 硬盘大小;
  3. 若硬件信息不存在,替换为 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)

需求

  1. 创建加密文件 passdb.yml,包含 2 个变量:pw_dev: ab1234、pw_man: cd5678;
  2. 加密 / 解密密码为 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)

需求

  1. 下载用户列表 name_list.yml;
  2. dev 职位用户:在 test01/test02 组创建,用 pw_dev 密码,属补充组 devops;
  3. man 职位用户:在 web 组创建,用 pw_man 密码,属补充组 opsmgr;
  4. 密码采用 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)

需求

  1. 下载加密文件 topsec.yml(原密码 banana);
  2. 将密码改为 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 核心场景:

  1. 环境配置:清单、配置文件、权限基础;
  2. 基础任务:YUM 仓库、软件安装、计划任务;
  3. 角色管理:自定义角色、系统角色、Galaxy 角色;
  4. 进阶功能:LVM 管理、模板部署、保险库加密、用户批量创建;
  5. 验证逻辑:每个步骤均包含明确的验证命令,确保任务落地生效。

所有操作均基于 RHEL9 环境,符合企业级 Ansible 自动化规范,可直接复用或根据实际需求调整。



网站公告

今日签到

点亮在社区的每一天
去签到