I have a simple ACL for a Cisco router. I cannot figure out how to make the playbook idempotent. It always detects a change.
- name: Create new vty acl
cisco.ios.ios_config:
lines:
- 5 permit tcp 172.16.0.0 0.15.255.255 any eq 22
parents: ip access-list extended vty-acl-in
before: no ip access-list extended vty-acl-in
match: exact
replace: block
[WARNING]: ansible-pylibssh not installed, falling back to paramiko
redirecting (type: action) cisco.ios.ios_config to cisco.ios.ios
[WARNING]: To ensure idempotency and correct diff the input configuration lines should be similar to how they appear if present in the running configuration on device
changed: [rtr2] => {“banners”: {}, “changed”: true, “commands”: [“no ip access-list extended vty-acl-in”, “ip access-list extended vty-acl-in”, “5 permit tcp 172.16.0.0 0.15.255.255 any eq 22”], “updates”: [“no ip access-list extended vty-acl-in”, “ip access-list extended vty-acl-in”, “5 permit tcp 172.16.0.0 0.15.255.255 any eq 22”]}
sh ver
Cisco IOS Software, Linux Software (I86BI_LINUX-ADVENTERPRISEK9-M), Version 15.4(1)T, DEVELOPMENT TEST SOFTWARE
Technical Support: Support - Cisco Support and Downloads – Documentation, Tools, Cases - Cisco
Copyright (c) 1986-2013 by Cisco Systems, Inc.
Compiled Sat 23-Nov-13 03:28 by prod_rel_team
Something that comes to mind when looking at your playbook snip here is that you are specifying a before action to remove the ACL and then implement it. Ansible may be detecting that as a change, since inherently it is changing something.
Furthermore,
Have you tried to implement this ACL using the cisco.ios.ios_aclsl module, instead of the cisco.ios.ios_config module? The ACL module can be found here.
At the bottom of the module, before the examples section, there is a “state” section, which specifies how ansible should treat implementing it’s config:
Hey @Jonathan thanks for looking at my issue. I’ve tried the acl module and the config module and still no lucky. I tried your code with the standard acl and it’s still saying changed on subsequent runs of the play. This other forum post said to include the before: no acl format but that doesn’t work for me either? https://github.com/ansible/ansible/issues/47067
So I tried running the apparent “fix” in the github post, and it seemed to make things worse.
Here is the code for reference:
- name: ACL Playbook to test idempotency
hosts: LAB
#serial: 1
gather_facts: no
vars:
Ansible_test:
- "10 permit 10.10.1.0 0.0.0.255"
- "15 permit 10.10.80.0 0.0.0.255"
- "20 deny any log"
tasks:
- name: Configure test ACL
cisco.ios.ios_config:
lines: "{{ Ansible_test }}"
parents: ip access-list standard Ansible-test
match: line
replace: block
before: no ip access-list standard Ansible-test
register: result
Before I ran the playbook as written above, the first of my switches in my lab would always come back as “ok” (i.e not changed). Now when running this version of the playbook I get all three switches firing off as “changed”.
I can confirm that when I ran my version, Ansible did register the “before: no ip access-list standard Ansible-test” did register as a change when I viewed the results using very very very very verbose mode -vvvv on my playbook run.
More to follow I’m sure…
This may be related to what version of IOS you/we are running, here is a list of the versions in my lab below:
Just got the github example play to be idempotent with a virtual router IOSv 15.9(3)M6. I am still trying to make it work for extended acls though. The difference being standard acls can have the acl name and rule in one line vs the extended acl declares the acl name then you go into the sub-config of that acl and declare your aces.
- name: "Ensure access_list mgmt_acl_90"
ios_config:
save_when: "modified"
lines:
- "access-list 90 permit 172.16.0.0 0.3.255.255"
match: line
replace: block
before: "no access-list 90"
register: result
I tried using the “diff_ignore_lines” option with no success,
diff_ignore_lines: [ "no ip access-list extended vty-acl", "ip access-list extended vty-acl"]
Extended ACL play with ios_acls module, not idempotent,
Extended ACL play with config module, not idempotent,
- name: load new acl into device
ios_config:
lines:
- 10 permit tcp 172.16.0.0 0.3.255.255 any eq 22
parents: ip access-list extended test
before: no ip access-list extended test
match: exact
Tried several permutations of the following to get extended acl to be idempotent,
- name: load new acl into device
ios_config:
lines:
- 10 permit tcp 172.16.0.0 0.3.255.255 any eq 22
parents: ip access-list extended test
before: no ip access-list extended test
match: line
diff_ignore_lines: ["no ip access-list extended test"]
diff_against: running
The verbose output seems like it should ignore but it’s not?