TASK [Set fact whether VLAN exists] ************************************************************************************************************************************************** fatal: [switch-01]: FAILED! => {"msg": "template error while templating string: Could not load \"search\": 'search'. String: {{ vlan_output.stdout | search('VLAN\\\\s+' + VLAN + '\\\\s+') is not none }}. Could not load \"search\": 'search'"}
Thank you for the correction. But script only skipping a host where the VLAN is and proceeds to one that do not have. I need it to abort executing on another device if one of the host already has the VLAN`ansible-playbook add-vlan.yml -i inventory
Enter VLAN ID to add: 54
Enter VLAN ID Name: VID-54-TEST
PLAY [Gather VLAN facts from Cisco devices] ******************************************************************************************************************************************
TASK [Check if VLAN exists] **********************************************************************************************************************************************************
fatal: [switch-02]: FAILED! => {“changed”: false, “msg”: "show vlan id 54\r\r\nVLAN 54 not found in current VLAN database\r\n\r\n\r\n\rswitch# "}
ok: [switch-01]
TASK [Debug vlan_output variable] ****************************************************************************************************************************************************
ok: [switch-01] => {
“vlan_output”: {
“changed”: false,
“failed”: false,
“stdout”: [
“VLAN Name Status Ports\n---- -------------------------------- --------- -------------------------------\n54 VLAN0054 active \n\nVLAN Type Vlan-mode\n---- ----- ----------\n54 enet CE \n\nRemote SPAN VLAN\n----------------\nDisabled \n\nPrimary Secondary Type Ports\n------- --------- --------------- -------------------------------------------”
“stdout_lines”: [
“VLAN Name Status Ports”,
“---- -------------------------------- --------- -------------------------------”,
"54 VLAN0054 active ",
“VLAN Type Vlan-mode”,
“---- ----- ----------”,
"54 enet CE ",
“Remote SPAN VLAN”,
“----------------”,
"Disabled ",
“Primary Secondary Type Ports”,
“------- --------- --------------- -------------------------------------------”
TASK [Debug etherports variable] *****************************************************************************************************************************************************
ok: [switch-01] => {
“etherports”: [
“Ethernet1/20”,
“Ethernet1/15”
TASK [Set fact whether VLAN exists] **************************************************************************************************************************************************
ok: [switch-01]
TASK [Send notification if VLAN already exists] **************************************************************************************************************************************
ok: [switch-01]
TASK [End Play if VLAN exists] *******************************************************************************************************************************************************
skipping: [switch-01]
TASK [Debug vlan_output variable] ****************************************************************************************************************************************************
ok: [switch-02] => {
“vlan_output”: {
“changed”: false,
“failed”: true,
“msg”: "show vlan id 54\r\r\nVLAN 54 not found in current VLAN database\r\n\r\n\r\n\rswitch# "
TASK [Debug etherports variable] *****************************************************************************************************************************************************
ok: [switch-02] => {
“etherports”: [
“Ethernet1/24”,
“Ethernet1/25”
TASK [Adding VLAN ID to Database] ****************************************************************************************************************************************************
changed: [switch-02]
TASK [Merge provided configuration with device configuration] ************************************************************************************************************************
changed: [switch-02] => (item=Ethernet1/24)
changed: [switch-02] => (item=Ethernet1/25)
TASK [Send notification message via Mattermost if VLAN is added] *********************************************************************************************************************
ok: [switch-02]
PLAY RECAP ***************************************************************************************************************************************************************************
switch-01 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
switch-02 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0 `
Edited the snippet above. Not sure why the regex_search fails to find your vlan in the output, but we should already know it’s there when the first command succeeds right? I just removed the set_fact step and conditional on the end_play.
I think the issue with the regex_search was that successful output had ‘%04d’ padded the VLAN id: 54 VLAN0054 active
which is "{{ VLAN }} VLAN{{ '%04d' | format(VLAN) }} active"
in ansible.
So maybe try this if you want to continue double-checking the output.
- name: Set fact whether VLAN exists
vars:
search: ".*{{ VLAN }} VLAN{{ '%04d' | format(VLAN) }} active.*"
set_fact:
vlan_exists: "{{ vlan_output.stdout | regex_search(search)}}"
Getting below error. Tried to figure out but no success
TASK [Set fact whether VLAN exists] *****************************************************************************************************************************************************************
fatal: [switch-01]: FAILED! => {"msg": "An unhandled exception occurred while templating '.*{{ VLAN }} VLAN{{ '%04d' | format(VLAN) }} active.*'. Error was a <class 'ansible.errors.AnsibleError'>, original message: Unexpected templating type error occurred on (.*{{ VLAN }} VLAN{{ '%04d' | format(VLAN) }} active.*): %d format: a real number is required, not str. %d format: a real number is required, not str"}
fatal: [switch-02]: FAILED! => {"msg": "An unhandled exception occurred while templating '.*{{ VLAN }} VLAN{{ '%04d' | format(VLAN) }} active.*'. Error was a <class 'ansible.errors.AnsibleError'>, original message: Unexpected templating type error occurred on (.*{{ VLAN }} VLAN{{ '%04d' | format(VLAN) }} active.*): %d format: a real number is required, not str. %d format: a real number is required, not str"}
Cysco_Colloh:
VLAN{{ '%04d' | format(VLAN) }} active.*): %d format: a real number is required, not str. %d format: a real number is required, not str
And this is the documentation for the format
filter and that links to the printf
-style String Formatting documentation.
@chris I think it’s treating his VLAN as a string since he’s entering it through prompt, not as a var.
So: search: ".*{{ VLAN }} VLAN{{ '%04d' | format(VLAN|int) }} active.*"
should fix the typing.
That said, @Cysco_Colloh, it looks like VLAN0054
is the name field from the output? If that’s the case, it may be coincidence that it is “VLAN” + <0-padded-54>. Unless you can say with confidence that all of the names of your vlans are consistent (or even better, programmatic), then I can’t say my search string will be consistent.
On another note, while we have spent a lot of effort trying to help you achieve the process you’re going for, I can’t help but wonder if there’s an easier way to do all of this if you can change your approach.
Ansible is meant to be idempotent, where you can run the same playbook over and over again and never do the same thing twice. Obviously you want to do that with your vlans by making sure they’re unique to your switches. You could define the vlans in your host_vars for each switch, and then have the playbook only configure the vlans defined per switch. Depending on how many switches and vlans you have, that might be tedius, but at least then you would know the switches would get the vlans you want them to have. You could create the list of vlans you want first, gather facts about what vlans are there after they’re configured, and remove any extra vlans that weren’t in the original list (or at least notify you/network admins that there are ‘rogue’ vlans on a given switch).