Ansible modify global applicative variable - variables

on Ansible 2.2, I want to implement this logic:
---
- name "PLB1"
- hosts: localhost
- tasks:
... init variable/fact X ...
- name "PLB2"
- hosts: huge_group
- tasks:
... each run add something to variable X ...
- name "PLB3"
- hosts: localhost
- tasks
- debug:
msg="{{X}}"
I don't understand how to define and then modify the global variable (or fact) X
Could you help me?
Riccardo

There are no global variables in Ansible.
Please look at your task again – do you really need them?
There is hostvars workaround exist:
---
- hosts: localhost
gather_facts: no
tasks:
- set_fact:
counter: 0
- hosts: mygroup
gather_facts: no
serial: 1
tasks:
- set_fact:
counter: "{{ hostvars['localhost'].counter | int + 1 }}"
delegate_to: localhost
delegate_facts: yes
- hosts: localhost
gather_facts: no
tasks:
- debug:
var: counter
Note serial: 1 for second Play – it is used to reread hostvars between task runs. If you don't use serial run, variable's value will be the same for all hosts.

Related

Ansible playbook passing variable to next play

I have built a playbook in ansible that creates 2 groups of ec2 instances.
In a second playbook, I want that the first play lists the existing group to the user so the user can choose one. Then in a second play, use this group in hosts
---
- name: playbook
hosts: localhost
vars_prompt:
- name: groupvar
prompt: "Select a group"
private: no
tasks:
- name: task 1
debug:
msg: "{{ groupvar}}"
- name: Another play
hosts: "{{ groupvar }}"
# ...
How can I pass on the value of groupvar to the second play in this playbook?
Note: make sure you are not simply re-inventing the existing --limit option of the ansible-playbook command line
As you found out, vars_prompt do not survive the play they're declared in. In that case you have to use set_fact. Here is an example using your above code as a starting point:
- name: playbook
hosts: localhost
vars_prompt:
- name: groupvar
prompt: "Select a group"
private: no
tasks:
- name: task 1
debug:
msg: "{{ groupvar }}"
- name: Save value in a fact for current host
set_fact:
groupvar: "{{ groupvar }}"
- name: Another play running on above chosen group
# Remember we have set the fact on current host above which was localhost
hosts: "{{ hostvars['localhost'].groupvar }}"
# ... rest of your play.

Ansible put in same option command all values of elements of list

OS: W2K16 Server
Ansible: 2.9.9
I search the method to put several vars in the winshell command, but this code launch 3 time the winshell command:
- name: "ntp conf"
win_shell: |
'w32tm /config /manualpeerlist: {{ item }} /syncfromflags:MANUAL'
with_items:
- 192.168.0.1
- 192.168.0.10
- 192.168.0.100
I Desire, the command is launched:
w32tm /config /manualpeerlist:"192.168.0.1 192.168.0.10 192.168.0.100" /syncfromflags:MANUAL'
Please don't referme to "ntp" ansible module, this is a example, I need to understand how to get multiple values from a list and run with one shoot.
Thank's a lot!
Put the peers into a list and join the items, e.g.
- command:
cmd: |
echo "{{ _peers|join(' ') }}"
register: result
vars:
_peers:
- 192.168.0.1
- 192.168.0.10
- 192.168.0.100
- debug:
var: result.stdout
gives
result.stdout: 192.168.0.1 192.168.0.10 192.168.0.100

Ansible: Issues with vars_prompt, error: variable is undefined

I think I may be using vars_prompt incorrectly because when I define a variable (used as a host) from command line, the host is used for the following task correctly:
ansible-playbook newfile -v -e 'target_host=uat:prd'
- hosts '{{ target_host }}'
tasks:
...
But when I define the same variable using vars_prompt:
- name: run task
hosts: localhost
gather_facts: no
vars_prompt:
- name: target_host
prompt: please choose a host site
private: no
- hosts: '{{ target_host }}'
tasks:
...
I get error: 'target_host' is undefined pointing at the - hosts: '{{ target_host }}'
Note: it does ask the prompt before getting the error
Thank you for the suggestion to add to host group #JBone. Sadly I have already tried this approach and I get:
Failed to connect to the host via ssh: ssh: Could not resolve hostname uat:prd: Name or service not known
Even though if I fill the host in the playbook as uat:prd it runs on each host
this approach does work for uat or prd by themselves but not uat:prd
you should add this variable value to a new host group using add_host module.
- name: run task
hosts: localhost
gather_facts: no
vars_prompt:
- name: target_host
prompt: please choose a host site
private: no
tasks:
- name: add host
add_host:
name: "{{ target_host }}"
groups: new_hosts_grp
- hosts: new_hosts_grp
tasks:
...
try that one.

