Bookmark this page

Guided Exercise: Defining and Using Variables

In this exercise, you will define and use variables in a playbook.

Outcomes

You should be able to:

  • Define variables in a playbook.

  • Create various tasks that include defined variables.

  • Execute an ad hoc command that displays output from the setup module when the connection method is network_cli and examine the results.

  • Employ a Jinja2 template to generate magic variable data and examine the results.

  • Create a playbook containing a play that uses a variable explicitly set using the --extra-vars (-e) option.

  • Run the play you created using the -e option (--extra-vars).

  • Review the various kinds of variables and how they are set.

Open a terminal window on the workstation VM and change to your ~/proj/ directory.

Procedure 3.1. Instructions

  1. Create an iosping3.yml file by copying the iosping2.yml playbook you created in Lab2 and replacing the IP addresses with a pair of variables named utility_ipv4 and tower_ipv4. These may be defined as play variables in a vars block at the top of a play. A variable that is set at the top of a play is a play variable. Play variables are defined (in scope) only within the play at the top of which they are set.

    [student@workstation proj]$ cp iosping2.yml iosping3.yml
    [student@workstation proj]$ cat iosping3.yml
    ---
    - name: A reachability test
      hosts: cs01
      vars:
        utility_ipv4: 172.25.250.8
        tower_ipv4: 172.25.250.9
    
      tasks:
      - name: "Test reachability to utility: {{ utility_ipv4 }}"
        ios_ping:
          dest: "{{ utility_ipv4 }}"
    
      - name: "Test reachability to tower: {{ tower_ipv4 }}"
        ios_ping:
          dest: "{{ tower_ipv4 }}"
  2. Verify the syntax of the playbook and run the play. The IOS device password is student.

    [student@workstation proj]$ ansible-playbook --syntax-check iosping3.yml
    [student@workstation proj]$ ansible-playbook iosping3.yml
  3. What happens when a variable is defined as a play variable (that is, set in a vars block at the top of a play) and we set the value of the same variable on the command line?

    [student@workstation proj]$ ansible-playbook \
    > iosping3.yml -e 'utility_ipv4=172.25.250.254'
    SSH password: student
    
    PLAY [A reachability test] *****************************************************
    
    TASK [Test reachability to utility: 172.25.250.254] ****************************
    ok: [cs01]
    
    TASK [Test reachability to tower: 172.25.250.9] ********************************
    ok: [cs01]
    
    PLAY RECAP *********************************************************************
    cs01                      : ok=2   changed=0   unreachable=0   failed=0

    It does the right thing by treating the value set in the playbook file as a default and overriding it with the value specified in the command line with the -e option.

  4. Create an iosping4.yml playbook that has one play, and defines the variable dest as a play variable set to 172.25.250.9. Use the internal variable inventory_hostname to provide more information when the play runs. The resulting playbook should have the following contents:

    ---
    - name: A reachability test
      hosts: cs01
      vars:
        dest: 172.25.250.9
    
      tasks:
    
      - name: "test reachability from {{ inventory_hostname }} to {{ dest }}"
        ios_ping:
          dest: "{{ dest }}"
  5. Verify the syntax and run the play at least twice. The first time, let it use the default value. Then run it again and set the value of dest using the -e command-line option:

    [student@workstation proj]$ ansible-playbook --syntax-check iosping4.yml
    [student@workstation proj]$ ansible-playbook iosping4.yml
    [student@workstation proj]$ ansible-playbook iosping4.yml -e 'dest=172.25.250.254'
  6. Create an iosping5.yml playbook that sets the value of dest using vars_file instead of the vars block. The new playbook will perform the same task as the previous one.

    The point is to demonstrate two of the many ways in which variables can be defined: either within the playbook itself in a vars block at the top of a play (as you did when you defined dest in iosping4.yml), or loaded from a file using vars_files (as you will see with iosping5.yml, using vars/myvars.yml).

    There are valid use cases for doing it both ways. Define it in the playbook for simplicity, when you want everything contained in a single file. Define data using vars files when so much data must be defined that it seems awkward or unwieldy to put it in the playbook.

    1. Create a vars/ directory:

      [student@workstation proj]$ mkdir vars
    2. Create a text file in this directory named myvars.yml and set the value of dest in this file:

      [student@workstation proj]$ echo 'dest: 172.25.250.9' > vars/myvars.yml
    3. Copy iosping4.yml to iosping5.yml:

      [student@workstation proj]$ cp iosping4.yml iosping5.yml
    4. Replace the vars block with a vars_files statement. The file should appear as follows:

      ---
      - name: A reachability test
        hosts: cs01
        vars_files:
          - vars/myvars.yml
      
        tasks:
      
        - name: "test reachability from {{ inventory_hostname }} to {{ dest }}"
          ios_ping:
            dest: "{{ dest }}"
    5. Check the syntax, then run the play. Test it both with the default value and using the -e option to set the value of dest to something different.

      1. Without using the --extra-vars (-e) option:

        [student@workstation proj]$ ansible-playbook iosping5.yml
        SSH password: student
        
        PLAY [A reachability test] *****************************************************
        
        TASK [Test reachability from cs01 to 172.25.250.9] *****************************
        ok: [cs01]
        
        PLAY RECAP *********************************************************************
        cs01                      : ok=1   changed=0   unreachable=0   failed=0
      2. Using the --extra-vars (-e) option to set dest:

        [student@workstation proj]$ ansible-playbook \
        > -e 'dest=172.25.250.8' iosping5.yml
        SSH password: student
        
        PLAY [A reachability test] *****************************************************
        
        TASK [Test reachability from cs01 to 172.25.250.8] *****************************
        ok: [cs01]
        
        PLAY RECAP *********************************************************************
        cs01                      : ok=1   changed=0   unreachable=0   failed=0
  7. Execute an ad hoc command that displays output from the setup module when the connection method is network_cli and examine the results. Type ansible -m setup spine01 | more and browse through the data returned. You can use ansible-doc setup to learn more about the setup module, or visit the setup module page at the Ansible documentation website. The connection method for spine01 should be set to network_cli. Notice that when you browse through the data, all or nearly all of it is about the local host, not spine01. Remember that the password for VyOS devices is vyos.

    When people are seeking a way to display all of the magic variables and facts about a host that are available, they are often directed to the setup module. This exercise demonstrates that the setup module, when used in conjunction with network devices, returns facts pertaining to the local host (the control node), not the network device. You must use a module from the *os_facts family to gather facts from network devices. For VyOS devices, for instance, use the vyos_facts module.

  8. Employ a Jinja2 template to generate magic variable data and examine the results.

    1. Create a j2 subdirectory if it does not already exist:

      [student@workstation proj]$ mkdir j2
    2. Create a Jinja2 template named j2/magic.j2 that contains the following content:

      hostvars:
      
        {{ hostvars | to_nice_yaml }}
      
      groups:
      
        {{ groups | to_nice_yaml }}
      
      group_names:
      
        {{ group_names | to_nice_yaml }}
      
      inventory_hostname:
      
        {{ inventory_hostname | to_nice_yaml }}
      
      play_hosts:
      
        {{ play_hosts | to_nice_yaml }}
    3. Create a playbook, named magic.yml, that uses the template module with the j2/magic.j2 template to write a file named magic.out. The magic.yml content should be similar to the following:

      ---
      - name: write magic variables to a file using a template
        hosts: cs01
      
        tasks:
      
        - name: do it
          template:
            src: j2/magic.j2
            dest: magic.out
    4. Execute the ansible-playbook command to run the play in the magic.yml playbook. The SSH password for cs01 is student.

      [student@workstation proj]$ ansible-playbook magic.yml
      SSH password: student
      
      PLAY [write magic variables to a file using a template] ************************
      
      TASK [do it] *******************************************************************
      changed: [cs01]
      
      PLAY RECAP *********************************************************************
      cs01                      : ok=1   changed=1   unreachable=0   failed=0
    5. Examine the contents of the magic.out file. A range of data is available by way of these preexisting variables.

      [student@workstation proj]$ less magic.out
  9. Create a playbook containing a play that uses a variable explicitly set using the --extra-vars (-e) option.

    1. Create a playbook named ios-tracert1.yml that performs the traceroute IOS command using an extra variable named dest. Include the following content in your playbook:

      ---
      - name: >
         illustrate the use of the
         --extra-vars (-e) option by
         using the ios_command module
         and running the traceroute command
         when destination is {{ dest }}
        hosts: cs01
      
        tasks:
      
          - name: traceroute to dest
            ios_command:
              commands:
                - traceroute {{ dest }} probe 2 timeout 2
            register: result
      
          - name: show result
            debug:
              var: result.stdout_lines
    2. Run the play you created using the -e option (--extra-vars).

      [student@workstation proj]$ ansible-playbook -e 'dest=172.25.250.254' ios-tracert1.yml
      SSH password: student
      
      PLAY [illustrate the use of the --extra-vars (-e) option by using the ios_command
      module by running the traceroute command when destination is 172.25.250.254] ***
      
      TASK [traceroute to 172.25.250.254] ********************************************
      ok: [cs01]
      
      TASK [show result] *************************************************************
      ok: [cs01] => {
          "result.stdout_lines": [
              [
                      "Type escape sequence to abort.",
                      "Tracing the route to 172.25.250.254",
                      "VRF info: (vrf in name/id, vrf out name/id)",
                      " 1 172.25.250.254 3 msec 2 msec"
              ]
          ]
      }
      
      PLAY RECAP *********************************************************************
      cs01                      : ok=2   changed=0   unreachable=0   failed=0

This concludes the guided exercise.

Revision: do457-2.5-4693601