自動化メンテナンスツール------ANsible
77854 ワード
**
Ansible
**AnsibleはPythonを使用して開発された自動化管理ツールで、Michael DeHaanによって開始、開発、作成され、Redhatによって買収されました.AnsibleはGitHubでも上位10位のPython種目で、その熱さを見ることができます.公式サイトのAnsibleの定義は:Ansible is the simplest way to automate apps and IT infrastructure.つまり、AnsibleはアプリケーションとITインフラストラクチャの自動化を実現する東東であり、ここではsimplestを使用していると自信を持っており、最も簡単で便利です!**
Ansibleの応用分野
**
Ansible主要コンポーネント
**
使用環境の設定
**
**
コンフィギュレーション
**
実験環境構成パスワードなしログイン
**
commandの使用
**
**
shellモジュールの使用
**
**
copyモジュール
**
**
fileモジュール
**
**
fetchモジュール
**
**
cronモジュール
**
**
サービスモジュール
**
**
userモジュール
**
scriptモジュール
**
setupモジュール
**
このモジュールは主に情報収集に用いられ,factsコンポーネントを呼び出すことによって実現される.factsコンポーネントはAnsibleが管理対象機器の情報を収集するための機能であり、setupモジュールを使用して機器のすべてのfacts情報を調べることができ、filterを使用して指定された情報を表示することができます.全体のfacts情報は1つのJSONフォーマットのデータ構造の中で包装されて、ansible_factsは最上位レベルの値です.factsは変数であり,内蔵変数である.各ホストの各種情報は、cpuパーティクル数、メモリサイズなどfactsの変数に存在します.呼び出し後、対応するホストの情報が多く返され、後の操作では異なる情報に基づいて異なる操作を行うことができます.redhatシリーズがyumでインストールされ、debianシリーズがaptでソフトウェアがインストールされます.
メモリ情報の表示
Ansible
**AnsibleはPythonを使用して開発された自動化管理ツールで、Michael DeHaanによって開始、開発、作成され、Redhatによって買収されました.AnsibleはGitHubでも上位10位のPython種目で、その熱さを見ることができます.公式サイトのAnsibleの定義は:Ansible is the simplest way to automate apps and IT infrastructure.つまり、AnsibleはアプリケーションとITインフラストラクチャの自動化を実現する東東であり、ここではsimplestを使用していると自信を持っており、最も簡単で便利です!**
Ansibleの応用分野
**
Ansible主要コンポーネント
Ansible:Ansible
Host Inventory: Ansible , ssh ,root ,ip 。
Playbooks:YAML , , , 。
Core Modules:Ansible Ansible , ;Ansible , core Modules , Host Inventory , 。
Custom Modules: , Ansible , 。
Connection Plugins: ,Ansible Host 。
**
使用環境の設定
**
[root@server1 rhel7]# ls
ansible-2.1.0.0-1.el7.noarch.rpm python2-paramiko-1.16.1-1.el7.noarch.rpm
libtomcrypt-1.17-23.el7.x86_64.rpm python-httplib2-0.7.7-3.el7.noarch.rpm
libtommath-0.42.0-4.el7.x86_64.rpm python-keyczar-0.71c-2.el7.noarch.rpm
python2-crypto-2.6.1-9.el7.x86_64.rpm sshpass-1.05-5.el7.x86_64.rpm
python2-ecdsa-0.13-4.el7.noarch.rpm
[root@server1 rhel7]# yum install * -y
[root@server1 rhel7]# ansible --version
ansible 2.1.0.0
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides
**
コンフィギュレーション
**
Ansible
nventory = /etc/ansible/hosts # inventory
library = /usr/share/ansible # Ansible , , (:)
forks = 5 # , 5
sudo_user = root #
remote_port = 22 # , 22 , ,
host_key_checking = False # SSH , True/False。
timeout = 60 # SSH ,
log_path = /var/log/ansible.log # ansible ( )
Ansible Inventory ( )
ansible_ssh_host ssh
ansible_ssh_port ssh
ansible_ssh_user ssh
ansible_ssh_pass ssh
ansible_sudo sudo
ansible_sudo_pass sudo
** [root@server1 rhel7]# vim /etc/ansible/hosts**
# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
# - Comments begin with the '#' character
# - Blank lines are ignored
# - Groups of hosts are delimited by [header] elements
# - You can enter hostnames or ip addresses
# - A hostname/ip can be a member of multiple groups
***********************
servers
[servers]
172.25.15.250
172.25.15.[21:22]
[servers:vars] ***
ansible_ssh_user='root'
ansible_ssh_pass='westos'
ansible host_key
# uncomment this to disable SSH key host checking
host_key_checking = False
ansible , ,-m 。
, ping ping, ssh 。
[root@server1 rhel7]# ansible servers -m ping
172.25.15.22 | SUCCESS => {
"changed": false,
"ping": "pong"
}
172.25.15.21 | SUCCESS => {
"changed": false,
"ping": "pong"
}
172.25.15.250 | SUCCESS => {
"changed": false,
"ping": "pong"
}
command
[root@server1 rhel7]# ansible servers -m command -a 'whoami'
172.25.15.21 | SUCCESS | rc=0 >>
root
172.25.15.22 | SUCCESS | rc=0 >>
root
172.25.15.250 | SUCCESS | rc=0 >>
root
command whoami,-a 。 shell :
[root@server1 rhel7]# ansible servers -m shell -a 'whoami'
172.25.15.22 | SUCCESS | rc=0 >>
root
172.25.15.21 | SUCCESS | rc=0 >>
root
172.25.15.250 | SUCCESS | rc=0 >>
root
[root@server1 ~]# ansible servers -m command -a 'ss -ntl'
172.25.15.22 | SUCCESS | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
172.25.15.21 | SUCCESS | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
実験環境構成パスワードなしログイン
[root@server2 ~]# ssh-keygen
[root@server2 ~]# ssh-copy-id [email protected]
**
commandの使用
**
, 。 。 shell , $HOME ",">","|",";","&" ( (shell) )。 , | 。
:
chdir # ,
executable # shell ,
free_form # Linux , Ansible -a 。
creates # , , ,
removes # , ,
[root@server1 ~]# ansible servers -m command -a 'chdir=/mnt/ ls'
172.25.15.21 | SUCCESS | rc=0 >>
cmdline-jmxclient-0.10.3.jar
zabbix
zabbix-api
zabbix-api.sh
zabbix-java-gateway-3.4.6-1.el7.x86_64.rpm
zabbix_java_gateway.conf
172.25.15.22 | SUCCESS | rc=0 >>
rhel7
zabbix
**
shellモジュールの使用
**
shell shell , shell , 。
[root@server1 ~]# ansible servers -m shell -a 'cat /etc/passwd |grep "root"'
172.25.15.22 | SUCCESS | rc=0 >>
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
172.25.15.21 | SUCCESS | rc=0 >>
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
172.25.15.250 | SUCCESS | rc=0 >>
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
**
copyモジュール
**
, 。
src # 。 , 。 , , "rsync"
content # "src",
dest # ,
backup # , ,
directory_mode # ,
force # , , "yes", ; "no", 。 "yes"
others # file
[root@server1 mnt]# ansible servers -m copy -a 'src=/mnt/file1 dest=/mnt/file1'
172.25.15.22 | SUCCESS => {
"changed": false,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/mnt/file1",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/mnt/file1",
"size": 0,
"state": "file",
"uid": 0
}
172.25.15.21 | SUCCESS => {
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/mnt/file1",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0644",
"owner": "root",
"size": 0,
"src": "/root/.ansible/tmp/ansible-tmp-1534386247.74-117390907672439/source",
"state": "file",
"uid": 0
}
[root@server2 mnt]# ll file1
-rw-r--r-- 1 root root 0 8 16 10:24 file1
[root@server1 mnt]# ansible servers -m copy -a 'src=/mnt/file2 dest=/mnt/file2 mode=777 '
172.25.15.21 | SUCCESS => {
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/mnt/file2",
"gid": 0,
"group": "root",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0777",
"owner": "root",
"size": 0,
"src": "/root/.ansible/tmp/ansible-tmp-1534386413.23-276115183740525/source",
"state": "file",
"uid": 0
}
172.25.15.22 | SUCCESS => {
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/mnt/file2",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"path": "/mnt/file2",
"size": 0,
"state": "file",
"uid": 0
}
[root@server1 mnt]# ansible servers -m shell -a 'ls -l /mnt/'
172.25.15.21 | SUCCESS | rc=0 >>
total 784
-rwxr-xr-x 1 root root 284 Aug 14 17:31 1.sh
-rwxr-xr-x 1 root root 447 Aug 14 17:34 2.sh
-rw-r--r-- 1 root root 0 Aug 16 10:24 file1
-rwxrwxrwx 1 root root 0 Aug 16 10:26 file2
172.25.15.22 | SUCCESS | rc=0 >>
total 8
-rw-r--r-- 1 root root 0 Aug 16 10:23 file1
-rwxrwxrwx 1 root root 0 Aug 16 10:26 file2
**
fileモジュール
**
, 、 、 。
:
force # , , ; , , , :yes|no
group # / 。 mode: /
owner # / 。 path: /
recurse # , , src: , state=link
dest # , state=link
state # , :
directory: ,
file: ,
link:
hard:
touch: , , ,
absent: 、
!!!
[root@server1 mnt]# ansible servers -m file -a 'path=/mnt/file3 state=directory'
172.25.15.21 | SUCCESS => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/mnt/file3",
"size": 6,
"state": "directory",
"uid": 0
}
172.25.15.22 | SUCCESS => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/mnt/file3",
"size": 6,
"state": "directory",
"uid": 0
}
[root@server1 mnt]# ansible servers -m shell -a 'ls -l /mnt/'
172.25.15.22 | SUCCESS | rc=0 >>
total 8
-rw-r--r-- 1 root root 0 Aug 16 10:23 file1
-rwxrwxrwx 1 root root 0 Aug 16 10:26 file2
drwxr-xr-x 2 root root 6 Aug 16 10:33 file3
drwxrwxr-x 2 root root 4096 Aug 16 09:17 rhel7
drwxrwxr-x 5 root root 4096 Aug 15 16:29 zabbix
172.25.15.21 | SUCCESS | rc=0 >>
total 784
-rw-r--r-- 1 root root 0 Aug 16 10:24 file1
-rwxrwxrwx 1 root root 0 Aug 16 10:26 file2
drwxr-xr-x 2 root root 6 Aug 16 10:33 file3
[root@server1 mnt]# ansible servers -m file -a 'path=/mnt/file1 state=absent'
172.25.15.21 | SUCCESS => {
"changed": true,
"path": "/mnt/file1",
"state": "absent"
}
172.25.15.22 | SUCCESS => {
"changed": true,
"path": "/mnt/file1",
"state": "absent"
}
172.25.15.250 | SUCCESS => {
"changed": true,
"path": "/mnt/file1",
"state": "absent"
}
[root@server1 mnt]# ansible servers -m shell -a 'ls -l /mnt/'
172.25.15.21 | SUCCESS | rc=0 >>
total 784
-rwxrwxrwx 1 root root 0 Aug 16 10:26 file2
drwxr-xr-x 2 root root 6 Aug 16 10:33 file3
-rw-r--r-- 1 root root 0 Aug 16 10:43 file4
172.25.15.22 | SUCCESS | rc=0 >>
total 8
-rwxrwxrwx 1 root root 0 Aug 16 10:26 file2
drwxr-xr-x 2 root root 6 Aug 16 10:33 file3
-rw-r--r-- 1 root root 0 Aug 16 10:43 file4
drwxrwxr-x 2 root root 4096 Aug 16 09:17 rhel7
drwxrwxr-x 5 root root 4096 Aug 15 16:29 zabbix
**
fetchモジュール
**
( ) 。
:
dest:
src: , file,
[root@server1 mnt]# ansible 172.25.15.21 -m fetch -a 'src=/mnt/test1 dest=/mnt'
172.25.15.21 | SUCCESS => {
"changed": true,
"checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"dest": "/mnt/172.25.15.21/mnt/test1",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"remote_checksum": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
"remote_md5sum": null
}
[root@server1 mnt]# ls
172.25.15.21 file2 file3 file4 rhel7 zabbix
[root@server1 mnt]# cd 172.25.15.21/
[root@server1 172.25.15.21]# ls
mnt
[root@server1 172.25.15.21]# cd mnt/
[root@server1 mnt]# ls
test1
**
cronモジュール
**
cron 。
crontab , , :
day= # ( 1-31, , /2, )
hour= # ( 0-23, , /2, )
minute= # ( 0-59, , /2, )
month= # ( 1-12, *, /2, )
weekday= # ( 0-6 for Sunday-Saturday,, )
job= #
name= #
reboot # , , special_time
special_time # , :reboot( ),annually( ),monthly( ),weekly( ),daily( ),hourly( )
state # ,present , ,absent
user #
[root@server1 mnt]# ansible servers -m cron -a 'name="show time" minute=*/5 job="/bin/date &> /dev/null"'
172.25.15.21 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"show time"
]
}
172.25.15.22 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"show time"
]
}
172.25.15.250 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"show time"
]
}
[root@server1 mnt]# ansible servers -m shell -a 'crontab -l'
172.25.15.21 | SUCCESS | rc=0 >>
#Ansible: show time
*/5 * * * * /bin/date &> /dev/null
172.25.15.22 | SUCCESS | rc=0 >>
#Ansible: show time
*/5 * * * * /bin/date &> /dev/null
172.25.15.250 | SUCCESS | rc=0 >>
#Ansible: show time
*/5 * * * * /bin/date &> /dev/null
[root@server1 mnt]# ansible servers -m cron -a 'name="show time" minute=*/5 job="/bin/date &> /dev/null" state=absent '
172.25.15.21 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
172.25.15.22 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
172.25.15.250 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
[root@server1 mnt]# ansible servers -m shell -a 'crontab -l'
172.25.15.21 | SUCCESS | rc=0 >>
172.25.15.22 | SUCCESS | rc=0 >>
172.25.15.250 | SUCCESS | rc=0 >>
**
サービスモジュール
**
。
:
arguments #
enabled # 。
name= #
runlevel # , 。
sleep # , 。 2 。( 。)
state # , :started---> , stopped---> , restarted---> , reloaded--->
[root@server1 mnt]# ansible 172.25.15.21 -m service -a 'name=mariadb state=started enabled=true'
172.25.15.21 | SUCCESS => {
"changed": true,
"enabled": true,
"name": "mariadb",
"state": "started"
}
3306
[root@server1 mnt]# ansible 172.25.15.21 -m shell -a 'ss -ntl'
172.25.15.21 | SUCCESS | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 50 *:3306 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
[root@server1 mnt]# ansible 172.25.15.21 -m service -a 'name=mariadb state=stopped '
172.25.15.21 | SUCCESS => {
"changed": true,
"name": "mariadb",
"state": "stopped"
}
[root@server1 mnt]# ansible 172.25.15.21 -m shell -a 'ss -ntl'
172.25.15.21 | SUCCESS | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
**
userモジュール
**
。
:
comment #
createhome #
force # state=absent , userdel –force .
group #
groups # , (groups=)
home #
move_home # home= ,
name #
non_unique # ID
password #
remove # state=absent , userdel –remove
shell # shell
state # , , absent
system # , 。
uid # uid
[root@server1 mnt]# ansible servers -m user -a 'name=bobo uid=11111'
172.25.15.21 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 11111,
"home": "/home/bobo",
"name": "bobo",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 11111
}
172.25.15.22 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 11111,
"home": "/home/bobo",
"name": "bobo",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 11111
}
[root@server1 mnt]# ansible servers -m shell -a 'cat /etc/passwd |grep bobo'
172.25.15.21 | SUCCESS | rc=0 >>
bobo:x:11111:11111::/home/bobo:/bin/bash
172.25.15.22 | SUCCESS | rc=0 >>
bobo:x:11111:11111::/home/bobo:/bin/bash
172.25.15.250 | SUCCESS | rc=0 >>
bobo:x:11111:11111::/home/bobo:/bin/bash
[root@server1 mnt]# ansible servers -m user -a 'name=bobo state=absent'
172.25.15.22 | SUCCESS => {
"changed": true,
"force": false,
"name": "bobo",
"remove": false,
"state": "absent"
}
172.25.15.21 | SUCCESS => {
"changed": true,
"force": false,
"name": "bobo",
"remove": false,
"state": "absent"
}
172.25.15.250 | SUCCESS => {
"changed": true,
"force": false,
"name": "bobo",
"remove": false,
"state": "absent"
}
[root@server1 mnt]# ansible servers -m shell -a 'cat /etc/passwd |grep bobo'
172.25.15.250 | FAILED | rc=1 >>
172.25.15.21 | FAILED | rc=1 >>
scriptモジュール
。
, :
, , :
#!/bin/bash
date >> /tmp/disk_total.log
df -lh >> /tmp/disk_total.log
[root@server1 mnt]# ansible servers -m script -a '/mnt/172.25.15.21/mnt/1.sh'
172.25.15.21 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "",
"stdout": "",
"stdout_lines": []
}
172.25.15.22 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "",
"stdout": "",
"stdout_lines": []
}
172.25.15.250 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "",
"stdout": "",
"stdout_lines": []
[root@server1 mnt]# ansible servers -m shell -a 'cat /tmp/disk_total.log'
172.25.15.21 | SUCCESS | rc=0 >>
Thu Aug 16 11:53:48 CST 2018
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rhel-root 18G 1.6G 16G 9% /
devtmpfs 486M 0 486M 0% /dev
tmpfs 497M 0 497M 0% /dev/shm
tmpfs 497M 13M 484M 3% /run
tmpfs 497M 0 497M 0% /sys/fs/cgroup
/dev/sda1 497M 132M 366M 27% /boot
/dev/mapper/rhel-home 2.0G 33M 2.0G 2% /home
tmpfs 100M 0 100M 0% /run/user/0
172.25.15.22 | SUCCESS | rc=0 >>
Thu Aug 16 11:50:15 CST 2018
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rhel-root 18G 1.6G 16G 9% /
devtmpfs 486M 0 486M 0% /dev
tmpfs 497M 0 497M 0% /dev/shm
tmpfs 497M 13M 484M 3% /run
tmpfs 497M 0 497M 0% /sys/fs/cgroup
/dev/sda1 497M 132M 366M 27% /boot
/dev/mapper/rhel-home 2.0G 33M 2.0G 2% /home
tmpfs 100M 0 100M 0% /run/user/0
Thu Aug 16 11:53:48 CST 2018
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/rhel-root 18G 1.6G 16G 9% /
devtmpfs 486M 0 486M 0% /dev
tmpfs 497M 152K 497M 1% /dev/shm
tmpfs 497M 13M 484M 3% /run
tmpfs 497M 0 497M 0% /sys/fs/cgroup
**
setupモジュール
**
このモジュールは主に情報収集に用いられ,factsコンポーネントを呼び出すことによって実現される.factsコンポーネントはAnsibleが管理対象機器の情報を収集するための機能であり、setupモジュールを使用して機器のすべてのfacts情報を調べることができ、filterを使用して指定された情報を表示することができます.全体のfacts情報は1つのJSONフォーマットのデータ構造の中で包装されて、ansible_factsは最上位レベルの値です.factsは変数であり,内蔵変数である.各ホストの各種情報は、cpuパーティクル数、メモリサイズなどfactsの変数に存在します.呼び出し後、対応するホストの情報が多く返され、後の操作では異なる情報に基づいて異なる操作を行うことができます.redhatシリーズがyumでインストールされ、debianシリーズがaptでソフトウェアがインストールされます.
メモリ情報の表示
[root@server1 mnt]# ansible servers -m setup -a 'filter="*mem*"'
172.25.15.21 | SUCCESS => {
"ansible_facts": {
"ansible_memfree_mb": 648,
"ansible_memory_mb": {
"nocache": {
"free": 874,
"used": 118
},
"real": {
"free": 648,
"total": 992,
"used": 344
},
"swap": {
"cached": 0,
"free": 0,
"total": 0,
"used": 0
}
},
"ansible_memtotal_mb": 992
},
"changed": false
}
shell
[root@server1 mnt]# ansible servers -m shell -a 'free -m'
172.25.15.22 | SUCCESS | rc=0 >>
total used free shared buff/cache available
Mem: 992 143 569 13 279 682
Swap: 0 0 0
172.25.15.21 | SUCCESS | rc=0 >>
total used free shared buff/cache available
Mem: 992 82 651 13 258 750
Swap: 0 0 0
172.25.15.250 | SUCCESS | rc=0 >>
total used free shared buff/cache available
Mem: 3834 2606 134 194 1093 753
Swap: 3071 1 3070
[root@server1 mnt]# ansible servers -m setup -a 'filter="*mem*"' --tree /mnt/facts
172.25.15.22 | SUCCESS => {
"ansible_facts": {
"ansible_memfree_mb": 551,
"ansible_memory_mb": {
"nocache": {
"free": 787,
"used": 205
},
"real": {
"free": 551,
"total": 992,
"used": 441
},
"swap": {
"cached": 0,
"free": 0,
"total": 0,
"used": 0
}
},
[root@server1 facts]# cat 172.25.15.21
{"ansible_facts": {"ansible_memfree_mb": 645, "ansible_memory_mb": {"nocache": {"free": 872, "used": 120}, "real": {"free": 645, "total": 992, "used": 347}, "swap": {"cached": 0, "free": 0, "total": 0, "used": 0}}, "ansible_memtotal_mb": 992}, "changed": false}[root@server1 facts]# ^C
[root@server1 facts]# pwd
/mnt/facts