Skip to content
Oct 2 / Greg

Why Am I Aaron Rabkin(Trickery Chicago)

Hey everybody, I’m Greg Sowell and this is Why Am I, a podcast where I talk to interesting people and try to trace a path to where they find themselves today.  My guest this go around is Aaron Rabkin from Trickery Chicago.  Aaron is: an artist, actor, performer, door greeter, and also a magician.  As he puts it, he has a comedy show that is disguised as a magic show.  His performance is magic with comedic threads woven together and some of the best improvisational pieces to create an unforgettable experience.  And hey, maybe you are the unpaid intern Aaron’s been waiting for.  I hope you enjoy this chat with Aaron.
<
Youtube version here:
Please show them some love on their socials here: https://www.trickerychicago.com/.
If you want to support the podcast you can do so via https://www.patreon.com/whyamipod (this gives you access to bonus content including their Fantasy Restaurant!)
Sep 25 / Greg

Why Am I Ana Dee

Hey everybody, I’m Greg Sowell and this is Why Am I, a podcast where I talk to interesting people and try to trace a path to where they find themselves today.  My guest this go around is Ana Dee or sometimes known by her alter ego Rebekka Blue.  This kid had 3 jobs by age of 14, currently owns three online stores, has 1.1M followers on tiktok, a podcaster, has a wildly successful onlyfans, and her simple goal is nothing short of full rights for sex workers…I mean what have you done today?  Ana has an incredible drive matched only by the size of her heart.  This professional goddess is a pretty awesome human.  I hope you enjoy this chat with Ana.
<
Youtube version here:
If you want to support the podcast you can do so via https://www.patreon.com/whyamipod (this gives you access to bonus content including their Fantasy Restaurant!)
Sep 18 / Greg

Why Am I Lady Pink

Hey everybody, I’m Greg Sowell and this is Why Am I, a podcast where I talk to interesting people and try to trace a path to where they find themselves today.  My guest this go around is Lady Pink.  Pink is known for a lot of things: she was an accomplished graffiti artist, she’s potentially a hip-hop icon as the lead in the defining movie Wild Style, BUT those are all just origin stories; she defines herself as an artist.  I quickly realized that she is a person that knows their purpose and power, so I had better not mess around, but I also learned that she adores kids and gives a LOT of herself and a lot of her time to growing and nurturing them.  I love that dichotomy; she’s my kind of people.  I hope you enjoy this conversation with Pink.
<
Youtube version here:
Please show them some love on their socials here:https://www.ladypinknyc.com/, https://www.instagram.com/ladypinknyc/?hl=en.
If you want to support the podcast you can do so via https://www.patreon.com/whyamipod (this gives you access to bonus content including their Fantasy Restaurant!)
Sep 17 / Greg

Cisco Full Interface Configuration Compliance Checking With Ansible

This runs through all of my Cisco switch ports and ensures they are compliant with my configuration templates. It then builds pretty reports and emails them along with a CSV of the info. I’m building the reporting piece based on my reporting blog post here. The good part about this automation is that it will look at the full interface config, no matter what is added, be it vlans, port security, dot1x, etc., it will catch and compare it all.

The premise here is that all interfaces should contain an identifying description like: adminuser, mfguser, printer, ap. Each one of these description types will have a template they should match. So in the above example there would be four base templates. Of course each site would have a different VLAN, but that’s the good part of using a Jinja2 template, I can do variable replacement on the VLAN portion very easily. The playbook will then do all the comparisons and build the report(I’ll get into further detail down below).

Video Demo

Playbooks And Templates

First, you can find all of my materials here.
Here are my Jinja2 template files. I was lazy and only created a couple for demo purposes, but you’d need one for each interface type.
This is the printer.yml template:

1
2
3
4
5
6
7
interface {{ port_value.key }}
 description printer
 no ip address
 shutdown
 negotiation auto
 no mop enabled
 no mop sysid

As you can see above I’m doing variable replacement for the interface name(that way it will match what is physically on the device itself). Now if this was a switchport, which in a real environment it would be, we’d have VLAN info that we would be replacing.

Now for the playbook. I have this one named check-port-main-role.yml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
---
# uses this role https://github.com/gregsowell/ansible-report
- name: reporting non compliance on interface configs
  hosts: csr1000v
  gather_facts: false
  vars:
    int_descs: 
      - adminuser
      - mfguser
      - printer
      - ap
      - uplink
 
    headers: Hostname,reason,config
 
  tasks:
  - name: use ios facts to grab interface desc with all interfaces
    cisco.ios.ios_facts:
      gather_subset:
        - interfaces
      gather_network_resources:
        - l2_interfaces
    register: port_info
 
  - name: make the collected info a list for looping over
    set_fact:
      port_list: "{{ port_info.ansible_facts.ansible_net_interfaces | dict2items }}"
 
  - name: loop through each interface and do the compliance checking.  This calls another task file for the work.
    include_tasks: check-port-role.yml
    loop: "{{ port_list }}"    
    loop_control:
      loop_var: port_value
