Skip to content
Jun 19 / thebrotherswisp

The Brothers WISP 138 – Active vs PON, Terragraph Teaser, Batfish

This week we have Greg, Chad Wachs, and new face Colin Zapalac talking about talking.

**Sponsors**
Sonar.software
Kwikbit.com
Towercoverage.com
**/Sponsors**

This week we talk about:
Active vs PON deployment – why am I seeing so much active fiber being deployed? What am I missing?
Brownfield deployment options when you don’t have aerial ability
It’s getting HOT. Anyone protecting gear from heat? Routers hitting 220F internal temps
Colin: DDB enclosures with Pentair AC, mini-splits in MDF’s
Preview Siklu Terragraph test?
Peltier cooling
MTK newsletter 100
Colin’s automated edgeswitch update script
batfish
Mikrotik Knots tracking

Here’s the video:(if you don’t see it, hit refresh)

Jun 6 / thebrotherswisp

The Brothers WISP 137 – Local Proxy ARP, Carrier Ethernet Drop, GPEN21 CPE

This week we have Greg and Nick A. catching up after skipping an episode…did anyone notice?

**Sponsors**
Sonar.software
Kwikbit.com
Towercoverage.com
**/Sponsors**

This week we talk about:
L2 isolation addition – Mikrotik introduced Local Proxy Arp – MTK responds to all ARP requests on an interface.
Using a switch to connect border/core services – eases transition, can be complicated with direct BGP peer flaps.
UBNT 60LR? Carrier Ethernet Drop
Cisco EEM for flapping a port
AutoIT for scripting
GPEN21 as FTTH CPE
OEO kit
FS switches for FTTH project

Here’s the video:(if you don’t see it, hit refresh)

May 25 / Greg

Cyberark Per Host Password Lookup In The Ansible Automation Platform

Cyberark Central Credential provider has some killer features with one of particular interest(for this article that is) which is the ability to have a different password per host. It seems pretty bonkers to think you can maintain separate passwords for 100 different devices, but CA does it, and not only that, it has facilities that can change the password each time it’s used *galaxy brain*.

This post demonstrates how to do a per-host lookup inside the Tower/Control environment.

Demo Video

Cyberark Setup

In my CA environment I have a safe named “test” that I’m using.
In the root folder of test I’ve created three password objects, each for the switches I plan to connect to. Each object is named the same as the inventory hostname from ansible: sw1, sw2, sw3.

All of the connection info along with the walkthrough is in my CA AIM blog post.

Playbook

I’m first going to say that given my drothers I would have used the Cyberark lookup plugin, but you have to have the Central Credential software installed on your server, and I’ve yet to get a copy of it. The playbook to make that work is here:

I instead used the cyberark collection that contains the cyberark_credential module, which can be found here.

Looking at the playbook above I have a variable that I’ve setup(and I’m replacing at runtime from my tower environment) named ca_base_url.
The other cyberark info is just presented plain text, but notice that I had to supply my cert and key. This is why I wanted to use the lookup plugin, so I wouldn’t have to put a link to the cert/key anytime I wanted to use it…but I digress.

The real magic happens in the query section of the first task:

1
query: "Safe=test;Object={{ inventory_hostname }}"

I’m connecting to the safe named “test” and for each host in the current run I’m pulling the password object that is named the same as their “inventory_name”. Having these two match is how I key the two items together(the host to their respective password).

I next set the ansible_password variable for each host based on the password I just looked up. Now, when ansible subsequently attempts to connect to any inventory host it will do so via the password that was just pulled.

Make note that any task that either did the lookup or set the variables also had the no_log option set to true so that the passwords are never exposed in the logging.

Conclusion

The Cyberark per-host lookup process isn’t too difficult, it’s just a slight mind-shift from what we are used to. If you have any questions or comments, please let me know. Thanks and happy automating!

May 24 / Greg

Using Collections With Ansible Tower/Ansible Control

Collections are the new hotness for ansible, so you should start adjusting to it now…that means I’ll have to start converting my playbooks little by little now. That’s because ansible 2.9 allows for both standard modules and collections to work in tandem. So do the thing if you haven’t already.

You have multiple options when trying to install collections into your tower environment, and I’m going to cover a couple here.

Manual collection install

If you are going to manually install these files from the CLI, keep in mind that Tower runs as the AWX user, so you will need to su awx before doing most of these installs.
First you can pull collections straight from Ansible galaxy.

1
ansible-galaxy collection install my_namespace.my_collection

You can also download the archive file and do an offline install:

1
ansible-galaxy collection install my_namespace-my_collection-1.0.0.tar.gz -p ./collections

You can download certified collections via the automation hub(it allows you to grab them as archives right off the cloud.redhat.com site). After that the install process is just the same.

Automatic collection install

The best way to automatically pull collections is via a requirements file.

First, in your git repository(or other SCM system) create a folder called “collections” and add a file inside named “requirements.yml”
So I wanted to dynamically pull the Arista EOS collection so I did it as follows(/collections/requirements.yml):

1
2
3
4
---
collections:
# Install the Arista EOS collection
- arista.eos

Now when I run the playbook it will reach out to the repository in question and pull the content.
Keep in mind that it doesn’t fully install the collection. I can’t create a new repo with playbooks and start using that collection without either a manual install or a requirements file. It’s for this reason that in my lab environment I simply do a manual install so I can use it in all of my playbooks without keeping track.

If you are using certified content and you want to pull directly from the Automation hub, look at this documentation; it walks through the settings required.
In newer versions of Tower/control the “Primary Galaxy Server” options are no longer present and that portion will be completed via custom credentials as shown in this video.
Here’s the screen shots from my machine:
First I created two credentials:

The first connects to the automation hub:

Galaxy Server URL:

1
https://cloud.redhat.com/api/automation-hub/

Auth Server URL:

1
https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token

I then create a credential to connect to the standard public galaxy servers:

I now set the Tower/control server to use these creds:


The order in which you select them is the order in which the server will check for download. In my case I want to ensure that my automation hub link is set first, so it will check there, then fall back to checking galaxy. That means I’ll unselect them both, then add them back in the correct order:

Good luck and happy automating!

May 23 / thebrotherswisp

The Brothers WISP 136 – Network Compliance, Labs, 100Gb Mikrotik

