AAP Survey Ideas

I’m trying to think of ways to better approach having a user fill in a set of variables that I use to automate upgrading the IOS version of network devices. Long-term I would like to present to the customer a survey that allows them to enter in a model number (that matches the model pulled from ios_facts) and enter a subset of variables nested under that model. The variables names are consistent across all models, however, the value will change as not all devices will be on the same version, or require the same files.

Here is an example of my group_vars directory. These variables are used extensively throughout the automation.

models:
  "C9200L-48P-4G":
    ios_version: "17.09.03"
    ios_binary: "cat9k_lite_iosxe.17.09.03.SPA.bin"
    ios_size_kb: 459631
    ios_md5: "0db5031f6e92fc8745bd8b5bc94aefc0"
  "C9200L-24P-4G":
    ios_version: "17.09.03"
    ios_binary: "cat9k_lite_iosxe.17.09.03.SPA.bin"
    ios_size_kb: 459631
    ios_md5: "0db5031f6e92fc8745bd8b5bc94aefc0"
  "C9300-48U":
    ios_version: "17.09.03"
    ios_binary: "cat9k_iosxe.17.09.03.SPA.bin"
    ios_size_kb: 1217759
    ios_md5: "68aa9aa3449616e245fdba42a8258dbb"
  "C9300-24U":
    ios_version: "17.09.03"
    ios_binary: "cat9k_iosxe.17.09.03.SPA.bin"
    ios_size_kb: 1217759
    ios_md5: "68aa9aa3449616e245fdba42a8258dbb"
  "C9300X-12Y":
    ios_version: "17.09.03"
    ios_binary: "cat9k_iosxe.17.09.03.SPA.bin"
    ios_size_kb: 1217759
    ios_md5: "68aa9aa3449616e245fdba42a8258dbb"

It’s a matter of preference and how your company/group deals with requests.

We have a webpage with a request page, where users can answer a few questions, and I kick off Ansible in the background to complete what is needed, using those answers/variables.

If you use Zendesk/ServiceNow/etc., you can have them submit a form, and through the various APIs, have that produce a variable file based on the answers - that variable file can be used.

Just two examples, there are hundreds of possibilities out there…

Hope this helps!

1 Like

I was wondering if you could build a webpage for this. How do you pass the variable to AAP to be ran in the playbook? And have you found a way to add, or update nested variables in group_vars by chance?

We use awxcli for that?

I don’t use AWX.

My website is written in Python Flask. I have a page that gathers all the information (variables) that I need, and then I do an SSH into my Ansible server, and kick off a straight ansible-playbook call, feeding it the variables, as if I was running it manually from the Ansible server.

Simple, but effective for me…

1 Like

Ansible Runner might be a solution for those not using AWX/AAP

While not technically updating group_vars, you can override group_vars (and host_vars) with ansible.builtin.set_fact. But be aware that while variables defined in group_vars may contain Jinja2 template expressions that pull in values from other variables (and therefore are lazily evaluated at the point of use), all templates in values assigned by set_fact are fully evaluated at the point of assignment. For example:

---
# test-overrides.yml
- name: Test partially defined variables
  hosts: localhost
  gather_facts: false
  vars:
    my_warn: yellow
    my_error: red
    my_colors:
      warn: '{{ my_warn }}'
      error: '{{ my_error }}'
  tasks:
    - name: Override my_colors adding an 'okay' color
      ansible.builtin.set_fact:
        my_colors2: '{{ {"okay": "green"} | combine(my_colors) }}'
        my_error: pink

    - name: Show our colors
      ansible.builtin.debug:
        msg: |
          my_colors: {{ my_colors }}
          my_colors2: {{ my_colors2 }}

The last task produces:

TASK [Show our colors] *********************************
ok: [localhost] => 
  msg: |-
    my_colors: {'warn': 'yellow', 'error': 'pink'}
    my_colors2: {'okay': 'green', 'warn': 'yellow', 'error': 'red'}

The combine filter added 'okay': 'green' (actually, it added the my_colors dict to the {'okay': 'green'} dict) to create my_colors2. Note that it used the values of my_warn and my_error at the time of the assignment to create my_colors2. That is, my_colors2 contains the values yellow and red, not jinja templates for my_warn and my_error.

In contrast, my_colors still contains those jinja templates, so when the set_fact task overrides the my_error variable with the my_error fact and assigns it the value pink, subsequent use of my_colors['error'] resolves to pink — or whatever value my_error resolves to at the time.

Note also that if, instead of creating the my_colors2 fact, we had created a my_colors fact, it would have hidden (because of variable precedence) the original variable of the same name, effectively replacing it for the rest of the play. While my_colors (the fact) would have gained the 'okay': 'green' key:value pair, it would have no Jinja templates as values; they would have all been resolved to literal strings.

2 Likes