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 |
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!