This week we have Greg and Nick A. catching up after skipping an episode…did anyone notice?

**Sponsors**
Sonar.software
Kwikbit.com
Towercoverage.com
**/Sponsors**

This week we talk about:
Network compliance detection/alerting via Ansible
Wispamerica update from anyone that went?
Arista vEOS lab eddition free if you just create a guest account!
Mikrotik home app
MLAG on Mikrotik V7
Router OS 7.1beta6 has included a new model number(supposing it isn’t a joke) crs520-4xs-16xq – 4x 25gbit + 16x 100gbit
John Oz says that HE rebuilds their filters once a day, so you better hope you are advertising at that time LOL
Wonder how hard that would be to do via automation…hmmmm

Here’s the video:(if you don’t see it, hit refresh)

May 3 / Greg

Detecting/Alerting On Network Compliance Via The Ansible Automation Platform

This demo uses the Ansible Automation Platform to perform compliance checks on network infrastructure. It uses vendor agnostic settings files to allow configuration/compliance checking against different vendors/models of equipment. These playbooks aren’t just about compliance, they will do: standard configuration of the equipment, compliance testing and alerting, and also remediation.

The method I employ here isn’t the end-all be-all, but it is how a lot of folks do it. Keep in mind that every organization is different, so expect to adjust this to fit your needs.

Video Demo

Files

The Github repo with all of the files are here.

The best way to see how all of the pieces fit together is via the above video(there’s a lot explanation in there). I’m going to cover in depth a couple of specific playbooks.
First I’ll say, this is what my workflow template looks like in my ansible controller:

This corresponds to my main job templates. The order is:
– Run the pre process. This creates a blank file I refer to as the compliance file. As I run though the other playbooks they will fill this file out with anything non compliant.
– NTP configuration playbook. In this one it will determine if it is a Cisco or Arista device, then configure NTP servers based on a regionalized configuration files. If it’s in “compliance mode” it will fill out the compliance file.
– SNMP configuration playbook. This is much the same as the NTP playbook only it’s configuring SNMP community strings.
– The post processing playbook checks if the compliance file is empty. If it is, it does nothing. If there are entries, then that means there were non compliant entries, so it connects to servicenow and generates an incidence based on the contents of the file.

For NTP I first hit this playbook:

In here I’m really looking at the inventory object for each host and determining what network_os they are running. If it is Cisco I call the Cisco specific task file, and if it is Arista, I pull the Arista specific task file.

This is the Cisco specific task file:

In here I build several variables: one variable consists of the currently configured NTP servers on the device, another is the imported server(my source of truth), I then build a variable that is the command format for the new servers(ntp server x.x.x.x), and last I do a diff on the existing and the SoT to find out what servers exist and need to be removed.
I then remove the non compliant servers, and add any servers that should be in place.
If the playbook is run in check mode(a condition where I verify what changes WOULD be made) and I have the “compliance_check” variable defined, then I’ll start the compliance code block. Here I find anything that should be removed and add an entry to the compliance file. Last I find anything that should be added and add it to the compliance file.

Here’s an example of the NTP server file. Again, this is stored as just the raw servers, so it’s easy to take the servers and apply them to each vendors configuration format.

I then do the same for SNMP and last I hit this file for post processing:

In here I load the contents of the compliance file into a variable. If the variable has entries I then use the new ServiceNow collection to create an incident in SNOW with the contents of the file.

Conclusion

While I could create a playbook just for compliance, it is a waste of time/resources for me to do so. If I make one playbook that can provision, detect/alert on compliance, and then perform remediation all with just a little bit of additional effort, then I’m going to do so.

If you would change this for your environment, let me know, I’d like to see how your environment differs.
As always, thanks and happy compliance 😉

May 3 / Greg

Import Into ServiceNow CMDB Via Ansible ServiceNow Collection

It seems these days that at least half of my customers are using SNOW as their ITSM, so I’m always looking for ways to automate against it. RedHat recently launched a new collection that works directly with SNOW. In V1 release is the ability to work with problems, incidents, change requests, and configuration items(which are your CMDB entries). Playing with the collection is nice, but I wanted to do something interesting, so I made a way to use it to import switches into the CMDB in a repeatable manner.

Video Demo

Files

All files can be found here in my public github repo. I’ll start with the template file I’m going to be importing into SNOW. This will more likely be a CSV or something of the like, and perhaps I’ll update this in the future, but for now it’s a simple YAML file:

In the file I’m adding the important bits like name, serial number, IP address, and make/model. I’m using the name as the key, so each will need to be unique in my environment. Believe it or not, The sys_id field is they key in the database, so the system will let me add the exact same device info 100 times if I want to…each having it’s own entry in the database. I always have unique device names, so I’m using that.

Next I’ll look at the main playbook:

I setup a few variables in the vars section, most notably, which CMDB these entries should live in.
Task 1 reads in the file that I’m going to be importing into the database “snow-col-config-template.yml”.
Task 2 reads all of the existing CMDB entries and saves them into the “all_config_items” variable.
The final task loops through each entry to import and calls a sub task. I do this because I need to have a loop with an inner loop, and this is the simplest way to accomplish it.

This is the sub task that’s called for each entry ready from the import file.

This file consists of two tasks.
Task 1 takes each switch at a time and checks to see if it already exists in the database. Again, I’m matching based on name. Now this module isn’t idempotent unfortunately, so when it finds a match, it will show changed each time it runs. This isn’t necessarily a bad thing, in fact it really won’t hurt anything, I’ve just become a fan of idempotent modules(so expect to see the orange “changed” output). The output of this run is saved as a variable.
Task 2 runs and checks the previously created variable and sees if there was a change made. If there was a change made, then I know that the record existed already, so do nothing. If the record didn’t exist, then this task will go ahead and create it. Since this module doesn’t support idempotency I have to check if it already exists, otherwise it will create multiple entries for the same device…and you’ll have a bad time.

Running The Automation In Ansible Automation Platform

To view the CMDB now before I do the run I follow these three steps:

