0%

Ansible-part7: set facts, set variable

what is set_fact

Set fact is a module which allows setting new variables. These variables are set on a host-by-host base just like facts discovered by the setup module.

In ansible, there are some default info of hosts in hostvars variable, such as “ansible_check_mode”, “group_names” etc, and also the “ansible_facts”, which is not default show up, only when gather_facts is set to “yes”, it will show the details of ansible_fact. Except these two kinds of info, I can also use set_fact module to create my own info pair.

1
2
3
4
5
6
7
8
- name: set fact
hosts: all
gather_facts: no

tasks:
- name: gather facts
debug:
var: hostvars[ansible_host] #ansible_host is variable name, which means cube4200 and ansible-node1 in this case

Let’s look at he output of this playbook,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
anna@ansible-controller:~/Desktop/ansible-code/inventory/modules/set-fact module$ ansible-playbook site.yml 

PLAY [set fact] ************************************************************************

TASK [gather facts] ********************************************************************
ok: [cube4200] => {
"hostvars[ansible_host]": {
"ansible_check_mode": false,
"ansible_connection": "ssh",
"ansible_diff_mode": false,
"ansible_facts": {},
"ansible_forks": 5,
"ansible_inventory_sources": [
"/home/anna/Desktop/ansible-code/inventory/modules/set-fact module/hosts"
],
"ansible_playbook_python": "/usr/bin/python2",
"ansible_run_tags": [
"all"
],
"ansible_skip_tags": [],
"ansible_user": "anna",
"ansible_verbosity": 0,
"ansible_version": {
"full": "2.9.9",
"major": 2,
"minor": 9,
"revision": 9,
"string": "2.9.9"
},
"group_names": [
"web2"
],
"groups": {
"all": [
"cube4200",
"ansible-node1"
],
"ungrouped": [],
"web1": [
"ansible-node1"
],
"web2": [
"cube4200"
]
},
"inventory_dir": "/home/anna/Desktop/ansible-code/inventory/modules/set-fact module",
"inventory_file": "/home/anna/Desktop/ansible-code/inventory/modules/set-fact module/hosts",
"inventory_hostname": "cube4200",
"inventory_hostname_short": "cube4200",
"omit": "__omit_place_holder__a53469922527cea947bde7fea01f0f911fe92d8c",
"playbook_dir": "/home/anna/Desktop/ansible-code/inventory/modules/set-fact module"
}
}
ok: [ansible-node1] => {
"hostvars[ansible_host]": {
"ansible_check_mode": false,
"ansible_connection": "ssh",
"ansible_diff_mode": false,
"ansible_facts": {},
"ansible_forks": 5,
"ansible_inventory_sources": [
"/home/anna/Desktop/ansible-code/inventory/modules/set-fact module/hosts"
],
"ansible_playbook_python": "/usr/bin/python2",
"ansible_run_tags": [
"all"
],
"ansible_skip_tags": [],
"ansible_user": "pi",
"ansible_verbosity": 0,
"ansible_version": {
"full": "2.9.9",
"major": 2,
"minor": 9,
"revision": 9,
"string": "2.9.9"
},
"group_names": [
"web1"
],
"groups": {
"all": [
"cube4200",
"ansible-node1"
],
"ungrouped": [],
"web1": [
"ansible-node1"
],
"web2": [
"cube4200"
]
},
"inventory_dir": "/home/anna/Desktop/ansible-code/inventory/modules/set-fact module",
"inventory_file": "/home/anna/Desktop/ansible-code/inventory/modules/set-fact module/hosts",
"inventory_hostname": "ansible-node1",
"inventory_hostname_short": "ansible-node1",
"omit": "__omit_place_holder__a53469922527cea947bde7fea01f0f911fe92d8c",
"playbook_dir": "/home/anna/Desktop/ansible-code/inventory/modules/set-fact module"
}
}

PLAY RECAP *****************************************************************************
ansible-node1 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
cube4200 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

eventhought gather_facts is “no”, ansible still show some basic info of every hosts.
If gather_facts is “yes”, except the default info, ansible will show ansible-facts info which included a lots of system info of every hosts.

If I add set_fact module, and create a variable named test_set_fact, it will show in the output of hostvars, notice line 56 and line 105

