Nacharbeiten: Ersatz: create-users (#289)
Co-authored-by: Michael Grote <michael.grote@posteo.de> Reviewed-on: mg/ansible#289 Co-authored-by: mg <michael.grote@posteo.de> Co-committed-by: mg <michael.grote@posteo.de>
This commit is contained in:
parent
c4d933607c
commit
b8655a1fab
11 changed files with 3 additions and 809 deletions
|
@ -19,7 +19,7 @@
|
||||||
### mgrote.user
|
### mgrote.user
|
||||||
users:
|
users:
|
||||||
- username: mg
|
- username: mg
|
||||||
password: "{{ lookup('keepass', 'mg_linux_password_cleartext', 'password') }}"
|
password: "{{ lookup('keepass', 'mg_linux_password_hash', 'password') }}"
|
||||||
update_password: on_create
|
update_password: on_create
|
||||||
groups: ssh, sudo, xrdp
|
groups: ssh, sudo, xrdp
|
||||||
state: present
|
state: present
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
allow_sudo: true
|
allow_sudo: true
|
||||||
allow_passwordless_sudo: true
|
allow_passwordless_sudo: true
|
||||||
- username: munin
|
- username: munin
|
||||||
password: "{{ lookup('keepass', 'munin_linux_password_cleartext', 'password') }}"
|
password: "{{ lookup('keepass', 'munin_linux_password_hash', 'password') }}"
|
||||||
update_password: on_create
|
update_password: on_create
|
||||||
groups: root
|
groups: root
|
||||||
state: present
|
state: present
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
allow_sudo: true
|
allow_sudo: true
|
||||||
allow_passwordless_sudo: true
|
allow_passwordless_sudo: true
|
||||||
- username: ansible-user
|
- username: ansible-user
|
||||||
password: "{{ lookup('keepass', 'ansible_user_linux_password_cleartext', 'password') }}"
|
password: "{{ lookup('keepass', 'ansible_user_linux_password_hash', 'password') }}"
|
||||||
update_password: on_create
|
update_password: on_create
|
||||||
groups: ssh, sudo
|
groups: ssh, sudo
|
||||||
state: present
|
state: present
|
||||||
|
|
7
roles/ryandaniels.create_users/.gitignore
vendored
7
roles/ryandaniels.create_users/.gitignore
vendored
|
@ -1,7 +0,0 @@
|
||||||
.vaultpass
|
|
||||||
.retry
|
|
||||||
secret
|
|
||||||
*.secret
|
|
||||||
.venv
|
|
||||||
.vscode
|
|
||||||
*.tmp
|
|
|
@ -1,95 +0,0 @@
|
||||||
---
|
|
||||||
language: python
|
|
||||||
python: "2.7"
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
# Make sure everything's up to date.
|
|
||||||
- sudo apt-get update -qq
|
|
||||||
|
|
||||||
install:
|
|
||||||
# Install Ansible.
|
|
||||||
- pip install ansible
|
|
||||||
# - |
|
|
||||||
# if [ -f requirements.yml ]; then
|
|
||||||
# ansible-galaxy install --roles-path ../ -r requirements.yml
|
|
||||||
# fi
|
|
||||||
|
|
||||||
# Add ansible.cfg to pick up roles path.
|
|
||||||
# - "printf '[defaults]\nroles_path = ../' > ansible.cfg"
|
|
||||||
- "{ echo '[defaults]'; echo 'roles_path = ../'; } >> ansible.cfg"
|
|
||||||
|
|
||||||
script:
|
|
||||||
# Check the role/playbook's syntax.
|
|
||||||
- ansible-playbook -i tests/inventory tests/test.yml --syntax-check
|
|
||||||
- ansible-playbook -i tests/inventory tests/test-passchange.yml --syntax-check
|
|
||||||
|
|
||||||
# Run the role/playbook with ansible-playbook.
|
|
||||||
- "ansible-playbook -i tests/inventory tests/test.yml --connection=local --become"
|
|
||||||
|
|
||||||
# Run the role/playbook again, checking to make sure it's idempotent.
|
|
||||||
- >
|
|
||||||
ansible-playbook -i tests/inventory tests/test.yml --connection=local --become
|
|
||||||
| grep -q 'changed=0.*failed=0'
|
|
||||||
&& (echo 'Idempotence test: pass' && exit 0)
|
|
||||||
|| (echo 'Idempotence test: fail' && exit 1)
|
|
||||||
|
|
||||||
# Check users are setup
|
|
||||||
- id testuser101 | grep --silent "testuser101"
|
|
||||||
- id testuser102 | grep --silent "testuser102"
|
|
||||||
- id testuser103 | grep --silent "testuser103"
|
|
||||||
- id testuser104 | grep --silent "testuser104"
|
|
||||||
- id testuser105 | grep --silent "testuser105"
|
|
||||||
- id testuser106 | grep --silent "testuser106"
|
|
||||||
- id testuser107 | grep --silent "testuser107"
|
|
||||||
- id testuser108 | grep --silent "testuser108"
|
|
||||||
- id testuser109 | grep --silent "testuser109"
|
|
||||||
- id testuser110 | grep --silent "testuser110"
|
|
||||||
- id testuser111 | grep --silent "testuser111"
|
|
||||||
- sudo grep testuser101 /etc/shadow | awk -F":" '{exit $2!="$6$/y5RGZnFaD3f$96xVdOAnldEtSxivDY02h.DwPTrJgGQl8/MTRRrFAwKTYbFymeKH/1Rxd3k.RQfpgebM6amLK3xAaycybdc.60"}'
|
|
||||||
- sudo grep testuser102 /etc/shadow | awk -F":" '{exit $2!="$6$F/KXFzMa$ZIDqtYtM6sOC3UmRntVsTcy1rnsvw.6tBquOhX7Sb26jxskXpve8l6DYsQyI1FT8N5I5cL0YkzW7bLbSCMtUw1"}'
|
|
||||||
- grep --silent "^testuser101:" /etc/group
|
|
||||||
- ls -lgd /home/testuser101 | awk '{exit $3!="testuser101"}'
|
|
||||||
- sudo ls -lg /home/testuser101/.ssh/authorized_keys | awk '{exit $3!="testuser101"}'
|
|
||||||
- sudo cat /home/testuser101/.ssh/authorized_keys | wc -l | grep --silent "2"
|
|
||||||
- sudo chage -l testuser101 | grep "Account expires" | awk '{exit $4!="never"}'
|
|
||||||
- sudo chage -l testuser105 | grep "Account expires" | awk '{exit $4!="Jan"}'
|
|
||||||
- sudo cat /etc/sudoers|grep --silent "^testuser102 "
|
|
||||||
# Check UID is set as specified
|
|
||||||
- grep sshuser /etc/passwd | awk -F":" '{exit $3!="1099"}'
|
|
||||||
# Check group(s) are set for users
|
|
||||||
- grep "^groupcommon:" /etc/group | grep --silent testuser106
|
|
||||||
- grep "^testgroupweb:" /etc/group | grep --silent testuser107
|
|
||||||
# Check group not set on webserver
|
|
||||||
- grep "^testgroupdb:" /etc/group | grep --silent testuser107 || echo "success, testgroupdb not found"
|
|
||||||
# Check primary group set
|
|
||||||
- id -gn testuser105 | grep --silent "group105primary"
|
|
||||||
# Check primary group id set
|
|
||||||
- id -gn testuser106 | grep --silent "group106primary"
|
|
||||||
- id -g testuser106 | grep --silent 2222
|
|
||||||
# Check ssh key for user was created
|
|
||||||
- sudo cat /home/testuser108/.ssh/id_rsa | grep --silent "BEGIN RSA PRIVATE KEY"
|
|
||||||
- sudo cat /home/testuser109/.ssh/id_rsa | grep --silent "BEGIN RSA PRIVATE KEY"
|
|
||||||
# Check no ssh key for user was created
|
|
||||||
- sudo test ! -f /home/testuser110/.ssh/id_rsa
|
|
||||||
# Check key is encrypted
|
|
||||||
- sudo cat /home/testuser109/.ssh/id_rsa | grep --silent "ENCRYPTED"
|
|
||||||
# Check key size is correct
|
|
||||||
- sudo ssh-keygen -lf /home/testuser109/.ssh/id_rsa | awk '{exit $1!="4096"}'
|
|
||||||
# Check if not system account
|
|
||||||
- id -u testuser101 | awk '{exit ($1<1000)?"0":"1"}' || echo "success, not system account"
|
|
||||||
# Check if system account
|
|
||||||
- id -u testuser111 | awk '{exit ($1<1000)?"0":"1"}'
|
|
||||||
# Run the role/playbook again but change a password, and change password where on_create is set
|
|
||||||
- "ansible-playbook -i tests/inventory tests/test-passchange.yml --connection=local --become"
|
|
||||||
|
|
||||||
# Check password changed or not
|
|
||||||
- sudo grep testuser101 /etc/shadow | awk -F":" '{exit $2!="$6$/y5RGZnFaD3f$96xVdOAnldEtSxivDY02h.DwPTrJgGQl8/MTRRrFAwKTYbFymeKH/1Rxd3k.RQfpgebM6amLK3xAaycybdc.60"}'
|
|
||||||
- sudo grep testuser102 /etc/shadow | awk -F":" '{exit $2!="$6$F/KXFzMa$ZIDqtYtM6sOC3UmRnt__NEW_SHOULD_CHANGE__6jxskXpve8l6DYsQyI1FT8N5I5cL0YkzW7bLbSCMtUw1"}'
|
|
||||||
# Confirm you locked yourself out
|
|
||||||
- sudo grep testuser103 /etc/shadow | awk -F":" '{exit $2!="!"}'
|
|
||||||
# Confirm ssh key was changed and only 1 entry in file
|
|
||||||
- sudo grep --silent "^ssh-rsa AAABNEW.... test104@server" /home/testuser104/.ssh/authorized_keys
|
|
||||||
- sudo cat /home/testuser104/.ssh/authorized_keys | wc -l | grep --silent "1"
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
webhooks: https://galaxy.ansible.com/api/v1/notifications/
|
|
|
@ -1,21 +0,0 @@
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2017 Ryan Daniels
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
|
@ -1,230 +0,0 @@
|
||||||
# ansible-role-create-users
|
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/ryandaniels/ansible-role-create-users.svg?branch=master)](https://travis-ci.org/ryandaniels/ansible-role-create-users)
|
|
||||||
|
|
||||||
Role to manage users on linux.
|
|
||||||
Manage users in the user list config file (list is in the file vars/secret).
|
|
||||||
Add users (with specific uid), change passwords, lock/unlock user accounts, manage sudo access (per user), add ssh key(s) for sshkey based authentication, set user's primary group and gid, add user (append) to group(s) and group will be created if doesn't exist.
|
|
||||||
This is done on a per "group" basis (Ansible group variables), as set in the config file. The group comes from the Ansible group as set for a server in the inventory file.
|
|
||||||
|
|
||||||
More detailed example can be found in the blog post: [User Management with Ansible](https://ryandaniels.ca/blog/ansible-user-management/)
|
|
||||||
|
|
||||||
Note: Deleting users is not done on purpose.
|
|
||||||
|
|
||||||
## Distros tested
|
|
||||||
|
|
||||||
* Ubuntu 18.04 / 16.04
|
|
||||||
* CentOS / RHEL: 7.x, 6.5, 5.9
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
Requires Ansible 2.6 (due to previous [bug 20096](https://github.com/ansible/ansible/issues/20096) with un-expiring users)
|
|
||||||
|
|
||||||
## ansible-vault
|
|
||||||
|
|
||||||
Use ansible-vault to encrypt sensitive info from git.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cat vars/secret
|
|
||||||
#encrypt if cleartext (before git commit/push)
|
|
||||||
ansible-vault encrypt vars/secret
|
|
||||||
|
|
||||||
#Edit encrypted file:
|
|
||||||
ansible-vault edit vars/secret
|
|
||||||
|
|
||||||
vi .vaultpass
|
|
||||||
-Enter the password for Ansible Vault from Password Safe
|
|
||||||
chmod 600 .vaultpass
|
|
||||||
vi ansible.cfg
|
|
||||||
#Insert the following lines
|
|
||||||
[defaults]
|
|
||||||
vault_password_file = ./.vaultpass
|
|
||||||
```
|
|
||||||
|
|
||||||
## .gitignore
|
|
||||||
|
|
||||||
```bash
|
|
||||||
vi .gitignore
|
|
||||||
#Insert the following lines
|
|
||||||
.vaultpass
|
|
||||||
.retry
|
|
||||||
secret
|
|
||||||
*.secret
|
|
||||||
```
|
|
||||||
|
|
||||||
## How to generate password
|
|
||||||
|
|
||||||
* on Ubuntu - Install "whois" package
|
|
||||||
|
|
||||||
```bash
|
|
||||||
mkpasswd --method=SHA-512
|
|
||||||
```
|
|
||||||
|
|
||||||
* on RedHat - Use Python
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python -c 'import crypt,getpass; print(crypt.crypt(getpass.getpass(), crypt.mksalt(crypt.METHOD_SHA512)))'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Default Settings
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
#Note: 'debug_enabled_default: true' will put hashed passwords in the output.
|
|
||||||
debug_enabled_default: false
|
|
||||||
default_update_password: on_create
|
|
||||||
default_shell: /bin/bash
|
|
||||||
```
|
|
||||||
|
|
||||||
## User Settings
|
|
||||||
|
|
||||||
File Location: vars/secret
|
|
||||||
|
|
||||||
* **username**: username - no spaces **(required)**
|
|
||||||
* **uid**: The numerical value of the user's ID (optional)
|
|
||||||
* **user_state**: present|lock **(required)**
|
|
||||||
* **password**: sha512 encrypted password (optional). If not set, password is set to "!"
|
|
||||||
* **update_password**: always|on_create (optional, default is on_create to be safe).
|
|
||||||
**WARNING**: when 'always', password will be change to password value.
|
|
||||||
If you are using 'always' on an **existing** users, **make sure to have the password set**.
|
|
||||||
* **comment**: Full name and Department or description of application (optional) (But you should set this!)
|
|
||||||
* **primarygroup**: Primary group name (optional).
|
|
||||||
* **primarygid**: Primary group ID (optional). If same gid is reused on server the playbook will fail. If same duplicate group is specified with different gid, last configured will be used.
|
|
||||||
**WARNING**: changing the primarygroup and/or primarygid of **existing** users will not change permissions of existing files belonging to that user. Also old entries will remain in /etc/group. Use with caution.
|
|
||||||
* **groups**: Comma separated list of groups the user will be added to (appended). If group doesn't exist it will be created on the specific server. This is not the primary group (primary group is not modified)
|
|
||||||
* **shell**: path to shell (optional, default is /bin/bash)
|
|
||||||
* **ssh_key**: ssh key for ssh key based authentication (optional)
|
|
||||||
NOTE: 1 key can go on single line, but if multiple keys, use formatting below from first example.
|
|
||||||
* **exclusive_ssh_key**: yes|no (optional, default: no)
|
|
||||||
**WARNING**: exclusive_ssh_key: yes - will remove any ssh keys not defined here! no - will add any key specified.
|
|
||||||
* **generate_ssh_key**: Whether to generate a SSH key for the user in question. (optional, default is 'no')
|
|
||||||
NOTE: This will not overwrite an existing SSH key
|
|
||||||
* **ssh_key_bits**: Optionally specify number of bits in SSH key to create. (optional, default set by ssh-keygen)
|
|
||||||
* **ssh_key_passphrase**: Set a passphrase for the SSH key. If no passphrase is provided, the SSH key will default to having no passphrase.
|
|
||||||
* **use_sudo**: yes|no (optional, default no)
|
|
||||||
* **use_sudo_nopass**: yes|no (optional, default no). yes = passwordless sudo.
|
|
||||||
* **system**: yes|no (optional, default no). yes = create system account (uid < 1000). Does not work on existing users.
|
|
||||||
* **servers**: sub-element list of servers where changes are made. **(required)**
|
|
||||||
These are the Ansible groups from your Ansible inventory file. In below examples, `webserver` would be the 3 servers in the `webserver` Ansible inventory `webserver1`, `webserver2`, and `webserver3`.
|
|
||||||
|
|
||||||
Note:
|
|
||||||
You can have duplicate usernames on different servers, if you want to have different settings. See below example of testuser102 has sudo on servers defined as the `webserver` group in the inventory, but no sudo on the `database` group.
|
|
||||||
|
|
||||||
## Example Ansible Inventory file
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
[webserver]
|
|
||||||
webserver1
|
|
||||||
webserver2
|
|
||||||
webserver3
|
|
||||||
|
|
||||||
[database]
|
|
||||||
db1
|
|
||||||
db2
|
|
||||||
db3
|
|
||||||
|
|
||||||
[monitoring]
|
|
||||||
monitor1
|
|
||||||
```
|
|
||||||
|
|
||||||
## Example config file (vars/secret)
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
users:
|
|
||||||
- username: testuser101
|
|
||||||
password: $6$/y5RGZnFaD3f$96xVdOAnldEtSxivDY02h.DwPTrJgGQl8/MTRRrFAwKTYbFymeKH/1Rxd3k.RQfpgebM6amLK3xAaycybdc.60
|
|
||||||
update_password: on_create
|
|
||||||
comment: Test User 100
|
|
||||||
shell: /bin/bash
|
|
||||||
ssh_key: |
|
|
||||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx8crAHG/a9QBD4zO0ZHIjdRXy+ySKviXVCMIJ3/NMIAAzDyIsPKToUJmIApHHHF1/hBllqzBSkPEMwgFbXjyqTeVPHF8V0iq41n0kgbulJG testuser101@server1
|
|
||||||
ssh-rsa AAAA.... testuser101@server2
|
|
||||||
exclusive_ssh_key: yes
|
|
||||||
use_sudo: no
|
|
||||||
use_sudo_nopass: no
|
|
||||||
user_state: present
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
- username: testuser102
|
|
||||||
password: $6$F/KXFzMa$ZIDqtYtM6sOC3UmRntVsTcy1rnsvw.6tBquOhX7Sb26jxskXpve8l6DYsQyI1FT8N5I5cL0YkzW7bLbSCMtUw1
|
|
||||||
update_password: always
|
|
||||||
comment: Test User 101
|
|
||||||
groups: testcommon, testgroup102web
|
|
||||||
shell: /bin/sh
|
|
||||||
use_sudo: yes
|
|
||||||
user_state: present
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
|
|
||||||
- username: testuser102
|
|
||||||
password: $6$F/KXFzMa$ZIDqtYtM6sOC3UmRntVsTcy1rnsvw.6tBquOhX7Sb26jxskXpve8l6DYsQyI1FT8N5I5cL0YkzW7bLbSCMtUw1
|
|
||||||
update_password: always
|
|
||||||
comment: Test User 101
|
|
||||||
groups: testcommon, testgroup102db
|
|
||||||
shell: /bin/sh
|
|
||||||
user_state: present
|
|
||||||
servers:
|
|
||||||
- database
|
|
||||||
|
|
||||||
- username: testuser103
|
|
||||||
password: $6$wBxBAqRmG6O$gPbg9hYShkuIe3YKMFujwiKsPKZHNFwoK4yCyTOlploljz53YSoPdCn9P5k8Qm0z062Q.8hvJ6DnnQQjwtrnS0
|
|
||||||
user_state: present
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
|
|
||||||
- username: testuser104
|
|
||||||
primarygroup: testgroup104primary
|
|
||||||
ssh_key: ssh-rsa AAAB.... test103@server
|
|
||||||
exclusive_ssh_key: no
|
|
||||||
use_sudo: no
|
|
||||||
user_state: present
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
- username: testuser105
|
|
||||||
uid: 1099
|
|
||||||
password: $6$XEnyI5UYSw$Rlc6tXtECtqdJ3uFitrbBlec1/8Fx2obfgFST419ntJqaX8sfPQ9xR7vj7dGhQsfX8zcSX3tumzR7/vwlIH6p/
|
|
||||||
primarygroup: testgroup105primary
|
|
||||||
primarygid: 2222
|
|
||||||
ssh_key: ssh-rsa AAAB.... test107@server
|
|
||||||
generate_ssh_key: yes
|
|
||||||
ssh_key_bits: 4096
|
|
||||||
use_sudo: no
|
|
||||||
user_state: lock
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
```
|
|
||||||
|
|
||||||
## Example Playbook create-users.yml
|
|
||||||
|
|
||||||
```bash
|
|
||||||
---
|
|
||||||
- hosts: '{{inventory}}'
|
|
||||||
vars_files:
|
|
||||||
- vars/secret
|
|
||||||
become: yes
|
|
||||||
roles:
|
|
||||||
- create-users
|
|
||||||
```
|
|
||||||
|
|
||||||
## Prep
|
|
||||||
|
|
||||||
* install ansible
|
|
||||||
* create keys
|
|
||||||
* ssh to client to add entry to known_hosts file
|
|
||||||
* configure client server authorized_keys
|
|
||||||
* run ansible commands
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Create all users
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ansible-playbook create-users.yml --ask-vault-pass --extra-vars "inventory=all-dev" -i hosts
|
|
||||||
```
|
|
|
@ -1,5 +0,0 @@
|
||||||
---
|
|
||||||
#Note: 'debug_enabled_default: true' will put hashed passwords in the output.
|
|
||||||
debug_enabled_default: false
|
|
||||||
default_update_password: on_create
|
|
||||||
default_shell: /bin/bash
|
|
|
@ -1,36 +0,0 @@
|
||||||
---
|
|
||||||
galaxy_info:
|
|
||||||
role_name: create-users
|
|
||||||
author: Ryan Daniels
|
|
||||||
description: Role to manage users on linux
|
|
||||||
license: MIT
|
|
||||||
min_ansible_version: 2.6
|
|
||||||
platforms:
|
|
||||||
- name: EL
|
|
||||||
versions:
|
|
||||||
- all
|
|
||||||
- name: GenericUNIX
|
|
||||||
versions:
|
|
||||||
- all
|
|
||||||
- any
|
|
||||||
- name: Fedora
|
|
||||||
versions:
|
|
||||||
- all
|
|
||||||
- name: Ubuntu
|
|
||||||
versions:
|
|
||||||
- all
|
|
||||||
- name: GenericLinux
|
|
||||||
versions:
|
|
||||||
- all
|
|
||||||
- any
|
|
||||||
- name: Debian
|
|
||||||
versions:
|
|
||||||
- all
|
|
||||||
galaxy_tags:
|
|
||||||
- system
|
|
||||||
- users
|
|
||||||
- ssh
|
|
||||||
- accounts
|
|
||||||
- user
|
|
||||||
|
|
||||||
dependencies: []
|
|
|
@ -1,193 +0,0 @@
|
||||||
---
|
|
||||||
- name: debug variable group_names
|
|
||||||
debug: var=group_names
|
|
||||||
when: debug_enabled_default | bool
|
|
||||||
|
|
||||||
- name: debug variable users
|
|
||||||
debug: var=users
|
|
||||||
when: debug_enabled_default | bool
|
|
||||||
|
|
||||||
- name: Add group | create primary group before adding user to group
|
|
||||||
group:
|
|
||||||
name: "{{ item.0.primarygroup }}"
|
|
||||||
gid: "{{ item.0.primarygid | default(omit) }}"
|
|
||||||
state: present
|
|
||||||
when: item.0.primarygroup is defined and item.1 in group_names
|
|
||||||
with_subelements:
|
|
||||||
- "{{ users }}"
|
|
||||||
- servers
|
|
||||||
loop_control:
|
|
||||||
label: "primarygroup: {{ item.0.primarygroup if item.0.primarygroup is defined else '' }}, primarygid: {{ item.0.primarygid if item.0.primarygid is defined else 'default' }}" # noqa 204
|
|
||||||
|
|
||||||
# Get unique list of groups to create on the server (var is different on each server)
|
|
||||||
# Still keeps formatting of comma separated list and converts to list (even if whitespace)
|
|
||||||
- name: set_fact - get groups as list per server
|
|
||||||
set_fact:
|
|
||||||
groups_as_list: "{{ (groups_as_list|default([]) + item.0.groups.split(','))|map('trim')|list|sort|unique }}"
|
|
||||||
with_subelements:
|
|
||||||
- "{{ users }}"
|
|
||||||
- servers
|
|
||||||
when: item.0.groups is defined and item.1 in group_names
|
|
||||||
loop_control:
|
|
||||||
label: "username: {{ item.0.username }}, groups_as_list: {{ item.0.groups if item.0.groups is defined else '' }}"
|
|
||||||
|
|
||||||
- name: debug show groups_as_list
|
|
||||||
debug: var=groups_as_list
|
|
||||||
when: debug_enabled_default | bool
|
|
||||||
|
|
||||||
- name: Add group | create groups before adding user to group
|
|
||||||
group:
|
|
||||||
name: "{{ item }}"
|
|
||||||
state: present
|
|
||||||
when: groups_as_list is defined
|
|
||||||
loop: "{{ groups_as_list }}"
|
|
||||||
loop_control:
|
|
||||||
label: "groups: {{ item }}"
|
|
||||||
|
|
||||||
- name: Add users | create users, shell, home dirs
|
|
||||||
user:
|
|
||||||
name: "{{ item.0.username }}"
|
|
||||||
uid: "{{ item.0.uid | default(omit, True) }}"
|
|
||||||
password: "{{ item.0.password if item.0.password is defined else '!' }}"
|
|
||||||
update_password: "{{ item.0.update_password if item.0.update_password is defined else default_update_password }}"
|
|
||||||
group: "{{ item.0.primarygroup | default(omit) }}"
|
|
||||||
groups: "{{ item.0.groups | default(omit) }}"
|
|
||||||
shell: "{{ item.0.shell if item.0.shell is defined else default_shell }}"
|
|
||||||
createhome: yes
|
|
||||||
system: "{{ item.0.system | default(omit) }}"
|
|
||||||
comment: "{{ item.0.comment if item.0.comment is defined else '' }}"
|
|
||||||
state: present #hard-coded in case user sets state of absent. Choice made to never delete accounts!
|
|
||||||
# expires: -1 #unlock account if locked ###Doesn't work like chage..
|
|
||||||
# command: chage -E -1 {{ item.0.username }} #unlock password authentication
|
|
||||||
# register: user_results
|
|
||||||
when: (item.0.user_state == 'present' or item.0.user_state == 'lock') and item.1 in group_names
|
|
||||||
#works but not multiple servers #and 'centos6' in "{{ group_names }}"
|
|
||||||
with_subelements:
|
|
||||||
- "{{ users }}"
|
|
||||||
- servers
|
|
||||||
loop_control:
|
|
||||||
label: "username: {{ item.0.username }}, user_state: {{ item.0.user_state }}, password: {{ 'True' if item.0.password is defined else 'False' }}, update_password: {{ item.0.update_password if item.0.update_password is defined else default_update_password }}, primarygroup: {{ item.0.primarygroup if item.0.primarygroup is defined else ''}}, groups: {{ item.0.groups if item.0.groups is defined else ''}}, servers: {{ item.1 if item.1 is defined else '' }}, group_names: {{ group_names }}" # noqa 204
|
|
||||||
|
|
||||||
- name: Add users | Unlock password login (set expiry to -1)
|
|
||||||
user:
|
|
||||||
name: "{{ item.0.username }}"
|
|
||||||
expires: -1 #unlock account if locked
|
|
||||||
# command: chage -E -1 {{ item.0.username }} #unlock password authentication
|
|
||||||
# register: user_results
|
|
||||||
when: item.0.user_state == 'present' and item.1 in group_names
|
|
||||||
with_subelements:
|
|
||||||
- "{{ users }}"
|
|
||||||
- servers
|
|
||||||
loop_control:
|
|
||||||
label: "username: {{ item.0.username }}, user_state: {{ item.0.user_state }}"
|
|
||||||
|
|
||||||
#- debug: var=user_results
|
|
||||||
|
|
||||||
#DONE: Change to user module once -1 bug fixed.
|
|
||||||
#DONE: Follow issue https://github.com/ansible/ansible/issues/20096
|
|
||||||
# - name: Add users | Unlock password login (set expiry to -1)
|
|
||||||
# chage:
|
|
||||||
# user: "{{ item.0.username }}"
|
|
||||||
# sp_expire: -1
|
|
||||||
# # command: chage -E -1 {{ item.username }} #unlock password authentication
|
|
||||||
# when: item.0.user_state == 'present' and item.1 in group_names
|
|
||||||
# with_subelements:
|
|
||||||
# - "{{ users }}"
|
|
||||||
# - servers
|
|
||||||
# loop_control:
|
|
||||||
# label: "username: {{item.0.username}}, user_state: {{ item.0.user_state }}"
|
|
||||||
|
|
||||||
##DONE user module doesn't work properly? expires=0 doesn't change anything. expires=1+ always updates??
|
|
||||||
##Use chage module instead
|
|
||||||
# - name: Lock users | Lock password & ssh key authentication
|
|
||||||
# chage:
|
|
||||||
# user: "{{ item.0.username }}"
|
|
||||||
# sp_expire: 0
|
|
||||||
# # command: chage -E 0 {{ item.0.username }} #Alternative lock password & ssh key authentication
|
|
||||||
# when: item.0.user_state == 'lock' and item.1 in group_names
|
|
||||||
# with_subelements:
|
|
||||||
# - "{{ users }}"
|
|
||||||
# - servers
|
|
||||||
# loop_control:
|
|
||||||
# label: "username: {{item.0.username}}, user_state: {{ item.0.user_state }}"
|
|
||||||
|
|
||||||
- name: Lock users | Lock password & ssh key authentication
|
|
||||||
user:
|
|
||||||
name: "{{ item.0.username }}"
|
|
||||||
expires: 0 #lock account if not locked
|
|
||||||
# command: chage -E 0 {{ item.0.username }} #Alternative lock password & ssh key authentication
|
|
||||||
# register: user_results
|
|
||||||
when: item.0.user_state == 'lock' and item.1 in group_names
|
|
||||||
with_subelements:
|
|
||||||
- "{{ users }}"
|
|
||||||
- servers
|
|
||||||
loop_control:
|
|
||||||
label: "username: {{ item.0.username }}, user_state: {{ item.0.user_state }}"
|
|
||||||
|
|
||||||
#Not needed, sp_expire -1 locks password authentication as well.
|
|
||||||
#- name: Lock users | Lock password login
|
|
||||||
# command: passwd -l {{ item.username }} #lock password authentication
|
|
||||||
# when: item.user_state == 'lock'
|
|
||||||
# with_items: "{{ users }}"
|
|
||||||
|
|
||||||
- name: SSH Keys | Add authorized key for ssh key authentication
|
|
||||||
authorized_key:
|
|
||||||
user: "{{ item.0.username }}"
|
|
||||||
key: "{{ item.0.ssh_key }}"
|
|
||||||
exclusive: "{{ item.0.exclusive_ssh_key if item.0.exclusive_ssh_key is defined else 'no' }}"
|
|
||||||
state: present
|
|
||||||
when: item.0.ssh_key is defined and item.1 in group_names
|
|
||||||
with_subelements:
|
|
||||||
- "{{ users }}"
|
|
||||||
- servers
|
|
||||||
loop_control:
|
|
||||||
label: "username: {{ item.0.username }}, ssh_key: {{ 'True' if item.0.ssh_key is defined else 'False' }}, exclusive_ssh_key: {{ item.0.exclusive_ssh_key if item.0.exclusive_ssh_key is defined else 'False' }}" # noqa 204
|
|
||||||
|
|
||||||
- name: SSH Keys | Generate ssh key
|
|
||||||
user:
|
|
||||||
name: "{{ item.0.username }}"
|
|
||||||
generate_ssh_key: "{{ item.0.generate_ssh_key | default(false) }}"
|
|
||||||
ssh_key_bits: "{{ item.0.ssh_key_bits | default(omit) }}"
|
|
||||||
ssh_key_passphrase: "{{ item.0.ssh_key_passphrase | default(omit) }}"
|
|
||||||
when: item.0.generate_ssh_key is defined and item.1 in group_names
|
|
||||||
with_subelements:
|
|
||||||
- "{{ users }}"
|
|
||||||
- servers
|
|
||||||
loop_control:
|
|
||||||
label: "username: {{ item.0.username }}, generate_ssh_key: {{ 'True' if item.0.generate_ssh_key is defined else 'False' }}, ssh_key_bits: {{ item.0.ssh_key_bits if item.0.ssh_key_bits is defined else '' }}, ssh_key_passphrase: {{ 'True' if item.0.ssh_key_passphrase is defined else 'False' }} "
|
|
||||||
|
|
||||||
- name: Sudo | add to sudoers file and validate
|
|
||||||
lineinfile:
|
|
||||||
dest: /etc/sudoers
|
|
||||||
state: present
|
|
||||||
regexp: '^{{ item.0.username }} '
|
|
||||||
# line: '{{ item.0.username }} ALL=(ALL) NOPASSWD:ALL'
|
|
||||||
line: "{{ item.0.username }} ALL=(ALL) {{ 'NOPASSWD:' if ( item.0.use_sudo_nopass|d(false) ) else '' }}ALL"
|
|
||||||
validate: 'visudo -cf %s'
|
|
||||||
environment:
|
|
||||||
PATH: /usr/sbin:/usr/local/sbin:/sbin
|
|
||||||
# TODO: Fix literal compare
|
|
||||||
when: item.0.use_sudo|d(false)|bool == true and item.1 in group_names # noqa 601
|
|
||||||
with_subelements:
|
|
||||||
- "{{ users }}"
|
|
||||||
- servers
|
|
||||||
loop_control:
|
|
||||||
label: "username: {{ item.0.username }}, use_sudo: {{ item.0.use_sudo|d(false) }}, use_sudo_nopass: {{ item.0.use_sudo_nopass|d(false) }}"
|
|
||||||
#environment fixes Redhat issue of hard-coded path to visudo
|
|
||||||
|
|
||||||
- name: Sudo | remove from sudoers file and validate
|
|
||||||
lineinfile:
|
|
||||||
dest: /etc/sudoers
|
|
||||||
state: absent
|
|
||||||
regexp: '^{{ item.0.username }} '
|
|
||||||
line: '{{ item.0.username }}'
|
|
||||||
validate: 'visudo -cf %s'
|
|
||||||
environment:
|
|
||||||
PATH: /usr/sbin:/usr/local/sbin:/sbin
|
|
||||||
# TODO: Fix literal compare
|
|
||||||
when: item.0.use_sudo|d(false)|bool == false and item.1 in group_names # noqa 601
|
|
||||||
with_subelements:
|
|
||||||
- "{{ users }}"
|
|
||||||
- servers
|
|
||||||
loop_control:
|
|
||||||
label: "username: {{ item.0.username }}, use_sudo: {{ item.0.use_sudo|d(false) }}"
|
|
|
@ -1,2 +0,0 @@
|
||||||
[webserver]
|
|
||||||
localhost
|
|
|
@ -1,91 +0,0 @@
|
||||||
---
|
|
||||||
- hosts: localhost
|
|
||||||
remote_user: root
|
|
||||||
|
|
||||||
vars:
|
|
||||||
debug_enabled_default: false
|
|
||||||
|
|
||||||
users:
|
|
||||||
- username: testuser101
|
|
||||||
password: $6$/y5RGZnFaD3f$96xVdOAnldEtS__NEW_SHOULD_NOT_CHANGE__bFymeKH/1Rxd3k.RQfpgebM6amLK3xAaycybdc.60
|
|
||||||
update_password: on_create
|
|
||||||
comment: Test User 100
|
|
||||||
shell: /bin/bash
|
|
||||||
ssh_key: |
|
|
||||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx8crAHG/a9QBD4zO0ZHIjdRXy+ySKviXVCMIJ3/NMIAAzDyIsPKToUJmIApHHHF1/hBllqzBSkPEMwgFbXjyqTeVPHF8V0iq41n0kgbulJG testuser101@server1
|
|
||||||
ssh-rsa AAAA.... testuser101@server2
|
|
||||||
exclusive_ssh_key: yes
|
|
||||||
use_sudo: no
|
|
||||||
user_state: present
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
- username: testuser102
|
|
||||||
password: $6$F/KXFzMa$ZIDqtYtM6sOC3UmRnt__NEW_SHOULD_CHANGE__6jxskXpve8l6DYsQyI1FT8N5I5cL0YkzW7bLbSCMtUw1
|
|
||||||
update_password: always
|
|
||||||
comment: Test User 101
|
|
||||||
groups: testnew102
|
|
||||||
shell: /bin/sh
|
|
||||||
use_sudo: yes
|
|
||||||
user_state: present
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
- username: testuser103
|
|
||||||
update_password: always
|
|
||||||
use_sudo: no
|
|
||||||
user_state: present
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
- username: testuser104
|
|
||||||
ssh_key: ssh-rsa AAABNEW.... test104@server
|
|
||||||
exclusive_ssh_key: yes
|
|
||||||
use_sudo: no
|
|
||||||
user_state: present
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
- username: testuser105
|
|
||||||
uid: 1099
|
|
||||||
password: $6$XEnyI5UYSw$Rlc6tXtECtqdJ3uFitrbBlec1/8Fx2obfgFST419ntJqaX8sfPQ9xR7vj7dGhQsfX8zcSX3tumzR7/vwlIH6p/
|
|
||||||
primarygroup: group105primary
|
|
||||||
ssh_key: ssh-rsa AAAB.... test107@server
|
|
||||||
use_sudo: no
|
|
||||||
user_state: lock
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
- username: testuser106
|
|
||||||
user_state: present
|
|
||||||
primarygroup: group106primary
|
|
||||||
primarygid: 2222
|
|
||||||
groups: groupcommon
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
|
|
||||||
- username: testuser107
|
|
||||||
user_state: present
|
|
||||||
groups: groupcommon, testgroupweb
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
|
|
||||||
- username: testuser107
|
|
||||||
user_state: present
|
|
||||||
groups: groupcommon, testgroupdb
|
|
||||||
servers:
|
|
||||||
- database
|
|
||||||
|
|
||||||
roles:
|
|
||||||
- ansible-role-create-users
|
|
|
@ -1,126 +0,0 @@
|
||||||
---
|
|
||||||
- hosts: localhost
|
|
||||||
remote_user: root
|
|
||||||
|
|
||||||
vars:
|
|
||||||
debug_enabled_default: false
|
|
||||||
|
|
||||||
users:
|
|
||||||
- username: testuser101
|
|
||||||
password: $6$/y5RGZnFaD3f$96xVdOAnldEtSxivDY02h.DwPTrJgGQl8/MTRRrFAwKTYbFymeKH/1Rxd3k.RQfpgebM6amLK3xAaycybdc.60
|
|
||||||
update_password: on_create
|
|
||||||
comment: Test User 100
|
|
||||||
shell: /bin/bash
|
|
||||||
ssh_key: |
|
|
||||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx8crAHG/a9QBD4zO0ZHIjdRXy+ySKviXVCMIJ3/NMIAAzDyIsPKToUJmIApHHHF1/hBllqzBSkPEMwgFbXjyqTeVPHF8V0iq41n0kgbulJG testuser101@server1
|
|
||||||
ssh-rsa AAAA.... testuser101@server2
|
|
||||||
exclusive_ssh_key: yes
|
|
||||||
use_sudo: no
|
|
||||||
user_state: present
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
- username: testuser102
|
|
||||||
password: $6$F/KXFzMa$ZIDqtYtM6sOC3UmRntVsTcy1rnsvw.6tBquOhX7Sb26jxskXpve8l6DYsQyI1FT8N5I5cL0YkzW7bLbSCMtUw1
|
|
||||||
update_password: always
|
|
||||||
comment: Test User 101
|
|
||||||
groups: testnew102
|
|
||||||
shell: /bin/sh
|
|
||||||
use_sudo: yes
|
|
||||||
user_state: present
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
- username: testuser103
|
|
||||||
password: $6$wBxBAqRmG6O$gPbg9hYShkuIe3YKMFujwiKsPKZHNFwoK4yCyTOlploljz53YSoPdCn9P5k8Qm0z062Q.8hvJ6DnnQQjwtrnS0
|
|
||||||
update_password: always
|
|
||||||
use_sudo: no
|
|
||||||
user_state: present
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
- username: testuser104
|
|
||||||
ssh_key: ssh-rsa AAAB.... test104@server
|
|
||||||
exclusive_ssh_key: no
|
|
||||||
use_sudo: no
|
|
||||||
user_state: present
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
- username: testuser105
|
|
||||||
uid: 1099
|
|
||||||
password: $6$XEnyI5UYSw$Rlc6tXtECtqdJ3uFitrbBlec1/8Fx2obfgFST419ntJqaX8sfPQ9xR7vj7dGhQsfX8zcSX3tumzR7/vwlIH6p/
|
|
||||||
primarygroup: group105primary
|
|
||||||
ssh_key: ssh-rsa AAAB.... test107@server
|
|
||||||
use_sudo: no
|
|
||||||
user_state: lock
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
- username: testuser106
|
|
||||||
user_state: present
|
|
||||||
primarygroup: group106primary
|
|
||||||
primarygid: 2222
|
|
||||||
groups: groupcommon
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
|
|
||||||
- username: testuser107
|
|
||||||
user_state: present
|
|
||||||
groups: groupcommon, testgroupweb
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
|
|
||||||
- username: testuser107
|
|
||||||
user_state: present
|
|
||||||
groups: groupcommon, testgroupdb
|
|
||||||
servers:
|
|
||||||
- database
|
|
||||||
|
|
||||||
- username: testuser108
|
|
||||||
user_state: present
|
|
||||||
generate_ssh_key: yes
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
- username: testuser109
|
|
||||||
user_state: present
|
|
||||||
generate_ssh_key: yes
|
|
||||||
ssh_key_bits: 4096
|
|
||||||
ssh_key_passphrase: "use_vault_instead_of_cleartext_for_production"
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
- username: testuser110
|
|
||||||
user_state: present
|
|
||||||
generate_ssh_key: no
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
- username: testuser111
|
|
||||||
user_state: present
|
|
||||||
system: yes
|
|
||||||
servers:
|
|
||||||
- webserver
|
|
||||||
- database
|
|
||||||
- monitoring
|
|
||||||
|
|
||||||
roles:
|
|
||||||
- ansible-role-create-users
|
|
Loading…
Reference in a new issue