Building an ansible job to run customized CLI configurations

So, I’m new to ansible, and I’m hoping to find ways to meet a customize-able CLI deployment scenario, where 99% of the commands are the same across devices, but a handful will be unique.

I was originally thinking about using a single response file would cover the 99% (in my example I’m trying to configure multiple ProxySG’s at the same time).

There are really two unknowns here (possibly 3).

The first:

I need to configure 3 network interfaces across 12 devices, all having a different IP’s and subnet masks. Is there a way to sequentially pull this from a list lets say I have response files like:

interface 1 list

10.0.0.100 - coordinates to the first device
10.0.0.101
etc

interface 2 list
10.0.1.100
10.0.1.101

or what would be the best way to accomplish this kind of task.

The second:

I’d like for obvious reasons, not store passwords in the playbook

If I added something like this:

vars_prompt:

  • name: ‘enable_password’
    prompt: ‘Enable password:’
    private: yes
    encrypt: ‘sha512_crypt’
    confirm: yes
    salt_size: 7

how would I use this in the script. After I ssh into the device I would need to type a password for the enable which is what i’m trying to then present through the script in a secure way.

Finally, I guess is there anything special I would need to properly use a cli configuration separate from linux installation playbooks?

Thanks in advance!

So, I'm new to ansible, and I'm hoping to find ways to meet a
customize-able CLI deployment scenario, where 99% of the commands are the
same across devices, but a handful will be unique.

I was originally thinking about using a single response file would cover
the 99% (in my example I'm trying to configure multiple ProxySG's at the
same time).

There are really two unknowns here (possibly 3).

The first:

I need to configure 3 network interfaces across 12 devices, all having a
different IP's and subnet masks. Is there a way to sequentially pull this
from a list lets say I have response files like:

interface 1 list

10.0.0.100 - coordinates to the first device
10.0.0.101
etc

interface 2 list
10.0.1.100
10.0.1.101

or what would be the best way to accomplish this kind of task.

The information is a little sparse so it difficult to give a exact answer.
Ansible can loop over list and dictionary, and a combination of them.

Variables can be assign to host/device or to group, how you structure it depends on what you are trying to do.

The second:

I'd like for obvious reasons, not store passwords in the playbook

If I added something like this:

vars_prompt:
  - name: 'enable_password'
    prompt: 'Enable password:'
    private: yes
    encrypt: 'sha512_crypt'
    confirm: yes
    salt_size: 7

  how would I use this in the script. After I ssh into the device I would
need to type a password for the enable which is what i'm trying to then
present through the script in a secure way.

vars_prompt create a variable with the name you give in name: that contain the content.
You use is with {{ enable_password }} in Ansible.

Since you need to do this interactively you need to use the expect module.

So here’s an example:

enable

config terminal
appliance-name “proxy1

interface 0:0 ;mode
label “MGMT”
ip-address 10.0.0.100 255.255.255.0
exit

interface 1:0 ;mode
label “unused”
reject-inbound enable
disable
exit

interface 1:1 ;mode
label “VLAN TAG#”
ip-address 10.0.0.10 255.255.255.128
native-vlan #
exit

interface 2:0 ;mode
label “unused”
reject-inbound enable
disable
exit

interface 2:1 ;mode
label “VLAN TAG#”
ip-address 10.0.0.140 255.255.255.128
native-vlan #
exit

Now, obviously the items in bold are values that need to be customized in the ansible script. So I don’t think I can put this into the response file, unless I can somehow pass values into a response file for example:

NAME-file (list of 10 machine names)
MGMT-file (IP address the mgmt port)
if1:1-file (IP addresses of this interface)
if2:1-file (IP address of the third interface)

It was either that, or possibly figuring out a way to do a for loop style playbook where each loop would target the next machine in the list. Fortunately, the IP addresses for these devices are sequential.

One of the many methods is to scp or sftp the full config as a template to the device and save as startup or running config and reload it. Then you don’t need to muck around with as much expect logic.

I mean I guess I can build them all out and may be easier, however I was hoping to figure out this iterative process mostly because I’m looking at rolling out somewhere around 100 appliances across the globe (not just proxySG), that will all need similar interface tweaks.

Just to make it easy to explain I assume that you only have one prompt, the only different when prompt is different is that you need to split the list in smaller ones.

The principal of expect is like this
- expect:
    command: a-command
    reponses:
      prompt1/question:
        - answer 1
        - answer 2
        ...

so the prompt just take a list, this can be built before the expect command.

vars:
  dynmatic_responds:
    - <password>
    - <proxy>
    - 10.0.0.100
    - 10.0.0.10
    - 10.0.0.140
  response:
    - enable
    - '{{ dynmatic_responds.0 }}'
    - config terminal
    - appliance-name "{{ dynmatic_responds.1 }}"
    - interface 0:0 ;mode
    - label "MGMT"
    - ip-address {{ dynmatic_responds.2 }} 255.255.255.0
    - exit
    - interface 1:0 ;mode
    - label "unused"
    - reject-inbound enable
    - disable
    - exit
    - interface 1:1 ;mode
    - label "VLAN TAG#"
    - ip-address {{ dynmatic_responds.3 }} 255.255.255.128
    - native-vlan #
    - exit
    - interface 2:0 ;mode
    - label "unused"
    - reject-inbound enable
    - disable
    - exit
    - interface 2:1 ;mode
    - label "VLAN TAG#"
    - ip-address {{ dynmatic_responds.4 }} 255.255.255.128
    - native-vlan #
    - exit

So the task would be
    reponses:
      prompt1/question: {{ response }}
        
This is just and example of how it could be done, I would find a way to make it even more dynamic.
But here you have the skeleton in responses and each device would have a uniq dynmatic_responds.

Hopefully this give you an idea of how this could be done.