1
2
3
4
5
6
7
8
9
10
- name: set fact
hosts: all
gather_facts: no

tasks:
- name: test facts
set_fact:
test_set_fact: "variable from set fact"
- debug:
var: hostvars[ansible_host] #ansible_host is variable name, which means cube4200 and ansible-node1 in this case

Let’s look at the output

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
anna@ansible-controller:~/Desktop/ansible-code/inventory/modules/set-fact module$ ansible-playbook site.yml 

PLAY [set fact] ***************************************************************************************************************************************************************************************************************************************

TASK [test facts] *************************************************************************************************************************************************************************************************************************************
ok: [cube4200]
ok: [ansible-node1]

TASK [debug] ******************************************************************************************************************************************************************************************************************************************
ok: [cube4200] => {
"hostvars[ansible_host]": {
"ansible_check_mode": false,
"ansible_connection": "ssh",
"ansible_diff_mode": false,
"ansible_facts": {},
"ansible_forks": 5,
"ansible_inventory_sources": [
"/home/anna/Desktop/ansible-code/inventory/modules/set-fact module/hosts"
],
"ansible_playbook_python": "/usr/bin/python2",
"ansible_run_tags": [
"all"
],
"ansible_skip_tags": [],
"ansible_user": "anna",
"ansible_verbosity": 0,
"ansible_version": {
"full": "2.9.9",
"major": 2,
"minor": 9,
"revision": 9,
"string": "2.9.9"
},
"group_names": [
"web2"
],
"groups": {
"all": [
"cube4200",
"ansible-node1"
],
"ungrouped": [],
"web1": [
"ansible-node1"
],
"web2": [
"cube4200"
]
},
"inventory_dir": "/home/anna/Desktop/ansible-code/inventory/modules/set-fact module",
"inventory_file": "/home/anna/Desktop/ansible-code/inventory/modules/set-fact module/hosts",
"inventory_hostname": "cube4200",
"inventory_hostname_short": "cube4200",
"omit": "__omit_place_holder__d4f2446f1f2a785d53a7d7fe3b7b731b4fa322b3",
"playbook_dir": "/home/anna/Desktop/ansible-code/inventory/modules/set-fact module",
"test_set_fact": "variable from set fact"
}
}
ok: [ansible-node1] => {
"hostvars[ansible_host]": {
"ansible_check_mode": false,
"ansible_connection": "ssh",
"ansible_diff_mode": false,
"ansible_facts": {},
"ansible_forks": 5,
"ansible_inventory_sources": [
"/home/anna/Desktop/ansible-code/inventory/modules/set-fact module/hosts"
],
"ansible_playbook_python": "/usr/bin/python2",
"ansible_run_tags": [
"all"
],
"ansible_skip_tags": [],
"ansible_user": "pi",
"ansible_verbosity": 0,
"ansible_version": {
"full": "2.9.9",
"major": 2,
"minor": 9,
"revision": 9,
"string": "2.9.9"
},
"group_names": [
"web1"
],
"groups": {
"all": [
"cube4200",
"ansible-node1"
],
"ungrouped": [],
"web1": [
"ansible-node1"
],
"web2": [
"cube4200"
]
},
"inventory_dir": "/home/anna/Desktop/ansible-code/inventory/modules/set-fact module",
"inventory_file": "/home/anna/Desktop/ansible-code/inventory/modules/set-fact module/hosts",
"inventory_hostname": "ansible-node1",
"inventory_hostname_short": "ansible-node1",
"omit": "__omit_place_holder__d4f2446f1f2a785d53a7d7fe3b7b731b4fa322b3",
"playbook_dir": "/home/anna/Desktop/ansible-code/inventory/modules/set-fact module",
"test_set_fact": "variable from set fact"
}
}

PLAY RECAP ********************************************************************************************************************************************************************************************************************************************
ansible-node1 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
cube4200 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

At last line of every hosts,I can see the "test_set_fact": "variable from set fact", which is the variable and value I set in the playbook before.

How to use set_fact varible

I can call this variable directly in playbook

1
2
3
4
5
6
tasks:
- name: test facts
set_fact:
test_set_fact: "variable from set fact"
- debug:
var: test_set_fact

