Variables in Ansible

Variables are used to store values that can be later used in the playbook.

  • Host variable

    • We will use our default inventory file - /etc/ansible/hosts
  • In this inventory file, we will define 2 variables for server 2

    Demo Inventory file - server1

    server2 http_port=8080 pkg=httpd server3

  • These 2 variables http_port and pkg are only applicable for server2. Now we will use these variables with the ansible playbook.

  • For accessing variables in a playbook we define variable names inside double curly braces {{variable name}}

---                  
- hosts: group1     
  user: ansible    
  become: yes  
  connection: ssh   
  gather_facts: no   
  tasks:
    - name: Testing first variaable http_port
      debug:        # debug is a module name
        msg: "The HTTP port is {{http_port}}"
    - name: Testing second variable package name
      debug:
        msg: " The package name is {{pkg}}"
  • Group variables

    • Group variables can be assigned to a group and all the hosts part of that group have access to these variables.
# Inventory file

[app]    # app is a group consisting 2 servers
  server1
  server3
[db]      # db is also another group of 2 servers
  server2
  server4
[db:var]  # defining variables for db group servers
  http_port=8080  #these 2 variables are accessible to all server in db group
  pkg=httpd
# Inventory group variables yaml file

---                  
- hosts: db         # we are trying to access variables in the db group     
  user: ansible    
  become: yes  
  connection: ssh   
  gather_facts: no   
  tasks:
    - name: Testing first variable http_port
      debug:       
         msg: "The HTTP port is {{http_port}}"
    - name: Testing second variable package name
      debug:
         msg: " The package name is {{pkg}}"
# Defining variables in a playbook

- hosts: server2
  user: ansible
  become: yes
  connection: ssh
  vars:             # Defining a playbook under vars section
    pkgname: httpd   
  tasks:
    - name: Install package
      yum:
        name: '{{pkgname}}'     # Accessing the variable pkgname
        state: installed
  • We can pass any package name as a value to variable pkgname and that package will be installed in server2

Defining variables using the command line

  • Variables can also be passed on the command line like below using --extra-vars argument or -e in key=value format and variable separated by space

  • ansible-playbook text.yml --extra-vars "one_var = test1 other_var = test2"

  • All the values will be treated as strings. If we have some value in integer or boolean then a better way is to define these in JSON format

  • ansible-playbook test.yml --extra-vars '{"one_var":"test1", "other_var":"test2"}'

  • If we have a JSON or YAML file then we can also import it into our playbook like below

  • ansible-playbook test.yml --extra-vars "@file1.json"

      # Accessing variables using the command line
    
      - hosts: server2
        user: ansible
        become: yes
        connection: ssh
        vars: 
          username: CJ     # Defining variables
        tasks:
          - name: Show user details
            debug:
              msg: "USERNAME = {{username}}"    # Printing username
    
    • We define a variable username with a value of CJ. In this, we will define the same variable using the username and assign a different value using the command line

    • ansible-playbook command_line_vars.yml -e "username = admin"

  1. User-Defined Variables

The variable defined in the playbook simply in key-value pair

2. System facts

  • These are the default variables in which the Ansible Control Server stores information after discovering from nodes. Ansible_facts contain all information in JSON format.

  • {{ansible_facts['devices']['xvda']['mode1']}}

  • {{ansible_facts['nodename']}}

3. Registered Variables

  • These are the variables in which the output of your task will be stored on the Ansible Control Server. When we want to run a command on a remote computer and then store the output in a variable and use a piece of information from the output later in playbooks.

  • E.g. - When we run a command service httpd status and register its output in a variable apache_status

# Register variable in playbook

- hosts: server2
  user: ansible
  become: yes
  connection: ssh
  gather_facts: no
  tasks:
    - name: Get web server status
      command: service httpd status
      register: apache_status
    - name: web server status only
      debug:
        var: apache_status
  • Here apache_status is variable so the output of the command "service httpd status" will be stored in the variable apache_status. So by using the register variable, you can store the output of the task. To print that output we use debug module. It will return output in JSON format

  • Whenever you executed any task or command ansible will give you some return values like. - changed, cmd, delta, end, failed, rc, start, stderr, stderr_lines, stdout, stdout_lines

  • These return values depend on the task you executed. In the above return values our output will be stored in stdout, So to print exact output without any extra return values we can use like variablename.stdout or you can use stdout_lines. Stdout_lines will split the output into line by line.

# Printing web server status using register variable

- hosts: server2
  user: ansible
  become: yes
  connection: ssh
  gather_facts: no
  tasks:
    - name: Get web server status
      command: service httpd status
      register: apache_status
    - name: web server status only
      debug:
        var: apache_status.stdout_lines
  1. Special Variable
  • Variables which is default to the system and can not be set by the user directly. But these will contain the data related to the system's internal state like version, and forks.

  • E.g.- inverntory_file, ansible_connection

  • When running a playbook, there may be information that you need to collect at runtime. We can collect the information from the end user by specifying a

  • vars_prompt section in the playbook.

# Taking variable value during run time

---
- hosts: localhost
  user: ansible
  become: yes
  connection: ssh
  gather_facts: no
  vars_prompt:
    - name: user_name
      prompt: Enter user name
      private: no
    - name: password
      prompt: Enter password
      private: yes
  tasks:
    - name: Printing username and password
      debug:
          msg: "Username is {{user_name}} and password is {{password}}"
  • private: no - means the user can see the entered text in the terminal

  • private: yes - means the user will not see anything in the terminal while entering the password

  • We will create a separate YAML or JSON file which will only contain a bunch of variables and using a playbook we will refer to this YAML or JSON file to read and access the variable value.

  • Reading from YAML file

# variables.yaml file

USERNAME: CJ
COURSE: Ansible
TOPIC: Variables
# Accessing variables from variables.yaml file

---
- name: Collect variables from YAML file
  hosts: localhost
  gather_facts: no
  var_files: variables.yaml     # Accessing variables.yaml file
  tasks:
      - name: varaibles from yaml file
        debug:
          msg:  # Printing variables defined in variables.yaml file
            - "Username is {{USERNAME}}"   
            - "This is {{COURSE}}"
            - "Leaning {{TOPIC}}"
  • Reading from JSON file
# variables.json file

{
    "a": 50,
    "b": [1,2,3,4],
    "c": {"one":1, "two":2}
}
# Accessing variables from variables.json file

---
- name: Collect variables from JSON file
  hosts: localhost
  gather_facts: no
  var_files:
      - ~/custom_vars.json
  tasks:
    - name: varaibles from json file
      debug:
        msg: 
          - "Value of b is {{b}}"
          - "Second index value of b is {{b[1]}}"

I hope you enjoyed this article, if you have any questions, comments, or feedback or if I made a mistake feel free to comment down below.


Did you find this article valuable?

Support DevOps With CJ by becoming a sponsor. Any amount is appreciated!