介绍
Ansible 是一个被广泛使用的 IT 自动化工具,它简化了基础设施管理和部署。在这个实验(Lab)中,我们将探讨如何使用 Ansible 以长格式列出文件和目录。你将学习如何设置 Ansible,创建 playbook,并使用内置模块从远程系统列出文件信息。通过完成这个实验,你将获得 Ansible 命令和技术的实践经验,这些经验可以增强你的自动化工作流程。
Ansible 是一个被广泛使用的 IT 自动化工具,它简化了基础设施管理和部署。在这个实验(Lab)中,我们将探讨如何使用 Ansible 以长格式列出文件和目录。你将学习如何设置 Ansible,创建 playbook,并使用内置模块从远程系统列出文件信息。通过完成这个实验,你将获得 Ansible 命令和技术的实践经验,这些经验可以增强你的自动化工作流程。
在这一步,我们将在系统上安装 Ansible,并创建一个基本的 inventory 文件来管理我们的本地环境。
首先,让我们使用包管理器安装 Ansible:
sudo apt update
sudo apt install -y ansible
安装完成后,通过检查 Ansible 的版本来验证它是否正确安装:
ansible --version
你应该看到类似这样的输出:
ansible [core 2.12.0]
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/labex/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3/dist-packages/ansible
ansible collection location = /home/labex/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/bin/ansible
python version = 3.10.x (default, Ubuntu 22.04)
jinja version = 3.0.3
libyaml = True
一个 inventory 文件是 Ansible 可以使用的被管理节点的列表。对于这个实验,我们将创建一个简单的 inventory 文件,其中包含我们的本地机器。
为我们的 Ansible 项目创建一个目录:
mkdir -p ~/project/ansible-lab
cd ~/project/ansible-lab
现在,使用 VS Code 编辑器创建一个 inventory 文件:
~/project/ansible-lab 目录inventory.ini[local]
localhost ansible_connection=local
这个 inventory 文件定义了一个名为 local 的组,该组仅包含我们的 localhost,并指定 Ansible 应该在本地连接而不是使用 SSH。
让我们创建一个基本的 Ansible 配置文件来指定默认设置:
ansible-lab 目录并选择“New File”ansible.cfg[defaults]
inventory = inventory.ini
host_key_checking = False
这个配置文件告诉 Ansible 默认使用我们的 inventory.ini 文件,并禁用 SSH 主机密钥检查,这对于实验环境很有用。
让我们通过运行一个简单的命令来测试我们的 Ansible 设置:
cd ~/project/ansible-lab
ansible local -m ping
你应该看到类似这样的输出:
localhost | SUCCESS => {
"changed": false,
"ping": "pong"
}
这确认了 Ansible 已正确配置,并且可以与我们的本地机器通信。
在这一步,我们将创建一个基本的 Ansible playbook 来列出文件和目录。Playbook 是 YAML 文件,它定义了一组要在被管理节点上执行的任务。
在我们开始创建 playbook 之前,让我们了解一下什么是 playbook:
让我们创建一个简单的 playbook 来列出 /etc 目录的内容:
~/project/ansible-lab 目录list_files.yml---
- name: List files and directories
hosts: local
tasks:
- name: Get directory listing
command: ls -l /etc
register: directory_contents
- name: Display directory contents
debug:
var: directory_contents.stdout_lines
让我们了解一下这个 playbook 的作用:
---) 表示 YAML 文档的开始name: List files and directories 是 play 的描述性名称hosts: local 指定此 play 将在 local 组中的主机上运行(在我们的 inventory 中定义)tasks: 开始要执行的任务列表ls -l /etc 并将结果存储在名为 directory_contents 的变量中directory_contents.stdout_lines 变量的内容现在让我们运行我们的 playbook:
cd ~/project/ansible-lab
ansible-playbook list_files.yml
你应该看到类似这样的输出:
PLAY [List files and directories] *****************************************************
TASK [Gathering Facts] ****************************************************************
ok: [localhost]
TASK [Get directory listing] **********************************************************
changed: [localhost]
TASK [Display directory contents] *****************************************************
ok: [localhost] => {
"directory_contents.stdout_lines": [
"total 1088",
"drwxr-xr-x 2 root root 4096 Apr 15 12:34 acpi",
"drwxr-xr-x 3 root root 4096 Apr 15 12:34 alternatives",
"-rw-r--r-- 1 root root 3028 Aug 1 2017 bash.bashrc",
"drwxr-xr-x 2 root root 4096 Apr 15 12:34 bash_completion.d",
"... [more files and directories] ..."
]
}
PLAY RECAP ***************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
输出显示了 /etc 目录的内容,采用长格式,其中包括权限、所有者、组、大小和修改日期。
现在让我们修改我们的 playbook 以列出 /home/labex 目录的内容:
list_files.yml 文件/etc 更改为 /home/labex---
- name: List files and directories
hosts: local
tasks:
- name: Get directory listing
command: ls -l /home/labex
register: directory_contents
- name: Display directory contents
debug:
var: directory_contents.stdout_lines
再次运行 playbook:
ansible-playbook list_files.yml
输出现在将显示 /home/labex 目录的内容,而不是 /etc。
在上一步中,我们使用了 command 模块来运行 ls -l 命令。虽然这可行,但 Ansible 提供了更专用的模块来处理文件和目录:ansible.builtin.file 模块。在这一步中,我们将学习如何将此模块与 ansible.builtin.find 模块一起使用,以更 Ansible 原生的方式列出文件。
ansible.builtin.find 模块旨在查找与特定条件匹配的文件。与 command 模块相比,它提供了一种更强大、更灵活的方式来列出文件。
让我们创建一个使用 find 模块的新 playbook:
~/project/ansible-lab 目录find_files.yml---
- name: Find files with Ansible
hosts: local
tasks:
- name: Find all files in /etc
ansible.builtin.find:
paths: /etc
file_type: any
register: found_files
- name: Display the first 10 files
debug:
var: found_files.files[:10]
此 playbook 使用 find 模块来定位 /etc 目录中的所有文件和目录,然后显示前 10 个项目。
让我们运行 playbook:
cd ~/project/ansible-lab
ansible-playbook find_files.yml
你应该看到包含有关每个文件的详细信息的输出,包括:
现在,让我们创建一个更全面的 playbook,它以长格式显示文件,并包含所有详细信息:
long_format.yml---
- name: List files in long format
hosts: local
tasks:
- name: Find files in /etc
ansible.builtin.find:
paths: /etc
file_type: any
recurse: no
register: found_files
- name: Create a formatted list of files
set_fact:
formatted_files: "{{ formatted_files | default([]) + [item] }}"
loop: "{{ found_files.files }}"
loop_control:
label: "{{ item.path }}"
vars:
item_info: >-
{{ item.mode }} {{ item.uid | string | ljust(5) }}
{{ item.gid | string | ljust(5) }} {{ item.size | string | ljust(10) }}
{{ item.mtime | string | ljust(11) }} {{ item.path }}
- name: Display files in long format
debug:
msg: "{{ formatted_files[:10] }}"
此 playbook:
find 模块来定位 /etc 目录中的文件ls -l 命令的输出让我们运行 playbook:
ansible-playbook long_format.yml
输出将以类似于 ls -l 命令的格式显示文件详细信息。
使用 Ansible 模块的一个优点是能够根据各种条件过滤文件。让我们创建一个 playbook,它仅列出配置文件(以 .conf 结尾的文件):
filter_files.yml---
- name: List filtered files in long format
hosts: local
tasks:
- name: Find configuration files in /etc
ansible.builtin.find:
paths: /etc
patterns: "*.conf"
file_type: file
register: conf_files
- name: Display configuration files
debug:
msg: "{{ item.mode }} {{ item.uid }} {{ item.gid }} {{ item.size }} {{ item.mtime }} {{ item.path }}"
loop: "{{ conf_files.files }}"
loop_control:
label: "{{ item.path }}"
此 playbook:
find 模块来定位 /etc 目录中以 .conf 结尾的文件让我们运行 playbook:
ansible-playbook filter_files.yml
输出将仅显示 /etc 目录中 .conf 文件的详细信息。
让我们再创建一个 playbook 来比较 find 模块的输出与传统的 ls -l 命令:
compare_methods.yml---
- name: Compare listing methods
hosts: local
tasks:
- name: Get directory listing with ls command
command: ls -l /etc/passwd
register: ls_output
- name: Get file info with find module
ansible.builtin.find:
paths: /etc
patterns: "passwd"
file_type: file
register: find_output
- name: Display ls command output
debug:
var: ls_output.stdout_lines
- name: Display find module output
debug:
var: find_output.files[0]
此 playbook:
command 模块在 /etc/passwd 文件上运行 ls -lfind 模块来定位相同的文件让我们运行 playbook:
ansible-playbook compare_methods.yml
你现在可以看到这两种方法之间的区别:
ls -l 命令以传统的 Unix 格式给你一行文本find 模块给你一个结构化的数据对象,你可以在 Ansible 中操作它在这一步中,我们将学习如何创建一个 Ansible 角色用于文件列表。角色是一种组织 playbook 并使其更可重用的方法。当你需要在多个 playbook 或项目中执行相同的任务时,这尤其有用。
一个 Ansible 角色是一组任务、变量、文件、模板和其他资源,它们被分组到一个标准的目录结构中。角色使重用代码并与他人共享代码更容易。
角色的标准目录结构如下所示:
roles/
rolename/
tasks/ ## 角色主要任务
handlers/ ## 由任务触发的处理器
defaults/ ## 默认变量
vars/ ## 角色变量
files/ ## 静态文件
templates/ ## 模板
meta/ ## 角色元数据
让我们创建一个角色,用于以长格式列出文件:
cd ~/project/ansible-lab
mkdir -p roles/file_lister/tasks
cd ~/project/ansible-lab
~/project/ansible-lab/roles/file_lister/tasksmain.yml---
## Tasks for file_lister role
- name: Find files in the specified directory
ansible.builtin.find:
paths: "{{ path | default('/etc') }}"
patterns: "{{ patterns | default('*') }}"
file_type: "{{ file_type | default('any') }}"
recurse: "{{ recurse | default(false) }}"
register: found_files
- name: Display files in long format
debug:
msg: "{{ item.mode }} {{ item.uid }} {{ item.gid }} {{ item.size }} {{ item.mtime }} {{ item.path }}"
loop: "{{ found_files.files | sort(attribute='path') }}"
loop_control:
label: "{{ item.path }}"
when: show_details | default(true)
- name: Display only file paths
debug:
msg: "{{ item.path }}"
loop: "{{ found_files.files | sort(attribute='path') }}"
loop_control:
label: "{{ item.path }}"
when: not (show_details | default(true))
此角色:
现在,让我们创建一个使用我们新角色的 playbook:
~/project/ansible-lab 目录use_role.yml---
- name: Use file listing role
hosts: local
roles:
- role: file_lister
vars:
path: "/etc"
patterns: "*.conf"
file_type: "file"
show_details: true
此 playbook:
file_lister 角色让我们运行 playbook:
cd ~/project/ansible-lab
ansible-playbook use_role.yml
你应该看到输出,显示 /etc 目录中所有 .conf 文件的详细信息。
角色的优点之一是我们可以通过更改变量轻松地自定义其行为。让我们创建另一个 playbook,该 playbook 使用具有不同参数的角色:
custom_listing.yml---
- name: Custom file listing
hosts: local
roles:
- role: file_lister
vars:
path: "/home/labex"
patterns: "*.yml"
file_type: "file"
show_details: false
此 playbook:
file_lister 角色/home/labex 目录中查找让我们运行 playbook:
ansible-playbook custom_listing.yml
你应该看到 /home/labex 目录中所有 YAML 文件的列表,没有详细信息。
最后,让我们创建一个更高级的 playbook,它使用我们的角色来生成文件报告:
generate_report.yml---
- name: Generate file listing report
hosts: local
vars:
report_path: "~/project/ansible-lab/file_report.txt"
tasks:
- name: Find files in the specified directory
ansible.builtin.find:
paths: "/etc"
patterns: "*.conf"
file_type: "file"
register: found_files
- name: Create report header
copy:
dest: "{{ report_path }}"
content: |
File Listing Report
Generated on: {{ ansible_date_time.date }} at {{ ansible_date_time.time }}
-----------------------------------------------------------
Mode Owner Group Size Modified Path
-----------------------------------------------------------
force: yes
- name: Append file information to report
lineinfile:
path: "{{ report_path }}"
line: "{{ item.mode }} {{ item.uid }} {{ item.gid }} {{ item.size | string | ljust(10) }} {{ item.mtime }} {{ item.path }}"
loop: "{{ found_files.files | sort(attribute='path') }}"
loop_control:
label: "{{ item.path }}"
- name: Display report location
debug:
msg: "Report generated at {{ report_path }}"
此 playbook:
/etc 目录中查找 .conf 文件让我们运行 playbook:
ansible-playbook generate_report.yml
运行 playbook 后,你可以查看报告:
cat ~/project/ansible-lab/file_report.txt
你应该看到一个格式化的报告,列出 /etc 目录中的所有 .conf 文件。
在这个实验中,你已经学习了如何使用 Ansible 以长格式列出文件和目录。你获得了以下方面的实践经验:
ls -l 命令的基本 playbook这些技能将帮助你自动化跨基础设施的文件管理任务,并将文件列表集成到更大的自动化工作流程中。随着你继续使用 Ansible,你可以基于这些概念构建更复杂的自动化,以管理整个环境中的文件、目录及其权限。