0

I'm sure someone here can solve my problem. I am creating users on hosts that are defined in my Ansible hosts file. BUT when the users wish to login, the root user needs to define the user password. I need to automate the creation of user passwords.

To create user passwords with a playbook we can’t specify the password in clear text, we can only do that by supplying a hash:

 - name: Add Users + Assign to Group
   user:
      name: "{{ item }}"
      password: $6$ul4TACYvHI.kmGUK$j32lU8fNbX.eW0DZOqnnDlP8i0...

To create the hash, the 1st step is to define the password by logging into the target server as root, and then use python-crypt to create the hash. Once running the command, the terminal will then provide the hash, which I paste into the playbook. ( in the below example, the password is “ansible”)

python -c 'import crypt; print crypt.crypt("ansible")'

When I run the playbook against the target server, I can then login as the user that the playbook created with the password I defined using python-crypt (in this case I login as user2 with the password “ansible” )

login as: user2

user1@10.65.8.50's password: "ansible"


[user1@hostname ~]$

This means that I have to create the hash in the terminal of the server where I am creating users, then copy and paste that hash into the playbook. Not too much trouble if I have one server but If I am running the playbook against 100 servers then I need to log in to 100 servers as root and create 100 hashes then define all of those hashes in the playbook, which is not very automated!

So what is needed is the ability to execute python-crypt from the playbook, grep the hash that is created, then put this in the playbook. Do you have any ideas on how to do this? not even specifically in Ansible, I don’t expect you guys to write the playbook for me. Maybe think about how you would do this in your tool of choice, e.g PowerShell. Once I have an understanding of the process then I can translate it to a playbook.

Any help is much appreciated!

davetherave
  • 3
  • 1
  • 3
  • You can use the ansible password module to generate the password on a text file and then read that file to use the hash on your user. I know its not the best solution, but you can work it out from that. Take a look: https://docs.ansible.com/ansible/2.5/plugins/lookup/password.html – Kelson Silva May 11 '18 at 20:11
  • Thanks for this @Kelson Silva, I missed this when looking through the ansible documentation if I am being honest. I will try this out, but as you say, maybe not the ideal solution. – davetherave May 11 '18 at 20:34
  • hmmm, not sure how this exactly solves my problem after looking at this more closely (not complaining at your suggestion @Kelson Silva , I appreciate your input) it may well be the solution, but I think I have a misunderstanding of how this could be incorporated into my playbook effectively. – davetherave May 11 '18 at 21:01
  • Are the passwords predefined or you want to automate them also? – imjoseangel May 12 '18 at 07:05

2 Answers2

0

This is sort of a far out answer, and I have not tested this, but I've been considering a way of using ansible-vault in an automated way so that I can deploy an application without defining passwords beforehand, while keeping an encrypted record of the password once it's created.

The playbook below shows one way that you might:

  • generate a password on the remote host,
  • use that password on the remote host,
  • store an encrypted copy of that password on the local (control) system.

Again, this is untested and it's possible it can't work for some reason I haven't anticipated, but I actually think it should be able to work like this (only relevant tasks shown):

ansible.cfg

vault_password_file = /path/to/vault_password_file

playbook.yml

---
- hosts: example_com
  gather_facts: true
  become: true

  vars:
    password_var_name: "example_com_db_password"
    vault_vars_file: "example_com_vault.yml"

  tasks:
    - name: Find out if we have already set a password.
      command: "grep \"'password' => '',\" settings.php"
      args:
        chdir: "/path/to/settings"
      register: password_in_file

    - name: Create a password and use ansible-vault to write it.
      block:
        - name: Create a new password.
          command: "apg -a1 -m32 -n1"
          register: new_vault_password
          no_log: true

        - name: Encrypt the new password.
          command: "ansible-vault encrypt \"{{ new_vault_password.stdout }}\""
          register: new_vault_password_encrypted
          no_log: true

        - name: Write the encrypted password to our local ansible-vault file.
          lineinfile:
            path: "{{ playbook_dir }}/{{ vault_file }}"
            line: "{{ password_var_name }}: {{ new_vault_password_encrypted.stdout }}"
            insertafter: "EOF"
          when: password_in_file.stdout = 0
          delegate_to: localhost

        - name: Write the unencrypted password into our remote settings file.
          lineinfile:
            path: "/path/to/settings/settings.php"
            line: "  'password' => '{{ new_password.stdout }}',"
            regexp: "^  'password' => '',$"
          no_log: true

So the tldr for this is that:

  • we have an Ansible config file ansible.cfg.
  • that file contains the path to our ansible-vault password file.
  • We have a local unencrypted file for dynamic Ansible variables.
  • we check to see if we need to proceed with creating a new password etc.
  • if so, we create a password.
  • then we encrypt it.
  • then we write the unencrypted password to the settings file.
  • then we write the encrypted password to our local, un-encrypted variables file.

bhotel
  • 472
  • 5
  • 11
0

Set your password in a variable like FAP, add it to your script to create the user:

  - name: "Encrypt password for target system"
    command: "python -c 'import crypt; print crypt.crypt(\"{{ FAP }}\")'"
    register: EFAP
  - name: "Add user USER1"
    user: name="USER1" state="present" password="{{ EFAP.stdout }}"

I've tested this with a complex password and works fine

Friedrich 'Fred' Clausen
  • 3,321
  • 8
  • 39
  • 70
Scotty
  • 1
  • 1