Creating a new user and password with Ansible
If you read Ansible's manual for user
module, it'll direct you to the Ansible-examples github repo for details how to use password
parameter.
There you'll see that your password must be hashed.
- hosts: all
user: root
vars:
# created with:
# python -c 'import crypt; print crypt.crypt("This is my Password", "$1$SomeSalt$")'
password: $1$SomeSalt$UqddPX3r4kH3UL5jq5/ZI.
tasks:
- user: name=tset password={{password}}
If your playbook or ansible command line has your password as-is in plain text, this means your password hash recorded in your shadow file is wrong. That means when you try to authenticate with your password its hash will never match.
Additionally, see Ansible FAQ regarding some nuances of password parameter and how to correctly use it.
How do I create a user and set a password using ansible?
The python example shown in the documentation depends on what version of crypt is running on the OS you are using.
I generated the crypt on OS X and the server I was targetting is ubuntu.
Due to differences in which implementation of crypt is offered by the OS, the result is different and incompatible.
Use this instead:
http://pythonhosted.org/passlib/
Passlib is a password hashing library for Python 2 & 3, which provides
cross-platform implementations of over 30 password hashing algorithms,
as well as a framework for managing existing password hashes. It’s
designed to be useful for a wide range of tasks, from verifying a hash
found in /etc/shadow, to providing full-strength password hashing for
multi-user application.
>>> # import the hash algorithm
>>> from passlib.hash import sha512_crypt
>>> # generate new salt, and hash a password
>>> hash = sha512_crypt.encrypt("password")
>>> hash
'$6$rounds=656000$BthPsosdEpqOM7Qd$l/ln9nyEfxM67ea8Bvb79JoW50pGjf6iM87taIvfSmpjasE4/wBG1.60pFS6W992T7Q1q2wikMbxYUvMHD1tT1'
User password creation in ansible playbook
in the second task you have "password | password_hash('sha512', 'mysecretsalt') }}"
it must be "{{ password | password_hash('sha512', 'mysecretsalt') }}"
to use use te var password
or "{{ 'password' | password_hash('sha512', 'mysecretsalt') }}"
to use the word password
as password.
How to pass a user / password in ansible command
The docs say you can specify the password via the command line:
-k
,--ask-pass
.
ask for connection password
Ansible can also store the password in the ansible_password
variable on a per-host basis.
Ansible create Users and Group
Couple of things:
- To use variables from
ubuntu
file you need specify the vars file in playbook. - To use
default_user_password
as a variable, remove the quotes'
- If you want
admin
as the users primary group then usegroup
attribute instead.groups
on the other hand takes a list and add the users to the listed groups.
And, if the group isn't created yet on the target machine then first create the group using group module.
Playbook after the above changes.
---
- name: Create Users & Groups
hosts: target1
gather_facts: false
vars_files: ubuntu
tasks:
- name: Create group
group:
name: "{{ admin_group }}"
state: present
- name: Create Users Task
user:
name: "{{ item }}"
state: present
password: "{{ default_user_password | password_hash('sha512','A512') }}"
shell: /bin/bash
group: "{{ admin_group }}"
loop:
- Rajini
- Kamal
Create password and write it to file
I'm not 100% sure I understood your question.
The below will take your actual user list, create a new one with a generated password for each and store the result in a single file for all users. Bonus: if the file exists, the var will be initialized from there bypassing the password creation.
Notes:
- The below can be enhanced. You can put the block tasks for file creation in a separate file and use a conditional include so that the skipped loop iteration do not take place at all when the file already exists.
- I obviously did not take security into account here and I strongly suggest you secure the way your file is stored.
Demo playbook:
---
- name: Create random passwords and store
hosts: localhost
gather_facts: false
vars:
users_with_pass_file: /tmp/test_pass.txt
students:
- Username: testuser1
E-Mail: student1@student.com
- Username: testuser2
E-Mail: student2@student.com
tasks:
- name: Try to load users and passwords from file if it exists
vars:
file_content: "{{ lookup('ansible.builtin.file', users_with_pass_file, errors='ignore') }}"
ansible.builtin.set_fact:
users_with_pass: "{{ file_content }}"
when:
- file_content | length > 0
# Unfortunately, there is no test 'is list' in jinja2...
- file_content is iterable
- file_content is not mapping
- file_content is not string
ignore_errors: true
changed_when: false
register: load_from_disk
- name: Create user list with passwords and store it if it does not exists (or is malformed...)
block:
- name: Create the list
vars:
user_password: "{{ lookup('ansible.builtin.password', '/dev/null', length=12) }}"
ansible.builtin.set_fact:
users_with_pass: "{{ users_with_pass | default([]) + [item | combine({'password': user_password})] }}"
loop: "{{ students }}"
- name: Store the result
ansible.builtin.copy:
dest: "{{ users_with_pass_file }}"
content: "{{ users_with_pass | to_json }}"
when: load_from_disk is skipped or load_from_disk is failed
- name: Show the result
ansible.builtin.debug:
var: users_with_pass
first run (with used ansible version):
$ ansible-playbook --version
ansible-playbook 2.10.1
config file = None
configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.6/dist-packages/ansible
executable location = /usr/local/bin/ansible-playbook
python version = 3.6.9 (default, Jul 17 2020, 12:50:27) [GCC 8.4.0]
$ ansible-playbook test.yml
PLAY [Create random passwords and store] ***********************************************************************************************************************************************************************************************
TASK [Try to load users and passwords from file if it exists] **************************************************************************************************************************************************************************
[WARNING]: Unable to find '/tmp/test_pass.txt' in expected paths (use -vvvvv to see paths)
skipping: [localhost]
TASK [Create the list] *****************************************************************************************************************************************************************************************************************
ok: [localhost] => (item={'Username': 'testuser1', 'E-Mail': 'student1@student.com'})
ok: [localhost] => (item={'Username': 'testuser2', 'E-Mail': 'student2@student.com'})
TASK [Store the result] ****************************************************************************************************************************************************************************************************************
changed: [localhost]
TASK [Show the result] *****************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"users_with_pass": [
{
"E-Mail": "student1@student.com",
"Username": "testuser1",
"password": "5l1RG7HzqaKMWJcH:mRH"
},
{
"E-Mail": "student2@student.com",
"Username": "testuser2",
"password": "tZvLT3LVj3_60GV_WoQd"
}
]
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
Second run:
PLAY [Create random passwords and store] ***********************************************************************************************************************************************************************************************
TASK [Try to load users and passwords from file if it exists] **************************************************************************************************************************************************************************
ok: [localhost]
TASK [Create the list] *****************************************************************************************************************************************************************************************************************
skipping: [localhost] => (item={'Username': 'testuser1', 'E-Mail': 'student1@student.com'})
skipping: [localhost] => (item={'Username': 'testuser2', 'E-Mail': 'student2@student.com'})
TASK [Store the result] ****************************************************************************************************************************************************************************************************************
skipping: [localhost]
TASK [Show the result] *****************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"users_with_pass": [
{
"E-Mail": "student1@student.com",
"Username": "testuser1",
"password": "5l1RG7HzqaKMWJcH:mRH"
},
{
"E-Mail": "student2@student.com",
"Username": "testuser2",
"password": "tZvLT3LVj3_60GV_WoQd"
}
]
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
Getting error when changing Ansible password
I'd try to do this with an async task and check back on the result with the new password:
- hosts: rhel
become: yes
tasks:
- name: Set ansible password.
ansible.builtin.user:
name: ansible
update_password: always
password: "{{ new_ansible_pw_var | password_hash ('sha512')}}"
async: 15
poll: 0
register: change_ansible_password
- name: Check ansible password change was successful
vars:
ansible_password: "{{ new_ansible_pw_var }}"
async_status:
jid: "{{ change_ansible_password.ansible_job_id }}"
register: job_result
until: job_result.finished
retries: 15
delay: 1
- name: polite guests always clean after themselves when necessary (see doc)
vars:
ansible_password: "{{ new_ansible_pw_var }}"
async_status:
jid: "{{ change_ansible_password.ansible_job_id }}"
mode: cleanup
Related Topics
Link Extraction from a Google Page in Bash
Can't Load Mod_Wsgi Compiled for Python 3
What Is The Analogue of an Ndis Filter in Linux
Perl and Bash Variable Substitution, with Hexadecimal Characters and Repeat Count
Linux Intel 64Bit Assembly Division
Sed: Remove Whole Words Containg a Character Class
How to Compare The Size of Two Directories
Rename Multiple Files - Linux/Ubuntu
Cygwin Xwin Server Randomly Loses Connection
Format and Filter File to CSV Table
Why This Shell Won't Work If It's Called from Rc.Local But Ssh
What's The Relation Between 32/64-Bit Application, Os and Processor
Mq Explorer - Could Not Load Swt Library
Cannot Kill Redis-Server on Linux
Fastest Way to Determine User Permissions in /Etc/Sudoer
Sublime Text 2 Build (Ctrl +B) Intel Fortran Compiler