Automate IOS device local password change

Hey all,

I just wanted to share a playbook that I found entirely too useful recently. The playbook generates a new unique 16 char ascii password (it does this for each device in the host file), and then the playbook uses the cisco.ios.ios_user module to update the local username and password with the newly generated password.

After that is done, the password is written to the correct “{{inventory_hostname}}:vars” section of the host file and the value “ansible_password” is searched for and changed.

The new password is then also written to a file under the hostname of the IOS device in the host_vars directory as a precautionary measure, as I found there were always a few instances where the password would be changed, added to it’s respective file in the host_vars directory, but not updated in the host.ini file.

---
- name: Updates each IOS device with unique 16 char ascii password. 

  gather_facts: no

  vars_prompt:
    - name: hosts 
      prompt: "Which group should we run the playbook against?"
      private: no
      default: LAB
#    - name: "ansible_user"
#      prompt: "Enter your username"
#      private: no
#    - name: "ansible_password"
#      prompt: "Enter your password"
#      private: yes

  hosts: "{{hosts}}"

  tasks:

   - name: Runs show run | section username and stores the output in a variable called 'user_account' for later use.
     cisco.ios.command:
      commands:
        - show run | sec user
     register: user_account
     
   - name: Get only the standard output in position zero of the output
     set_fact:
       second_line: "{{ user_account.stdout_lines[0] }}"

   - name: Generate a new 16 character ascii password and store that password in the var 'new_password'.
     set_fact:
       new_password: "{{ lookup('password', '/dev/null length=24 chars=ascii_letters+digits!@#$%&()/') }}"

   - name: Change the password of the local admin accounts and use the new password in the var 'new_password'. 
     cisco.ios.ios_user:
      name: administrator
      configured_password: "{{new_password}}"
      password_type: secret
      update_password: always
      state: present

   - name: Update the host.ini file with the newly generated password.
     ansible.builtin.ini_file:
        path: "YOUR/PATH"
        section: "{{inventory_hostname}}:vars"
        option: "ansible_password"
        value: "{{new_password}}"
   
   - name: Save the newly configured password to a local .txt file as a precaution for it not getting written to the host.ini file correctly. 
     local_action:
       module: lineinfile
       dest: "../host_vars/LAB/{{inventory_hostname}}.yaml"
       create: yes
       line: "{{inventory_hostname}} new administrator password is: {{new_password}}\n"
       

I hope this playbook is useful to somebody out there!