Ansible Variables: A Comprehensive Guide

Ansible Variables: A Comprehensive Guide

#day70 of #90daysofdevops

ยท

8 min read

What are Ansible Variable

In Ansible, variables are used to store and retrieve values that can be referenced in playbooks, roles, templates, and other Ansible components. They provide a way to make playbooks more flexible and reusable by allowing you to parameterize your configurations.

Why Use Ansible Variables:

  1. Dynamic Configurations: Variables enable you to create dynamic configurations based on the values assigned at runtime. This is useful for adapting configurations to different environments or changing requirements.

  2. Reusability: Variables promote playbook and role reusability. By defining variables, you can create generic playbooks and roles that can be easily adapted to different scenarios without modifying the underlying code.

  3. Readability: Variables enhance the readability of your playbooks. Instead of hardcoding values, you can use descriptive variable names to make your playbooks more understandable and maintainable.

  4. Parameterization: Variables allow you to parameterize your playbooks, making it easier to customize configurations for specific use cases or environments.


Working with variables

In Ansible, you can define and reference variables to make your playbooks more flexible and reusable. Here's a breakdown of how to define and reference variables using Ansible:

1. Defining Variables:

Playbook Variables:

You can define variables directly inside a playbook using the vars keyword.

---
- name: Defining Variables Example
  hosts: all
  vars:
    fav_color: yellow
    fav_number: 42
    greeting: "Hello, Ansible!"

In this example:

  • fav_color, fav_number, and greeting are variables defined at the playbook level.

2. Referencing Variables:

Ansible uses the Jinja2 templating system to work with variables. You can reference variables using double curly braces {{ }}.

---
- name: Referencing Variables Example
  hosts: all
  vars:
    fav_color: yellow
    fav_number: 42
    greeting: "Hello, Ansible!"

  tasks:
    - name: Display Variables
      debug:
        msg: |
          My favorite color is {{ fav_color }}.
          My favorite number is {{ fav_number }}.
          {{ greeting }}

In this example:

  • The debug task uses Jinja2 templating to reference the values of fav_color, fav_number, and greeting.

3. Running the Playbook:

Save the playbook in a file (e.g., variables_example.yml) and run it using the ansible-playbook command:

ansible-playbook variables_example.yml

4. Expected Output:

The output should display the values of the referenced variables:

PLAY [Referencing Variables Example] ***********

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

TASK [Display Variables] *************
ok: [your_target_host] => {
    "msg": "My favorite color is yellow.\nMy favorite number is 42.\nHello, Ansible!"
}

PLAY RECAP ********************
your_target_host: ok=2 changed=0 unreachable=0 failed=0 skipped=0

Creating lists and dictionaries

Certainly! Let's break down the information about creating lists and dictionaries in Ansible variables:

1. Creating Lists:

You can define lists in Ansible variables using the square bracket notation:

vars:
  port_nums: [21, 22, 23, 25, 80, 443]

Alternatively, you can use a more explicit syntax:

vars:
  port_nums:
    - 21
    - 22
    - 23
    - 25
    - 80
    - 443

Accessing elements in the list:

- name: Show 2nd item in port_nums
  debug:
    msg: "SSH port is {{ port_nums[1] }}"

Index is started form o to n-1

2. Creating Dictionaries:

You can define dictionaries in Ansible variables using the key-value pair notation:

vars:
  users:
    bob:
      username: bob
      uid: 1122
      shell: /bin/bash
    lisa:
      username: lisa
      uid: 2233
      shell: /bin/sh

Accessing elements in the dictionary:

- name: Show the uid of bob
  debug:
    msg: "UID of bob is {{ users.bob.uid }}"

3. Running the Playbook:

Save the playbook in a file (e.g., variables_playbook.yml) and run it using the ansible-playbook command:

ansible-playbook variables_playbook.yml

4. Expected Output:

The output should display the specified elements from the lists and dictionaries:

PLAY [Working with variables] ************
TASK [Show 2nd item in port_nums] **********
ok: [node1] => {
    "msg": "SSH port is 22"
}

TASK [Show the uid of bob] *************
ok: [node1] => {
    "msg": "UID of bob is 1122"
}

PLAY RECAP ********************
node1: ok=2 changed=0 unreachable=0 failed=0 skipped=0.

Including external variables

Certainly! Let's break down the information about including external variables in Ansible playbooks:

1. Using vars_files Keyword:

You can create an external file, for example, myvars.yml, containing your variables:

myvars.yml:

---
port_nums: [21, 22, 23, 25, 80, 443]
users:
  bob:
    username: bob
    uid: 1122
    shell: /bin/bash
  lisa:
    username: lisa
    uid: 2233
    shell: /bin/sh

Now, in your playbook (variables_playbook.yml), you can include these variables using the vars_files keyword:

variables_playbook.yml:

---
- name: Working with variables
  hosts: node1
  vars_files:
    - myvars.yml

  tasks:
    - name: Show 2nd item in port_nums
      debug:
        msg: "SSH port is {{ port_nums[1] }}"

    - name: Show the uid of bob
      debug:
        msg: "UID of bob is {{ users.bob.uid }}"

2. Using include_vars Module:

Alternatively, you can use the include_vars module to dynamically load external variables in your playbook:

variables_playbook.yml:

---
- name: Working with variables
  hosts: node1

  tasks:
    - name: Load the variables
      include_vars: myvars.yml

    - name: Show 2nd item in port_nums
      debug:
        msg: "SSH port is {{ port_nums[1] }}"

3. Running the Playbook:

Save the playbook in a file (e.g., variables_playbook.yml) and run it using the ansible-playbook command:

