Saturday, 6 December 2025

Ansible 11. Variables - classification

Ansible variables are used to store values that can be reused across tasks, plays, or templates. They come in different types and scopes. Here’s a detailed breakdown:

1. Based on Scope / Where Defined

Variable TypeDescriptionExample
Inventory variablesDefined per host or group in the inventory file.db_servers ansible_host=192.168.0.156 ansible_user=oracle
Host variablesSpecific to a host, usually in the host_vars/<hostname> folder./host_vars/oe101db.yml: db_name: SSRDB
Group variablesShared across a group, usually in the group_vars/<groupname> folder./group_vars/db_servers.yml: oracle_home: /u01/app/oracle
Play variablesDefined inside a play in the playbook under the vars: keyword.vars: sga_size: 3GB pga_size: 1GB
Task variablesDefined for a single task using the vars: keyword.name: Create DB tablespace vars: ts_name: USERS
Registered variablesStore the output of a task for reuse later using the register: keyword.command: "hostname" register: host_out
Extra variablesPassed at runtime using the -e or --extra-vars command-line option.ansible-playbook play.yml -e "env=prod db_name=SSRDB"
2. Based on Data Type

TypeDescriptionExample
StringSequence of characters.db_name: SSRDB
IntegerNumbers.port: 1521
FloatDecimal numbers.threshold: 0.75
BooleanTrue/False values.enabled: true
List (array)Sequence of items.disks: ["/u01", "/u02", "/u03"]
Dictionary (hash/map)Key-value pairs.yaml users: user1: oracle user2: grid
Complex / NestedList of dictionaries or nested structures.yaml databases: - name: SSRDB sga: 3GB - name: TESTDB sga: 1GB

3. Automatic/Magic Variables (Facts and Special)

VariableDescription
ansible_hostnameHostname of the target machine.
inventory_hostnameHostname as defined in inventory.
ansible_os_familyOS family (RedHat, Debian).
ansible_userRemote user used to connect.
ansible_all_ipv4_addressesList of IPv4 addresses.
ansible_playbook_dirDirectory of the current playbook.
hostvarsAccess variables of another host.
groupsAccess hosts in a group.

A simple example.

[oracle@oel01db ansible-project]$ cat ./playbooks/var_demo.yml
- hosts: db_servers
  vars:
    db_name: SSRDB
    sga_size: 3GB

  tasks:
    - name: Print DB name
      debug:
        msg: "Database name is {{ db_name }} with SGA {{ sga_size }}"
[oracle@oel01db ansible-project]$
[oracle@oel01db ansible-project]$ ansible-playbook -i ./inventory/hosts ./playbooks/var_demo.yml

PLAY [db_servers] ******************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************************************************************************************************************
ok: [192.168.0.156]

TASK [Print DB name] ***************************************************************************************************************************************************************************************************************
ok: [192.168.0.156] => {
    "msg": "Database name is SSRDB with SGA 3GB"
}

PLAY RECAP *************************************************************************************************************************************************************************************************************************
192.168.0.156              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[oracle@oel01db ansible-project]$


Once you define a variable there are different way to refer it

MethodExampleUse case
{{ region }}msg: "{{ region }}"Most common
vars['region']msg: "{{ vars['region'] }}"Dynamic variable names
hostvarshostvars['host1']['region']Access variable of another host
set_factmy_region: "{{ region }}"Create/rename variable
Loopsloop: ["{{ region }}"]Use in iteration
An example using postgres database setup

I've installed postgres on my managed node(192.168.0.156) , lets use this set up for learning variables.

[oracle@oel01db ansible-project]$ psql -h 192.168.0.156 -p 5432 -U postgres -d postgres
Password for user postgres:
psql (15.13)
Type "help" for help.

postgres=#

 Playbook to check postgres info

[oracle@oel01db ansible-project]$ cat ./playbooks/postgres_db_info.yml --- - name: Connect to PostgreSQL database using variables hosts: db_servers gather_facts: no become: yes become_user: postgres vars: db_hostname: "{{ inventory_hostname }}" db_name_to_check: "postgres" db_port_number: 5432 tasks: - name: Check status of the 'postgres' database community.postgresql.postgresql_info: login_host: "{{ db_hostname }}" # Use login_host instead of host login_port: "{{ db_port_number }}" # Use login_port instead of port login_db: "{{ db_name_to_check }}" # Use login_db instead of db login_user: "postgres"
login_password: "postgres" register: postgres_status - name: Display connection result debug: msg: > Successfully connected to {{ db_name_to_check }} on {{ db_hostname }}. Database size: {{ postgres_status.databases[db_name_to_check].size }} [oracle@oel01db ansible-project]$ [oracle@oel01db ansible-project]$

community.postgresql.postgresql_info:
This is an Ansible module from the community.postgresql collection. Purpose: gather information about PostgreSQL databases. Can return database size, owners, encoding, tables, etc. The result is stored in a variable (register: postgres_status).
For this to playbook to work we need to install 

1) Ensure community.postgresql collection is installed

Run on your control node:

ansible-galaxy collection install community.postgresql

(PostgreSQL modules are not included by default.)


2)  Make sure the host has psycopg2 package

On the managed node (target DB server):

sudo yum install python3-psycopg2 -y

[oracle@oel01db ansible-project]$ ansible-playbook -i ./inventory/hosts ./playbooks/postgres_db_info.yml

PLAY [Connect to PostgreSQL database using variables] ***************************************************************************************************************************************************************************************

TASK [Check status of the 'postgres' database] **********************************************************************************************************************************************************************************************
fatal: [192.168.0.156]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "msg": "Failed to import the required Python library (psycopg2) on oel02db.mydb.com's Python /usr/bin/python. Plase read module documentation and install in the appropriate location. If the required library is installed, but Ansible is using the wrong Python interpreter, please consult the documentation on ansible_python_interpreter"}

PLAY RECAP **********************************************************************************************************************************************************************************************************************************
192.168.0.156              : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

[oracle@oel01db ansible-project]$

What’s happening

  1. You installed python3-psycopg2 on the managed host.

  2. Ansible, by default, is using /usr/bin/python (likely Python 2.7) on that host:

"discovered_interpreter_python": "/usr/bin/python"
  1. Python 2 doesn’t have psycopg2 installed, so the module fails.

Installing python3-psycopg2 alone is not enough unless Ansible uses Python 3.

postgres@oel02db:~$ /usr/bin/python --version

Python 2.7.5

postgres@oel02db:~$ /usr/bin/python3 --version

Python 3.6.8

postgres@oel02db:~$

Solution: Tell Ansible to use Python 3

Option 1: Set in inventory

Edit your inventory for the db host:

[db_servers] 192.168.0.156 ansible_python_interpreter=/usr/bin/python3

Option 2: Set in the playbook

Add at the top under vars::

vars: ansible_python_interpreter: /usr/bin/python3 db_hostname: "{{ inventory_hostname }}" db_name_to_check: "postgres" db_port_number: 5432

 I updated my playbook.

[oracle@oel01db ansible-project]$ vi ./playbooks/postgres_db_info.yml

[oracle@oel01db ansible-project]$ cat ./playbooks/postgres_db_info.yml | grep -i ansible_python_interpreter

    ansible_python_interpreter: /usr/bin/python3

[oracle@oel01db ansible-project]$


[oracle@oel01db ansible-project]$ ansible-playbook -i ./inventory/hosts ./playbooks/postgres_db_info.yml

PLAY [Connect to PostgreSQL database using variables] ***************************************************************************************************************************************************************************************

TASK [Check status of the 'postgres' database] **********************************************************************************************************************************************************************************************
ok: [192.168.0.156]

TASK [Display connection result] ************************************************************************************************************************************************************************************************************
ok: [192.168.0.156] => {
    "msg": "Successfully connected to postgres on 192.168.0.156. Database size: 91198255\n"
}

PLAY RECAP **********************************************************************************************************************************************************************************************************************************
192.168.0.156              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

[oracle@oel01db ansible-project]$


No comments:

Post a Comment

Building a Safer PostgreSQL CI/CD Pipeline with GitHub Actions: Dev → PR Review → Test Promotion

In my previous post, we explored a simple push-to-main deployment strategy . While functional, that model is not considered an industry best...