Ansible random generated passwords

hey, my issue is this:
i can’t use any mysql modules for my playbook as we user also CentOs7 servers which are not compatible with those modules.

This is my role:

- name: Check if "{{ dbuser }}" user exists
  shell: "{{ check_user }}"
  register: db_user_exists
  ignore_errors: true
  changed_when: false
  failed_when: false

- name: Creates user for "{{ username | replace('.','_')}}_db"
  shell: "{{ create_user }}"
  when: db_user_exists.stdout == ""

- name: Grant privileges on "{{ db }}" to "{{ dbuser }}"
  shell: "{{ priv_user }}"
  when: db_user_exists.stdout == ""

- name: Flush privileges
  shell: "{{ flush_priv }}"
  when: db_user_exists.stdout == ""

And here are my vars inside the vars folder:

user_pass_gen: "{{ lookup('community.general.random_string', length=13, min_lower=1, min_upper=1, min_numeric=1, min_special=1, override_special='-_=+!#$()[]') }}"
dbuser: "{{ username | replace('.','_')}}_user"
SECRETPASS: "{{ lookup('file', '/XXX/XXX/XXX') }}"
check_user: mysql -u XXX_db -p"{{ pass }}" -e "SELECT user FROM mysql.user WHERE user = '{{ dbuser }}';"
create_user: mysql -u XXX_XX -p"{{ pass }}" -e "CREATE USER {{ dbuser }}@localhost IDENTIFIED BY '{{ user_pass_gen }}';" 2>/dev/null
priv_user: mysql -u XXX_XX -p"{{ pass }}" -e "GRANT ALL PRIVILEGES ON {{ username | replace('.','_')}}_db.* TO '{{ dbuser}}'@'localhost';" 2>/dev/null
flush_priv: mysql -u XXX_XX -p"{{ pass }}" -e "flush privileges;"

At the end, a db and user are created, and I see the password of the user.
I can also use these details for other playbooks.

Ths strange thing is, when I copy the password and try to connect to mysql using that user and password, it won’t let me in.

BUT!

If within the playbook itself I will set the password as 1234 for example, (instead of the generated password) everything works just fine.

I tried to generate a password with or without special characters, with and without numbers and etc…

Any ides?

Thx a lot

XXX are for secret information

You have removed the suggested use of three backticks to surround code with from the post template, and have rendered your posting largely unreadable to me.

Sorry I don’t understand what you mean

This is the text pre-populated in the new post box. :slight_smile:

2 Likes

Hi,

No idea as is. Perhaps try to remove shell stderr nullrouting from your mysql user creation command, see if you catch an error.

I’d also try to use mysql modules just to check if behavior is consistant, though I understand you can’t rely on those in the end.

Also, I agree with @jpmens, please format your code; it would be easier to decipher this way. Thanks !

It seems like your user password can have bash parameter expansion characters in it ($!()[] for example), and you double quote the password in your shell command.

instead of "{{ pass }}" in your mysql commands, try '{{ pass }}'

edit: I see you mentioned trying without special characters, so my idea may not be good. Still might be worth double checking?

1 Like

I think you’re right on the quote thing ! I just ran this quick and dirty playbook in verbose mode several times in a row:

- hosts: localhost
  connection: local
  vars:
    user_pass_gen: "{{ lookup('community.general.random_string', length=13, min_lower=1, min_upper=1, min_numeric=1, min_special=1, override_special='-=+!#$()[]') }}"
    my_command: "echo {{ user_pass_gen }}"
  tasks:
    - shell: "{{ my_command }}"

And it fails from time to time as some chars are misinterpreted by shell (which is sh by default, so no bash parameter expansions, but close !).

Just correctly quoting {{ user_pass_gen }} where you want to use it seems to work fine:

...
    my_command: "echo \"{{ user_pass_gen }}\""
...
2 Likes

I would also suggest using an actual password generator and using a seed to make it idempotent (unlike the random_string generator).

ansible.builtin.password lookup – retrieve or generate a random password, stored in a file — Ansible Community Documentation

user_pass_gen: "{{ lookup('ansible.builtin.password', '/dev/null', length=13, chars=['ascii_letters', 'digits'] seed=inventory_hostname) }}"

1 Like

I love the password lookup plugin, and TIL about seed instead of using a file for idempotency (which I might not be able to). Thanks, @Denney-tech

1 Like