I am using Ansible / Ansible Tower and would like to determine what facts are available on my Windows host. The documentation states that I can run the following:
ansible hostname -m setup
How would I incorporate this into a playbook I run from Tower so I can gather the information from hosts?
Here is the current Playbook per the assistance given:
# This play outputs the facts of the Windows targets in scope
- name: Gather Windows Facts
hosts: "{{ target }}"
gather_facts: yes
tasks:
- setup:
register: ansible_facts
- debug: item
with_dict: ansible_facts
However, running this produces the following error:
ERROR! this task 'debug' has extra params, which is only allowed in
the following modules: command, shell, script, include, include_vars,
add_host, group_by, set_fact, raw, meta
Use gather_facts which is true by default. It is equivalent to running setup module.
- hosts: ....
gather_facts: yes
The facts are saved in ansible variables to be used in playbooks. See System Facts
There are many ways to display the ansible facts. For you to understand how it works, try the following:
- hosts: 127.0.0.1
gather_facts: true
tasks:
- setup:
register: ansible_facts
- debug: item
with_dict: ansible_facts
Testing and working through it, this is working for me:
- name: Gather Windows Facts
hosts: "{{ target }}"
tasks:
- debug: var=vars
- debug: var=hostvars[inventory_hostname]
Related
I have this example role where I install some packages based on the OS and package manager:
# THIS IS IN tasks/main.yml
- name: Ensure archlinux-keyring is updated
community.general.pacman:
name: archlinux-keyring
state: latest
update_cache: yes
when: ansible_pkg_mgr == "pacman"
If this role is run as part of a playbook, Ansible will gather the facts and everything is just fine. However, if I run it as a standalone role:
ansible localhost -m include_role -a name=examplerole
I get this error
localhost | FAILED! => {
"msg": "The conditional check 'ansible_pkg_mgr == \"pacman\"' failed. The error was: error while evaluating conditional (ansible_pkg_mgr == \"pacman\"): 'ansible_pkg_mgr' is undefined
I know I can force Ansible to gather these facts inside the role, but gathering facts over and over again will be super slow (as this is a recurring problem I have with several roles, and I can't always include them in a playbook, and also, if they ARE in a playbook, this isn't needed).
Is there any way to check if facts were already gathered, and gather them inside of the role only when needed?
Regarding
...Is there any way to check if facts were already gathered ... gather them inside of the role only when needed?
and if you like to gather facts based on conditionals only, you may have a look into the following example
- hosts: localhost
become: false
gather_facts: false
tasks:
- name: Show Gathered Facts
debug:
msg: "{{ hostvars['localhost'].ansible_facts }}"
- name: Gather date and time only
setup:
gather_subset:
- "date_time"
- "!min"
when: ansible_date_time is not defined
- name: Show Gathered Facts
debug:
msg: "{{ ansible_facts }}"
which is gathering date and time only and if not defined before.
This means, regarding
gathering facts over and over again will be super slow
it is recommended to get familiar with the data structure of the gathered facts and the possible subsets in order to gather only the information which is needed. And as well with Caching facts.
Further Documentation
setup module – Gathers facts about remote hosts
What is the exact list of Ansible setup min?
I am trying to access Ansible facts for a different host than my target host. Following is my sample playbook. But facts are not collected for util server when I run the below play. Can someone help me, how can I access facts of a different server?
---
- hosts: build
gather_facts: yes
vars:
dist: "{{ hostvars['util']['ansible_facts']['distribution'] }}"
tasks:
- name: Demo Magic variables
debug:
var: "{{ dist }}"
Simply gather the needed facts from your desired server prior to using them. The simplest solution:
---
- name: Gather facts from util server
hosts: util
- name: Do our job
hosts: build
vars:
dist: "{{ hostvars['util']['ansible_facts']['distribution'] }}"
tasks:
- name: Demo Magic variables
debug:
var: "{{ dist }}"
I have this task:
- name: Install OpenJDK
become: true
apt:
name: openjdk-8-jre-headless
cache_valid_time: 60
state: latest
I want to run it in all hosts, including localhost. How can I tell Ansible to include localhost in the hosts for just one play?
You just add localhost to the pattern of targeted hosts in your play. Note that, unless your re-define it in your inventory, localhost is implicit and does not match the all special group.
The global idea
---
- name: This play will target all hosts in inventory
hosts: all
tasks:
- debug:
msg: I'm a dummy task
- name: This play will target all inventory hosts AND implicit localhost
hosts: all:localhost
tasks:
- debug:
msg: Yet an other dummy task
I'm running a playbook which houses multiple roles targets multiple hosts
The goal is to deploy a VM and use it's IP to deploy an app.
My playbook, has two roles, using "build_vm" role I'm able to display IP address via debug, yet when passing ipaddr variable to second role, Ansible complains that the variable is not defined
- hosts: linux
become: true
roles:
- build_vm
- tasks:
- debug: msg="{{ ipaddr }}"
- hosts: "{{ ipaddr }}"
roles:
- deploy_app
I have used set_fact with and ran into same issue, I wonder what I should be using here? dynamic inventory? I have searched sparse docs online and I'm unable to find an intuitive example to follow.
There are many ways to using add_host. In this example, I am adding the new host to a group and using it in a later play.
- hosts: linux
become: true
roles:
- build_vm
- tasks:
- debug: msg="{{ ipaddr }}"
- name: Add ipaddr to host inventory
add_host: name="{{ ipaddr }}" group=NewHostGroup
- hosts: NewHostGroup
roles:
- deploy_app
my inventory file's contents -
[webservers]
x.x.x.x ansible_ssh_user=ubuntu
[dbservers]
x.x.x.x ansible_ssh_user=ubuntu
in my tasks file which is in common role i.e. it will run on both hosts but I want to run a following task on host webservers not in dbservers which is defined in inventory file
- name: Install required packages
apt: name={{ item }} state=present
with_items:
- '{{ programs }}'
become: yes
tags: programs
is when module helpful or there is any other way? How could I do this ?
If you want to run your role on all hosts but only a single task limited to the webservers group, then - like you already suggested - when is your friend.
You could define a condition like:
when: inventory_hostname in groups['webservers']
Thank you, this helps me too.
hosts file:
[production]
host1.dns.name
[internal]
host2.dns.name
requirements.yml file:
- name: install the sphinx-search rpm from a remote repo on x86_64 - internal host
when: inventory_hostname in groups['internal']
yum:
name: http://sphinxsearch.com/files/sphinx-2.2.11-1.rhel7.x86_64.rpm
state: present
- name: install the sphinx-search rpm from a remote repo on i386 - Production
when: inventory_hostname in groups['production']
yum:
name: http://sphinxsearch.com/files/sphinx-2.2.11-2.rhel6.i386.rpm
state: present
An alternative to consider in some scenarios is -
delegate_to: hostname
There is also this example form the ansible docs, to loop over a group. https://docs.ansible.com/ansible/latest/user_guide/playbooks_delegation.html -
- hosts: app_servers
tasks:
- name: gather facts from db servers
setup:
delegate_to: "{{item}}"
delegate_facts: True
loop: "{{groups['dbservers']}}"