My inventory file looks like below
[all]
1.1.1.1 var1=vaule1 app_var2=vaule2
2.2.2.2 var1=vaule3 app_var2=vaule4
My task playbook, to create file if not exists and add content using host variable
- name: "Creating file_with content"
ansible.builtin.file:
path: "path-tofile/.test.txt"
state: touch
content: "app_env=hostvars[inventory_hostname]['var1']"
register: app_env_status
File is created with empty content, can somebody help here, does i am access variable correctly or my task has any issues.
There is no parameter content in the module file. Having run the task below
- file:
path: /tmp/test.txt
state: touch
content: "{{ var1 }}"
you must have seen the error message:
fatal: ... Unsupported parameters for (file) module: content. ...
Instead of file, use the module copy. The task below does the job
- copy:
dest: /tmp/test.txt
content: "{{ var1 }}"
Example of a complete project for testing
shell> tree .
.
├── ansible.cfg
├── hosts
└── pb.yml
0 directories, 3 files
shell> cat ansible.cfg
[defaults]
gathering = explicit
collections_path = $HOME/.local/lib/python3.9/site-packages/
inventory = $PWD/hosts
roles_path = $PWD/roles
remote_tmp = ~/.ansible/tmp
retry_files_enabled = false
stdout_callback = yaml
shell> cat hosts
[test]
test_11 var1=v1 var2=v2
test_13 var1=v3 var2=v4
[test:vars]
ansible_connection=ssh
ansible_user=admin
ansible_become=yes
ansible_become_user=root
ansible_become_method=sudo
ansible_python_interpreter=/usr/local/bin/python3.8
ansible_perl_interpreter=/usr/local/bin/perl
shell> ansible-playbook pb.yml
PLAY [all] ***********************************************************************************
TASK [copy] **********************************************************************************
changed: [test_11]
changed: [test_13]
PLAY RECAP ***********************************************************************************
test_11: ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_13: ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
shell> ssh admin#test_11 cat /tmp/test.txt
v1
shell> ssh admin#test_13 cat /tmp/test.txt
v3
Related
I have a task , in which I need to select the target environment/hosts amongst the multiple inventory files placed in different folders under inventories/ directory. The selection is based on the version passed as a variable.
inventories/
preprod/
group_vars/
hosts.ini
...
systest/
group_vars/
hosts.ini
...
uat/
group_vars/
hosts.ini
...
So if the version varaiable is 1.x.x then the hosts.ini under preprod should be selected, if its 2.x.x then the hosts.ini under systest should be selected and if its 3.x.x the hosts.ini under uat should be selected.
---
- name: Select hosts from multiple inventories based on version passed as a variable
hosts: all
vars:
version: '1.0'
tasks:
- name: Get hosts from first inventory
set_fact:
hosts_1: "{{ groups['inventory_1'] | selectattr('version', 'equalto', version) | map(attribute='hostname') | list }}"
- name: Get hosts from second inventory
set_fact:
hosts_2: "{{ groups['inventory_2'] | selectattr('version', 'equalto', version) | map(attribute='hostname') | list }}"
- name: Merge hosts from both inventories
set_fact:
hosts: "{{ hosts_1 + hosts_2 }}"
- name: Run tasks with hosts
debug:
msg: "{{ item }}"
loop: "{{ hosts }}"
Short answer: Copy the inventory file in the first play, refresh_inventory, and use it in the second play. Unfortunately, this does not refresh group_vars from the directories. As a workaround put the group_vars into the inventory files.
Details: Given the project for testing
shell> tree .
.
├── ansible.cfg
├── hosts.env
├── inventory
│ ├── preprod
│ │ └── hosts.ini
│ ├── systest
│ │ └── hosts.ini
│ └── uat
│ └── hosts.ini
└── pb.yml
4 directories, 6 files
Put the group_vars into the inventory files
shell> cat inventory/preprod/hosts.ini
[all]
preprod1
preprod2
preprod3
[all:vars]
env_gv=preprod
shell> cat inventory/systest/hosts.ini
systest1
systest2
systest3
[all:vars]
env_gv=systest
shell> cat inventory/uat/hosts.ini
[all]
uat1
uat2
uat3
[all:vars]
env_gv=uat
The playbook
shell> cat pb.yml
- hosts: localhost
vars:
envs:
1: preprod
2: systest
3: uat
env: "{{ envs[version.split('.').0|int] }}"
tasks:
- debug:
msg: "Use environment: {{ env }}"
- copy:
src: "{{ playbook_dir }}/inventory/{{ env }}/hosts.ini"
dest: "{{ playbook_dir }}/hosts.env"
- meta: refresh_inventory
- hosts: all
tasks:
- block:
- debug:
var: ansible_play_hosts_all
- debug:
var: env_gv
run_once: true
gives
version=1.0 works in the environment preprod
shell> ansible-playbook -i hosts.env -e version=1.0 pb.yml
PLAY [localhost] ****************************************************************************************
TASK [debug] ********************************************************************************************
ok: [localhost] =>
msg: 'Use environment: preprod'
TASK [copy] *********************************************************************************************
changed: [localhost]
TASK [meta] *********************************************************************************************
PLAY [all] **********************************************************************************************
TASK [debug] ********************************************************************************************
ok: [preprod1] =>
ansible_play_hosts_all:
- preprod1
- preprod2
- preprod3
TASK [debug] ********************************************************************************************
ok: [preprod1] =>
env_gv: preprod
PLAY RECAP **********************************************************************************************
localhost: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
preprod1: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
version=2.0 works in the environment systest
shell> ansible-playbook -i hosts.env -e version=2.0 pb.yml
PLAY [localhost] ****************************************************************************************
TASK [debug] ********************************************************************************************
ok: [localhost] =>
msg: 'Use environment: systest'
TASK [copy] *********************************************************************************************
changed: [localhost]
TASK [meta] *********************************************************************************************
PLAY [all] **********************************************************************************************
TASK [debug] ********************************************************************************************
ok: [systest1] =>
ansible_play_hosts_all:
- systest1
- systest2
- systest3
TASK [debug] ********************************************************************************************
ok: [systest1] =>
env_gv: systest
PLAY RECAP **********************************************************************************************
localhost: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
systest1: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
version=3.0 works in the environment uat
shell> ansible-playbook -i hosts.env -e version=3.0 pb.yml
PLAY [localhost] ****************************************************************************************
TASK [debug] ********************************************************************************************
ok: [localhost] =>
msg: 'Use environment: uat'
TASK [copy] *********************************************************************************************
changed: [localhost]
TASK [meta] *********************************************************************************************
PLAY [all] **********************************************************************************************
TASK [debug] ********************************************************************************************
ok: [uat1] =>
ansible_play_hosts_all:
- uat1
- uat2
- uat3
TASK [debug] ********************************************************************************************
ok: [uat1] =>
env_gv: uat
PLAY RECAP **********************************************************************************************
localhost: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
uat1: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Example. Precedence of group_vars. YAML format.
shell> tree .
.
├── ansible.cfg
├── group_vars
│ └── all.yml
├── hosts
├── inventories
│ ├── preprod
│ │ └── hosts
│ ├── systest
│ │ └── hosts
│ └── uat
│ └── hosts
├── inventory
│ ├── group_vars
│ │ └── all.yml
│ └── hosts
└── pb.yml
7 directories, 9 files
shell> cat group_vars/all.yml
env_gv3: playbook group_vars/all
shell> cat inventory/group_vars/all.yml
env_gv2: inventory group_vars/all
shell> cat inventories/preprod/hosts
all:
hosts:
preprod1:
preprod2:
preprod3:
vars:
env_gv1: preprod1 inventory file group_vars
env_gv2: preprod2 inventory file group_vars
env_gv3: preprod3 inventory file group_vars
shell> cat inventories/systest/hosts
all:
hosts:
systest1:
systest2:
systest3:
vars:
env_gv1: systest1 inventory file group_vars
env_gv2: systest2 inventory file group_vars
env_gv3: systest3 inventory file group_vars
shell> cat inventories/uat/hosts
all:
hosts:
uat1:
uat2:
uat3:
vars:
env_gv1: uat1 inventory file group_vars
env_gv2: uat2 inventory file group_vars
env_gv3: uat3 inventory file group_vars
shell> cat pb.yml
- hosts: localhost
vars:
envs:
1: preprod
2: systest
3: uat
env: "{{ envs[version.split('.').0|int] }}"
tasks:
- debug:
msg: "Use environment: {{ env }}"
- copy:
src: "{{ playbook_dir }}/inventories/{{ env }}/hosts"
dest: "{{ playbook_dir }}/inventory/hosts"
- meta: refresh_inventory
- hosts: all
tasks:
- block:
- debug:
var: ansible_play_hosts_all
- debug:
msg: |
env_gv1: {{ env_gv1 }}
env_gv2: {{ env_gv2 }}
env_gv3: {{ env_gv3 }}
run_once: true
shell> ansible-playbook -i inventory/hosts -e version=2.0 pb.yml
shows that variable precedence:
inventory file or script group vars
inventory group_vars/all
playbook group_vars/all
works as expected
PLAY [localhost] ****************************************************************************************
TASK [debug] ********************************************************************************************
ok: [localhost] =>
msg: 'Use environment: systest'
TASK [copy] *********************************************************************************************
changed: [localhost]
TASK [meta] *********************************************************************************************
PLAY [all] **********************************************************************************************
TASK [debug] ********************************************************************************************
ok: [systest1] =>
ansible_play_hosts_all:
- systest1
- systest2
- systest3
TASK [debug] ********************************************************************************************
ok: [systest1] =>
msg: |-
env_gv1: systest1 inventory file group_vars
env_gv2: inventory group_vars/all
env_gv3: playbook group_vars/all
PLAY RECAP **********************************************************************************************
localhost: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
systest1: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
i need to create an ansible job to execute the shell script which is having arguments for different environments (one playbook which will be applicable to all environments test, QA and prod by providing argument in the command). for example, I need to execute script ABC.sh for which normal command is
sh ABC.sh /105t (for test execution) or sh ABC.sh /105q (for QA execution).
Can someone please help me with the playbook for this? Thanks!!
I tried the below format in YML file in gitlab.
-name: execute the script
tasks:
name: execute the ABC script
script: sh script_dir_path/ABC.sh /105t
The job ran successfully but it did not trigger the script execution.
Use the module script. It runs a local script on a remote node after transferring it. For example, given the tree
shell> tree .
.
├── ansible.cfg
├── hosts
├── pb.yml
└── script_dir_path
└── ABC.sh
Create a simple script that displays the first argument
shell> cat script_dir_path/ABC.sh
echo $1
The playbook below runs on all remote hosts. It will transfer the script to the remotes, run it with the argument arg, and display the result
shell> cat pb.yml
- hosts: all
tasks:
- script:
cmd: "script_dir_path/ABC.sh {{ arg }}"
register: out
- debug:
var: out.stdout
Given the inventory
shell> cat hosts
test_11
test_13
The playbook works as expected
shell> ansible-playbook pb.yml -e arg=/105t
PLAY [all] ***********************************************************************************
TASK [script] ********************************************************************************
changed: [test_11]
changed: [test_13]
TASK [debug] *********************************************************************************
ok: [test_11] =>
out.stdout: |-
/105t
ok: [test_13] =>
out.stdout: |-
/105t
PLAY RECAP ***********************************************************************************
test_11: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_13: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
I tried lookup on machine installed on it ansible and it works, but when uploading playbook to awx it does not work.
- name: get file
set_fact:
policer: "{{ lookup('file', 'file.txt') }}"
it gives An unhandled exception occurred while running the lookup plugin 'file'. Error was a <class 'ansible.errors.AnsibleError'>, original message: could not locate file in lookup"
although the file in the same repo of playbook, and have worked on machine but not awx. And if there is something specific to remote hosts how to know the path
Ansible Lookup plugins "execute and are evaluated on the Ansible control machine."
The play works fine when you run it at the localhost (control machine) where the file is located
shell> hostname
test_11
shell> cat /tmp/file.txt
content of file /tmp/file.txt
shell> cat pb1.yml
- hosts: localhost
vars:
policer: "{{ lookup('file', '/tmp/file.txt') }}"
tasks:
- debug:
var: policer
shell> ansible-playbook pb1.yml
PLAY [localhost] *****************************************************************************
TASK [debug] *********************************************************************************
ok: [localhost] =>
policer: content of file /tmp/file.txt
PLAY RECAP ***********************************************************************************
localhost: ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
When you move to another controller (might be AWX) the file remains at the remote host (test_11 in the example) and is not available at the localhost controller. You can test it. See the block below
shell> hostname
awx
shell> cat /tmp/file.txt
cat: /tmp/file.txt: No such file or directory
shell> ssh admin#test_11 cat /tmp/file.txt
content of file /tmp/file.txt
shell> cat pb2.yml
- hosts: test_11
vars:
policer: "{{ lookup('file', '/tmp/file.txt') }}"
tasks:
- block:
- stat:
path: /tmp/file.txt
register: st
- debug:
var: st.stat.exists
delegate_to: localhost
- debug:
var: policer
shell> ansible-playbook pb2.yml
PLAY [test_11] *******************************************************************************
TASK [stat] **********************************************************************************
ok: [test_11 -> localhost]
TASK [debug] *********************************************************************************
ok: [test_11 -> localhost] =>
st.stat.exists: false
TASK [debug] *********************************************************************************
[WARNING]: Unable to find '/tmp/file.txt' in expected paths (use -vvvvv to see paths)
fatal: [test_11]: FAILED! =>
msg: 'An unhandled exception occurred while templating ''{{ lookup(''file'', ''/tmp/file.txt'') }}''. Error was a <class ''ansible.errors.AnsibleError''>, original message: An unhandled exception occurred while running the lookup plugin ''file''. Error was a <class ''ansible.errors.AnsibleError''>, original message: could not locate file in lookup: /tmp/file.txt. could not locate file in lookup: /tmp/file.txt'
PLAY RECAP ***********************************************************************************
test_11: ok=2 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
There are many options for how to fix it. The trivial one is moving also the file to the localhost controller. If the file remains at the remote host you can either read it by command or slurp, or fetch it. The module command always reports changed. The modules slurp and fetch are idempotent.
Read the file by command
shell> cat pb3.yml
- hosts: test_11
vars:
policer: "{{ out.stdout }}"
tasks:
- command: cat /tmp/file.txt
register: out
- debug:
var: policer
shell> ansible-playbook pb3.yml
PLAY [test_11] *******************************************************************************
TASK [command] *******************************************************************************
changed: [test_11]
TASK [debug] *********************************************************************************
ok: [test_11] =>
policer: content of file /tmp/file.txt
PLAY RECAP ***********************************************************************************
test_11: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Read the file by slurp. This should be used for smaller files only because (quoting from slurp): "This module returns an ‘in memory’ base64 encoded version of the file, take into account that this will require at least twice the RAM as the original file size."
shell> cat pb4.yml
- hosts: test_11
vars:
policer: "{{ out.content|b64decode }}"
tasks:
- slurp:
path: /tmp/file.txt
register: out
- debug:
var: policer
shell> ansible-playbook pb4.yml
PLAY [test_11] *******************************************************************************
TASK [slurp] *********************************************************************************
ok: [test_11]
TASK [debug] *********************************************************************************
ok: [test_11] =>
policer: |-
content of file /tmp/file.txt
PLAY RECAP ***********************************************************************************
test_11: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
The next option is to fetch the file to the local directory dest (will be created). By default, the file(s) is stored in the directory named by the remote host
shell> cat pb5.yml
- hosts: test_11
vars:
file_path: "/tmp/fetched_files/{{ inventory_hostname }}/tmp/file.txt"
policer: "{{ lookup('file', file_path) }}"
tasks:
- fetch:
src: /tmp/file.txt
dest: /tmp/fetched_files
- debug:
var: policer
shell> ansible-playbook pb5.yml
PLAY [test_11] *******************************************************************************
TASK [fetch] *********************************************************************************
changed: [test_11]
TASK [debug] *********************************************************************************
ok: [test_11] =>
policer: content of file /tmp/file.txt
PLAY RECAP ***********************************************************************************
test_11: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
shell> cat /tmp/fetched_files/test_11/tmp/file.txt
content of file /tmp/file.txt
Notes
An absolute path to the file is used in the examples. See The magic of ‘local’ paths on how to use relative paths locally.
I am unable to find why this simple pattern doesn't seem to match anything. I have two Ansible hosts as targets. This is my inventory file:
[web_Xubuntu]
192.168.160.128
[database_Fedora]
192.168.160.132
And this is what my YAML playbook looks like:
# Hosts: where our play will run and options it will run with
hosts: *Fedora
become: True
#gather_facts: False
# Vars: variables that will apply to the play, on all target systems
vars:
motd: "Welcome to Fedora Linux - Ansible Rocks\n"
# Tasks: the list of tasks that will be executed within the playbook
tasks:
- name: Configure a MOTD (message of the day)
copy:
content: "{{ motd }}"
dest: /etc/motd
notify: MOTD changed
# Handlers: the list of handlers that are executed as a notify key from a task
handlers:
- name: MOTD changed
debug:
msg: The MOTD was changed
On processing this playbook, Ansible reports the following error:
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: Expecting value: line 1 column 1 (char 0)
Syntax Error while loading YAML.
found undefined alias
The offending line appears to be:
# Hosts: where our play will run and options it will run with
hosts: *Fedora
^ here
What is the right way to use a wildcard?
You can use the asterisk *( wildcard) with FQDN or IP only. For example,
192.0.*
*.example.com
*.com
See Patterns: targeting hosts and groups.
Use the inventory plugin constructed if you want to run all *Fedora groups. See
shell> ansible-doc -t inventory constructed
For example, given the tree
shell> tree .
.
├── ansible.cfg
├── inventory
│ ├── 01-hosts
│ └── 02-constructed.yml
└── pb.yml
1 directory, 4 files
the inventory
shell> cat inventory/01-hosts
[web_Xubuntu]
192.168.160.128
[database_Fedora]
192.168.160.132
[web_Fedora]
192.168.160.133
the contructed plugin
shell> cat inventory/02-constructed.yml
plugin: constructed
groups:
Fedora: group_names|select('regex', '^.*Fedora$')
Test the inventory
shell> ansible-inventory -i inventory --list --yaml
all:
children:
Fedora:
hosts:
192.168.160.132: {}
192.168.160.133: {}
database_Fedora:
hosts:
192.168.160.132: {}
ungrouped: {}
web_Fedora:
hosts:
192.168.160.133: {}
web_Xubuntu:
hosts:
192.168.160.128: {}
Then, test the playbook
shell> cat pb.yml
- hosts: Fedora
gather_facts: false
tasks:
- debug:
var: inventory_hostname
gives
shell> ansible-playbook -i inventory pb.yml
PLAY [Fedora] *********************************************************************************
TASK [debug] **********************************************************************************
ok: [192.168.160.132] =>
inventory_hostname: 192.168.160.132
ok: [192.168.160.133] =>
inventory_hostname: 192.168.160.133
PLAY RECAP ************************************************************************************
192.168.160.132: ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.160.133: ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
I'm new to Ansible and trying to fetch hosts from below config.yaml file instead of inventory, to run tasks on those hosts. How can I do this in main playbook?
service:
web-app:
common:
tomcat:
port: 80
hosts:
all:
- abc.com
- pqr.com
Is there a way to access abc.com and pqr.com in my playbook, if I have to run certain tasks on those servers?
The base: loading the data
The base ansible functions needed for the following examples are:
The file lookup plugin to load the content of a file present on the controller.
The from_yaml filter to read the file content as yaml formatted data
For both examples below, I added your above yaml example (after fixing the indentation issues) to files/service_config.yml. Simply change the name of the file if it is in a files subdir, or use the full path to the file if it is outside of your project.
Combining the above, you can get your list of hosts with the following jinja2 expression.
{{ (lookup('file', 'service_config.yml') | from_yaml).service.hosts.all }}
Note: if your custom yaml file is not present on your controller, you will firts need to get the data locally by using the slurp or fetch modules
Use in memory inventory
In this example, I create a dynamic group custom_group running a add_hosttask on a play targeted to localhost and later target that custom group in the next play. This is probably the best option if you have a large set of tasks to run on those hosts.
---
- name: Prepare environment
hosts: localhost
gather_facts: false
vars:
# Replace with full path to actual file
# if this one is not in your 'files' subdir
my_config_file: service_config.yml
my_custom_hosts: "{{ (lookup('file', my_config_file) | from_yaml).service.hosts.all }}"
tasks:
- name: Create dynamic group from custom yaml file
add_host:
name: "{{ item }}"
group: custom_group
loop: "{{ my_custom_hosts }}"
- name: Play on new custom group
hosts: custom_group
gather_facts: false
tasks:
- name: Show we can actually contact the group
debug:
var: inventory_hostname
Which gives:
PLAY [Prepare environment] **********************************************************************************************************************************************************************************************************************************************
TASK [Create dynamic group from custom yaml file] ***********************************************************************************************************************************************************************************************************************
changed: [localhost] => (item=abc.com)
changed: [localhost] => (item=pqr.com)
PLAY [Play on new custom group] *****************************************************************************************************************************************************************************************************************************************
TASK [Show we can actually contact the group] ***************************************************************************************************************************************************************************************************************************
ok: [abc.com] => {
"inventory_hostname": "abc.com"
}
ok: [pqr.com] => {
"inventory_hostname": "pqr.com"
}
PLAY RECAP **************************************************************************************************************************************************************************************************************************************************************
abc.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
localhost : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
pqr.com : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Use delegation
In the following example, I use task delegation to change the target host inside a play targeted to other hosts.
This is more suited if you have few tasks to run on the custom hosts and/or you need facts from the current play hosts to run those tasks. See the load balancer example in the above doc for a more in depth explanation.
---
- name: Delegation example
hosts: localhost
gather_facts: false
vars:
# Replace with full path to actual file
# if this one is not in your 'files' subdir
my_config_file: service_config.yml
my_custom_hosts: "{{ (lookup('file', my_config_file) | from_yaml).service.hosts.all }}"
tasks:
- name: Task played on our current target host list
debug:
var: inventory_hostname
- name: Fake task delegated to our list of custom host
# Note: we play it only once so it does not repeat
# if the play `hosts` param is a group of several targets
# This is for example only and is not really delegating
# anything in this case. Replace with your real life task
debug:
msg: "I would run on {{ item }} with facts from {{ inventory_hostname }}"
delegate_to: "{{ item }}"
run_once: true
loop: "{{ my_custom_hosts }}"
Which gives:
PLAY [Delegation example] ***********************************************************************************************************************************************************************************************************************************************
TASK [Task played on our current target host list] **********************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"inventory_hostname": "localhost"
}
TASK [Fake task delegated to our list of custom host] *******************************************************************************************************************************************************************************************************************
ok: [localhost -> abc.com] => (item=abc.com) => {
"msg": "I would run on abc.com with facts from localhost"
}
ok: [localhost -> pqr.com] => (item=pqr.com) => {
"msg": "I would run on pqr.com with facts from localhost"
}
PLAY RECAP **************************************************************************************************************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0