#    when: port_value.value.description == 'printer'
 
  - name: send the compliance email
    ansible.builtin.include_role:
      name: ansible-report
    vars: 
      action_type: email

This playbook doesn’t do all of the work, but it gets us started. I’ll break the above playbook down into separate bites so I can talk about each individually.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
---
# uses this role https://github.com/gregsowell/ansible-report
- name: reporting non compliance on interface configs
  hosts: csr1000v
  gather_facts: false
  vars:
    int_descs: 
      - adminuser
      - mfguser
      - printer
      - ap
      - uplink
 
    headers: Hostname,reason,config

In the above I setup the variables. int_descs are the interface description types that should be configured on our infrastructure. The switch ports can have additional info on the end, but should start with these basic descriptions to follow corporate policy. These descriptions will directly map to default templates(these are the templates described at the beginning of this section).
You’ll also notice the headers section at the end. These are the headers for the CSV file being created for the report.

1
2
3
4
5
6
7
8
9
10
11
12
  tasks:
  - name: use ios facts to grab interface desc with all interfaces
    cisco.ios.ios_facts:
      gather_subset:
        - interfaces
      gather_network_resources:
        - l2_interfaces
    register: port_info
 
  - name: make the collected info a list for looping over
    set_fact:
      port_list: "{{ port_info.ansible_facts.ansible_net_interfaces | dict2items }}"

Here I’m starting the first two tasks. I’m using the ios_facts module to pull all of the interfaces on the device along with their associated descriptions. This works well if it is a single switch or a large stack of switches. Keep in mind that a switch stack has one management IP, and when I query that single device it will tell me about all interfaces across the stack.
Next I convert the port info into a list so that I’m able to loop over it.

1
2
3
4
5
6
7
8
9
10
11
12
  - name: loop through each interface and do the compliance checking.  This calls another task file for the work.
    include_tasks: check-port-role.yml
    loop: "{{ port_list }}"    
    loop_control:
      loop_var: port_value
#    when: port_value.value.description == 'printer'
 
  - name: send the compliance email
    ansible.builtin.include_role:
      name: ansible-report
    vars: 
      action_type: email

This is the final couple of tasks. I’ll start with the very last; it sends the report email attaching the CSV. This is using my report role.
The second to last task is what is really doing the work in this playbook. For each host I connect to this task will loop over each port. Each port it loops over it will run them through the task file named check-port-role.yml. This task file is what does the bulk of the processing.

check-port-role.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
---
- name: grab the port config and save to variable
  cisco.ios.command: 
    commands: "show run int {{ port_value.key }} | b interface"
  register: port_config_1
 
- name: variable clean up.  It has some undesirable stuff in.
  set_fact: 
    port_config_1: "{{ port_config_1 | regex_replace('end') | trim}}"
 
- name: pre populate the port config 2 variable
  set_fact: 
    port_config_2: notfound
 
- name: loop through description types and once found, set the port config 2 via the template of that name.
  when: port_value.value.description is search(item) 
  set_fact: 
    port_config_2: "{{ lookup('template', item + '.yml') }}"
#  ignore_errors: true
  loop: "{{ int_descs }}"
 
