In this post, we are going to see, What is ansible facts (or) playbook variables and how to use these facts various types of facts such as Dictionary, List, Normal Text.
Also covered, What does ansible Gathering facts tasks do in ansible playbook execution, data types of ansible variables and how to know the data type of ansible variable including how to access the ansible dictionary and list objects.
We are going to start from the ansible Gathering facts. As ansible collected facts are considered as the ansible playbook variables (or) facts.
Let us start.
What are Ansible Facts (or) variables
Ansible collects pretty much all the information about the remote hosts as it runs a playbook. The task of collecting this remote system information is called as Gathering Facts
by ansible and the details collected are generally known as facts
or variables
This information can be obtained manually using Ansible ad-hoc command and a specialized module named setup. In fact, ansible playbooks call this setup module by default to perform Gathering Facts
task
The ansible ad-hoc command to invoke the ansible setup module is given below.
ansible <hostname (or) hostgroup> -m setup
The Execution output the setup module is given below
Ansible Facts List or Index
Here is the list of facts would be returned when you run the ansible hostgroup -m setup
command against any host group.
Ansible setup
module does the same action what gathering_facts
does during the ansible playbook execution. in fact gathering_facts
use setup
module to collect the facts.
These Ansible facts would be collected for each hosts in your hostgroup before the playbook execution until you disable it explicitely by defining gather_facts: false
Everything within the
ansible_facts
key in the returned dictionary is available as a variable in your playbooks and templates.For example these are some of the variables/facts name you can directly call with Jinja2 syntax
{{ <variable name> }}
- ansible_architecture
- ansible_app_ipv4_address
- ansible_distribution etc
But you need to know how to use these facts properly based on their datatype. which is discussed in detail here.
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"172.31.21.77"
],
"ansible_all_ipv6_addresses": [
"fe80::812:67ff:fe49:e819"
],
"ansible_apparmor": {
"status": "disabled"
},
"ansible_architecture": "x86_64",
"ansible_bios_date": "08/24/2006",
"ansible_bios_version": "4.2.amazon",
"ansible_cmdline": {
"BOOT_IMAGE": "/boot/vmlinuz-3.10.0-957.1.3.el7.x86_64",
"LANG": "en_US.UTF-8",
"console": "ttyS0,115200",
"crashkernel": "auto",
"ro": true,
"root": "UUID=f41e390f-835b-4223-a9bb-9b45984ddf8d"
},
"ansible_date_time": {
"date": "2020-02-10",
"day": "10",
"epoch": "1581317308",
"hour": "06",
"iso8601": "2020-02-10T06:48:28Z",
"iso8601_basic": "20200210T064828664797",
"iso8601_basic_short": "20200210T064828",
"iso8601_micro": "2020-02-10T06:48:28.664877Z",
"minute": "48",
"month": "02",
"second": "28",
"time": "06:48:28",
"tz": "UTC",
"tz_offset": "+0000",
"weekday": "Monday",
"weekday_number": "1",
"weeknumber": "06",
"year": "2020"
},
"ansible_default_ipv4": {
"address": "172.31.21.77",
"alias": "eth0",
"broadcast": "172.31.31.255",
"gateway": "172.31.16.1",
"interface": "eth0",
"macaddress": "0a:12:67:49:e8:19",
"mtu": 9001,
"netmask": "255.255.240.0",
"network": "172.31.16.0",
"type": "ether"
},
"ansible_default_ipv6": {},
"ansible_device_links": {
"ids": {},
"labels": {},
"masters": {},
"uuids": {
"xvda1": [
"f41e390f-835b-4223-a9bb-9b45984ddf8d"
]
}
},
"ansible_devices": {
"xvda": {
"holders": [],
"host": "",
"links": {
"ids": [],
"labels": [],
"masters": [],
"uuids": []
},
"model": null,
"partitions": {
"xvda1": {
"holders": [],
"links": {
"ids": [],
"labels": [],
"masters": [],
"uuids": [
"f41e390f-835b-4223-a9bb-9b45984ddf8d"
]
},
"sectors": "16775168",
"sectorsize": 512,
"size": "8.00 GB",
"start": "2048",
"uuid": "f41e390f-835b-4223-a9bb-9b45984ddf8d"
}
},
"removable": "0",
"rotational": "0",
"sas_address": null,
"sas_device_handle": null,
"scheduler_mode": "deadline",
"sectors": "16777216",
"sectorsize": "512",
"size": "8.00 GB",
"support_discard": "0",
"vendor": null,
"virtual": 1
}
},
"ansible_distribution": "CentOS",
"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": "Core",
"ansible_distribution_version": "7.6",
"ansible_dns": {
"nameservers": [
"172.31.0.2"
],
"search": [
"ec2.internal"
]
},
"ansible_domain": "ec2.internal",
"ansible_effective_group_id": 1000,
"ansible_effective_user_id": 1000,
"ansible_env": {
"HOME": "/home/centos",
"LANG": "C",
"LC_ALL": "C",
"LC_CTYPE": "UTF-8",
"LC_MESSAGES": "C",
"LESSOPEN": "||/usr/bin/lesspipe.sh %s",
"LOGNAME": "centos",
"LS_COLORS": "rs=0:di=38;5;27:ln=38;5;51:mh=44;38;5;15:pi=40;38;5;11:so=38;5;13:do=38;5;5:bd=48;5;232;38;5;11:cd=48;5;232;38;5;3:or=48;5;232;38;5;9:mi=05;48;5;232;38;5;15:su=48;5;196;38;5;15:sg=48;5;11;38;5;16:ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;21;38;5;15:ex=38;5;34:*.tar=38;5;9:*.tgz=38;5;9:*.arc=38;5;9:*.arj=38;5;9:*.taz=38;5;9:*.lha=38;5;9:*.lz4=38;5;9:*.lzh=38;5;9:*.lzma=38;5;9:*.tlz=38;5;9:*.txz=38;5;9:*.tzo=38;5;9:*.t7z=38;5;9:*.zip=38;5;9:*.z=38;5;9:*.Z=38;5;9:*.dz=38;5;9:*.gz=38;5;9:*.lrz=38;5;9:*.lz=38;5;9:*.lzo=38;5;9:*.xz=38;5;9:*.bz2=38;5;9:*.bz=38;5;9:*.tbz=38;5;9:*.tbz2=38;5;9:*.tz=38;5;9:*.deb=38;5;9:*.rpm=38;5;9:*.jar=38;5;9:*.war=38;5;9:*.ear=38;5;9:*.sar=38;5;9:*.rar=38;5;9:*.alz=38;5;9:*.ace=38;5;9:*.zoo=38;5;9:*.cpio=38;5;9:*.7z=38;5;9:*.rz=38;5;9:*.cab=38;5;9:*.jpg=38;5;13:*.jpeg=38;5;13:*.gif=38;5;13:*.bmp=38;5;13:*.pbm=38;5;13:*.pgm=38;5;13:*.ppm=38;5;13:*.tga=38;5;13:*.xbm=38;5;13:*.xpm=38;5;13:*.tif=38;5;13:*.tiff=38;5;13:*.png=38;5;13:*.svg=38;5;13:*.svgz=38;5;13:*.mng=38;5;13:*.pcx=38;5;13:*.mov=38;5;13:*.mpg=38;5;13:*.mpeg=38;5;13:*.m2v=38;5;13:*.mkv=38;5;13:*.webm=38;5;13:*.ogm=38;5;13:*.mp4=38;5;13:*.m4v=38;5;13:*.mp4v=38;5;13:*.vob=38;5;13:*.qt=38;5;13:*.nuv=38;5;13:*.wmv=38;5;13:*.asf=38;5;13:*.rm=38;5;13:*.rmvb=38;5;13:*.flc=38;5;13:*.avi=38;5;13:*.fli=38;5;13:*.flv=38;5;13:*.gl=38;5;13:*.dl=38;5;13:*.xcf=38;5;13:*.xwd=38;5;13:*.yuv=38;5;13:*.cgm=38;5;13:*.emf=38;5;13:*.axv=38;5;13:*.anx=38;5;13:*.ogv=38;5;13:*.ogx=38;5;13:*.aac=38;5;45:*.au=38;5;45:*.flac=38;5;45:*.mid=38;5;45:*.midi=38;5;45:*.mka=38;5;45:*.mp3=38;5;45:*.mpc=38;5;45:*.ogg=38;5;45:*.ra=38;5;45:*.wav=38;5;45:*.axa=38;5;45:*.oga=38;5;45:*.spx=38;5;45:*.xspf=38;5;45:",
"MAIL": "/var/mail/centos",
"PATH": "/usr/local/bin:/usr/bin",
"PWD": "/home/centos",
"SELINUX_LEVEL_REQUESTED": "",
"SELINUX_ROLE_REQUESTED": "",
"SELINUX_USE_CURRENT_RANGE": "",
"SHELL": "/bin/bash",
"SHLVL": "2",
"SSH_CLIENT": "49.207.135.44 41713 22",
"SSH_CONNECTION": "49.207.135.44 41713 172.31.21.77 22",
"SSH_TTY": "/dev/pts/0",
"TERM": "xterm-256color",
"USER": "centos",
"XDG_RUNTIME_DIR": "/run/user/1000",
"XDG_SESSION_ID": "3",
"_": "/usr/bin/python"
},
"ansible_eth0": {
"active": true,
"device": "eth0",
"features": {
"busy_poll": "off [fixed]",
"fcoe_mtu": "off [fixed]",
"generic_receive_offload": "on",
"generic_segmentation_offload": "on",
"highdma": "off [fixed]",
"hw_tc_offload": "off [fixed]",
"l2_fwd_offload": "off [fixed]",
"large_receive_offload": "off [fixed]",
"loopback": "off [fixed]",
"netns_local": "off [fixed]",
"ntuple_filters": "off [fixed]",
"receive_hashing": "off [fixed]",
"rx_all": "off [fixed]",
"rx_checksumming": "on [fixed]",
"rx_fcs": "off [fixed]",
"rx_gro_hw": "off [fixed]",
"rx_udp_tunnel_port_offload": "off [fixed]",
"rx_vlan_filter": "off [fixed]",
"rx_vlan_offload": "off [fixed]",
"rx_vlan_stag_filter": "off [fixed]",
"rx_vlan_stag_hw_parse": "off [fixed]",
"scatter_gather": "on",
"tcp_segmentation_offload": "on",
"tx_checksum_fcoe_crc": "off [fixed]",
"tx_checksum_ip_generic": "off [fixed]",
"tx_checksum_ipv4": "on [fixed]",
"tx_checksum_ipv6": "off [requested on]",
"tx_checksum_sctp": "off [fixed]",
"tx_checksumming": "on",
"tx_fcoe_segmentation": "off [fixed]",
"tx_gre_csum_segmentation": "off [fixed]",
"tx_gre_segmentation": "off [fixed]",
"tx_gso_partial": "off [fixed]",
"tx_gso_robust": "on [fixed]",
"tx_ipip_segmentation": "off [fixed]",
"tx_lockless": "off [fixed]",
"tx_nocache_copy": "off",
"tx_scatter_gather": "on",
"tx_scatter_gather_fraglist": "off [fixed]",
"tx_sctp_segmentation": "off [fixed]",
"tx_sit_segmentation": "off [fixed]",
"tx_tcp6_segmentation": "off [requested on]",
"tx_tcp_ecn_segmentation": "off [fixed]",
"tx_tcp_mangleid_segmentation": "off",
"tx_tcp_segmentation": "on",
"tx_udp_tnl_csum_segmentation": "off [fixed]",
"tx_udp_tnl_segmentation": "off [fixed]",
"tx_vlan_offload": "off [fixed]",
"tx_vlan_stag_hw_insert": "off [fixed]",
"udp_fragmentation_offload": "off [fixed]",
"vlan_challenged": "off [fixed]"
},
"hw_timestamp_filters": [],
"ipv4": {
"address": "172.31.21.77",
"broadcast": "172.31.31.255",
"netmask": "255.255.240.0",
"network": "172.31.16.0"
},
"ipv6": [
{
"address": "fe80::812:67ff:fe49:e819",
"prefix": "64",
"scope": "link"
}
],
"macaddress": "0a:12:67:49:e8:19",
"module": "xen_netfront",
"mtu": 9001,
"pciid": "vif-0",
"promisc": false,
"timestamping": [
"rx_software",
"software"
],
"type": "ether"
},
"ansible_fibre_channel_wwn": [],
"ansible_fips": false,
"ansible_form_factor": "Other",
"ansible_fqdn": "ip-172-31-21-77.ec2.internal",
"ansible_hostname": "ip-172-31-21-77",
"ansible_hostnqn": "",
"ansible_interfaces": [
"lo",
"eth0"
],
"ansible_is_chroot": true,
"ansible_iscsi_iqn": "",
"ansible_kernel": "3.10.0-957.1.3.el7.x86_64",
"ansible_kernel_version": "#1 SMP Thu Nov 29 14:49:43 UTC 2018",
"ansible_lo": {
"active": true,
"device": "lo",
"features": {
"busy_poll": "off [fixed]",
"fcoe_mtu": "off [fixed]",
"generic_receive_offload": "on",
"generic_segmentation_offload": "on",
"highdma": "on [fixed]",
"hw_tc_offload": "off [fixed]",
"l2_fwd_offload": "off [fixed]",
"large_receive_offload": "off [fixed]",
"loopback": "on [fixed]",
"netns_local": "on [fixed]",
"ntuple_filters": "off [fixed]",
"receive_hashing": "off [fixed]",
"rx_all": "off [fixed]",
"rx_checksumming": "on [fixed]",
"rx_fcs": "off [fixed]",
"rx_gro_hw": "off [fixed]",
"rx_udp_tunnel_port_offload": "off [fixed]",
"rx_vlan_filter": "off [fixed]",
"rx_vlan_offload": "off [fixed]",
"rx_vlan_stag_filter": "off [fixed]",
"rx_vlan_stag_hw_parse": "off [fixed]",
"scatter_gather": "on",
"tcp_segmentation_offload": "on",
"tx_checksum_fcoe_crc": "off [fixed]",
"tx_checksum_ip_generic": "on [fixed]",
"tx_checksum_ipv4": "off [fixed]",
"tx_checksum_ipv6": "off [fixed]",
"tx_checksum_sctp": "on [fixed]",
"tx_checksumming": "on",
"tx_fcoe_segmentation": "off [fixed]",
"tx_gre_csum_segmentation": "off [fixed]",
"tx_gre_segmentation": "off [fixed]",
"tx_gso_partial": "off [fixed]",
"tx_gso_robust": "off [fixed]",
"tx_ipip_segmentation": "off [fixed]",
"tx_lockless": "on [fixed]",
"tx_nocache_copy": "off [fixed]",
"tx_scatter_gather": "on [fixed]",
"tx_scatter_gather_fraglist": "on [fixed]",
"tx_sctp_segmentation": "on",
"tx_sit_segmentation": "off [fixed]",
"tx_tcp6_segmentation": "on",
"tx_tcp_ecn_segmentation": "on",
"tx_tcp_mangleid_segmentation": "on",
"tx_tcp_segmentation": "on",
"tx_udp_tnl_csum_segmentation": "off [fixed]",
"tx_udp_tnl_segmentation": "off [fixed]",
"tx_vlan_offload": "off [fixed]",
"tx_vlan_stag_hw_insert": "off [fixed]",
"udp_fragmentation_offload": "on",
"vlan_challenged": "on [fixed]"
},
"hw_timestamp_filters": [],
"ipv4": {
"address": "127.0.0.1",
"broadcast": "host",
"netmask": "255.0.0.0",
"network": "127.0.0.0"
},
"ipv6": [
{
"address": "::1",
"prefix": "128",
"scope": "host"
}
],
"mtu": 65536,
"promisc": false,
"timestamping": [
"rx_software",
"software"
],
"type": "loopback"
},
"ansible_local": {},
"ansible_lsb": {},
"ansible_machine": "x86_64",
"ansible_machine_id": "05cb8c7b39fe0f70e3ce97e5beab809d",
"ansible_memfree_mb": 3470,
"ansible_memory_mb": {
"nocache": {
"free": 3637,
"used": 150
},
"real": {
"free": 3470,
"total": 3787,
"used": 317
},
"swap": {
"cached": 0,
"free": 0,
"total": 0,
"used": 0
}
},
"ansible_memtotal_mb": 3787,
"ansible_mounts": [
{
"block_available": 1865058,
"block_size": 4096,
"block_total": 2094336,
"block_used": 229278,
"device": "/dev/xvda1",
"fstype": "xfs",
"inode_available": 4168335,
"inode_total": 4193792,
"inode_used": 25457,
"mount": "/",
"options": "rw,seclabel,relatime,attr2,inode64,noquota",
"size_available": 7639277568,
"size_total": 8578400256,
"uuid": "f41e390f-835b-4223-a9bb-9b45984ddf8d"
}
],
"ansible_nodename": "ip-172-31-21-77.ec2.internal",
"ansible_os_family": "RedHat",
"ansible_pkg_mgr": "yum",
"ansible_proc_cmdline": {
"BOOT_IMAGE": "/boot/vmlinuz-3.10.0-957.1.3.el7.x86_64",
"LANG": "en_US.UTF-8",
"console": [
"tty0",
"ttyS0,115200n8",
"ttyS0,115200"
],
"crashkernel": "auto",
"ro": true,
"root": "UUID=f41e390f-835b-4223-a9bb-9b45984ddf8d"
},
"ansible_processor": [
"0",
"GenuineIntel",
"Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz",
"1",
"GenuineIntel",
"Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz"
],
"ansible_processor_cores": 2,
"ansible_processor_count": 1,
"ansible_processor_threads_per_core": 1,
"ansible_processor_vcpus": 2,
"ansible_product_name": "HVM domU",
"ansible_product_serial": "NA",
"ansible_product_uuid": "NA",
"ansible_product_version": "4.2.amazon",
"ansible_python": {
"executable": "/usr/bin/python",
"has_sslcontext": true,
"type": "CPython",
"version": {
"major": 2,
"micro": 5,
"minor": 7,
"releaselevel": "final",
"serial": 0
},
"version_info": [
2,
7,
5,
"final",
0
]
},
"ansible_python_version": "2.7.5",
"ansible_real_group_id": 1000,
"ansible_real_user_id": 1000,
"ansible_selinux": {
"config_mode": "enforcing",
"mode": "enforcing",
"policyvers": 31,
"status": "enabled",
"type": "targeted"
},
"ansible_selinux_python_present": true,
"ansible_service_mgr": "systemd",
"ansible_ssh_host_key_ecdsa_public": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMc9csy0+KVonbapwODTVVpPj/5QN4/HC5I8UR8ayG2bSyG0QXXsY0N3Qup9oYtBkYgHg0Xq7ZGo87mbJGUvVWY=",
"ansible_ssh_host_key_ed25519_public": "AAAAC3NzaC1lZDI1NTE5AAAAIKZ9AnZvCSqODNTw3+Uy9zCxYfaqECDPR//ZEeZanFwA",
"ansible_ssh_host_key_rsa_public": "AAAAB3NzaC1yc2EAAAADAQABAAABAQDVGc8WmEEpiSF21ev/7AaSQ4Ipj1F4ugW/Mgise7kxpxpXZGaAjMGgfNQxANMnIyJJsjQmfKv+XX0g3eM46Si+hg19VSDmaMU660Z7PTfIR09vYt9A2OQ2x0IbfWkTEBFy/5LmPmwBCFDR3cyKoBakFPLISAPWTfbtTOOkqzkT2tmkLhMM+XkdwbGmGewU6e0Wp4XCBuvqeWRdfp8gkjorLFXdR4PDv/BUFPY7n7QhsYr2PdZE5MJmqRM+IM6qBy7VDdleKeB9pqSpq/Tb3c7tuFtqJQauDEaEyVAaOYOW5bQGv5Y3k8tF1Z9W+pYfAr0LqBeKjjFPPrS3L8Yc8gNr",
"ansible_swapfree_mb": 0,
"ansible_swaptotal_mb": 0,
"ansible_system": "Linux",
"ansible_system_capabilities": [
""
],
"ansible_system_capabilities_enforced": "True",
"ansible_system_vendor": "Xen",
"ansible_uptime_seconds": 282,
"ansible_user_dir": "/home/centos",
"ansible_user_gecos": "Cloud User",
"ansible_user_gid": 1000,
"ansible_user_id": "centos",
"ansible_user_shell": "/bin/bash",
"ansible_user_uid": 1000,
"ansible_userspace_architecture": "x86_64",
"ansible_userspace_bits": "64",
"ansible_virtualization_role": "guest",
"ansible_virtualization_type": "xen",
"discovered_interpreter_python": "/usr/bin/python",
"gather_subset": [
"all"
],
"module_setup": true
},
"changed": false
}
Hope the preceding execution output gives you a clear picture on what information (or) facts are being collected as part of gathering facts.
In some cases where you want to collect minimal facts about a machine like cpu
and memory
configuration alone. you can do that too.
Ansible setup
module lets you collect and filter selected attributes
ansible appservers -m setup -i ansible_hosts -a 'filter=ansible_distribution,ansible_distribution_version,ansible_memfree_mb,ansible_memtotal_mb,ansible_processor_cores*,ansible_architecture'
you can use the variable names directly in the filter like given above the result would be something like this.
Note*: The preceding facts or variables were taken using our development RHEL box. the results and the gathered facts may vary in your environment (or) setup.
How to use these ansible facts in your Playbook
You can use all of these variables in your playbook. by calling them in Jinja2
syntax. These variables could be used for so many cases/requirements like
- conditional based execution like when the remote hostname is "mwiapp01" or when the remote server's Operating system is "redhat"
- When the mount point used percentage is more than 80, the allowed the threshold
- To get the remote box information like hostname, fqdn, mac_address, Network interface details including ip address etc.
These are only a few purposes listed where the variables are used, there are quite a lot of scenarios where the ansible built-in variables (or) collected facts come in handy.
Though you can use all these variables at your convenience. You should be aware how to access the variable as they are stored in JSON tree (or) array.
To use the variable in your playbook and succeed at it. All you have to keep in mind is the the type of variable you are trying to access.
Ansible Gathered Facts or playbook variables belongs to one of the following types
- Dictionary
- List
- AnsibleUnsafeText
From the preceding execution output of setup
module , Let us do some categorization to find the different types of variables.
I have taken the first few lines of execution output and marked the variables with their corresponding types in the following snap.
As you see in the above picture, there are three data types in the return variables (or) gathered_facts. Basically, the Ansible UnSafe Text
is the statement which is an end variable or key (python) which holds the value. It can either be part of Dictionary or stand alone.
Here in the preceding example, ansible_architecture
and status
both belong to Ansible UnSafe Text datatype but they are different as the variable status
is part of a dictionary and another one is not
How to know the data type of variable (or) fact
Ansible provides a filter named type_debug to get the underlying python data type of a variable or fact
The Syntax to use the module is given below
{{ <the variable name> | type_debug }}
We will see the real-time execution and use of this module later in this post.
How to use the fact (or) variable appropriately in Ansible playbook
You can use these facts in your playbook for accomplishing your various requirements. Before we dive deep here is the quick example on how to get the Default IPv4 address
of the host
{{ ansible_default_ipv4.address }}
The preceding Jinja2 syntax would give you the default IPv4 address of your remote host.
Now let us learn further.
Let us start with the basics. For better understanding and to be in Sync, I am going to refer to the image Snap 1.0
given above, for this exercise.
As per the image, these are the variables and their corresponding types
- ansible_architecture – Ansible UnSafe Text
- ansible_apparmor – Dictionary
- ansible_all_ipv4_addresses – List
Having three variables for the three data types, Now let us go and write a playbook to access these different type of variables.
The following playbook is designed to display the data type of each variable and then print the value of them. As you could notice, to access the element of the
dictionary we are using the "." period sign
Likewise, if you would like to access the n'th element of the list. Just like python syntax. you should use listvariable[n]
here n represents the integer value of the index
---
- name: Ansible Variable Example Playbook
hosts: app
tasks:
# display the variable data type
- debug:
msg:
- " Data type of 'ansible_architecture' is {{ ansible_architecture | type_debug }} "
- " Data type of 'ansible_apparmor' is {{ ansible_apparmor | type_debug }} "
- " Data type of 'ansible_all_ipv4_addresses' is {{ ansible_all_ipv4_addresses | type_debug }} "
# Simply printing the value of fact which is Ansible UnSafe Text type
- debug:
msg: "{{ ansible_architecture }}"
# Accessing an element of dictionary
- debug:
msg: "{{ansible_apparmor.status}}"
# Accessing the list
- debug:
msg: "{{ansible_all_ipv4_addresses}}"
# Accessing the Second Element of the list
- debug:
msg: "{{ansible_all_ipv4_addresses[1]}}"
The Execution Output
How to Parse through the Dictionary variable in a loop
The following playbook could help you understand how to parse through the Dictionary and access the underlying keys of the dictionary
The playbook also provides a real-time test case where the gathered_facts (or) the variables are used.
---
- name: Ansible Variable Example Playbook
hosts: app
tasks:
# Print the Dictionary
- debug:
msg: "{{ansible_mounts}}"
# Parsing through Variable Dictionary
- debug:
msg: "Mount Point {{item.mount}} is at {{item.block_used/item.block_total*100}} percent "
loop: "{{ansible_mounts}}"
# Execute Host based task using variable
- name: Execute the command only mwiapp01 server
become: yes
become_user: root
shell: "uname -a"
when: "{{ ansible_hostname == 'mwiapp01'}}"
As you could notice,
The First task is to print the dictionary
The Second task is to parse through the dictionary and do a little math operation with the values of the dictionary. Basically, the second task is to state the used percentage of the mount points in remote servers.
In the second task what we do is that we parse through the dictionary named ansible_mounts
using loop
module and referring or accessing the key named mount
in the msg section and doing a little math there to find the percentage used.
The last task is targetted to run only on mwiapp01 server. When the ansible playbook runs on the corresponding server the task would be triggered. This way we can limit a task to run in a specific remote server.
The Execution Output
With this. Our article comes to an end
To help you master Ansible. we have compiled 25+ Ansible Playbooks
and Created a cheat sheet of ad hoc commands
you can refer.
Ansible Playbook Examples – Sample Ansible Playbooks | Devops Junction
Ansible AD HOC Command Examples – Ansible Cheat Sheet | Devops Junction
Cheers,
Sarav AK
Follow me on Linkedin My Profile Follow DevopsJunction onFacebook orTwitter For more practical videos and tutorials. Subscribe to our channel
Signup for Exclusive "Subscriber-only" Content