Using Ansible facts and variables

Using Ansible facts and variables

About this lab

The purpose of this lab is to show the use of variables and facts in an Ansible playbook.

vTeam Specialization Program

Pure Storage nominated me recently to join the Pure Storage vTeam Specialization program for New Stack. The idea behind the program is, to create an active community within Pure Storage. Allowing Puritans to learn and develop their skills and grow into a subject matter experts.

The program consists of training and lab exercises that are focussed on developing experience in the New Stack space (Kubernetes, Ansible, Open Stack and more).

Since I think there are more people out there how want to learn more about New Stack, I will blog my progress in a series of lab exercises.

Lab instructions

The purpose of this lab is to use variables and facts from Ansible for building a more dynamic playbook.

Name:Ansible variables and facts
Description:Use variables and facts in a playbook
Objective:Be able to create generic playbooks that utilize variables and facts
Task #1:Ensure facts are collected in the playbook
Task #2:Create variables for the FA credentials and NTP server
Task #3:Collect FlashArray facts
Task #4:Set a fact for the current NTP server on the array
Task #5:Compare NTP fact to NTP variable and action any change
Success Criteria:All PSO k8s resources are correctly running
Lab goals and tasks

This lab will be done in a single blog, since it doesn’t require too many steps. As said, I’ll be using the Kubernetes cluster and PSO installation that I’ve setup in the previous lab. My Kubernetes cluster is running on VMware and will use iSCSI and NFS to connect to FlashArray and FlashBlade, however for provisioning storage from Kubernetes using PSO it actually doesn’t matter, the steps are always the same.

Working with Ansible facts and variables

Let’s get into this, by just showing the complete playbook that I have created immediately. The playbook uses variables for the IP address and API token used against the Pure Ansible modules. If uses the purefa_info module to retrieve the current configuration from the array, uses the set_facts module to access just the NTP servers and finally uses the purefa_ntp module to reset the exact same NTP servers. Probably a quite senseless playbook, but it does touch the points for the lab.

The Ansible playbook

- name: My second Pure playbook
  hosts: localhost
  gather_facts: true
  collections:
    - purestorage.flasharray
    - purestorage.flashblade
  vars:
    fa1_url: 10.1.1.10
    fa1_api_token: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 
  tasks:
    - name: Get FlashArray information
      purefa_info:
        gather_subset:
          - config
        fa_url: "{{ fa1_url }}"
        api_token: "{{ fa1_api_token }}"
      register: array_info
    - set_fact:
        ntp_servers: "{{ array_info['purefa_info']['config']['ntp'] }}"

    - name: show default information
      debug:
        msg: "{{ ntp_servers }}"

    - name: Set NTP servers
      purefa_ntp:
        ntp_servers: "{{ ntp_servers }}"
        fa_url: "{{ fa1_url }}"
        api_token: "{{ fa1_api_token }}"

Static variables

So first let’s look at lines 7 – 9. Here I register some static variables that can be used in the rest of the playbook. Registering the array IP address and credentials is a good example of using static variables, since you generally reuse this information for multiple tasks.

Register a fact from ouput

Lines 11 – 19 make the call to the purefa_info module which we’ve seen before in a previous lab. However now we specify the fb_url and api_token by using the variables defined earlier. To access a variable you have to use double curly brackets, so to access the contents of variable fa1_url we use "{{ fa1_url }}". We save the output of the module to a dynamic variable called array_info.

Using the set_fact module

In addition to defining static variables and the output of a module, we can also use the set_fact module, allowing us to specify variables during the execution of the playbook. In this case I will use it to extract just the NTP server list from the array_info variable. This is our first touch of Jinja2, so let’s spend a bit of time on that. If we use the debug module to output the contents of the array_info variable, we see something like this:

ok: [localhost] => {
    "msg": {
        "changed": false, 
        "failed": false, 
        "purefa_info": {
            "config": {
                "console_lock": "disabled", 
                ...
                "ntp": [
                    "time1.purestorage.com", 
                    "time2.purestorage.com"
                ], 
                ...

So it’s a nested object or array, where the NTP servers are stored under purefa_info -> config -> ntp. To access just the NTP section, we can access that by specifying the path to the values like such array_info['purefa_info']['config']['ntp']. This will just return the array of time servers from the array_info variable. And we store that list as a new variable called ntp_servers. We output the variable on lines 21 – 23 using the debug module.

Finally we use the purefa_ntp module on lines 25 – 29, where we only use variables for the module. The fa_url and api_token from our static variables and ntp_servers from our dynamically created variable where we extracted the list of NTP servers from our array_info variable.

Conclusion

This was a quick one, however using variables and facts is critical to be able to create flexible playbooks. Also it allows you to use output from one module, to use in the next allowing you to orchestrate a string of tasks as we’ve seen in this (quite useless) example.

I hope you’ve enjoyed this post and hope to see you next time!

Leave a Reply

Your email address will not be published.