Working with Ansible Variable and Facts
Objectives
- Working with facts and variables in ansible
Pre-requisite
- Three working VMs; server, tester1 and tester2 with key based authentication
Sequence 1. Setting up the Environment
- Login as
ansible
user, create a project directory, base. Under this directory create an inventory file and add current host “server
” to the file.
[ansible@server ~]$ mkdir base [ansible@server ~]$ cd base [ansible@server base]$ vi inventory server tester1 tester2
- Create and Configure ansible.cfg, under the base project to identify how to connect remote hosts.
[ansible@server base]$ vi ansible.cfg [defaults] remote_user = ansible ; use ansible user host_key_checking = false inventory = inventory ; Inventory file exists in the current directory log_path = base.log ; base.log file will be created/used as log file [privilege_escalation] become = True ; Become someone else to perform tasks become_method = sudo ; use sudo become_user = root ; Become root user become_ask_pass = False , Don't ask for password with sudo
Sequence 2. Working with Ansible Variables
- Create a playbook hello-world.yml, under the base project to work with variables.
$ vi hello-world.yml - hosts: server vars: demo_var1: Welcome to The SkillPedia! tasks: - name: Variable Example in Ansible debug: msg: "{{ demo_var1 }}"
Here
demo_var1
variable is substituted by the value
Welcome to The SkillPedia!
when the playbook is run. It simply prints the message
Welcome to The SkillPedia!
.
- Create another playbook
yml
to holds 6 country names in a variableCountries
. Each of these can be accessed using index 0 as the first element. The example playbook below retrieve the valueSingapore
(Index 4).
$ vi
list_var.yml
- hosts: server vars: Countries: - India - Nepal - United States - China - Singapore - France tasks: - name: List variable in Ansible debug: msg: "{{ Countries [4] }}" The variable list can also be represented as:
vars: Countries: [India,Nepal,United States,China,Singapore,France]
- To list all items of the list, use the
with_items
module as given below.
- hosts: server vars: Countries: [India,Nepal,United States,China,Singapore,France] tasks: - name: Array variable in Ansible debug: msg: "{{ item }}" with_items: - "{{ Countries }}"
- Dictionary variables are supported in the playbook. To define the dictionary variable, ident the key-value pair below dictionary variable name. In this example,
vlans
is the dictionary variable whileid
andport
are the key-value pairs.
hosts: server vars: http_port: 8080 default_gateway: vlans: id: 10 port: 20 tasks: name: Configure default gateway system_configs: default_gateway_ip: "{{ default_gateway }}" name: Label port on vlan 10 vlan_config: vlan_id: "{{ vlans['id'] }}" port_id: 1/1/ {{ vlans['port'] }}
Sequence 3. Working with Ansible Facts
Ansible provides a list of
predefined variables
referred to as
Ansible facts
and gathered when a playbook is executed. Ansible
facts
can be referenced in Jinja2 templates and playbooks but cannot be altered or defined by the user.
- Here is the list of facts would be returned when you run the
$ ansible server -m setup
- Try the same command for tester1 and tester2 and compare the output.
$ ansible tester1 -m setup $ ansible tester2 -m setup
- If you want to access the
n’th
element of the list, use listvariable[n]. Create a playbook with following contents. If you are doing copy/paste, copy the content in a notepad file, remove the commented line (line starting with #) and them paste them in the vi editor.
--- - name: Ansible Variable Example Playbook hosts: server 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]}}"
- Screenshot of the File.
- The Execution Output
- To execute the playbook on all VMs change the host parameter as follows
- Output will be as given in the following screen shot.
- Login to “
server
” as root user and create a custom fact file called factthat retrieves date and time.
# mkdir -p /etc/ansible/facts.d # vi /etc/ansible/facts.d/date_time.fact
- Add the following lines in it.
#!/bin/bash DATE=`date` echo "{\"date\" : \"${DATE}\"}"
- Change the permissions to make it executable:
# chmod +x /etc/ansible/facts.d/date_time.fact
- Create a playbook on Ansible control node called check_date.yml.
$ vi check_date.yml --- - hosts: server tasks: - name: Get custom facts debug: msg: The custom fact is {{ansible_local.date_time}}
It should appear as given in following screenshot
- Append the fact file to the ansible_local variable. The ansible_local stores all the custom facts. Now run the playbook and observe Ansible retrieving information saved on the fact file:
$ ansible-playbook check_date.yml