Here’s the output from the launch:

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
TASK [Include the file that will be imported into SNOW] ************************
ok: [localhost]
TASK [Read all of the existing CMDB entries and save them to a variable] *******
ok: [localhost]
TASK [Loop to import devices.  This calls a sub task for processing] ***********
included: /tmp/awx_1056_3rnj557y/project/snow-col-config-import-sub.yml for localhost
included: /tmp/awx_1056_3rnj557y/project/snow-col-config-import-sub.yml for localhost
included: /tmp/awx_1056_3rnj557y/project/snow-col-config-import-sub.yml for localhost
included: /tmp/awx_1056_3rnj557y/project/snow-col-config-import-sub.yml for localhost
TASK [If sw1 already exists, update it's configuration] ************************
changed: [localhost] => (item={'attested_date': '', 'can_switch': 'false', 'stack': 'false', 'operational_status': 'operational', 'cpu_manufacturer': '', 'sys_updated_on': '2021-04-22 14:08:44', 'discovery_source': '', 'first_discovered': '', 'due_in': '', 'can_partitionvlans': 'false', 'gl_account': '', 'invoice_number': '', 'sys_created_by': 'admin', 'ram': '', 'warranty_expiration': '', 'cpu_speed': '', 'owned_by': '', 'checked_out': '', 'firmware_manufacturer': '', 'disk_space': '', 'sys_domain_path': '/', 'discovery_proto_id': '', 'maintenance_schedule': '', 'cost_center': '', 'attested_by': '', 'dns_domain': '', 'assigned': '', 'purchase_date': '', 'short_description': '1st lab switch', 'managed_by': '', 'range': '', 'firmware_version': '', 'can_print': 'false', 'last_discovered': '', 'ports': '', 'sys_class_name': 'cmdb_ci_ip_switch', 'cpu_count': '1', 'manufacturer': 'b7e831bdc0a80169015ae101f3c4d6cd', 'vendor': '', 'can_route': 'false', 'model_number': '3550', 'assigned_to': '', 'start_date': '', 'bandwidth': '', 'serial_number': '111', 'support_group': '', 'correlation_id': '', 'unverified': 'false', 'attributes': '', 'asset': '48af32ba07102010d42af03c7c1ed03b', 'skip_sync': 'false', 'device_type': 'switch', 'attestation_score': '', 'sys_updated_by': 'admin', 'sys_created_on': '2020-11-09 16:36:58', 'cpu_type': '', 'sys_domain': 'global', 'install_date': '', 'asset_tag': 'P1000611', 'hardware_substatus': '', 'fqdn': '', 'stack_mode': '', 'change_control': '', 'internet_facing': 'true', 'physical_interface_count': '', 'delivery_date': '', 'hardware_status': 'installed', 'channels': '', 'install_status': 'installed', 'supported_by': '', 'name': 'sw1', 'subcategory': 'IP', 'default_gateway': '', 'assignment_group': '', 'managed_by_group': '', 'can_hub': 'false', 'sys_id': '145f7e7a07102010d42af03c7c1ed06f', 'po_number': '', 'checked_in': '', 'sys_class_path': '/!!/!2/!!/!,', 'mac_address': '', 'company': '', 'justification': '', 'department': '', 'snmp_sys_location': '', 'comments': '', 'cost': '', 'sys_mod_count': '1', 'monitor': 'false', 'ip_address': '192.168.51.51', 'model_id': '80af727a07102010d42af03c7c1ed0e3', 'duplicate_of': '', 'sys_tags': '', 'cost_cc': 'USD', 'discovery_proto_type': '', 'order_date': '', 'schedule': '', 'environment': 'production', 'due': '', 'attested': 'false', 'location': '', 'category': 'Hardware', 'fault_count': '0', 'lease_id': ''})
skipping: [localhost] => (item={'attested_date': '', 'can_switch': 'false', 'stack': 'false', 'operational_status': 'operational', 'cpu_manufacturer': '', 'sys_updated_on': '2021-04-22 14:08:48', 'discovery_source': '', 'first_discovered': '', 'due_in': '', 'can_partitionvlans': 'false', 'gl_account': '', 'invoice_number': '', 'sys_created_by': 'admin', 'ram': '', 'warranty_expiration': '', 'cpu_speed': '', 'owned_by': '', 'checked_out': '', 'firmware_manufacturer': '', 'disk_space': '', 'sys_domain_path': '/', 'discovery_proto_id': '', 'maintenance_schedule': '', 'cost_center': '', 'attested_by': '', 'dns_domain': '', 'assigned': '', 'purchase_date': '', 'short_description': '2nd lab switch', 'managed_by': '', 'range': '', 'firmware_version': '', 'can_print': 'false', 'last_discovered': '', 'ports': '', 'sys_class_name': 'cmdb_ci_ip_switch', 'cpu_count': '1', 'manufacturer': 'b7e831bdc0a80169015ae101f3c4d6cd', 'vendor': '', 'can_route': 'false', 'model_number': '3550', 'assigned_to': '', 'start_date': '', 'bandwidth': '', 'serial_number': '222', 'support_group': '', 'correlation_id': '', 'unverified': 'false', 'attributes': '', 'asset': '0d81877607102010d42af03c7c1ed0e9', 'skip_sync': 'false', 'device_type': '', 'attestation_score': '', 'sys_updated_by': 'admin', 'sys_created_on': '2020-11-09 16:45:14', 'cpu_type': '', 'sys_domain': 'global', 'install_date': '', 'asset_tag': 'P1000612', 'hardware_substatus': '', 'fqdn': '', 'stack_mode': '', 'change_control': '', 'internet_facing': 'true', 'physical_interface_count': '', 'delivery_date': '', 'hardware_status': 'installed', 'channels': '', 'install_status': 'installed', 'supported_by': '', 'name': 'sw2', 'subcategory': 'IP', 'default_gateway': '', 'assignment_group': '', 'managed_by_group': '', 'can_hub': 'false', 'sys_id': '5a61877607102010d42af03c7c1ed0f3', 'po_number': '', 'checked_in': '', 'sys_class_path': '/!!/!2/!!/!,', 'mac_address': '', 'company': '', 'justification': '', 'department': '', 'snmp_sys_location': '', 'comments': '', 'cost': '', 'sys_mod_count': '1', 'monitor': 'false', 'ip_address': '192.168.51.52', 'model_id': '80af727a07102010d42af03c7c1ed0e3', 'duplicate_of': '', 'sys_tags': '', 'cost_cc': 'USD', 'discovery_proto_type': '', 'order_date': '', 'schedule': '', 'environment': 'production', 'due': '', 'attested': 'false', 'location': '', 'category': 'Hardware', 'fault_count': '0', 'lease_id': ''}) 
skipping: [localhost] => (item={'attested_date': '', 'can_switch': 'false', 'stack': 'false', 'operational_status': 'operational', 'cpu_manufacturer': '', 'sys_updated_on': '2021-04-21 17:44:42', 'discovery_source': '', 'first_discovered': '', 'due_in': '', 'can_partitionvlans': 'false', 'gl_account': '', 'invoice_number': '', 'sys_created_by': 'admin', 'ram': '', 'warranty_expiration': '', 'cpu_speed': '', 'owned_by': '', 'checked_out': '', 'firmware_manufacturer': '', 'disk_space': '', 'sys_domain_path': '/', 'discovery_proto_id': '', 'maintenance_schedule': '', 'cost_center': '', 'attested_by': '', 'dns_domain': '', 'assigned': '', 'purchase_date': '', 'short_description': '3rd lab switch', 'managed_by': '', 'range': '', 'firmware_version': '', 'can_print': 'false', 'last_discovered': '', 'ports': '', 'sys_class_name': 'cmdb_ci_ip_switch', 'cpu_count': '1', 'manufacturer': 'b7e831bdc0a80169015ae101f3c4d6cd', 'vendor': '', 'can_route': 'false', 'model_number': '3550', 'assigned_to': '', 'start_date': '', 'bandwidth': '', 'serial_number': '333', 'support_group': '', 'correlation_id': '', 'unverified': 'false', 'attributes': '', 'asset': '514aea5f07632010d42af03c7c1ed010', 'skip_sync': 'false', 'device_type': '', 'attestation_score': '', 'sys_updated_by': 'admin', 'sys_created_on': '2021-04-21 17:44:42', 'cpu_type': '', 'sys_domain': 'global', 'install_date': '', 'asset_tag': 'P1000613', 'hardware_substatus': '', 'fqdn': '', 'stack_mode': '', 'change_control': '', 'internet_facing': 'true', 'physical_interface_count': '', 'delivery_date': '', 'hardware_status': 'installed', 'channels': '', 'install_status': 'installed', 'supported_by': '', 'name': 'sw3', 'subcategory': 'IP', 'default_gateway': '', 'assignment_group': '', 'managed_by_group': '', 'can_hub': 'false', 'sys_id': '954aea5f07632010d42af03c7c1ed00f', 'po_number': '', 'checked_in': '', 'sys_class_path': '/!!/!2/!!/!,', 'mac_address': '', 'company': '', 'justification': '', 'department': '', 'snmp_sys_location': '', 'comments': '', 'cost': '', 'sys_mod_count': '0', 'monitor': 'false', 'ip_address': '192.168.51.53', 'model_id': '80af727a07102010d42af03c7c1ed0e3', 'duplicate_of': '', 'sys_tags': '', 'cost_cc': 'USD', 'discovery_proto_type': '', 'order_date': '', 'schedule': '', 'environment': 'production', 'due': '', 'attested': 'false', 'location': '', 'category': 'Hardware', 'fault_count': '0', 'lease_id': ''}) 
TASK [sw1 didn't already exist, so create it] **********************************
skipping: [localhost]
TASK [If sw2 already exists, update it's configuration] ************************
skipping: [localhost] => (item={'attested_date': '', 'can_switch': 'false', 'stack': 'false', 'operational_status': 'operational', 'cpu_manufacturer': '', 'sys_updated_on': '2021-04-22 14:08:44', 'discovery_source': '', 'first_discovered': '', 'due_in': '', 'can_partitionvlans': 'false', 'gl_account': '', 'invoice_number': '', 'sys_created_by': 'admin', 'ram': '', 'warranty_expiration': '', 'cpu_speed': '', 'owned_by': '', 'checked_out': '', 'firmware_manufacturer': '', 'disk_space': '', 'sys_domain_path': '/', 'discovery_proto_id': '', 'maintenance_schedule': '', 'cost_center': '', 'attested_by': '', 'dns_domain': '', 'assigned': '', 'purchase_date': '', 'short_description': '1st lab switch', 'managed_by': '', 'range': '', 'firmware_version': '', 'can_print': 'false', 'last_discovered': '', 'ports': '', 'sys_class_name': 'cmdb_ci_ip_switch', 'cpu_count': '1', 'manufacturer': 'b7e831bdc0a80169015ae101f3c4d6cd', 'vendor': '', 'can_route': 'false', 'model_number': '3550', 'assigned_to': '', 'start_date': '', 'bandwidth': '', 'serial_number': '111', 'support_group': '', 'correlation_id': '', 'unverified': 'false', 'attributes': '', 'asset': '48af32ba07102010d42af03c7c1ed03b', 'skip_sync': 'false', 'device_type': 'switch', 'attestation_score': '', 'sys_updated_by': 'admin', 'sys_created_on': '2020-11-09 16:36:58', 'cpu_type': '', 'sys_domain': 'global', 'install_date': '', 'asset_tag': 'P1000611', 'hardware_substatus': '', 'fqdn': '', 'stack_mode': '', 'change_control': '', 'internet_facing': 'true', 'physical_interface_count': '', 'delivery_date': '', 'hardware_status': 'installed', 'channels': '', 'install_status': 'installed', 'supported_by': '', 'name': 'sw1', 'subcategory': 'IP', 'default_gateway': '', 'assignment_group': '', 'managed_by_group': '', 'can_hub': 'false', 'sys_id': '145f7e7a07102010d42af03c7c1ed06f', 'po_number': '', 'checked_in': '', 'sys_class_path': '/!!/!2/!!/!,', 'mac_address': '', 'company': '', 'justification': '', 'department': '', 'snmp_sys_location': '', 'comments': '', 'cost': '', 'sys_mod_count': '1', 'monitor': 'false', 'ip_address': '192.168.51.51', 'model_id': '80af727a07102010d42af03c7c1ed0e3', 'duplicate_of': '', 'sys_tags': '', 'cost_cc': 'USD', 'discovery_proto_type': '', 'order_date': '', 'schedule': '', 'environment': 'production', 'due': '', 'attested': 'false', 'location': '', 'category': 'Hardware', 'fault_count': '0', 'lease_id': ''}) 
changed: [localhost] => (item={'attested_date': '', 'can_switch': 'false', 'stack': 'false', 'operational_status': 'operational', 'cpu_manufacturer': '', 'sys_updated_on': '2021-04-22 14:08:48', 'discovery_source': '', 'first_discovered': '', 'due_in': '', 'can_partitionvlans': 'false', 'gl_account': '', 'invoice_number': '', 'sys_created_by': 'admin', 'ram': '', 'warranty_expiration': '', 'cpu_speed': '', 'owned_by': '', 'checked_out': '', 'firmware_manufacturer': '', 'disk_space': '', 'sys_domain_path': '/', 'discovery_proto_id': '', 'maintenance_schedule': '', 'cost_center': '', 'attested_by': '', 'dns_domain': '', 'assigned': '', 'purchase_date': '', 'short_description': '2nd lab switch', 'managed_by': '', 'range': '', 'firmware_version': '', 'can_print': 'false', 'last_discovered': '', 'ports': '', 'sys_class_name': 'cmdb_ci_ip_switch', 'cpu_count': '1', 'manufacturer': 'b7e831bdc0a80169015ae101f3c4d6cd', 'vendor': '', 'can_route': 'false', 'model_number': '3550', 'assigned_to': '', 'start_date': '', 'bandwidth': '', 'serial_number': '222', 'support_group': '', 'correlation_id': '', 'unverified': 'false', 'attributes': '', 'asset': '0d81877607102010d42af03c7c1ed0e9', 'skip_sync': 'false', 'device_type': '', 'attestation_score': '', 'sys_updated_by': 'admin', 'sys_created_on': '2020-11-09 16:45:14', 'cpu_type': '', 'sys_domain': 'global', 'install_date': '', 'asset_tag': 'P1000612', 'hardware_substatus': '', 'fqdn': '', 'stack_mode': '', 'change_control': '', 'internet_facing': 'true', 'physical_interface_count': '', 'delivery_date': '', 'hardware_status': 'installed', 'channels': '', 'install_status': 'installed', 'supported_by': '', 'name': 'sw2', 'subcategory': 'IP', 'default_gateway': '', 'assignment_group': '', 'managed_by_group': '', 'can_hub': 'false', 'sys_id': '5a61877607102010d42af03c7c1ed0f3', 'po_number': '', 'checked_in': '', 'sys_class_path': '/!!/!2/!!/!,', 'mac_address': '', 'company': '', 'justification': '', 'department': '', 'snmp_sys_location': '', 'comments': '', 'cost': '', 'sys_mod_count': '1', 'monitor': 'false', 'ip_address': '192.168.51.52', 'model_id': '80af727a07102010d42af03c7c1ed0e3', 'duplicate_of': '', 'sys_tags': '', 'cost_cc': 'USD', 'discovery_proto_type': '', 'order_date': '', 'schedule': '', 'environment': 'production', 'due': '', 'attested': 'false', 'location': '', 'category': 'Hardware', 'fault_count': '0', 'lease_id': ''})
skipping: [localhost] => (item={'attested_date': '', 'can_switch': 'false', 'stack': 'false', 'operational_status': 'operational', 'cpu_manufacturer': '', 'sys_updated_on': '2021-04-21 17:44:42', 'discovery_source': '', 'first_discovered': '', 'due_in': '', 'can_partitionvlans': 'false', 'gl_account': '', 'invoice_number': '', 'sys_created_by': 'admin', 'ram': '', 'warranty_expiration': '', 'cpu_speed': '', 'owned_by': '', 'checked_out': '', 'firmware_manufacturer': '', 'disk_space': '', 'sys_domain_path': '/', 'discovery_proto_id': '', 'maintenance_schedule': '', 'cost_center': '', 'attested_by': '', 'dns_domain': '', 'assigned': '', 'purchase_date': '', 'short_description': '3rd lab switch', 'managed_by': '', 'range': '', 'firmware_version': '', 'can_print': 'false', 'last_discovered': '', 'ports': '', 'sys_class_name': 'cmdb_ci_ip_switch', 'cpu_count': '1', 'manufacturer': 'b7e831bdc0a80169015ae101f3c4d6cd', 'vendor': '', 'can_route': 'false', 'model_number': '3550', 'assigned_to': '', 'start_date': '', 'bandwidth': '', 'serial_number': '333', 'support_group': '', 'correlation_id': '', 'unverified': 'false', 'attributes': '', 'asset': '514aea5f07632010d42af03c7c1ed010', 'skip_sync': 'false', 'device_type': '', 'attestation_score': '', 'sys_updated_by': 'admin', 'sys_created_on': '2021-04-21 17:44:42', 'cpu_type': '', 'sys_domain': 'global', 'install_date': '', 'asset_tag': 'P1000613', 'hardware_substatus': '', 'fqdn': '', 'stack_mode': '', 'change_control': '', 'internet_facing': 'true', 'physical_interface_count': '', 'delivery_date': '', 'hardware_status': 'installed', 'channels': '', 'install_status': 'installed', 'supported_by': '', 'name': 'sw3', 'subcategory': 'IP', 'default_gateway': '', 'assignment_group': '', 'managed_by_group': '', 'can_hub': 'false', 'sys_id': '954aea5f07632010d42af03c7c1ed00f', 'po_number': '', 'checked_in': '', 'sys_class_path': '/!!/!2/!!/!,', 'mac_address': '', 'company': '', 'justification': '', 'department': '', 'snmp_sys_location': '', 'comments': '', 'cost': '', 'sys_mod_count': '0', 'monitor': 'false', 'ip_address': '192.168.51.53', 'model_id': '80af727a07102010d42af03c7c1ed0e3', 'duplicate_of': '', 'sys_tags': '', 'cost_cc': 'USD', 'discovery_proto_type': '', 'order_date': '', 'schedule': '', 'environment': 'production', 'due': '', 'attested': 'false', 'location': '', 'category': 'Hardware', 'fault_count': '0', 'lease_id': ''}) 
TASK [sw2 didn't already exist, so create it] **********************************
skipping: [localhost]
TASK [If sw3 already exists, update it's configuration] ************************
skipping: [localhost] => (item={'attested_date': '', 'can_switch': 'false', 'stack': 'false', 'operational_status': 'operational', 'cpu_manufacturer': '', 'sys_updated_on': '2021-04-22 14:08:44', 'discovery_source': '', 'first_discovered': '', 'due_in': '', 'can_partitionvlans': 'false', 'gl_account': '', 'invoice_number': '', 'sys_created_by': 'admin', 'ram': '', 'warranty_expiration': '', 'cpu_speed': '', 'owned_by': '', 'checked_out': '', 'firmware_manufacturer': '', 'disk_space': '', 'sys_domain_path': '/', 'discovery_proto_id': '', 'maintenance_schedule': '', 'cost_center': '', 'attested_by': '', 'dns_domain': '', 'assigned': '', 'purchase_date': '', 'short_description': '1st lab switch', 'managed_by': '', 'range': '', 'firmware_version': '', 'can_print': 'false', 'last_discovered': '', 'ports': '', 'sys_class_name': 'cmdb_ci_ip_switch', 'cpu_count': '1', 'manufacturer': 'b7e831bdc0a80169015ae101f3c4d6cd', 'vendor': '', 'can_route': 'false', 'model_number': '3550', 'assigned_to': '', 'start_date': '', 'bandwidth': '', 'serial_number': '111', 'support_group': '', 'correlation_id': '', 'unverified': 'false', 'attributes': '', 'asset': '48af32ba07102010d42af03c7c1ed03b', 'skip_sync': 'false', 'device_type': 'switch', 'attestation_score': '', 'sys_updated_by': 'admin', 'sys_created_on': '2020-11-09 16:36:58', 'cpu_type': '', 'sys_domain': 'global', 'install_date': '', 'asset_tag': 'P1000611', 'hardware_substatus': '', 'fqdn': '', 'stack_mode': '', 'change_control': '', 'internet_facing': 'true', 'physical_interface_count': '', 'delivery_date': '', 'hardware_status': 'installed', 'channels': '', 'install_status': 'installed', 'supported_by': '', 'name': 'sw1', 'subcategory': 'IP', 'default_gateway': '', 'assignment_group': '', 'managed_by_group': '', 'can_hub': 'false', 'sys_id': '145f7e7a07102010d42af03c7c1ed06f', 'po_number': '', 'checked_in': '', 'sys_class_path': '/!!/!2/!!/!,', 'mac_address': '', 'company': '', 'justification': '', 'department': '', 'snmp_sys_location': '', 'comments': '', 'cost': '', 'sys_mod_count': '1', 'monitor': 'false', 'ip_address': '192.168.51.51', 'model_id': '80af727a07102010d42af03c7c1ed0e3', 'duplicate_of': '', 'sys_tags': '', 'cost_cc': 'USD', 'discovery_proto_type': '', 'order_date': '', 'schedule': '', 'environment': 'production', 'due': '', 'attested': 'false', 'location': '', 'category': 'Hardware', 'fault_count': '0', 'lease_id': ''}) 
skipping: [localhost] => (item={'attested_date': '', 'can_switch': 'false', 'stack': 'false', 'operational_status': 'operational', 'cpu_manufacturer': '', 'sys_updated_on': '2021-04-22 14:08:48', 'discovery_source': '', 'first_discovered': '', 'due_in': '', 'can_partitionvlans': 'false', 'gl_account': '', 'invoice_number': '', 'sys_created_by': 'admin', 'ram': '', 'warranty_expiration': '', 'cpu_speed': '', 'owned_by': '', 'checked_out': '', 'firmware_manufacturer': '', 'disk_space': '', 'sys_domain_path': '/', 'discovery_proto_id': '', 'maintenance_schedule': '', 'cost_center': '', 'attested_by': '', 'dns_domain': '', 'assigned': '', 'purchase_date': '', 'short_description': '2nd lab switch', 'managed_by': '', 'range': '', 'firmware_version': '', 'can_print': 'false', 'last_discovered': '', 'ports': '', 'sys_class_name': 'cmdb_ci_ip_switch', 'cpu_count': '1', 'manufacturer': 'b7e831bdc0a80169015ae101f3c4d6cd', 'vendor': '', 'can_route': 'false', 'model_number': '3550', 'assigned_to': '', 'start_date': '', 'bandwidth': '', 'serial_number': '222', 'support_group': '', 'correlation_id': '', 'unverified': 'false', 'attributes': '', 'asset': '0d81877607102010d42af03c7c1ed0e9', 'skip_sync': 'false', 'device_type': '', 'attestation_score': '', 'sys_updated_by': 'admin', 'sys_created_on': '2020-11-09 16:45:14', 'cpu_type': '', 'sys_domain': 'global', 'install_date': '', 'asset_tag': 'P1000612', 'hardware_substatus': '', 'fqdn': '', 'stack_mode': '', 'change_control': '', 'internet_facing': 'true', 'physical_interface_count': '', 'delivery_date': '', 'hardware_status': 'installed', 'channels': '', 'install_status': 'installed', 'supported_by': '', 'name': 'sw2', 'subcategory': 'IP', 'default_gateway': '', 'assignment_group': '', 'managed_by_group': '', 'can_hub': 'false', 'sys_id': '5a61877607102010d42af03c7c1ed0f3', 'po_number': '', 'checked_in': '', 'sys_class_path': '/!!/!2/!!/!,', 'mac_address': '', 'company': '', 'justification': '', 'department': '', 'snmp_sys_location': '', 'comments': '', 'cost': '', 'sys_mod_count': '1', 'monitor': 'false', 'ip_address': '192.168.51.52', 'model_id': '80af727a07102010d42af03c7c1ed0e3', 'duplicate_of': '', 'sys_tags': '', 'cost_cc': 'USD', 'discovery_proto_type': '', 'order_date': '', 'schedule': '', 'environment': 'production', 'due': '', 'attested': 'false', 'location': '', 'category': 'Hardware', 'fault_count': '0', 'lease_id': ''}) 
changed: [localhost] => (item={'attested_date': '', 'can_switch': 'false', 'stack': 'false', 'operational_status': 'operational', 'cpu_manufacturer': '', 'sys_updated_on': '2021-04-21 17:44:42', 'discovery_source': '', 'first_discovered': '', 'due_in': '', 'can_partitionvlans': 'false', 'gl_account': '', 'invoice_number': '', 'sys_created_by': 'admin', 'ram': '', 'warranty_expiration': '', 'cpu_speed': '', 'owned_by': '', 'checked_out': '', 'firmware_manufacturer': '', 'disk_space': '', 'sys_domain_path': '/', 'discovery_proto_id': '', 'maintenance_schedule': '', 'cost_center': '', 'attested_by': '', 'dns_domain': '', 'assigned': '', 'purchase_date': '', 'short_description': '3rd lab switch', 'managed_by': '', 'range': '', 'firmware_version': '', 'can_print': 'false', 'last_discovered': '', 'ports': '', 'sys_class_name': 'cmdb_ci_ip_switch', 'cpu_count': '1', 'manufacturer': 'b7e831bdc0a80169015ae101f3c4d6cd', 'vendor': '', 'can_route': 'false', 'model_number': '3550', 'assigned_to': '', 'start_date': '', 'bandwidth': '', 'serial_number': '333', 'support_group': '', 'correlation_id': '', 'unverified': 'false', 'attributes': '', 'asset': '514aea5f07632010d42af03c7c1ed010', 'skip_sync': 'false', 'device_type': '', 'attestation_score': '', 'sys_updated_by': 'admin', 'sys_created_on': '2021-04-21 17:44:42', 'cpu_type': '', 'sys_domain': 'global', 'install_date': '', 'asset_tag': 'P1000613', 'hardware_substatus': '', 'fqdn': '', 'stack_mode': '', 'change_control': '', 'internet_facing': 'true', 'physical_interface_count': '', 'delivery_date': '', 'hardware_status': 'installed', 'channels': '', 'install_status': 'installed', 'supported_by': '', 'name': 'sw3', 'subcategory': 'IP', 'default_gateway': '', 'assignment_group': '', 'managed_by_group': '', 'can_hub': 'false', 'sys_id': '954aea5f07632010d42af03c7c1ed00f', 'po_number': '', 'checked_in': '', 'sys_class_path': '/!!/!2/!!/!,', 'mac_address': '', 'company': '', 'justification': '', 'department': '', 'snmp_sys_location': '', 'comments': '', 'cost': '', 'sys_mod_count': '0', 'monitor': 'false', 'ip_address': '192.168.51.53', 'model_id': '80af727a07102010d42af03c7c1ed0e3', 'duplicate_of': '', 'sys_tags': '', 'cost_cc': 'USD', 'discovery_proto_type': '', 'order_date': '', 'schedule': '', 'environment': 'production', 'due': '', 'attested': 'false', 'location': '', 'category': 'Hardware', 'fault_count': '0', 'lease_id': ''})
TASK [sw3 didn't already exist, so create it] **********************************
skipping: [localhost]
TASK [If sw4 already exists, update it's configuration] ************************
skipping: [localhost] => (item={'attested_date': '', 'can_switch': 'false', 'stack': 'false', 'operational_status': 'operational', 'cpu_manufacturer': '', 'sys_updated_on': '2021-04-22 14:08:44', 'discovery_source': '', 'first_discovered': '', 'due_in': '', 'can_partitionvlans': 'false', 'gl_account': '', 'invoice_number': '', 'sys_created_by': 'admin', 'ram': '', 'warranty_expiration': '', 'cpu_speed': '', 'owned_by': '', 'checked_out': '', 'firmware_manufacturer': '', 'disk_space': '', 'sys_domain_path': '/', 'discovery_proto_id': '', 'maintenance_schedule': '', 'cost_center': '', 'attested_by': '', 'dns_domain': '', 'assigned': '', 'purchase_date': '', 'short_description': '1st lab switch', 'managed_by': '', 'range': '', 'firmware_version': '', 'can_print': 'false', 'last_discovered': '', 'ports': '', 'sys_class_name': 'cmdb_ci_ip_switch', 'cpu_count': '1', 'manufacturer': 'b7e831bdc0a80169015ae101f3c4d6cd', 'vendor': '', 'can_route': 'false', 'model_number': '3550', 'assigned_to': '', 'start_date': '', 'bandwidth': '', 'serial_number': '111', 'support_group': '', 'correlation_id': '', 'unverified': 'false', 'attributes': '', 'asset': '48af32ba07102010d42af03c7c1ed03b', 'skip_sync': 'false', 'device_type': 'switch', 'attestation_score': '', 'sys_updated_by': 'admin', 'sys_created_on': '2020-11-09 16:36:58', 'cpu_type': '', 'sys_domain': 'global', 'install_date': '', 'asset_tag': 'P1000611', 'hardware_substatus': '', 'fqdn': '', 'stack_mode': '', 'change_control': '', 'internet_facing': 'true', 'physical_interface_count': '', 'delivery_date': '', 'hardware_status': 'installed', 'channels': '', 'install_status': 'installed', 'supported_by': '', 'name': 'sw1', 'subcategory': 'IP', 'default_gateway': '', 'assignment_group': '', 'managed_by_group': '', 'can_hub': 'false', 'sys_id': '145f7e7a07102010d42af03c7c1ed06f', 'po_number': '', 'checked_in': '', 'sys_class_path': '/!!/!2/!!/!,', 'mac_address': '', 'company': '', 'justification': '', 'department': '', 'snmp_sys_location': '', 'comments': '', 'cost': '', 'sys_mod_count': '1', 'monitor': 'false', 'ip_address': '192.168.51.51', 'model_id': '80af727a07102010d42af03c7c1ed0e3', 'duplicate_of': '', 'sys_tags': '', 'cost_cc': 'USD', 'discovery_proto_type': '', 'order_date': '', 'schedule': '', 'environment': 'production', 'due': '', 'attested': 'false', 'location': '', 'category': 'Hardware', 'fault_count': '0', 'lease_id': ''}) 
skipping: [localhost] => (item={'attested_date': '', 'can_switch': 'false', 'stack': 'false', 'operational_status': 'operational', 'cpu_manufacturer': '', 'sys_updated_on': '2021-04-22 14:08:48', 'discovery_source': '', 'first_discovered': '', 'due_in': '', 'can_partitionvlans': 'false', 'gl_account': '', 'invoice_number': '', 'sys_created_by': 'admin', 'ram': '', 'warranty_expiration': '', 'cpu_speed': '', 'owned_by': '', 'checked_out': '', 'firmware_manufacturer': '', 'disk_space': '', 'sys_domain_path': '/', 'discovery_proto_id': '', 'maintenance_schedule': '', 'cost_center': '', 'attested_by': '', 'dns_domain': '', 'assigned': '', 'purchase_date': '', 'short_description': '2nd lab switch', 'managed_by': '', 'range': '', 'firmware_version': '', 'can_print': 'false', 'last_discovered': '', 'ports': '', 'sys_class_name': 'cmdb_ci_ip_switch', 'cpu_count': '1', 'manufacturer': 'b7e831bdc0a80169015ae101f3c4d6cd', 'vendor': '', 'can_route': 'false', 'model_number': '3550', 'assigned_to': '', 'start_date': '', 'bandwidth': '', 'serial_number': '222', 'support_group': '', 'correlation_id': '', 'unverified': 'false', 'attributes': '', 'asset': '0d81877607102010d42af03c7c1ed0e9', 'skip_sync': 'false', 'device_type': '', 'attestation_score': '', 'sys_updated_by': 'admin', 'sys_created_on': '2020-11-09 16:45:14', 'cpu_type': '', 'sys_domain': 'global', 'install_date': '', 'asset_tag': 'P1000612', 'hardware_substatus': '', 'fqdn': '', 'stack_mode': '', 'change_control': '', 'internet_facing': 'true', 'physical_interface_count': '', 'delivery_date': '', 'hardware_status': 'installed', 'channels': '', 'install_status': 'installed', 'supported_by': '', 'name': 'sw2', 'subcategory': 'IP', 'default_gateway': '', 'assignment_group': '', 'managed_by_group': '', 'can_hub': 'false', 'sys_id': '5a61877607102010d42af03c7c1ed0f3', 'po_number': '', 'checked_in': '', 'sys_class_path': '/!!/!2/!!/!,', 'mac_address': '', 'company': '', 'justification': '', 'department': '', 'snmp_sys_location': '', 'comments': '', 'cost': '', 'sys_mod_count': '1', 'monitor': 'false', 'ip_address': '192.168.51.52', 'model_id': '80af727a07102010d42af03c7c1ed0e3', 'duplicate_of': '', 'sys_tags': '', 'cost_cc': 'USD', 'discovery_proto_type': '', 'order_date': '', 'schedule': '', 'environment': 'production', 'due': '', 'attested': 'false', 'location': '', 'category': 'Hardware', 'fault_count': '0', 'lease_id': ''}) 
skipping: [localhost] => (item={'attested_date': '', 'can_switch': 'false', 'stack': 'false', 'operational_status': 'operational', 'cpu_manufacturer': '', 'sys_updated_on': '2021-04-21 17:44:42', 'discovery_source': '', 'first_discovered': '', 'due_in': '', 'can_partitionvlans': 'false', 'gl_account': '', 'invoice_number': '', 'sys_created_by': 'admin', 'ram': '', 'warranty_expiration': '', 'cpu_speed': '', 'owned_by': '', 'checked_out': '', 'firmware_manufacturer': '', 'disk_space': '', 'sys_domain_path': '/', 'discovery_proto_id': '', 'maintenance_schedule': '', 'cost_center': '', 'attested_by': '', 'dns_domain': '', 'assigned': '', 'purchase_date': '', 'short_description': '3rd lab switch', 'managed_by': '', 'range': '', 'firmware_version': '', 'can_print': 'false', 'last_discovered': '', 'ports': '', 'sys_class_name': 'cmdb_ci_ip_switch', 'cpu_count': '1', 'manufacturer': 'b7e831bdc0a80169015ae101f3c4d6cd', 'vendor': '', 'can_route': 'false', 'model_number': '3550', 'assigned_to': '', 'start_date': '', 'bandwidth': '', 'serial_number': '333', 'support_group': '', 'correlation_id': '', 'unverified': 'false', 'attributes': '', 'asset': '514aea5f07632010d42af03c7c1ed010', 'skip_sync': 'false', 'device_type': '', 'attestation_score': '', 'sys_updated_by': 'admin', 'sys_created_on': '2021-04-21 17:44:42', 'cpu_type': '', 'sys_domain': 'global', 'install_date': '', 'asset_tag': 'P1000613', 'hardware_substatus': '', 'fqdn': '', 'stack_mode': '', 'change_control': '', 'internet_facing': 'true', 'physical_interface_count': '', 'delivery_date': '', 'hardware_status': 'installed', 'channels': '', 'install_status': 'installed', 'supported_by': '', 'name': 'sw3', 'subcategory': 'IP', 'default_gateway': '', 'assignment_group': '', 'managed_by_group': '', 'can_hub': 'false', 'sys_id': '954aea5f07632010d42af03c7c1ed00f', 'po_number': '', 'checked_in': '', 'sys_class_path': '/!!/!2/!!/!,', 'mac_address': '', 'company': '', 'justification': '', 'department': '', 'snmp_sys_location': '', 'comments': '', 'cost': '', 'sys_mod_count': '0', 'monitor': 'false', 'ip_address': '192.168.51.53', 'model_id': '80af727a07102010d42af03c7c1ed0e3', 'duplicate_of': '', 'sys_tags': '', 'cost_cc': 'USD', 'discovery_proto_type': '', 'order_date': '', 'schedule': '', 'environment': 'production', 'due': '', 'attested': 'false', 'location': '', 'category': 'Hardware', 'fault_count': '0', 'lease_id': ''}) 
TASK [sw4 didn't already exist, so create it] **********************************
changed: [localhost]
PLAY RECAP *********************************************************************
localhost                  : ok=10   changed=4    unreachable=0    failed=0    skipped=4    rescued=0    ignored=0

This doesn’t format super well, but you can see the changed options for each one.

Here’s the view after the run:

So my existing devices were updated and new devices were added.

Conclusion

So this isn’t earth shattering, but could be useful if you need to do a one-time or perhaps a regular CMDB update/sync from another system. AAP could pull the CMDB entries from one system, then push them into SNOW. Let me know if you have any questions or comments and happy automating.