Like in my previous post in the new development version 2.2. from Ansible are new IOS and ASA core modules.
Here an example of the asa_config and asa_acl module to create and object-group in the first step and create the inside create access-list:
- name: Cisco ASA access-list config connection: local hosts: firewall gather_facts: false vars: cli: username: "{{ username }}" password: "{{ password }}" host: "{{ device_ip }}" authorize: yes auth_pass: cisco tasks: - name: create object group asa_config: lines: - network-object host 10.1.0.1 - network-object host 10.1.0.2 - network-object host 10.1.0.3 parents: ['object-group network dummy-group'] provider: "{{ cli }}" # register: result - name: configure access-list asa_acl: lines: - access-list acl_inside extended permit tcp object-group dummy-group any eq www - access-list acl_inside extended permit udp object-group dummy-group any eq domain - access-list acl_inside extended deny ip any any before: clear configure access-list acl_inside match: strict replace: block provider: "{{ cli }}" # register: result - debug: var=result
Here output when you run the playbook the first time:
ansible-playbook cisco/asa_access-list_config.yml -i cisco/hosts PLAY [Cisco ASA access-list config] ******************************************** TASK [create object group] ***************************************************** changed: [fw1] TASK [configure access-list] *************************************************** changed: [fw1] TASK [debug] ******************************************************************* ok: [fw1] => { "result": "VARIABLE IS NOT DEFINED!" } PLAY RECAP ********************************************************************* fw1 : ok=3 changed=2 unreachable=0 failed=0
Here the output then you run the playbook a second time, you see nothing is changed:
ansible-playbook cisco/asa_access-list_config.yml -i cisco/hosts PLAY [Cisco ASA access-list config] ******************************************** TASK [create object group] ***************************************************** ok: [fw1] TASK [configure access-list] *************************************************** ok: [fw1] TASK [debug] ******************************************************************* ok: [fw1] => { "result": "VARIABLE IS NOT DEFINED!" } PLAY RECAP ********************************************************************* fw1 : ok=3 changed=0 unreachable=0 failed=0
Read my new post about an Ansible Playbook for Cisco ASAv Firewall Topology
First thank you for post this works great!
Do you have any suggestions how to update multiple object-groups in asa with single playbook?
tasks:
– name: create object group
asa_config:
lines:
– network-object host 10.1.0.1
– network-object host 10.1.0.2
– network-object host 10.1.0.3
parents: [‘object-group network dummy-group’]
provider: “{{ cli }}”
# register: result
so this works ok for: object-group network dummy-group, but if i have another one that i would like to update, how would the format be?
For example:
tasks:
– name: create object group
asa_config:
lines:
– network-object host 10.1.0.1
– network-object host 10.1.0.2
– network-object host 10.1.0.3
parents: [‘object-group network dummy-group’]
– network-object host 192.168.0.1
– network-object host 192.168.0.2
parents: [‘object-group network dummy-group2’]
Thank you!
Eimis
Hi Eimis,
I was working on a complete Ansible Playbook for a Cisco ASA, is actually my next blog post I am currently working on, will publish it beginning of next week.
But you can have a look already at the my Github repo for this post:
https://github.com/berndonline/asa-lab-provision
For creating objects and object-groups I use a Jinja2 template instead of lines:
– name: include objects variables
include_vars:
file: “group_vars/objects.yml”
– name: create objects
asa_config:
src: “templates/objects.j2”
Jinja2 template objects.j2:
{% if objects is defined %}
{% for object, value in objects.items() %}
object network {{ object }}
{% if value and ‘host’ in value %}
host {{ value[‘host’] }}
{% endif %}
{% if value and ‘subnet’ in value %}
subnet {{ value[‘subnet’] }} {{ value[‘mask’] }}
{% endif %}
{% if ‘alias’ in value %}
description {{ value.alias }}
{% endif %}
{% endfor %}
{% endif %}
Have a look at my repo and come back next week when I am finished with my new post.
Best,
Bernd
Awesome Thank you for reply, looking forward!
Hi Eimis,
I published my new post about an Ansible Playbook for Cisco ASAv Firewall Topology, check it out.
Best,
Bernd
Hi Bernd,
Thank you very much for sharing!
Regards
Eimis
Hi!
Thanks for the example above works nicely. I’m trying to create a local username task, but I keep getting an error. Can you help me out on this one? here’s example:
—
– name: Cisco ASA access-list config
connection: local
hosts: firewall
gather_facts: false
vars:
cli:
host: 192.168.0.99
authorize: yes
auth_pass: xxxxxx
tasks:
– name: create local user
asa_config:
lines:
– username test password testing privilege 15
provider: “{{ cli }}”
#
register: print_output
– debug: var=print_output
I’m passing my ssh creds as arguments.
Thanks!
Fabian
Hi Fabian,
Ansible works a bit differently you should have a separate inventory file when you run a playbook. You can also group your devices in the inventory file if needed but there is no need to have the credentials in the inventory is just something what I do because of Ansible Vault to encrypt the inventory file.
Here an example inventory:
Here your playbook to create a user account:
Now just execute the playbook:
I hope that helps you to continue?
Best,
Bernd
Thank you for your help Bernd! Works good now.
Hi Bernd,
Thank you for replies and suggestions, have another question maybe you already have a playbook for it that would be great, for example modify class-map etc., if i have multiline update to class-map etc., it fails for me, here is examples of lines i need to execute,
“` – access-list global_mpc_1 line 1 extended deny ip any object-group Internal-Networks
– access-list global_mpc_1 line 2 extended permit ip any any
– class-map sfr
– match access-list global_mpc_1
– policy-map global_policy
– no description sfr
– class sfr
– sfr fail-open
“`
simple stuff like multiline access-list modifications i can those to work, but something more advanced when you enter into class-maps etc., wont seem to execute the rest of the commands, i am guessing ansible thinks its still on main conf t line.
thanks again!
Hello Eimis,
Updating multi line class maps for access lists is a problem I also faced. I never really got this to work with the older ansible versions (2.4.x).
Here is a role I have written for various policyframe work configuration but doesn’t really work replacing multi line objects:
https://github.com/berndonline/asa-lab-provision/blob/master/roles/policy-framework/tasks/main.yml
I have not tried it since then and the ansible asa network module might be not the right way and use instead the REST API of the ASA.
But if you find a way please let me know I am very interested getting this working.
Best,
Bernd
Hi Bernd,
I am running ansible 2.9.27. According to https://docs.ansible.com/ansible/2.9/modules/asa_config_module.html one should use connection: network_cli instead of the old provider object.
So this is my task:
– name: Create VLAN interface
asa_config:
match: line
parents:
– Interface GigabitEthernet0/2.{{ vlan }}
lines:
– description {{ short }}
– vlan {{ vlan }}
– nameif {{ short }}
– security-level 10
– ip address 172.27.{{ vlan }}.3 255.255.255.0
(ansible_connection: network_cli is located in group_vars)
When I run my playbook twice, I always get changed=1. The reason is located here: /usr/lib/python2.7/dist-packages/ansible/modules/network/asa/asa_config.py
# send the configuration commands to the device and merge
# them with the current running config
if not module.check_mode:
load_config(module, commands)
result[‘changed’] = True
(ANSIBLE_METADATA = {‘metadata_version’: ‘1.1’,’status’: [‘preview’],’supported_by’: ‘community’})
Why wasn’t this the case in your situation?
Best regards,
Lukas
Hi Lukas,
Sorry I can’t remember this, I haven’t used Ansible for a couple of years and the modules over time have changed quite a lot.
Good luck finding a config which hopefully works.
Take care,
Bernd