Birol Emekli
Birol Emekli

Reputation: 165

How to select mandatory character when generating random password with ansible?

I create a random password with Ansible. 4 characters in length.

- hosts: localhost
  vars:
    pwd_alias: "{{ lookup('password', '/dev/null length=4 chars=ascii_letters,digits,hexdigits,punctuation' ) }}"

  user: root
  tasks:
    - debug:
        msg: Sifre= {{pwd_alias}}

    - debug:
        msg: Sifre= {{pwd_alias}}

    - debug:
        msg: Sifre= {{pwd_alias}}

    - debug:
        msg: Sifre= {{pwd_alias}} 

I want it to be password example. I want the output to look like this example.

TASK [debug] 
ok: [localhost] => {
    "msg": "Sifre= Z/bO"
}

TASK [debug] 
ok: [localhost] => {
    "msg": "Sifre= a_4G"
}

TASK [debug] 
ok: [localhost] => {
    "msg": "Sifre= 9a&0"
}

TASK [debug] 
ok: [localhost] => {
    "msg": "Sifre= d.2C"
}
  1. ascii_letters = 1

  2. hexdigits = 1

  3. digits = 1

  4. punctuation = 1

I want him to generate a random password like this. But what the system produces sometimes changes. Sometimes there are no digits, sometimes there is no punctuation. I want these 4 features to be absolutely.

 ansible version = 2.7.10

This is how the outputs are

TASK [debug] 
ok: [localhost] => {
    "msg": "Sifre= Z/bh"
}

TASK [debug] 
ok: [localhost] => {
    "msg": "Sifre= a_-G"
}

TASK [debug] 
ok: [localhost] => {
    "msg": "Sifre= 9ad0"
}

TASK [debug] 
ok: [localhost] => {
    "msg": "Sifre= d.aC"
}

How do I get each character? Thank you so much

Upvotes: 4

Views: 3361

Answers (2)

Vladimir Botka
Vladimir Botka

Reputation: 68294

Generate the passwords in a separate file. Get random character from each set and create pwd_alias_list. Then shuffle and join the list.

$ cat generate-password-4.yml
- set_fact:
    pwd_alias_list: []
- set_fact:
    pwd_alias_list: "{{ pwd_alias_list + [
                        lookup('password', '/dev/null length=1 chars=' ~ item) ]
                        }}"
  loop:
    - ascii_letters
    - digits
    - hexdigits
    - punctuation
- set_fact:
    pwd_alias: "{{ pwd_alias_list|shuffle|join('') }}"

The tasks below

  tasks:
    - include_tasks: generate-password-4.yml
    - debug:
        var: pwd_alias
    - include_tasks: generate-password-4.yml
    - debug:
        var: pwd_alias
    - include_tasks: generate-password-4.yml
    - debug:
        var: pwd_alias
    - include_tasks: generate-password-4.yml
    - debug:
        var: pwd_alias

give

"pwd_alias": "ld(9"
"pwd_alias": "2R`9"
"pwd_alias": "O5(0"
"pwd_alias": "2>z5"

It's possible to make the generation of the password more flexible and create a list of the characters' sets my_char_specs and number of the repetitions my_repeat

$ cat generate-password.yml
- set_fact:
    pwd_alias_list: []
- set_fact:
    pwd_alias_list: "{{ pwd_alias_list + [
                        lookup('password', '/dev/null length=1 chars=' ~ item.0) ]
                        }}"
  with_nested:
    - "{{ my_char_specs }}"
    - "{{ range(0, my_repeat)|list }}"
- set_fact:
    pwd_alias: "{{ pwd_alias_list|shuffle|join('') }}"

The task below repeat the random choice from four sets four times

  vars:
    my_char_specs:
      - ascii_letters
      - digits
      - hexdigits
      - punctuation
    my_repeat: 4
  tasks:
    - include_tasks: generate-password.yml
    - debug:
        var: pwd_alias

and gives

"pwd_alias": "8=3[9BD(7?3bJ5y3"

Upvotes: 1

Nelson G.
Nelson G.

Reputation: 5441

This solution works, you need to generate each type chars separately then concatenate them :

- hosts: localhost
  vars:
    pwd_alias_digit1: "{{ lookup('password', '/dev/null length=1 chars=ascii_letters' ) }}"
    pwd_alias_digit2: "{{ lookup('password', '/dev/null length=1 chars=digits' ) }}"
    pwd_alias_digit3: "{{ lookup('password', '/dev/null length=1 chars=hexdigits' ) }}"
    pwd_alias_digit4: "{{ lookup('password', '/dev/null length=1 chars=punctuation' ) }}"
    pwd_alias: "{{ pwd_alias_digit1 + pwd_alias_digit2 + pwd_alias_digit3 + pwd_alias_digit4 }}"

  user: root
  tasks:
    - debug:
        msg: Sifre= {{pwd_alias}}

    - debug:
        msg: Sifre= {{pwd_alias}}

    - debug:
        msg: Sifre= {{pwd_alias}}

    - debug:
        msg: Sifre= {{pwd_alias}} 

Another way is to create your own password lookup plugin : my_password. It's easier to create a new plugin and use it simple in a playbook. It's better and the playbook will remain readable.

Upvotes: 1

Related Questions