Use of variables

Posted by FredFredrickson2 on Sat, 15 Jan 2022 12:01:26 +0100

Management variables

1. Introduction to Ansible variable

Ansible supports the use of variables to store values and reuse these values in all files of ansible projects. This simplifies the creation and maintenance of projects and reduces the number of errors.

With variables, you can easily manage the dynamic values of a given environment in an Ansible project. For example, a variable might contain the following values:

  • User to create
  • Packages to install
  • Services to restart
  • Files to delete
  • Archive to retrieve from the Internet

2. Named variable

The name of a variable must start with a letter and can only contain letters, numbers, and underscores

Invalid variable nameValid variable name
web serverweb_server
remote.fileremote_file
1st filefile_1
file1
remoteserver$1remote_server_1
remote_server1

3. Define variables

Variables can be defined at multiple locations in an Ansible project. However, these variables can be roughly reduced to three range levels:

  • Global scope: variables set from the command line or Ansible configuration
  • Play range: variables set in play and related structures
  • Host scope: tasks collected or registered by lists, facts, and variables set on host groups and individual hosts

If a variable with the same name is defined in more than one xeklh, the variable with the highest priority is used. Narrow scope takes precedence over broader scope: variables defined by the manifest will be overwritten by variables defined by playbook, which will be overwritten by variables defined on the command line.

4. Variables in playbook

When you write playbook, you can define your own variables and then call these values in your tasks. For example, it is called web_package variables can be defined with the value httpd. The task can then use the yum module to call this variable to install the httpd package.

The playbook variable can be defined in many ways. A common way is to put variables in the vars block at the beginning of Playbook:

[root@192 playbook]# vim /opt/test.yml
---
  - hosts: all
    vars:
      user: alice
      home: /home/alice

You can also define the playbook variable in an external file. Instead of using the vars block in the playbook, you can use vars instead_ Files directive, followed by a list of external variable file names relative to the playbook position:

[root@192 playbook]# cat test.yml 
---
- hosts: all
  vars_files:
    - ./user.yml

Then, playbook variables can be defined in this / these files using YAML format:

[root@192 playbook]# cat  user.yml
user: alice
home: /home/alice

Once variables are declared, they can be used in tasks. To reference a variable, you can put the variable name in double braces. When the task is executed, Ansible replaces the variable with its value. You must use quotation marks as the first value of the variable. This prevents Ansible from treating variable references as the beginning of the YAML dictionary.

[root@192 playbook]# cat  user.yml
vars:
  user: joe
tasks:
    # This line will read: Creates the user joe
  - name: Creates the user {{ user }}
    user:
      # This line will create the user named joe
      name: "{{ user }}"

5. Host and group variables

The list variables directly applied to the host are divided into two categories:

  • Host variable, applied to a specific host
  • Group management, which applies to a host group or all hosts in a group of hosts

Host variables take precedence over group variables, but variables defined in playbook take precedence over both.

One way to define host and group variables is to define them directly in the manifest file. This is an old practice and is not recommended, but you may encounter it in your future work.

Define ansible of 192.168.129.133_ User host variable:

[servers]
192.168.129.133 ansible_user=root 

Define the user group variable for the servers host group:

192.168.129.133
192.168.129.135

[servers:vars]
user=root

Define the user group variable of the servers group, which consists of two hosts. Each host group has two servers:

[servers1]
node1
node2

[servers2]
node3
node4

[servers:children]
servers1
servers2

[servers:vars]
user=hhh

Populate host and group variables with directories

The preferred way to define variables for hosts and host groups is to create groups in the same working directory as the manifest file or directory_ Vars and host_vars two directories. These two directories contain files for defining group variables and host variables, respectively.

The recommended practice is to use host_vars and groups_ The vars directory defines manifest variables instead of defining them directly in the manifest file.

In order to define the group variable for the servers group, you need to create a group named group_ The YAML file of vars / servers, and then the contents of the file will set the variable to the value using the same syntax as playbook:

user: alice

For example, in a scenario, you need to manage two data centers and define the data center hosts in the / opt/inventory manifest file:

[root@192 opt]# cd /opt/playbook/
[root@192 playbook]# cat inventory 
[datacenter1]
httpd

[datacenter2]
mysql

[datacenters:children]
datacenter1
datacenter2

6. Override variables from the command line

The list variables can be overwritten by the variables set in the playbook, and these two variables can be overwritten by passing parameters to the ansible or ansible playbook command on the command line. Variables set on the command line are called extra variables.

Additional variables are useful when you need to override the defined values of variables in a one-time playbook. For example:

[root@192 playbook]# cat hh.yml 
me: task1
  hosts: httpd
  tasks: 
    - name: Create user
      user:
        name: "{{user}}"
        state: present
[root@192 playbook]# ansible-playbook -e "user=qqkk" hh.yml 
PLAY [task1] *********************************************************************************************************

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

TASK [Create user] **********************************************************************************************************
changed: [192.168.129.133]

PLAY RECAP ***********************************************************************************************************
192.168.129.133            : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
[root@apache ~]# id qqkk
uid=1002(qqkk) gid=1002(qqkk) group=1002(qqkk)

7. Use array as variable

user1_first_name: Bob
user1_last_name: Jones
user1_home_dir: /users/bjones
user2_first_name: Anne
user2_last_name: Cook
user2_home_dir: /users/acook

This can be rewritten into an array named users:

users:
  bjones:
    first_name: Bob
    last_name: jones
    home_dir: /users/bjones
  acook:
    first_name: Anne
    last_name: Cook
    home_dir: /users/acook
You can then access user data using the following variables:
# Returns 'Bob'
users.bjones.first_name

# Returns '/users/acook'
users.acook.home_dir

Since variables are defined as Python dictionaries, alternative syntax can be used:

# Returns 'Bob'
users['bjones']['first-name']

# Returns '/users/acook'
users['acook']['home_dir']

Dot notation can cause problems if the key names are the same as those of python methods or properties, such as discard, copy, and add. Using bracket notation helps avoid conflicts and errors.

However, it should be noted that the two syntax described above are valid, but in order to facilitate troubleshooting, it is recommended to adopt one syntax consistently in all files of any given Ansible project.

8. Capture command output using registered variables

You can use the register statement to capture command output. The output is stored in a temporary variable and can then be used in the playbook for debugging purposes or for other purposes, such as specific configurations based on command output.

The following playbook demonstrates how to capture command output for debugging purposes:

[root@192 playbook]# cat www.yml
---
- name: Installs a package and prints the result
    hosts: all
    tasks:
      - name: Install the package
        yum:
          name: httpd
          state: installed
        register: install_result               
      - debug: var=install_result

When running the playbook, the debug module is used to install_result dump the value of the registered variable to the terminal.

[root@192 playbook]# ansible-playbook www.yml

PLAY [Installs a package and prints the result] **********************************************************************

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

TASK [Install the package] *******************************************************************************************
ok: [192.168.129.133]

TASK [debug] *********************************************************************************************************
ok: [192.168.129.133] => {
    "install_result": {
        "changed": false,
        "failed": false,
        "msg": "Nothing to do",
        "rc": 0,
        "results": []
    }
}

PLAY RECAP ***********************************************************************************************************
192.168.129.133            : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

Topics: Linux