Ansible, saving list of hosts into a variable

I have a playbook where I am first running a SQL statement to get a list of hosts from a database. I then save that list into a variable and want to run the next set of tasks over this list of hosts. But I am not sure how to do this or if it is even possible to dynamically define the hosts into an Ansible variable?
Below is a snippet of my code and what I am trying to do.
---
- hosts: all
gather_facts: no
tasks:
- name: Get list of hosts
command: sqlcmd -d testDB -q "SET NOCOUNT ON; SELECT DISTINCT HostName FROM Servers" -S "Central_Server" -h -1
register: sql_servers
- hosts: '{{ sql_servers.stdout_lines }}'
serial: 1
gather_facts: no
tasks:
........
other tasks
........
In the above code, I am trying to save the list of hosts into the sql_servers variables and want to run the 2nd set of my playbook over those hosts.
You're running the play with hosts: all. This implicates that there might be more hosts and, as a result, more lists of sql_servers too. Let's concatenate the lists. For example, whatever the source of the lists might be, given the inventory
shell> cat hosts
srv1 sql_servers='["a", "b"]'
srv2 sql_servers='["c", "a"]'
srv3 sql_servers='["e", "b"]'
the play
- hosts: all
tasks:
- set_fact:
srvs: "{{ ansible_play_hosts|
map('extract', hostvars, 'sql_servers')|
flatten|unique }}"
run_once: true
gives
srvs:
- a
- b
- c
- e
Now, use add_host and create group sql_servers
- add_host:
hostname: "{{ item }}"
groups: sql_servers
loop: "{{ srvs }}"
run_once: true
Use this group in the next play. The complete simplified playbook
- hosts: all
tasks:
- add_host:
hostname: "{{ item }}"
groups: sql_servers
loop: "{{ ansible_play_hosts|
map('extract', hostvars, 'sql_servers')|
flatten|unique }}"
run_once: true
- hosts: sql_servers
tasks:
- debug:
var: ansible_play_hosts_all
run_once: true
gives
ansible_play_hosts_all:
- a
- b
- c
- e
Fit the control flow to your needs.

Ansible how to ignore unreachable hosts before ansible 2.7.x

I'm using ansible to run a command against multiple servers at once. I want to ignore any hosts that fail because of the '"SSH Error: data could not be sent to remote host \"1.2.3.4\". Make sure this host can be reached over ssh"' error because some of the hosts in the list will be offline. How can I do this? Is there a default option in ansible to ignore offline hosts without failing the playbook? Is there an option to do this in a single ansible cli argument outside of a playbook?
Update: I am aware that the ignore_unreachable: true works for ansible 2.7 or greater, but I am working in an ansible 2.6.1 environment.
I found a good solution here. You ping each host locally to see if you can connect and then run commands against the hosts that passed:
---
- hosts: all
connection: local
gather_facts: no
tasks:
- block:
- name: determine hosts that are up
wait_for_connection:
timeout: 5
vars:
ansible_connection: ssh
- name: add devices with connectivity to the "running_hosts" group
group_by:
key: "running_hosts"
rescue:
- debug: msg="cannot connect to {{inventory_hostname}}"
- hosts: running_hosts
gather_facts: no
tasks:
- command: date
With current version on Ansible (2.8) something like this is possible:
- name: identify reachable hosts
hosts: all
gather_facts: false
ignore_errors: true
ignore_unreachable: true
tasks:
- block:
- name: this does nothing
shell: exit 1
register: result
always:
- add_host:
name: "{{ inventory_hostname }}"
group: reachable
- name: Converge
hosts: reachable
gather_facts: false
tasks:
- debug: msg="{{ inventory_hostname }} is reachable"