Ansible Random String Generator

To minimize configuration drift we can’t directly log into a system with admin privileges. Root is disabled through SSH and console on both servers and workstations. We can’t even directly log into a prod server at all. Every admin level task is done through Tower. Because of this, having a root password that’s usable and remember-able is essentially pointless (and insecure anyway).

I created an Ansible module to generate a random string based on a size parameter. This way any time the provisioning playbook is run against a system it will generate a new random password for the root user. If for some reason we need to triage a system, we can grant local admin access through tower for that time and then revoke it later so it’s audited.

Here’s the important bits of the module:

import string
import random 
from ansible.module_utils.basic import AnsibleModule

def random_generator(size, chars=string.ascii_letters + string.digits + '$#&@'):
    return ''.join(random.choice(chars) for _ in range(size))

module = AnsibleModule(
    argument_spec = dict(
    size = dict(required=True, type='int')
size = module.params.get('size')

    success = True
    ret_msg = str(random_generator(size))
except KeyError:
   success = False
   ret_msg = "Error"

if success:

if __name__ == "__main__":

Here’s an example playbook. Obviously in prod you wouldn’t have it display the string, this is just as an example.

- name: generate password 
    size: 40
  register: pass

- name: print password [not in production]
    var: pass

- name: set root password
    name: root
    password: "{{ pass.msg|password_hash('sha512') }}"

And here’s the output from a playbook run:


Another option is to use Jinja filters so you don’t need to create a module (I was doing it for practice). This way you just need to pass something into the password_hash filter. Here’s an example:

- name: generate random password
    name: root
    password: "{{ ansible_fqdn | password_hash('sha512') | password_hash('sha512') }}"

This will take the value for ansible_fqdn and pass it into the sha512 hash filter. This gives you a random 107 character password. Then it passes that string into the sha512 hash filter again to actually set the hash to that value.