ansible-playbook variables_playbook.yml

4. Expected Output:

The output should display the specified elements from the included external variables:

PLAY [Working with variables] ************
TASK [Load the variables] **************
ok: [node1]

TASK [Show 2nd item in port_nums] **********
ok: [node1] => {
    "msg": "SSH port is 22"
}

PLAY RECAP ********************
node1: ok=2 changed=0 unreachable=0 failed=0 skipped=0

Getting user input

Certainly! Let's break down the information about getting user input in Ansible playbooks using the vars_prompt keyword:

1. Using vars_prompt Keyword:

You can use the vars_prompt keyword to prompt the user for input during playbook execution. Here's an example playbook named greet.yml:

greet.yml:

---
- name: Greet the user
  hosts: node1

  # Use vars_prompt to get user input
  vars_prompt:
    - name: username
      prompt: "What's your name?"
      private: no

  tasks:
    - name: Greet the user
      debug:
        msg: "Hello {{ username }}"

In this example:

  • The vars_prompt section defines a list of variables to prompt the user for input.

  • name specifies the variable name (username in this case).

  • prompt provides the text to display when prompting the user.

  • private (optional) is set to no to display the user input on the screen as it is entered (set to yes to hide input).

2. Running the Playbook:

Save the playbook in a file (e.g., greet_playbook.yml) and run it using the ansible-playbook command:

ansible-playbook greet_playbook.yml

3. Expected Output:

When you run the playbook, Ansible will prompt you for input:

What's your name?: [Enter your name]

After entering your name, the playbook will continue, and the output will display the personalized greeting:

PLAY [Greet the user] ************
TASK [Greet the user] **************
ok: [node1] => {
    "msg": "Hello [your entered name]"
}

PLAY RECAP ********************
node1: ok=1 changed=0 unreachable=0 failed=0 skipped=0

This example demonstrates how to use vars_prompt to interactively get user input during the execution of an Ansible playbook.


Understanding variable precedence

Certainly! Let's break down the information about variable precedence in Ansible:

1. Variable Scopes and Precedence:

  • Ansible variables can be set at different scopes, including play level, host level (host_vars), and command-line level.

  • If the same variable is set at different levels, the most specific level takes precedence.

2. Example Playbook - variable-precedence.yml:

---
- name: Understanding Variable Precedence
  hosts: node1

  # Play-level variable
  vars:
    fav_distro: "Ubuntu"

  tasks:
    - name: Show value of fav_distro
      debug:
        msg: "Favorite distro is {{ fav_distro }}"

In this example:

  • The playbook has a variable named fav_distro set at the play level with the value "Ubuntu."

3. Running the Playbook with Command-line Override:

To demonstrate variable precedence, run the playbook with the -e (or --extra-vars) option to set the value of fav_distro to "CentOS" from the command line:

ansible-playbook variable-precedence.yml -e "fav_distro=CentOS"

4. Expected Output:

The output will reflect the overridden value from the command line:

PLAY [Understanding Variable Precedence] ***************************************
TASK [Show value of fav_distro] ************************************************
ok: [node1] => {
    "msg": "Favorite distro is CentOS"
}

5. Explanation:

  • The value of fav_distro on the command line ("CentOS") takes precedence over the play-level value ("Ubuntu"). This demonstrates that the command line has the highest precedence.

Ansible Variable Types:

  1. Playbook Variables:

    Defined at the playbook level using vars or vars_files. These variables are accessible to all tasks within the playbook.

     ---
     - hosts: all
       vars:
         my_variable: "Hello, Ansible!"
       tasks:
         - name: Display Variable
           debug:
             var: my_variable
    
  2. Inventory Variables: Defined in the inventory file using host or group variables. These variables apply to specific hosts or groups of hosts.

     [web_servers]
     server1 ansible_user=ubuntu my_variable="Web Server 1"
     server2 ansible_user=ubuntu my_variable="Web Server 2"
    
  3. Role Variables: Stored in roles and defined in the vars/main.yml file. These variables are specific to a particular role.

     # roles/my_role/vars/main.yml
     my_role_variable: "Role-specific variable"
    
  4. Fact Variables (Ansible Facts): Ansible collects information about remote hosts and makes it available as facts. These facts can be used as variables in your playbooks.

     ---
     - hosts: all
       tasks:
         - name: Display Hostname
           debug:
             var: ansible_hostname
    

Runnable Example:

Consider the following playbook that uses variables:

---
- hosts: web_servers
  vars:
    website_name: "My Awesome Website"
    web_servers:
      - name: server1
        ip: 192.168.1.101
      - name: server2
        ip: 192.168.1.102
  tasks:
    - name: Display Website Name
      debug:
        msg: "{{ website_name }}"

    - name: Display Web Servers
      debug:
        msg: "Server {{ item.name }} has IP {{ item.ip }}"
      loop: "{{ web_servers }}"

In this example:

  • website_name is a playbook variable.

  • web_servers is a playbook variable that contains a list of dictionaries.

  • item is a special variable used in loops to represent the current item being processed.

This playbook displays the website name and information about each web server. The use of variables makes it easy to adapt the playbook for different websites or server configurations.


Connect with me:)

Thank you for diving into this blog with me! I trust you found the information both helpful and enlightening. To stay updated on the latest in DevOps ๐Ÿš€, make sure to follow me. Remember, staying informed means staying ahead in the dynamic world of DevOps!

Feel free to connect with me on:

LinkedIn

Twitter

GitHub

For more updates and engaging discussions on DevOps, let's connect! ๐Ÿš€ #DevOpsCommunity

ย