Hi folks!
In the previous blog post, we have a glimpse of ansible and its use cases. Here, we will be continuing our quest in learning ansible with RedHat Developer version of Enterprise Linux.
Ansible has agentless architecture which means there is no need of any kind of extra utility to perform automation for ansible. It particularly uses python which already exists in most of the stable Linux versions. It uses OpenSSH and WinRM for communication with remote machines. This decreases chances of exploitation and provides efficient and secure way for automation.
I have explained the installation of Ansible in the previous post. Ansible requires installation on one master machine which acts as our host controller. In my lab-setup, I have,
1. host-controller
IP - 10.0.0.1 Hostname - server.sharma.com
2. remote machines
IP - 10.0.0.218 Hostname - node@218.sharma.com
IP - 10.0.0.227 Hostname - node@227.sharma.com
IP - 10.0.0.228 Hostname - node@228.sharma.com
IP - 10.0.0.229 Hostname - node@229.sharma.com
Ansible has a lot of tools in the toolkit. These tools are called modules. Each module extends ansible's capability for performing a particular task.There are more than 450 modules to work with. But, we will explore only some of the modules in this post. Using Ansible commands is very simple.
[root@server Desktop]# ansible localhost -m setup
Ansible command starts with 'ansible', then localhost for our host machine. Post that comes '-m' which represents a module name (setup). 'setup' module gathers facts about remote machine and result in a very good lump of information. We can filter out particular information as well, using '-a' to pass a direct command line argument and not a module.
[root@server Desktop]# ansible 10.0.0.218 -m setup -a filter='ansible_distribution_*'
10.0.0.218 | SUCCESS => {
"ansible_facts": {
"ansible_distribution_file_parsed": true,
"ansible_distribution_file_path": "/etc/redhat-release",
"ansible_distribution_file_variety": "RedHat",
"ansible_distribution_major_version": "7",
"ansible_distribution_release": "Maipo",
"ansible_distribution_version": "7.2"
},
"changed": false,
"failed": false
}
Similarly, we can ping every remote machine to check whether our remote machines are ready or not.
[root@server Desktop]# ansible 10.0.0.218 -m ping -k
SSH password:
10.0.0.218 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
As per the output, my ping is successful and it has returned a 'pong'. Here it has asked for SSH password because of '-k'. But this is not the way to do it. I mean, if there are a plenty of remote machines to automate we can't provide all the names here and then giving a password through user. To overcome such scenario, there is an 'inventory' file. 'inventory' file comprises of collection of hosts (nodes) against which Ansible can work with. So, in my host controller, I will create one file - 'inventory' and write the remote IPs with password and username.
[root@server Desktop]# vim inventory
[root@server Desktop]# cat inventory
10.0.0.218 ansible_ssh_user=q ansible_ssh_pass=q
10.0.0.229 ansible_ssh_user=q ansible_ssh_pass=q
10.0.0.228 ansible_ssh_user=q ansible_ssh_pass=q
10.0.0.227 ansible_ssh_user=q ansible_ssh_pass=q
After this, I can ping all the machines at once without even entering the password.
[root@server Desktop]# ansible all -i inventory -m ping
10.0.0.218 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
10.0.0.228 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
10.0.0.227 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
10.0.0.229 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
But I am still looking to give definition to my servers according to their purpose in the company. Like some are database servers, some are web servers and so on. And I don't want to repeat the password for every machine. Its the same thing, I have written over and over. What I can do is, creating groups for different servers and using variables to store the user-credentials. I will be defining a default inventory at '/etc/ansible/hosts'.
[root@server Desktop]# vim /etc/ansible/hosts
[root@server Desktop]# cat /etc/ansible/hosts
node218 ansible_ssh_host=10.0.0.218
node227 ansible_ssh_host=10.0.0.227
node228 ansible_ssh_host=10.0.0.228
node229 ansible_ssh_host=10.0.0.229
[webservers]
node218
node227
[dbservers]
node228
[lbservers]
node229
[datacenter:children]
webservers
dbservers
lbservers
[datacenter:vars]
ansible_ssh_user=q
ansible_ssh_pass=q
In the '/etc/ansible/hosts' file, I have declared individual hosts as nodes. Then, I have created three groups for webservers, dbservers, lbservers. Post that, I made an entry for a larger group called datacenter, whose children are all the groups. For all the groups, datacenter will be in supreme command, so I created variables for datacenter as 'vars' and provided the user credentials. Now there is no need to give credentials as well as inventory location in the ansible command.
[root@server Desktop]# ansible all -m ping
node227 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
node229 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
node218 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
node228 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
This is the setup with which we can install some packages very easily in a single command hassle free, provided the user whose credentials are given in inventory file, has the power to do so.
[root@server Desktop]# ansible webservers -m yum -a "name=httpd state=present"
node218 | SUCCESS => {
"changed": true,
"failed": false,
"msg": "Repository 'hadoopmain' is missing name in configuration, using id\n",
"rc": 0,
"results": [
"Loaded plugins: product-id, search-disabled-repos, subscription-manager\nThis system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-40.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n httpd x86_64 2.4.6-40.el7 hadoopmain 1.2 M\n\nTransaction Summary\n================================================================================\nInstall 1 Package\n\nTotal download size: 1.2 M\nInstalled size: 3.7 M\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : httpd-2.4.6-40.el7.x86_64 1/1 \n Verifying : httpd-2.4.6-40.el7.x86_64 1/1 \n\nInstalled:\n httpd.x86_64 0:2.4.6-40.el7 \n\nComplete!\n"
]
}
node227 | SUCCESS => {
"changed": true,
"failed": false,
"msg": "Repository 'hadoopmain' is missing name in configuration, using id\n",
"rc": 0,
"results": [
"Loaded plugins: product-id, search-disabled-repos, subscription-manager\nThis system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-40.el7 will be installed\n--> Processing Dependency: httpd-tools = 2.4.6-40.el7 for package: httpd-2.4.6-40.el7.x86_64\n--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-40.el7.x86_64\n--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.6-40.el7.x86_64\n--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.6-40.el7.x86_64\n--> Running transaction check\n---> Package apr.x86_64 0:1.4.8-3.el7 will be installed\n---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed\n---> Package httpd-tools.x86_64 0:2.4.6-40.el7 will be installed\n---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n httpd x86_64 2.4.6-40.el7 hadoopmain 1.2 M\nInstalling for dependencies:\n apr x86_64 1.4.8-3.el7 hadoopmain 103 k\n apr-util x86_64 1.5.2-6.el7 hadoopmain 92 k\n httpd-tools x86_64 2.4.6-40.el7 hadoopmain 82 k\n mailcap noarch 2.1.41-2.el7 hadoopmain 31 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package (+4 Dependent packages)\n\nTotal download size: 1.5 M\nInstalled size: 4.3 M\nDownloading packages:\n--------------------------------------------------------------------------------\nTotal 5.5 MB/s | 1.5 MB 00:00 \nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing : apr-1.4.8-3.el7.x86_64 1/5 \n Installing : apr-util-1.5.2-6.el7.x86_64 2/5 \n Installing : httpd-tools-2.4.6-40.el7.x86_64 3/5 \n Installing : mailcap-2.1.41-2.el7.noarch 4/5 \n Installing : httpd-2.4.6-40.el7.x86_64 5/5 \n Verifying : mailcap-2.1.41-2.el7.noarch 1/5 \n Verifying : httpd-tools-2.4.6-40.el7.x86_64 2/5 \n Verifying : apr-1.4.8-3.el7.x86_64 3/5 \n Verifying : apr-util-1.5.2-6.el7.x86_64 4/5 \n Verifying : httpd-2.4.6-40.el7.x86_64 5/5 \n\nInstalled:\n httpd.x86_64 0:2.4.6-40.el7 \n\nDependency Installed:\n apr.x86_64 0:1.4.8-3.el7 apr-util.x86_64 0:1.5.2-6.el7 \n httpd-tools.x86_64 0:2.4.6-40.el7 mailcap.noarch 0:2.1.41-2.el7 \n\nComplete!\n"
]
}
If the user is not able to do the same, let the ansible command ask for the password by appending '--ask-sudo-pass' in the same.
[root@server Desktop]# ansible webservers -m yum -a "name=httpd state=present" --ask-sudo-pass
[DEPRECATION WARNING]: The sudo command line option has been deprecated in
favor of the "become" command line arguments. This feature will be removed in
version 2.6. Deprecation warnings can be disabled by setting
deprecation_warnings=False in ansible.cfg.
SUDO password:
node227 | SUCCESS => {
"changed": false,
"failed": false,
"msg": "",
"rc": 0,
"results": [
"httpd-2.4.6-40.el7.x86_64 providing httpd is already installed"
]
}
node218 | SUCCESS => {
"changed": false,
"failed": false,
"msg": "",
"rc": 0,
"results": [
"httpd-2.4.6-40.el7.x86_64 providing httpd is already installed"
]
}
The last thing I would like to share is debugging in ansible ad-hoc commands. This is decided by the verbosity level given in the command.
Example 1:
[root@server Desktop]# ansible lbservers -m ping -v
No config file found; using defaults
node229 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
With Example 1, '-v' is passed which only gives debugging information about config file.
Example 2:
[root@server Desktop]# ansible lbservers -m ping -vvv
ansible 2.4.0.0
config file = None
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 11 2015, 17:47:16) [GCC 4.8.3 20140911 (Red Hat 4.8.3-9)]
No config file found; using defaults
Parsed /etc/ansible/hosts inventory source with ini plugin
META: ran handlers
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/ping.py
<10.0.0.229> ESTABLISH SSH CONNECTION FOR USER: q
<10.0.0.229> SSH: EXEC sshpass -d11 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o User=q -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/cc742780ab 10.0.0.229 '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<10.0.0.229> (0, '/home/q\n', '')
<10.0.0.229> ESTABLISH SSH CONNECTION FOR USER: q
<10.0.0.229> SSH: EXEC sshpass -d11 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o User=q -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/cc742780ab 10.0.0.229 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /home/q/.ansible/tmp/ansible-tmp-1510841273.0-271302847336239 `" && echo ansible-tmp-1510841273.0-271302847336239="` echo /home/q/.ansible/tmp/ansible-tmp-1510841273.0-271302847336239 `" ) && sleep 0'"'"''
<10.0.0.229> (0, 'ansible-tmp-1510841273.0-271302847336239=/home/q/.ansible/tmp/ansible-tmp-1510841273.0-271302847336239\n', '')
<10.0.0.229> PUT /tmp/tmp_i5vky TO /home/q/.ansible/tmp/ansible-tmp-1510841273.0-271302847336239/ping.py
<10.0.0.229> SSH: EXEC sshpass -d11 sftp -o BatchMode=no -b - -C -o ControlMaster=auto -o ControlPersist=60s -o User=q -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/cc742780ab '[10.0.0.229]'
<10.0.0.229> (0, 'sftp> put /tmp/tmp_i5vky /home/q/.ansible/tmp/ansible-tmp-1510841273.0-271302847336239/ping.py\n', '')
<10.0.0.229> ESTABLISH SSH CONNECTION FOR USER: q
<10.0.0.229> SSH: EXEC sshpass -d11 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o User=q -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/cc742780ab 10.0.0.229 '/bin/sh -c '"'"'chmod u+x /home/q/.ansible/tmp/ansible-tmp-1510841273.0-271302847336239/ /home/q/.ansible/tmp/ansible-tmp-1510841273.0-271302847336239/ping.py && sleep 0'"'"''
<10.0.0.229> (0, '', '')
<10.0.0.229> ESTABLISH SSH CONNECTION FOR USER: q
<10.0.0.229> SSH: EXEC sshpass -d11 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o User=q -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/cc742780ab -tt 10.0.0.229 '/bin/sh -c '"'"'/usr/bin/python /home/q/.ansible/tmp/ansible-tmp-1510841273.0-271302847336239/ping.py; rm -rf "/home/q/.ansible/tmp/ansible-tmp-1510841273.0-271302847336239/" > /dev/null 2>&1 && sleep 0'"'"''
<10.0.0.229> (0, '\r\n{"invocation": {"module_args": {"data": "pong"}}, "ping": "pong"}\r\n', 'Shared connection to 10.0.0.229 closed.\r\n')
node229 | SUCCESS => {
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"data": "pong"
}
},
"ping": "pong"
}
META: ran handlers
META: ran handlers
With Example 2, '-vvv' is passed which gives the information about ansible version, module location, python version, connection profile, etc.
Example 3:
[root@server Desktop]# ansible lbservers -m ping -vvvv
ansible 2.4.0.0
config file = None
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 11 2015, 17:47:16) [GCC 4.8.3 20140911 (Red Hat 4.8.3-9)]
No config file found; using defaults
setting up inventory plugins
Parsed /etc/ansible/hosts inventory source with ini plugin
Loading callback plugin minimal of type stdout, v2.0 from /usr/lib/python2.7/site-packages/ansible/plugins/callback/__init__.pyc
META: ran handlers
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/ping.py
<10.0.0.229> ESTABLISH SSH CONNECTION FOR USER: q
<10.0.0.229> SSH: EXEC sshpass -d11 ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o User=q -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/cc742780ab 10.0.0.229 '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<10.0.0.229> (0, '/home/q\n', 'OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 56: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug2: mux_client_hello_exchange: master version 4\r\ndebug3: mux_client_forwards: request forwardings: 0 local, 0 remote\r\ndebug3: mux_client_request_session: entering\r\ndebug3: mux_client_request_alive: entering\r\ndebug3: mux_client_request_alive: done pid = 4386\r\ndebug3: mux_client_request_session: session request sent\r\ndebug1: mux_client_request_session: master session id: 2\r\ndebug3: mux_client_read_packet: read header failed: Broken pipe\r\ndebug2: Received exit status from master 0\r\n')
<10.0.0.229> ESTABLISH SSH CONNECTION FOR USER: q
<10.0.0.229> SSH: EXEC sshpass -d11 ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o User=q -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/cc742780ab 10.0.0.229 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /home/q/.ansible/tmp/ansible-tmp-1510841304.79-155502950928476 `" && echo ansible-tmp-1510841304.79-155502950928476="` echo /home/q/.ansible/tmp/ansible-tmp-1510841304.79-155502950928476 `" ) && sleep 0'"'"''
<10.0.0.229> (0, 'ansible-tmp-1510841304.79-155502950928476=/home/q/.ansible/tmp/ansible-tmp-1510841304.79-155502950928476\n', 'OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 56: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug2: mux_client_hello_exchange: master version 4\r\ndebug3: mux_client_forwards: request forwardings: 0 local, 0 remote\r\ndebug3: mux_client_request_session: entering\r\ndebug3: mux_client_request_alive: entering\r\ndebug3: mux_client_request_alive: done pid = 4386\r\ndebug3: mux_client_request_session: session request sent\r\ndebug1: mux_client_request_session: master session id: 2\r\ndebug3: mux_client_read_packet: read header failed: Broken pipe\r\ndebug2: Received exit status from master 0\r\n')
<10.0.0.229> PUT /tmp/tmpji9Qoj TO /home/q/.ansible/tmp/ansible-tmp-1510841304.79-155502950928476/ping.py
<10.0.0.229> SSH: EXEC sshpass -d11 sftp -o BatchMode=no -b - -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o User=q -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/cc742780ab '[10.0.0.229]'
<10.0.0.229> (0, 'sftp> put /tmp/tmpji9Qoj /home/q/.ansible/tmp/ansible-tmp-1510841304.79-155502950928476/ping.py\n', 'OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 56: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug2: mux_client_hello_exchange: master version 4\r\ndebug3: mux_client_forwards: request forwardings: 0 local, 0 remote\r\ndebug3: mux_client_request_session: entering\r\ndebug3: mux_client_request_alive: entering\r\ndebug3: mux_client_request_alive: done pid = 4386\r\ndebug3: mux_client_request_session: session request sent\r\ndebug1: mux_client_request_session: master session id: 2\r\ndebug2: Remote version: 3\r\ndebug2: Server supports extension "posix-rename@openssh.com" revision 1\r\ndebug2: Server supports extension "statvfs@openssh.com" revision 2\r\ndebug2: Server supports extension "fstatvfs@openssh.com" revision 2\r\ndebug2: Server supports extension "hardlink@openssh.com" revision 1\r\ndebug2: Server supports extension "fsync@openssh.com" revision 1\r\ndebug3: Sent message fd 5 T:16 I:1\r\ndebug3: SSH_FXP_REALPATH . -> /home/q size 0\r\ndebug3: Looking up /tmp/tmpji9Qoj\r\ndebug3: Sent message fd 5 T:17 I:2\r\ndebug3: Received stat reply T:101 I:2\r\ndebug1: Couldn\'t stat remote file: No such file or directory\r\ndebug3: Sent message SSH2_FXP_OPEN I:3 P:/home/q/.ansible/tmp/ansible-tmp-1510841304.79-155502950928476/ping.py\r\ndebug3: Sent message SSH2_FXP_WRITE I:4 O:0 S:32768\r\ndebug3: SSH2_FXP_STATUS 0\r\ndebug3: In write loop, ack for 4 32768 bytes at 0\r\ndebug3: Sent message SSH2_FXP_WRITE I:5 O:32768 S:31422\r\ndebug3: SSH2_FXP_STATUS 0\r\ndebug3: In write loop, ack for 5 31422 bytes at 32768\r\ndebug3: Sent message SSH2_FXP_CLOSE I:4\r\ndebug3: SSH2_FXP_STATUS 0\r\ndebug3: mux_client_read_packet: read header failed: Broken pipe\r\ndebug2: Received exit status from master 0\r\n')
<10.0.0.229> ESTABLISH SSH CONNECTION FOR USER: q
<10.0.0.229> SSH: EXEC sshpass -d11 ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o User=q -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/cc742780ab 10.0.0.229 '/bin/sh -c '"'"'chmod u+x /home/q/.ansible/tmp/ansible-tmp-1510841304.79-155502950928476/ /home/q/.ansible/tmp/ansible-tmp-1510841304.79-155502950928476/ping.py && sleep 0'"'"''
<10.0.0.229> (0, '', 'OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 56: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug2: mux_client_hello_exchange: master version 4\r\ndebug3: mux_client_forwards: request forwardings: 0 local, 0 remote\r\ndebug3: mux_client_request_session: entering\r\ndebug3: mux_client_request_alive: entering\r\ndebug3: mux_client_request_alive: done pid = 4386\r\ndebug3: mux_client_request_session: session request sent\r\ndebug1: mux_client_request_session: master session id: 2\r\ndebug3: mux_client_read_packet: read header failed: Broken pipe\r\ndebug2: Received exit status from master 0\r\n')
<10.0.0.229> ESTABLISH SSH CONNECTION FOR USER: q
<10.0.0.229> SSH: EXEC sshpass -d11 ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o User=q -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/cc742780ab -tt 10.0.0.229 '/bin/sh -c '"'"'/usr/bin/python /home/q/.ansible/tmp/ansible-tmp-1510841304.79-155502950928476/ping.py; rm -rf "/home/q/.ansible/tmp/ansible-tmp-1510841304.79-155502950928476/" > /dev/null 2>&1 && sleep 0'"'"''
<10.0.0.229> (0, '\r\n{"invocation": {"module_args": {"data": "pong"}}, "ping": "pong"}\r\n', 'OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 56: Applying options for *\r\ndebug1: auto-mux: Trying existing master\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug2: mux_client_hello_exchange: master version 4\r\ndebug3: mux_client_forwards: request forwardings: 0 local, 0 remote\r\ndebug3: mux_client_request_session: entering\r\ndebug3: mux_client_request_alive: entering\r\ndebug3: mux_client_request_alive: done pid = 4386\r\ndebug3: mux_client_request_session: session request sent\r\ndebug1: mux_client_request_session: master session id: 2\r\ndebug3: mux_client_read_packet: read header failed: Broken pipe\r\ndebug2: Received exit status from master 0\r\nShared connection to 10.0.0.229 closed.\r\n')
node229 | SUCCESS => {
"changed": false,
"failed": false,
"invocation": {
"module_args": {
"data": "pong"
}
},
"ping": "pong"
}
META: ran handlers
META: ran handlers
With Example 3, '-vvv' is passed which also gives the same information about
ansible version, module location, python version, connection profile,
etc.
[root@server Desktop]# ansible lbservers -m ping -vvv | grep '<10.0.0.229>' -c
15
[root@server Desktop]# ansible lbservers -m ping -vvvv | grep '<10.0.0.229>' -c
15
While observing the output for Example 2 and Example 3, notice <10.0.0.218> is returned in 15 lines. But the result of Example 3 includes additional connection debugging information.