简体   繁体   中英

Creating user passwords from an Ansible Playbook

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, eg PowerShell. Once I have an understanding of the process then I can translate it to a playbook.

Any help is much appreciated!

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM