Skip to main content

Ansible Variables and Variables Precedence

Ansible Variables and Variables Precedence

What is a variable?

A variable is reference to data stored in a computer program.

How to define variable in Ansible?


Variables can be defined in inventory in two ways -
1. Host variables
[web]
host1 http_port=80
host2 http_port=443

2. Group variables
[web]
host1
host2

[web:vars]
http_port=80
proxy=proxy.example.com


You can directly define variables in a playbook:
- hosts: appgroup
 vars:
   http_port: 80


You can define your variables in a YAML file and store it in VARS folder.
You can include your variable file in your task file “using include_vars”.

Eg - include_vars: variable.yml

You can also use the variables defined in the remote system as facts.
To gather all the information about remote server you can run the command:

ansible hostname -m setup


You can also write own facts modules. “Facts.d” is one way to control some aspect of 
how systems are managed.

If a remotely managed system has an /etc/ansible/facts.d directory, any files in this directory 
ending in .fact, can be JSON, INI, or executable files returning JSON, and these can supply 
local facts in Ansible.

Eg - assume /etc/ansible/facts.d/http.fact contains:
[general]
http_port=80
ssl_port=22


You can also store result of a command into a variable.

- hosts: appgroup

 tasks:

    - shell: /usr/bin/foo
      register: foo_result
      ignore_errors: True

    - shell: /usr/bin/bar
      when: foo_result.rc == 5





You can also define your variables in different files.

- hosts: appgroup
 vars:
    http_port: 80
 vars_files:
   - /vars/http.yml



You can also set the variables in command line using --extra-vars or -e.

Eg: ansible-playbook test.yml -e "http_port=80"

Variable Precedence


If multiple variables of the same name are defined in different places, they get overwritten in a 
certain order.
Here is the order of variable precedence from low to high.
  • role defaults 
  • inventory file or script group vars 
  • inventory group_vars/all  
  • playbook group_vars/all 
  • inventory group_vars/* 
  • playbook group_vars/* 
  • inventory file or script host vars 
  • inventory host_vars/* 
  • playbook host_vars/* 
  • host facts / cached set_facts 
  • play vars 
  • play vars_prompt 
  • play vars_files 
  • role vars (defined in role/vars/main.yml) 
  • block vars (only for tasks in block) 
  • task vars (only for the task) 
  • include_vars 
  • set_facts / registered vars 
  • role (and include_role) params 
  • include params 
  • extra vars (always win precedence)

To verify this what I did, is to define the variables in different locations and then remove 
the values from those location one by one.
Here I have created a role to create a user in linux. You can see the files where I have 
defined those variables.


default/main.yml

---
# defaults file for ansible/roles/user

user_name: john_cena
...

/etc/ansible/hosts (group vars)

# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
#   - Comments begin with the '#' character
#   - Blank lines are ignored
#   - Groups of hosts are delimited by [header] elements
#   - You can enter hostnames or ip addresses
#   - A hostname/ip can be a member of multiple groups

[appgroup]
appserver1
appserver4

[appgroup:vars]
user_name=batista


/etc/ansible/hosts (host vars)

# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
#   - Comments begin with the '#' character
#   - Blank lines are ignored
#   - Groups of hosts are delimited by [header] elements
#   - You can enter hostnames or ip addresses
#   - A hostname/ip can be a member of multiple groups

[appgroup]
appserver1 user_name=roman_reigns
appserver4  user_name=roman_reigns


/tasks/main.yml (play vars)

---
# tasks file for ansible/roles/user

#- name: Include user yml file.
#  include_vars: "user.yml"

- name: Add the user
 vars:
    user_name: triple_h
 user:
    name: "{{ user_name }}"
    comment: John Doe
    uid: 1045
    group: vagrant
...


/vars/user.yml (include_file)

---

 user_name: edge
...


/tasks/main.yml (set_fact)

---
# tasks file for ansible/roles/user

- name: Set user name.
 set_fact:
    user_name: undertaker

- name: Add the user
 user:
    name: "{{ user_name }}"
    comment: John Doe
    uid: 1051
    group: vagrant
...



Extra vars

ansible-playbook add_user.yml -e “ user_name=cm_punk”


In this way you can check precedence of variables in ansible role.





Refernce

  • https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#accessing-complex-variable-data

Comments

Popular posts from this blog

EC2 Ssh Connection Refused

When ssh: connect to host ip_address port 22 Connection refused



Unable to access server???
Exactly when you see the error - “ssh: connect to host ip_address port 22: Connection refused” while connecting your AWS EC2 Instance. In order to find solution of the problem, you will go to AWS forum and other channels where you need to answers several questions first. But it's very difficult to find the actual problem. In order to get clues what the problem is, we should provide as many details as possible about what we have tried and the results we are getting. Because there are hundreds of reason why a server or service might not be accessible, also connectivity is one of the toughest issue to diagnose, especially when you are hosting something critical on your box. I've seen several topics on this problem, but none offers a solution to it.  I was not aware for what should I look at first. So I walk through from the very basics and investigated the following thing Use of verbose while ss…

jgit-flow maven plugin to Release Java Application

Introduction As a DevOps I need a smooth way to release the java application, so I compared two maven plugin that are used to release the java application and in the end I found that Jgit-flow plugin is far better than maven-release plugin on the basis of following points: Maven-release plugin creates .backup and release.properties files to your working directory which can be committed mistakenly, when they should not be. jgit-flow maven plugin doesn't create these files or any other file in your working directory.Maven-release plugin create two tags.Maven-release plugin does a build in the prepare goal and a build in the perform goal causing tests to run 2 times but jgit-flow maven plugin builds project once so tests run only once.If something goes wrong during the maven plugin execution, It become very tough to roll it back, on the other hand jgit-flow maven plugin makes all changes into the branch and if you want to roll back just delete that branch.jgit-flow maven plugin doesn…

VPC per envrionvment versus Single VPC for all environments

This blog talks about the two possible ways of hosting your infrastructure in Cloud, though it will be more close to hosting on AWS as it is a real life example but this problem can be applied to any cloud infrastructure set-up. I'm just sharing my thoughts and pros & cons of both approaches but I would love to hear from the people reading this blog about their take as well what do they think.


Before jumping right away into the real talk I would like to give a bit of background on how I come up with this blog, I was working with a client in managing his cloud infrastructure where we had 4 environments dev, QA, Pre Production and Production and each environment had close to 20 instances, apart from applications instances there were some admin instances as well such as Icinga for monitoring, logstash for consolidating logs, Graphite Server to view the logs, VPN server to manage access of people.




At this point we got into a discussion that whether the current infrastructure set-u…