- name: if desc not matched (it's not set properly) add line to report
  when: port_config_2 == 'notfound'
  ansible.builtin.include_role:
    name: ansible-report
  vars: 
    action_type: write
    write_line: "{{ inventory_hostname }},int desc mismatch,{{ port_config_1.stdout[0] | trim }}"
 
- name: if the desc is correct, but the config doesn't match the template, add a line to report
  when: port_config_1.stdout[0] | trim != port_config_2 | default('none') | trim and port_config_2 != 'notfound'
  ansible.builtin.include_role:
    name: ansible-report
  vars: 
    action_type: write
    write_line: "{{ inventory_hostname }},config mismatch,{{ port_config_1.stdout[0] | trim }}"

I’ll break this one into chunks again and explain what each does.

1
2
3
4
5
6
7
8
- name: grab the port config and save to variable
  cisco.ios.command: 
    commands: "show run int {{ port_value.key }} | b interface"
  register: port_config_1
 
- name: variable clean up.  It has some undesirable stuff in.
  set_fact: 
    port_config_1: "{{ port_config_1 | regex_replace('end') | trim}}"

First things first I connect to the interface and pull it’s config. This will give me the “show run” version, so full CLI.
Next I do a little cleanup on the variable so that it’s the raw config itself.

1
2
3
4
5
6
7
8
9
10
- name: pre populate the port config 2 variable
  set_fact: 
    port_config_2: notfound
 
- name: loop through description types and once found, set the port config 2 via the template of that name.
  when: port_value.value.description is search(item) 
  set_fact: 
    port_config_2: "{{ lookup('template', item + '.yml') }}"
#  ignore_errors: true
  loop: "{{ int_descs }}"

Next I’ll prepopulate the second variable so that I can easily tell if the description was found.
Now I’ll loop through all of the known good interface descriptions and compare those to what is configured on the interface itself. Once it matches it will pull the correct jinja2 template file and save it in the variable.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- name: if desc not matched (it's not set properly) add line to report
  when: port_config_2 == 'notfound'
  ansible.builtin.include_role:
    name: ansible-report
  vars: 
    action_type: write
    write_line: "{{ inventory_hostname }},int desc mismatch,{{ port_config_1.stdout[0] | trim }}"
 
- name: if the desc is correct, but the config doesn't match the template, add a line to report
  when: port_config_1.stdout[0] | trim != port_config_2 | default('none') | trim and port_config_2 != 'notfound'
  ansible.builtin.include_role:
    name: ansible-report
  vars: 
    action_type: write
    write_line: "{{ inventory_hostname }},config mismatch,{{ port_config_1.stdout[0] | trim }}"

These are the final two tasks. The first checks to see if the second port_config_2 variable says ‘notfound’. If it does that means that the interface description is wrong, so go ahead and write a line to the CSV saying as such.
The last task will also write a line in the CSV saying config mismatch IF the show run doesn’t match its corresponding template.

Here’s a sample report run from my test router:

Conclusion

This can easily be run against a small group of switches…or against thousands. It will allow you to quickly determine what devices are out of compliance for one reason or another so you can then do mitigation. In fact, I’m going to have a sister playbook that will allow you to modify the generated CSV here and use it for remediation.

If you have any questions or comments…ways you’d modify this to meet your needs, please let me know; I’d be happy to hear from you.

Sep 11 / Greg

Why Am I Molly Balloons

Hey everybody, I’m Greg Sowell and this is Why Am I, a podcast where I talk to interesting people and try to trace a path to where they find themselves today.  My guest this go around is Molly Balloons.  Imagine if you will, a 9 foot woman coming at you in the biggest balloon dress you’ve ever seen, but also wearing a 10 foot balloon crown, and sporting the biggest smile you’ve ever seen…that’s how some very lucky folks get to meet Molly for the first time!  She exudes an energy that makes me remember how anything is possible.  She says that 19 year olds remember things we’ve forgotten, but Molly hasn’t forgotten, and she’s here to remind you.  I hope you enjoy this frantically random chat with Molly.
Youtube version here:
If you want to support the podcast you can do so via https://www.patreon.com/whyamipod (this gives you access to bonus content including their Fantasy Restaurant!)
Sep 4 / Greg

Why Am I Spencer Crittenden

Hey everybody, I’m Greg Sowell and this is Why Am I, a podcast where I talk to interesting people and try to trace a path to where they find themselves today.  My guest this go around is Spencer Crittenden.  Spencer is kind of a big deal; you might recognize him from: the Harmontown podcast where he DM’d, the show Great Minds from the History Channel, Harmonquest where he DM’d, or from his guest spot on Community as Annie’s brother.  He’s also a very polished, fight me, podcaster on the That Happens podcast.  He’s also a deep thinker who strives to precisely articulate his emotions to others; he’s actually got a mastery I’ll probably never obtain. Real quick, pause this and go to patreon.com/thesixler and become part of his community, support your favorite creators, and then enjoy this chat with Spencer.
Youtube version here:
If you want to support the podcast you can do so via https://www.patreon.com/whyamipod (this gives you access to bonus content including their Fantasy Restaurant!)
Aug 28 / Greg

Why Am I Kat Walsh

Hey everybody, I’m Greg Sowell and this is Why Am I, a podcast where I talk to interesting people and try to trace a path to where they find themselves today.  My guest this go around is Kat Walsh.  Kat is many things: an awesome podcast host of not one, but two podcasts, an advocate of psychedelics, someone who’s uncannily articulate about their inner thoughts and workings, and she’s not alone(never alone).  I hope you enjoy this chat with Kat.
Youtube version here:
If you want to support the podcast you can do so via https://www.patreon.com/whyamipod (this gives you access to bonus content including their Fantasy Restaurant!)