Password management using ansible-vault
Prabhat Singh
Posted on July 3, 2022
Good Day Everyone!
Here is another post out of my learning these days on using ansible-vault.
I have been doing KodeKloud performance based tasks for a while and one of the tasks involved creating users and groups using ansible playbook. Passwords for the users have to be managed using ansible-vault.
I have not used ansible-vault earlier, so it's definitely a fun learning.
Task
Create an ansible playbook to perform the following task.
- Create users and groups given in the file users.yml
# cat /home/centos/users.yml
admins:
- rob
- tim
developers:
- mark
- john
For users in "admins" group, home directory should be created in the "/home/" directory.
For users in "developers" group, home directory should be set to "/var/www". Also it should not create any home directory with username in "/var/www/".
Password of users of admins group should be set to "adminpassword".
Password of users of developers group should be set to "developerpassword".
To encrypt the password, make use of ansible-vault secret file which is located at "/home/centos/vault/password.txt".
Solution
In order to complete the task, we'll need to look and complete the task from the last to first.
- Passwords for the users are supposed to be encrypted with the ansible-vault. Therefore, we need to make sure that the ansible.cfg file is configured with the vault password file.
Note: Password for ansible-vault must be kept at a safe location. I'm showing it for the sake of the exercise.
[centos@localhost vault]$ pwd
/home/centos/vault
[centos@localhost vault]$ cat password.txt
redhat
[centos@localhost vault]$ grep vault_password_file /etc/ansible/ansible.cfg
vault_password_file = /home/centos/vault/password.txt
- There are two strings given in the tasks points 4 & 5 which are required to be encrypted with ansible-vault and those encrypted password would then be used during the user creation process.
For this purpose, we will use ansible-vault command to encrypt the string. We will also name the encrypted string for admins user password to a variable called "admin_pwd" and for developers user password to a variable called "developer_pwd".
Note: Important thing to ensure here is that the variable name must not contain the hyphen "-". Otherwise, the password won't work for the user. This is from my experience while attempting the task.
[centos@localhost ~]$ ansible-vault encrypt_string 'adminpassword' --name 'admin_pwd'
admin_pwd: !vault |
$ANSIBLE_VAULT;1.1;AES256
30323636346564376638376364386335646463626662646535633863663265383563383238363236
3863623764366533313162346335653736323438656331370a373263643733623766373264613530
37333537663761383232313564343131663438303966386336663733633332343030633866613737
3139373661623137650a303936363562383335613437653365323737373430363831633164366334
3336
Encryption successful
[centos@localhost ~]$ ansible-vault encrypt_string 'developerpassword' --name 'developer_pwd'
developer_pwd: !vault |
$ANSIBLE_VAULT;1.1;AES256
61656230636461653861356530346230386461646436636533366665346264366666623264383130
3539343339626664383731363665306238386434306435620a653139353735366330336466346635
39623832663063373738306238343433396661373566653232383236613662343437313832326562
3166616232663137380a343133353439396261323939323365313339663464393266373437303335
36323633306333386435616639653730396266616334643536643936623465383131
Encryption successful
- As mentioned in the task point 3, users under developer group must have their home directory set to "/var/www". Let's ensure that directory is created into the system and appropriate permissions are applied to the directory.
[centos@localhost var]$ pwd
/var
[centos@localhost var]$ ls -ld www
drwxrwxrwx. 2 root root 27 Jul 2 17:53 www
Observe the permissions on the directory www. If it's not set, then use below command to update the permissions.
[centos@localhost var]$ sudo chmod 777 www
- Now that we have configured the vault_password_file, created the variables containing password for the users under admins and developers group and created the home directory for developers users, let us start working on creating the playbook to create the groups and users
[centos@localhost ~]$ cat playbook.yml
---
- hosts: localhost
vars_files: /home/centos/users.yml
vars:
admin_pwd: !vault |
$ANSIBLE_VAULT;1.1;AES256
30323636346564376638376364386335646463626662646535633863663265383563383238363236
3863623764366533313162346335653736323438656331370a373263643733623766373264613530
37333537663761383232313564343131663438303966386336663733633332343030633866613737
3139373661623137650a303936363562383335613437653365323737373430363831633164366334
3336
developer_pwd: !vault |
$ANSIBLE_VAULT;1.1;AES256
61656230636461653861356530346230386461646436636533366665346264366666623264383130
3539343339626664383731363665306238386434306435620a653139353735366330336466346635
39623832663063373738306238343433396661373566653232383236613662343437313832326562
3166616232663137380a343133353439396261323939323365313339663464393266373437303335
36323633306333386435616639653730396266616334643536643936623465383131
tasks:
- name: create group
group:
name: "{{ item }}"
state: present
loop:
- admins
- developers
- name: create admins users
user:
name: "{{ item }}"
create_home: yes
groups: admins, wheel
append: yes
password: "{{ admin_pwd | string | password_hash('sha512') }}"
loop: "{{ admins }}"
- name: create developers users
user:
name: "{{ item }}"
create_home: yes
home: /var/www
groups: developers
append: yes
password: "{{ developer_pwd | string | password_hash('sha512') }}"
loop: "{{ developers }}"
- vars_files is pointing to the file users.yml which contains the groups and users information.
- vars is pointing to the variables which were created using the ansible-vault command
- tasks list consists of the task first to create the groups given in the users.yml, then create the users using group and user modules of the ansible respectively.
- create_home=yes -> home directory is supposed to be created in the /home
- users in the admins group are also supposed to be sudo user, this is why groups: admins, wheels & append: yes have been added into the task. Similarly for users in the developers group, groups: developers
- password for users in the admins and developers should be set to admin_pwd and developer_pwd variables created during encrypt string step. Password strings are also required to be hashed so as not to expose during the playbook execution or otherwise.
- both user creation tasks consists of loop where values under the admins and developers list (array) are being used from users.yml
- Now it's time for playbook execution. Execute the ansible-playbook command to implement changes from playbook.yml
[centos@localhost ~]$ ansible-playbook playbook.yml
PLAY [localhost] *************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************
ok: [localhost]
TASK [create group] **********************************************************************************************************
ok: [localhost] => (item=admins)
ok: [localhost] => (item=developers)
TASK [create admins users] ***************************************************************************************************
changed: [localhost] => (item=rob)
changed: [localhost] => (item=tim)
TASK [create developers users] ***********************************************************************************************
changed: [localhost] => (item=mark)
changed: [localhost] => (item=john)
PLAY RECAP *******************************************************************************************************************
localhost : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[centos@localhost ~]$
Note: If you'd like to see the detailed output of the playbook execution, use "-vv" option with the ansible-playbook command.
# ansible-playbook playbook.yml -vv
References
Posted on July 3, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.