Ansible
Ansible 基础介绍
自动化运维优势
- 手动运维痛点:很容易遗漏某个步骤或错误地执行某个步骤,管理大量服务器很容易会出现差异。
- 自动化运维优势:通过标准化,确保快速、正确地部署和配置所有系统。 自动执行日常计划重复性任务,从而空出时间并专注于更重要的事情。 更快速的交付应用。
Ansible 核心特性
-
简单:Ansible Playbooks 是一个人们非常容易查阅,理解和更改的文本文件。
-
功能强大:可以使用Ansible部署应用,还可用于编排整个应用生命周期。
-
无代理:Ansible 是一个无代理的架构,通过OpenSSH或者WinRM连接到hosts,并执行任务,推送小的程序到这些主机上。
-
跨平台支持:可以管理Linux、UNIX、windows 和网络设备。
-
可以通过版本控制管理:Ansible Playbooks和projects是纯文本格式。
-
非常容易与其他系统集成: HP SA,Puppet,Jenkins,红帽卫星服务器等。
核心概念与架构
核心组件
-
控制节点:安装Ansible的主机,负责执行自动化任务。
-
受管节点:被Ansible管理的服务器、网络设备等。
-
Inventory:受管主机清单,定义需管理的主机及分组。
-
Playbook:自动化任务脚本,包含一个或多个Play,每个Play由一系列Task组成。
-
Module:任务执行单元,Ansible内置数百个模块,用于实现具体操作。
-
Plugin:扩展Ansible功能的代码片段。
环境部署与准备
实验环境规划
| 主机名 | IP地址 | 角色 | 操作系统 |
|---|---|---|---|
| controller | <192.168.108.10> | 控制节点 | CentOS 7 |
| node1 | <192.168.108.11> | 受管节点 | CentOS 7 |
| node2 | <192.168.108.12> | 受管节点 | CentOS 7 |
| node3 | <192.168.108.13> | 受管节点 | CentOS 7 |
Bash
#5个节点都要配置
cat >> /etc/hosts << EOF
192.168.108.10 controller
192.168.108.11 node1
192.168.108.12 node2
192.168.108.13 node3
EOF
配置控制节点 wan 用户使用wan用户免密登录所有节点,并免提sudo提权执行任何命令
Bash
#所有节点添加用户,并设置密码
useradd wan
echo xiaomi | passwd --stdin wan
#所有节点,配置免密提权
echo 'wan ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/wan
Bash
#controller节点
#安装sshpass
[root@controller ~]# yum install -y sshpass
#密钥登陆
[root@controller ~]# su - wan
[wan@controller ~]$ ssh node1
[wan@controller ~]$ ssh node2
[wan@controller ~]$ ssh node3
[wan@controller ~]$ ssh controller
#创建密钥对
[wan@controller ~]$ [ -d ~/.ssh ] || mkdir -m 700 .ssh
[wan@controller ~]$ ssh-keygen -t rsa -f .ssh/id_rsa -N ''
#推送公钥到目标主机
[wan@controller ~]$ for host in controller node{1..3}; do sshpass -p xiaomi ssh-copy-id wan@$host; done
#验证免密登录
[wan@controller ~]$ for host in controller node{1..3}; do ssh wan@$host hostname; done
controller
node1
node2
node3
#安装 ansible
[wan@controller ~]$ sudo yum install -y ansible
[root@controller ~]# ansible --version
ansible 2.9.27
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.5 (default, Oct 14 2020, 14:45:30) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
Ansible 基本使用
Ansible 清单
Ansible 软件包中文件
bash
[root@controller ~]# rpm -ql ansible
- 配置文件目录 /etc/ansible
- 执行文件目录/usr/bin
- lib依赖库目录 /usr/lib/python2.7/site-packages/ansible
- 插件 /usr/share/ansible/plugins
- Help文档目录 /usr/share/doc/ansible
- Man文档目录/usr/share/man/man1/
主机清单
Inventory 定义Ansible将要管理的一批主机。
静态主机清单
主机清单支持多种格式,例如ini、yaml、脚本等。
最简单的静态清单
受管节点的主机名或IP地址的列表,每行一个
bash
[root@controller ~]# vim inventory
[root@controller ~]# cat inventory
web1.example.com
web2.example.com
db1.example.com
db2.example.com
192.0.2.42
#验证主机是否在inventory中
[root@controller ~]# ansible --list-hosts -i inventory web1.example.com
hosts (1):
web1.example.com
[root@controller ~]# ansible --list-hosts -i inventory 192.0.2.42
hosts (1):
192.0.2.42
主机组
将受管节点组织为主机组,通过主机组,更加有效地对一系列系统运行Ansible
bash
[root@controller ~]# vim inventory
app1.example.com
[webservers]
web1.example.com
web2.example.com
[dbservers]
db1.example.com
db2.example.com
192.0.2.42
192.0.2.43
#验证
[root@controller ~]# ansible --list-hosts -i inventory webservers
hosts (2):
web1.example.com
web2.example.com
[root@controller ~]# ansible --list-hosts -i inventory dbservers
hosts (4):
db1.example.com
db2.example.com
192.0.2.42
192.0.2.43
有两个组总是存在的:
all:包含inventory中所有主机。
ungrouped:inventory中列出的,但不属于任何组的主机。
bash
[root@controller ~]# ansible --list-hosts -i inventory all
hosts (7):
app1.example.com
web1.example.com
web2.example.com
db1.example.com
db2.example.com
192.0.2.42
192.0.2.43
[root@controller ~]# ansible --list-hosts -i inventory ungrouped
hosts (1):
app1.example.com
根据需要,将主机分配在多个组中
bash
[root@controller ~]# vim inventory
[webservers]
web1.example.com
web2.example.com
192.168.3.7
[dbservers]
db1.example.com
db2.example.com
192.0.2.42
[eastdc]
web1.example.com
db1.example.com
[westdc]
web2.example.com
db2.example.com
#验证
[root@controller ~]# ansible --list-hosts -i inventory webservers
hosts (3):
web1.example.com
web2.example.com
192.168.3.7
[root@controller ~]# ansible --list-hosts -i inventory eastdc
hosts (2):
web1.example.com
db1.example.com
范围简写
通过指定主机名称或IP地址的范围来简化Ansible主机清单
bash
[root@controller ~]# vim inventory
[priv]
192.168.[4:7].[0:255]
[hosts]
host[01:20].example.com
[servers]
server[a:c].example.com
#验证
[root@controller ~]# ansible --list-hosts -i inventory hosts
hosts (20):
host01.example.com
host02.example.com
host03.example.com
host04.example.com
host05.example.com
host06.example.com
host07.example.com
host08.example.com
host09.example.com
host10.example.com
host11.example.com
host12.example.com
host13.example.com
host14.example.com
host15.example.com
host16.example.com
host17.example.com
host18.example.com
host19.example.com
host20.example.com
[root@controller ~]# ansible --list-hosts -i inventory priv
hosts (1024):
192.168.4.0
192.168.4.1
192.168.4.2
192.168.4.3
192.168.4.4
192.168.4.5
192.168.4.6
192.168.4.7
192.168.4.8
192.168.4.9
192.168.4.10
...
[root@controller ~]# ansible --list-hosts -i inventory servers
hosts (3):
servera.example.com
serverb.example.com
serverc.example.com
管理 ANSIBLE 配置文件
配置文件位置和优先级
- 环境变量 ANSIBLE_CONFIG
- ./ansible.cfg,当前位置中的 ansible.cfg,当前位置一般是项目目录。
- ~/.ansible.cfg
- /etc/ansible/ansible.cfg
bash
#环境准备
[wan@controller ~]$ mkdir web && cd web
#查看ansible命令当前使用的配置文件
[wan@controller web]$ ansible --version
ansible 2.9.27
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/wan/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/site-packages/ansible
executable location = /bin/ansible
python version = 2.7.5 (default, Oct 14 2020, 14:45:30) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
配置文件示例
bash
#编辑配置文件
[wan@controller web]$ cd /home/wan/web
[laogao@controller web]$ vim ansible.cfg
[defaults]
remote_user = wan
inventory = ./inventory
[privilege_escalation]
become = True
become_user = root
become_method = sudo
become_ask_pass = False
#编辑inventory
[wan@controller web]$ vim inventory
node1
node2
node3
#验证
[wan@controller web]$ ansible all -a hostname
node2 | CHANGED | rc=0 >>
node2
node1 | CHANGED | rc=0 >>
node1
node3 | CHANGED | rc=0 >>
node3
ansible-config
ansible-config view
查看当前ansible配合文件内容
bash
[wan@controller web]$ ansible --version|grep file
config file = /home/wan/web/ansible.cfg
[wan@controller web]$ ansible-config view
[defaults]
remote_user = wan
inventory = ./inventory
[privilege_escalation]
become = True
become_user = root
become_method = sudo
become_ask_pass = False
ansible-config dump
当前ansible生效的所有配置
bash
[wan@controller web]$ ansible-config dump
ACTION_WARNINGS(default) = True
AGNOSTIC_BECOME_PROMPT(default) = True
ALLOW_WORLD_READABLE_TMPFILES(default) = False
ANSIBLE_CONNECTION_PATH(default) = None
ANSIBLE_COW_PATH(default) = None
...
ansible-config list
查看所有配置参数用途,配置位置等
bash
[wan@controller web]$ ansible-config list
ACTION_WARNINGS:
default: true
description: [By default Ansible will issue a warning when received from a ta
action (module or action plugin), These warnings can be silenced by adjus
this setting to False.]
env:
- {name: ANSIBLE_ACTION_WARNINGS}
ini:
- {key: action_warnings, section: defaults}
name: Toggle action warnings
type: boolean
version_added: '2.5'
...
AD HOC 命令
bash
#检查环境
[wan@controller web]$ pwd
/home/wan/web
[wan@controller web]$ cat ansible.cfg
[defaults]
remote_user = wan
inventory = ./inventory
[privilege_escalation]
become = True
become_user = root
become_method = sudo
become_ask_pass = False
[wan@controller web]$ cat inventory
node1
node2
node3
ansible AD HOC 命令
命令作用: 快速执行单个Ansible任务,快速测试和更改很有用。
bash
#查看远程主机主机名
[wan@controller web]$ ansible all -m command -a "hostname"
node1 | CHANGED | rc=0 >>
node1
node2 | CHANGED | rc=0 >>
node2
node3 | CHANGED | rc=0 >>
node3
#检查远程主机操作系统版本
[wan@controller web]$ ansible all -m command -a "cat /etc/os-release"
node2 | CHANGED | rc=0 >>
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
node1 | CHANGED | rc=0 >>
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
node3 | CHANGED | rc=0 >>
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
#查看远程主机内存使用情况
[wan@controller web]$ ansible all -a "free -h"
node2 | CHANGED | rc=0 >>
total used free shared buff/cache available
Mem: 3.8G 584M 2.9G 14M 409M 3.0G
Swap: 7.9G 0B 7.9G
node3 | CHANGED | rc=0 >>
total used free shared buff/cache available
Mem: 3.8G 575M 2.9G 14M 411M 3.0G
Swap: 7.9G 0B 7.9G
node1 | CHANGED | rc=0 >>
total used free shared buff/cache available
Mem: 3.8G 586M 2.9G 14M 411M 3.0G
Swap: 7.9G 0B 7.9G
#统计远程主机指定目录文件数量
[wan@controller web]$ ansible all -a "ls -l /etc | wc -l"
node1 | FAILED | rc=2 >>
/etc:
total 1352
drwxr-xr-x. 3 root root 101 Dec 8 14:07 abrt
-rw-r--r--. 1 root root 16 Dec 8 14:11 adjtime
-rw-r--r--. 1 root root 1529 Apr 1 2020 aliases
-rw-r--r--. 1 root root 12288 Dec 8 14:12 aliases.db
drwxr-xr-x. 3 root root 65 Dec 8 14:08 alsa
...
#查看IP地址
[wan@controller web]$ ansible all -a "ip -br a"
node2 | CHANGED | rc=0 >>
lo UNKNOWN 127.0.0.1/8 ::1/128
ens33 UP 192.168.108.12/24 fe80::c179:5c4f:976c:94ff/64 fe80::b322:6dab:8288:9902/64 fe80::2681:61f4:a416:364/64
virbr0 DOWN
virbr0-nic DOWN
node1 | CHANGED | rc=0 >>
lo UNKNOWN 127.0.0.1/8 ::1/128
ens33 UP 192.168.108.11/24 fe80::c179:5c4f:976c:94ff/64 fe80::b322:6dab:8288:9902/64 fe80::2681:61f4:a416:364/64
virbr0 DOWN
virbr0-nic DOWN
node3 | CHANGED | rc=0 >>
lo UNKNOWN 127.0.0.1/8 ::1/128
ens33 UP 192.168.108.13/24 fe80::c179:5c4f:976c:94ff/64 fe80::b322:6dab:8288:9902/64
virbr0 DOWN
virbr0-nic DOWN
ansible-doc 命令
bash
[wan@controller web]$ ansible-doc -h
usage: ansible-doc [-h] [--version] [-v] [-M MODULE_PATH]
[--playbook-dir BASEDIR]
[-t {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,module,strategy,vars}]
[-j] [-F | -l | -s | --metadata-dump]
[plugin [plugin ...]]
plugin documentation tool
positional arguments:
plugin Plugin
optional arguments:
--metadata-dump **For internal testing only** Dump json metadata for
all plugins.
--playbook-dir BASEDIR
Since this tool does not use playbooks, use this as a
substitute playbook directory.This sets the relative
path for many features including roles/ group_vars/
etc.
--version show program's version number, config file location,
configured module search path, module location,
executable location and exit
-F, --list_files Show plugin names and their source files without
summaries (implies --list)
-M MODULE_PATH, --module-path MODULE_PATH
prepend colon-separated path(s) to module library (def
ault=~/.ansible/plugins/modules:/usr/share/ansible/plu
gins/modules)
-h, --help show this help message and exit
-j, --json Change output into json format.
-l, --list List available plugins
-s, --snippet Show playbook snippet for specified plugin(s)
-t {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,module,strategy,vars}, --type {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,module,strategy,vars}
Choose which plugin type (defaults to "module").
Available plugin types are : ('become', 'cache',
'callback', 'cliconf', 'connection', 'httpapi',
'inventory', 'lookup', 'netconf', 'shell', 'module',
'strategy', 'vars')
-v, --verbose verbose mode (-vvv for more, -vvvv to enable
connection debugging)
See man pages for Ansible CLI options or website for tutorials
https://docs.ansible.com
copy 模块(文件 / 目录拷贝)
从控制端拷贝文件 / 目录到远程主机,支持权限、属主、内容直接写入等
bash
[wan@controller web]$ touch /tmp/local_file.txt
[wan@controller web]$ ansible all -m copy -a "src=/tmp/local_file.txt dest=/opt/remote_file.txt"
node2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/opt/remote_file.txt",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0644",
"owner": "root",
"size": 0,
"src": "/home/wan/.ansible/tmp/ansible-tmp-1766810483.33-109099-176552868635834/source",
"state": "file",
"uid": 0
}
node3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/opt/remote_file.txt",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0644",
"owner": "root",
"size": 0,
"src": "/home/wan/.ansible/tmp/ansible-tmp-1766810483.33-109100-237042745288134/source",
"state": "file",
"uid": 0
}
node1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/opt/remote_file.txt",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0644",
"owner": "root",
"size": 0,
"src": "/home/wan/.ansible/tmp/ansible-tmp-1766810483.32-109097-133951145018670/source",
"state": "file",
"uid": 0
}
command 模块
允许管理员在受管节点的命令行中运行任意命令
bash
[wan@controller web]$ ansible node1 -m command -a 'hostname'
node1 | CHANGED | rc=0 >>
node1
[wan@controller web]$ ansible node1 -m command -a 'hostname' -o
node1 | CHANGED | rc=0 | (stdout) node1
shell 模块
允许将要执行的命令作为参数传递给该模块
bash
[wan@controller web]$ ansible node1 -m command -a set
node1 | FAILED | rc=2 >>
[Errno 2] No such file or directory
[wan@controller web]$ ansible node1 -m shell -a set
node1 | CHANGED | rc=0 >>
BASH=/bin/sh
BASHOPTS=cmdhist:extquote:force_fignore:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
...
编写和运行 Playbook
Playbook 介绍
playbook 是一个文本文件,其中包含由一个或多个按特定顺序运行的play组成的列表。play是针对清单中选定的主机运行的一组有序任务。play可以让将一系列冗长而复杂的手动管理任务转变为可轻松重复的例程,并且具有可预测性。
Vim 编辑器设置
bash
#使用vim编写playbook时tab键可以一次空两格
[wan@controller web]$ vim ~/.vimrc
set ai ts=2
Playbook 编写
bash
#yaml格式起始行,一般不省略
---
# play具有属性:name,hosts,become,tasks,缩进一致
# name属性,用于简要描述play
- name: Enable intranet services
# hosts属性,用于定义要在哪个受管理节点执行
hosts: node1
# tasks属性,用于描述play中任务
tasks:
- name: latest version of httpd and firewalld installed
# 指明模块名,也就是要执行的任务
yum:
# 执行要操作的rpm包名称
name:
# rpm包名称是-开头的列表格式,或者逗号分隔的列表格式
- httpd
- firewalld
# 定义软件包的状态,lastet为最新版本
state: latest
- name: test html page is installed
# copy模块,用于将content属性值写入到目标文件
copy:
content: "Welcome wan WebSite!\n"
dest: /var/www/html/index.html
- name: firewalld enabled and running
# service模块,用于启用并启动firewalld服务
service:
name: firewalld
enabled: yes
state: started
# yaml格式结束行,一般省略
...
Playbook 运行
bash
[wan@controller web]$ vim playbook.yaml
---
- name: Enable intranet services
hosts: node1
tasks:
- name: latest version of httpd and firewalld installed
yum:
name:
- httpd
- firewalld
state: latest
- name: test html page is installed
copy:
content: "Welcome wan WebSite!\n"
dest: /var/www/html/index.html
- name: firewalld enabled and running
service:
name: firewalld
enabled: yes
state: started
- name: firewalld permits access to httpd service
firewalld:
service: http
permanent: yes
state: enabled
immediate: yes
- name: httpd enabled and running
service:
name: httpd
enabled: true
state: started
- name: Test intranet web server
hosts: localhost
become: no
tasks:
- name: connect to intranet web server
uri:
url: http://node1
return_content: yes
status_code: 200
...
#执行
[wan@controller web]$ ansible-playbook playbook.yaml
PLAY [Enable intranet services] ************************************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
TASK [latest version of httpd and firewalld installed] *************************
changed: [node1]
TASK [test html page is installed] *********************************************
changed: [node1]
TASK [firewalld enabled and running] *******************************************
ok: [node1]
TASK [firewalld permits access to httpd service] *******************************
changed: [node1]
TASK [httpd enabled and running] ***********************************************
changed: [node1]
PLAY [Test intranet web server] ************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [connect to intranet web server] ******************************************
ok: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
node1 : ok=6 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
语法检查
选项--syntax-check,只检查剧本语法,不执行剧本
bash
[wan@controller web]$ ansible-playbook --syntax-check playbook.yaml
playbook: playbook.yaml
修改文件并将其复制到主机
file 模块
bash
#创建文件或修改文件属性
[wan@controller web]$ vim playbook.yaml
---
- hosts: node1
gather_facts: no
tasks:
- name: Touch a file and set permissions
file:
path: /tmp/testfile
owner: wan
group: wheel
mode: 0640
state: touch
#执行
[wan@controller web]$ ansible-playbook playbook.yaml
PLAY [node1] *******************************************************************
TASK [Touch a file and set permissions] ****************************************
changed: [node1]
PLAY RECAP *********************************************************************
node1 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
replace 模块
使用正则表达式匹配内容,将匹配的内容替换成指定的内容
bash
[wan@controller web]$ vim playbook.yaml
---
- hosts: node1
gather_facts: no
tasks:
- name: replace multi line
replace:
path: /tmp/testfile
regexp: '^Hello World.*'
replace: 'Hello wan'
#执行
[wan@controller web]$ ansible-playbook playbook.yaml
PLAY [node1] *******************************************************************
TASK [replace multi line] ******************************************************
ok: [node1]
PLAY RECAP *********************************************************************
node1 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
stat 模块
stat 模块检索文件的信息
bash
[wan@controller web]$ vim playbook.yaml
---
- hosts: node1
gather_facts: no
tasks:
- stat:
path: /tmp/testfile
checksum_algorithm: md5
register: result
- debug:
msg: "/tmp/testfile md5 is {{ result.stat.checksum }}"
- debug:
var: result
#执行
[wan@controller web]$ ansible-playbook playbook.yaml
PLAY [node1] *******************************************************************
TASK [stat] ********************************************************************
ok: [node1]
TASK [debug] *******************************************************************
ok: [node1] => {
"msg": "/tmp/testfile md5 is d41d8cd98f00b204e9800998ecf8427e"
}
TASK [debug] *******************************************************************
ok: [node1] => {
"result": {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"failed": false,
"stat": {
"atime": 1766812593.8159432,
"attr_flags": "",
"attributes": [],
"block_size": 4096,
"blocks": 0,
"charset": "binary",
"checksum": "d41d8cd98f00b204e9800998ecf8427e",
"ctime": 1766812408.5149472,
"dev": 64768,
"device_type": 0,
"executable": false,
"exists": true,
"gid": 10,
"gr_name": "wheel",
"inode": 68122638,
"isblk": false,
"ischr": false,
"isdir": false,
"isfifo": false,
"isgid": false,
"islnk": false,
"isreg": true,
"issock": false,
"isuid": false,
"mimetype": "inode/x-empty",
"mode": "0640",
"mtime": 1766812408.5149472,
"nlink": 1,
"path": "/tmp/testfile",
"pw_name": "wan",
"readable": true,
"rgrp": true,
"roth": false,
"rusr": true,
"size": 0,
"uid": 1000,
"version": "18446744073355580978",
"wgrp": false,
"woth": false,
"writeable": true,
"wusr": true,
"xgrp": false,
"xoth": false,
"xusr": false
}
}
}
PLAY RECAP *********************************************************************
node1 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0