debug module will show only test_set_fact variable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
anna@ansible-controller:~/Desktop/ansible-code/inventory/modules/set-fact module$ ansible-playbook site.yml 

PLAY [set fact] ***************************************************************************************************************************************************************************************************************************************

TASK [test facts] *************************************************************************************************************************************************************************************************************************************
ok: [cube4200]
ok: [ansible-node1]

TASK [debug] ******************************************************************************************************************************************************************************************************************************************
ok: [cube4200] => {
"test_set_fact": "variable from set fact"
}
ok: [ansible-node1] => {
"test_set_fact": "variable from set fact"
}

another example
I am going to get the every hosts’s hostname info.

1
2
3
4
5
6
7
8
tasks:
- name: test facts
set_fact:
test_set_fact: "variable from set fact"
- command: cat /etc/hosts
register: hosts_result
- debug:
var: hosts_result

I put all the output of command cat /etc/hosts into variable named hosts_result, then it will show like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
anna@ansible-controller:~/Desktop/ansible-code/inventory/modules/set-fact module$ ansible-playbook site.yml 

PLAY [set fact] ***************************************************************************************************************************************************************************************************************************************

TASK [test facts] *************************************************************************************************************************************************************************************************************************************
ok: [cube4200]
ok: [ansible-node1]

TASK [command] ****************************************************************************************************************************************************************************************************************************************
changed: [ansible-node1]
changed: [cube4200]

TASK [debug] ******************************************************************************************************************************************************************************************************************************************
ok: [cube4200] => {
"hosts_result": {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"cmd": [
"cat",
"/etc/hosts"
],
"delta": "0:00:00.011381",
"end": "2020-06-13 14:38:12.510727",
"failed": false,
"rc": 0,
"start": "2020-06-13 14:38:12.499346",
"stderr": "",
"stderr_lines": [],
"stdout_lines": [
"127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4",
"::1 localhost localhost.localdomain localhost6 localhost6.localdomain6"
]
}
}
ok: [ansible-node1] => {
"hosts_result": {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"cmd": [
"cat",
"/etc/hosts"
],
"delta": "0:00:00.014459",
"end": "2020-06-13 21:38:08.778027",
"failed": false,
"rc": 0,
"start": "2020-06-13 21:38:08.763568",
"stderr": "",
"stderr_lines": [],
"stdout_lines": [
"127.0.0.1\tlocalhost",
"::1\t\tlocalhost ip6-localhost ip6-loopback",
"ff02::1\t\tip6-allnodes",
"ff02::2\t\tip6-allrouters",
"",
"127.0.1.1\ttreehouses"
],
"warnings": [
"Platform linux on host ansible-node1 is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information."
]
}
}

PLAY RECAP ********************************************************************************************************************************************************************************************************************************************
ansible-node1 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
cube4200 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

but I only want the “stdout_lines” info, so I am going to set “stdout_lines” to a variable named host_ip, and use set_fact module to do this, modified the playbook like this:

1
2
3
4
5
6
7
tasks:
- command: cat /etc/hosts
register: hosts_result
- set_fact:
host_ip: "{{hosts_result['stdout_lines']}}"
- debug:
var: host_ip

So the output will be like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
anna@ansible-controller:~/Desktop/ansible-code/inventory/modules/set-fact module$ ansible-playbook site.yml 

PLAY [set fact] ************************************************************************

TASK [command] *************************************************************************
changed: [ansible-node1]
changed: [cube4200]

TASK [set_fact] ************************************************************************
ok: [cube4200]
ok: [ansible-node1]

TASK [debug] ***************************************************************************
ok: [cube4200] => {
"host_ip": [
"127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4",
"::1 localhost localhost.localdomain localhost6 localhost6.localdomain6"
]
}
ok: [ansible-node1] => {
"host_ip": [
"127.0.0.1\tlocalhost",
"::1\t\tlocalhost ip6-localhost ip6-loopback",
"ff02::1\t\tip6-allnodes",
"ff02::2\t\tip6-allrouters",
"",
"127.0.1.1\ttreehouses"
]
}

PLAY RECAP *****************************************************************************
ansible-node1 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
cube4200 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

anna@ansible-controller:~/Desktop/ansible-code/inventory/modules/set-fact module$

It will show only the host ip which I want.