├── tests ├── .bashrc ├── id_rsa.pub ├── main.yml └── id_rsa ├── .ansible-lint ├── .vscode ├── extensions.json └── settings.json ├── .gitignore ├── tasks ├── main.yml ├── manage.yml ├── manage_user.yml └── manage_user_home.yml ├── .clog.toml ├── .editorconfig ├── meta ├── readme.yml └── main.yml ├── LICENSE ├── Makefile ├── defaults └── main.yml ├── .travis.yml ├── README.md └── CHANGELOG.md /tests/.bashrc: -------------------------------------------------------------------------------- 1 | # .bashrc file 2 | -------------------------------------------------------------------------------- /.ansible-lint: -------------------------------------------------------------------------------- 1 | exclude_paths: 2 | - ./meta/readme.yml 3 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "vscoss.vscode-ansible" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "*.yml": "ansible", 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.retry 3 | .DS_Store 4 | .vagrant 5 | .vscode/* 6 | !.vscode/settings.json 7 | !.vscode/extensions.json 8 | .idea 9 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - import_tasks: manage.yml 4 | tags: 5 | - system 6 | - users 7 | - manage 8 | - users-manage 9 | -------------------------------------------------------------------------------- /.clog.toml: -------------------------------------------------------------------------------- 1 | [clog] 2 | changelog = "CHANGELOG.md" 3 | repository = "https://github.com/weareinteractive/ansible-users" 4 | from-latest-tag = true 5 | -------------------------------------------------------------------------------- /tests/id_rsa.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key 2 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | # Change these settings to your own preference 9 | indent_size = 2 10 | indent_style = space 11 | 12 | # We recommend you to keep these unchanged 13 | charset = utf-8 14 | end_of_line = lf 15 | insert_final_newline = true 16 | trim_trailing_whitespace = true 17 | 18 | [Makefile] 19 | indent_style = tab 20 | -------------------------------------------------------------------------------- /tasks/manage.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Adding primary group 4 | ansible.builtin.group: 5 | name: "{{ users_group }}" 6 | state: present 7 | when: users_group is defined and users_group 8 | 9 | - name: Adding secondary groups 10 | ansible.builtin.group: 11 | name: "{{ item }}" 12 | state: present 13 | with_items: "{{ users_groups | default([]) }}" 14 | 15 | - name: Configure users 16 | include_tasks: manage_user.yml 17 | with_items: "{{ users }}" 18 | loop_control: 19 | loop_var: user 20 | 21 | - name: Removing users 22 | ansible.builtin.user: 23 | name: "{{ item.username if item.username is defined else item }}" 24 | state: absent 25 | remove: "{{ item.remove if item.remove is defined else omit }}" 26 | with_items: "{{ users_remove }}" 27 | -------------------------------------------------------------------------------- /meta/readme.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | galaxy_name: weareinteractive.users 4 | github_user: weareinteractive 5 | github_name: ansible-users 6 | badges: | 7 | [![Build Status](https://img.shields.io/travis/weareinteractive/ansible-users.svg)](https://travis-ci.org/weareinteractive/ansible-users) 8 | [![Galaxy](http://img.shields.io/badge/galaxy-weareinteractive.users-blue.svg)](https://galaxy.ansible.com/weareinteractive/users) 9 | [![GitHub tag](https://img.shields.io/github/tag/weareinteractive/ansible-users.svg)](https://github.com/weareinteractive/ansible-users/releases) 10 | [![GitHub stars](https://img.shields.io/github/stars/weareinteractive/ansible-users.svg?style=social&label=Star)](https://github.com/weareinteractive/ansible-users) 11 | description: | 12 | > * manages users and groups membership 13 | > * manages user's private key 14 | > * manages user's authorized keys 15 | 16 | **Note:** 17 | 18 | > Since Ansible Galaxy switched all role names to the organization name, this role has moved from `franklinkim.users` to `weareinteractive.users`! 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) We Are Interactive 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /tasks/manage_user.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: "Adding user '{{ user.username }}' to the system" 4 | ansible.builtin.user: 5 | name: "{{ user.username }}" 6 | uid: "{{ user.uid | default(omit) }}" 7 | home: "{{ user.home | default(users_home ~ '/' ~ user.username ) }}" 8 | comment: "{{ user.name | default(omit) }}" 9 | system: "{{ user.system | default(omit) }}" 10 | generate_ssh_key: "{{ user.ssh_key_generate | default(omit) }}" 11 | group: "{{ 12 | omit if user.group is defined and user.group == user.username 13 | else (user.group if user.group is defined else (users_group if users_group else omit)) 14 | }}" 15 | groups: "{{ user.groups|join(',') if user.groups is defined else users_groups|join(',') }}" 16 | append: "{{ user.append | default(omit) }}" 17 | password: "{{ user.password | default(omit) }}" 18 | ssh_key_file: ".ssh/id_{{ user.ssh_key_type | default(users_ssh_key_type) }}" 19 | ssh_key_passphrase: "{{ user.ssh_key_password | default(omit) }}" 20 | ssh_key_bits: "{{ user.ssh_key_bits | default(users_ssh_key_bits) }}" 21 | createhome: "{{ user.home_create | default(users_home_create) }}" 22 | shell: "{{ user.shell | default(users_shell | default(omit)) }}" 23 | update_password: "{{ user.update_password | default(omit) }}" 24 | when: user.user_create | default(users_user_create) 25 | 26 | - name: Configuring user's home 27 | import_tasks: manage_user_home.yml 28 | when: user.home_create | default(users_home_create) 29 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PWD=$(shell pwd) 2 | ROLE_NAME=weareinteractive.users 3 | ROLE_PATH=/etc/ansible/roles/$(ROLE_NAME) 4 | TEST_VERSION=ansible --version 5 | TEST_SYNTAX=ansible-playbook -v -i 'localhost,' -c local $(ROLE_PATH)/tests/main.yml --syntax-check 6 | TEST_PLAYBOOK=ansible-playbook -v -i 'localhost,' -c local $(ROLE_PATH)/tests/main.yml 7 | TEST_IDEMPOTENT=$(TEST_PLAYBOOK) | grep -q 'failed=0' && (echo 'Idempotence test: pass' && exit 0) || (echo 'Idempotence test: fail' && exit 1) 8 | TEST_CMD=$(TEST_VERSION); $(TEST_DEPS); $(TEST_SYNTAX); $(TEST_PLAYBOOK); $(TEST_IDEMPOTENT) 9 | 10 | docs: 11 | ansible-role docgen 12 | 13 | lint: 14 | ansible-lint . 15 | 16 | ubuntu%: TEST_DEPS=apt-get update && \ 17 | apt-get install -y python openssh-client 18 | 19 | ubuntu22.04: dist=ubuntu-22.04 20 | ubuntu22.04: .run 21 | 22 | ubuntu20.04: dist=ubuntu-20.04 23 | ubuntu20.04: .run 24 | 25 | ubuntu18.04: dist=ubuntu-18.04 26 | ubuntu18.04: .run 27 | 28 | ubuntu16.04: dist=ubuntu-16.04 29 | ubuntu16.04: .run 30 | 31 | debian%: TEST_DEPS=apt-get update && \ 32 | apt-get install -y openssh-client 33 | 34 | debian11: dist=debian-11 35 | debian11: .run 36 | 37 | debian10: dist=debian-10 38 | debian10: .run 39 | 40 | debian9: dist=debian-9 41 | debian9: .run 42 | 43 | debian8: dist=debian-8 44 | debian8: .run 45 | 46 | .run: 47 | @echo "RUN:" 48 | @echo " docker run -it --rm -v $(PWD):$(ROLE_PATH) ansiblecheck/ansiblecheck:$(dist) /bin/bash" 49 | @echo " $(TEST_CMD)" 50 | @docker run -it --rm -v $(PWD):$(ROLE_PATH) ansiblecheck/ansiblecheck:$(dist) /bin/bash -c "$(TEST_CMD)" 51 | -------------------------------------------------------------------------------- /tests/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: all 4 | become: yes 5 | roles: 6 | - weareinteractive.users 7 | vars: 8 | users: 9 | - username: root 10 | home: /root 11 | group: root 12 | authorized_keys: 13 | - "{{ lookup('file', 'tests/id_rsa.pub') }}" 14 | user_create: no 15 | - username: foobar 16 | name: Foo Bar 1 17 | - username: foobar_authorized_keys 18 | authorized_keys: 19 | - "{{ lookup('file', 'tests/id_rsa.pub') }}" 20 | home_create: yes 21 | - username: foobar_nohome 22 | home_create: no 23 | - username: foobar_groups 24 | groups: 25 | - users 26 | append: yes 27 | - username: foobar_groups_reset 28 | groups: [] 29 | group: foobar_groups_reset 30 | - username: foobar_home_mode 31 | home_mode: "0750" 32 | - username: foobar_key 33 | ssh_key: "{{ lookup('file', 'tests/id_rsa') }}" 34 | - username: foobar_keys 35 | ssh_keys: 36 | id_rsa_1: "{{ lookup('file', 'tests/id_rsa') }}" 37 | id_rsa_2: "{{ lookup('file', 'tests/id_rsa') }}" 38 | - username: foobar_key_generate 39 | ssh_key_generate: yes 40 | ssh_key_password: secret 41 | - username: foobar_system 42 | system: yes 43 | - username: foobar_file 44 | home_files: 45 | - "tests/.bashrc" 46 | users_group: staff 47 | users_groups: 48 | - www-data 49 | users_authorized_keys_exclusive: yes 50 | users_remove: 51 | - foobar 52 | - { username: foobar_key, remove: no } 53 | - { username: foobar_authorized_keys, remove: yes } 54 | 55 | -------------------------------------------------------------------------------- /tests/id_rsa: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEogIBAAKCAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzI 3 | w+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoP 4 | kcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2 5 | hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NO 6 | Td0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcW 7 | yLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQIBIwKCAQEA4iqWPJXtzZA68mKd 8 | ELs4jJsdyky+ewdZeNds5tjcnHU5zUYE25K+ffJED9qUWICcLZDc81TGWjHyAqD1 9 | Bw7XpgUwFgeUJwUlzQurAv+/ySnxiwuaGJfhFM1CaQHzfXphgVml+fZUvnJUTvzf 10 | TK2Lg6EdbUE9TarUlBf/xPfuEhMSlIE5keb/Zz3/LUlRg8yDqz5w+QWVJ4utnKnK 11 | iqwZN0mwpwU7YSyJhlT4YV1F3n4YjLswM5wJs2oqm0jssQu/BT0tyEXNDYBLEF4A 12 | sClaWuSJ2kjq7KhrrYXzagqhnSei9ODYFShJu8UWVec3Ihb5ZXlzO6vdNQ1J9Xsf 13 | 4m+2ywKBgQD6qFxx/Rv9CNN96l/4rb14HKirC2o/orApiHmHDsURs5rUKDx0f9iP 14 | cXN7S1uePXuJRK/5hsubaOCx3Owd2u9gD6Oq0CsMkE4CUSiJcYrMANtx54cGH7Rk 15 | EjFZxK8xAv1ldELEyxrFqkbE4BKd8QOt414qjvTGyAK+OLD3M2QdCQKBgQDtx8pN 16 | CAxR7yhHbIWT1AH66+XWN8bXq7l3RO/ukeaci98JfkbkxURZhtxV/HHuvUhnPLdX 17 | 3TwygPBYZFNo4pzVEhzWoTtnEtrFueKxyc3+LjZpuo+mBlQ6ORtfgkr9gBVphXZG 18 | YEzkCD3lVdl8L4cw9BVpKrJCs1c5taGjDgdInQKBgHm/fVvv96bJxc9x1tffXAcj 19 | 3OVdUN0UgXNCSaf/3A/phbeBQe9xS+3mpc4r6qvx+iy69mNBeNZ0xOitIjpjBo2+ 20 | dBEjSBwLk5q5tJqHmy/jKMJL4n9ROlx93XS+njxgibTvU6Fp9w+NOFD/HvxB3Tcz 21 | 6+jJF85D5BNAG3DBMKBjAoGBAOAxZvgsKN+JuENXsST7F89Tck2iTcQIT8g5rwWC 22 | P9Vt74yboe2kDT531w8+egz7nAmRBKNM751U/95P9t88EDacDI/Z2OwnuFQHCPDF 23 | llYOUI+SpLJ6/vURRbHSnnn8a/XG+nzedGH5JGqEJNQsz+xT2axM0/W/CRknmGaJ 24 | kda/AoGANWrLCz708y7VYgAtW2Uf1DPOIYMdvo6fxIB5i9ZfISgcJ/bbCUkFrhoH 25 | +vq/5CIWxCPp0f85R4qxxQ5ihxJ0YDQT9Jpx4TMss4PSavPaBH3RXow5Ohe+bYoQ 26 | NE5OgEXk2wVfZczCZpigBKbKZHNYcelXtTt/nP3rsCuGcM4h53s= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This role takes advantage of Ansible's user module. 3 | # All user related properties will fall back to Ansible's default values. 4 | # @see https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html 5 | # 6 | # users: 7 | # - username: foobar (required) 8 | # name: Foo Bar 9 | # uid: 1000 10 | # group: staff 11 | # password: xxxxx (a hash created with: mkpasswd) 12 | # groups: ["adm", "www-data"] 13 | # append: no (only append groups, leave others) 14 | # home_mode: "0750" 15 | # home_create: yes 16 | # home: /path/to/user/home 17 | # home_files: 18 | # - "/path/to/user/home/.bashrc" 19 | # - "/path/to/user/home/.bash_profile" 20 | # system: no 21 | # authorized_keys: 22 | # - "xxx" 23 | # - "{{ lookup('file', '/path/to/id_rsa.pub') }}" 24 | # authorized_keys_exclusive: yes 25 | # ssh_key_type: rsa 26 | # ssh_key_bits: 2048 27 | # ssh_key_password: "" 28 | # ssh_key_generate: no 29 | # ssh_key: "xxx" or "{{ lookup('file', '/path/to/id_rsa') }}" 30 | # ssh_keys: 31 | # id_rsa_1: "xxx" or "{{ lookup('file', '/path/to/id_rsa') }}" 32 | # id_rsa_2: "xxx" or "{{ lookup('file', '/path/to/id_rsa') }}" 33 | # shell: /bin/bash 34 | # update_password: always 35 | # user_create: yes 36 | # 37 | # users_remove: 38 | # - foobar 39 | # - { username: foobar, remove: no } 40 | 41 | # list of users to add 42 | users: [] 43 | # create the users 44 | users_user_create: yes 45 | # default user's dotfiles 46 | users_home_files: [] 47 | # users home directory 48 | users_home: /home 49 | # create user's home directory 50 | users_home_create: yes 51 | # default user's primary group for users 52 | users_group: 53 | # default user's secondary groups 54 | users_groups: [] 55 | # default user's home directory permissions 56 | users_home_mode: "0755" 57 | # default user login shell 58 | #users_shell: 59 | # default user's ssh key type 60 | users_ssh_key_type: rsa 61 | # default user's ssh key bits 62 | users_ssh_key_bits: 2048 63 | # default user's setting for authorized keys exclusive 64 | users_authorized_keys_exclusive: no 65 | # list of users to be removed 66 | users_remove: [] 67 | -------------------------------------------------------------------------------- /tasks/manage_user_home.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Setting user's home permissions 4 | file: 5 | dest: "{{ user.home | default(users_home ~ '/' ~ user.username) }}" 6 | owner: "{{ user.username }}" 7 | group: "{{ user.group if user.group is defined else (users_group if users_group else user.username) }}" 8 | mode: "{{ user.home_mode if user.home_mode is defined else users_home_mode }}" 9 | ignore_errors: "{{ ansible_check_mode }}" 10 | 11 | - name: Adding user's .ssh directory 12 | file: 13 | path: "{{ user.home | default(users_home ~ '/' ~ user.username) }}/.ssh" 14 | owner: "{{ user.username }}" 15 | group: "{{ user.group if user.group is defined else (users_group if users_group else user.username) }}" 16 | state: directory 17 | mode: 0700 18 | 19 | - name: Adding user's private SSH key 20 | copy: 21 | content: "{{ user.ssh_key }}" 22 | dest: "{{ user.home | default(users_home ~ '/' ~ user.username) }}/.ssh/id_{{ user.ssh_key_type | default('rsa') }}" 23 | owner: "{{ user.username }}" 24 | group: "{{ user.group if user.group is defined else (users_group if users_group else user.username) }}" 25 | mode: 0600 26 | when: user.ssh_key is defined 27 | no_log: true 28 | 29 | - name: Adding user's private keys 30 | copy: 31 | content: "{{ item.value }}" 32 | dest: "{{ user.home | default(users_home ~ '/' ~ user.username) }}/.ssh/{{ item.key }}" 33 | owner: "{{ user.username }}" 34 | group: "{{ user.group if user.group is defined else (users_group if users_group else user.username) }}" 35 | mode: 0600 36 | when: user.ssh_key is not defined and user.ssh_keys is defined 37 | with_dict: "{{ user.ssh_keys }}" 38 | 39 | - name: Adding user's authorized SSH keys 40 | authorized_key: 41 | key: "{{ user.authorized_keys | default([]) | join('\n') }}" 42 | user: "{{ user.username }}" 43 | exclusive: "{{ user.authorized_keys_exclusive | default(users_authorized_keys_exclusive) }}" 44 | ignore_errors: "{{ ansible_check_mode }}" 45 | 46 | - name: Adding user's home files 47 | copy: 48 | src: "{{ home_file }}" 49 | dest: "{{ user.home | default(users_home ~ '/' ~ user.username) }}/{{ home_file | basename }}" 50 | owner: "{{ user.username }}" 51 | group: "{{ user.group if user.group is defined else (users_group if users_group else user.username) }}" 52 | with_items: "{{ user.home_files | default(users_home_files) }}" 53 | loop_control: 54 | loop_var: home_file 55 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: franklin 4 | company: We Are Interactive 5 | description: Manages users 6 | min_ansible_version: 2.4 7 | license: MIT 8 | # Optionally specify the branch Galaxy will use when accessing the GitHub 9 | # repo for this role. During role install, if no tags are available, 10 | # Galaxy will use this branch. During import Galaxy will access files on 11 | # this branch. If travis integration is cofigured, only notification for this 12 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 13 | # (usually master) will be used. 14 | github_branch: master 15 | # 16 | # Below are all platforms currently available. Just uncomment 17 | # the ones that apply to your role. If you don't see your 18 | # platform on this list, let us know and we'll get it added! 19 | # 20 | platforms: 21 | - name: EL 22 | versions: 23 | # - all 24 | # - 5 25 | # - 6 26 | - 7 27 | #- name: GenericUNIX 28 | # versions: 29 | # - all 30 | # - any 31 | #- name: Solaris 32 | # versions: 33 | # - all 34 | # - 10 35 | # - 11.0 36 | # - 11.1 37 | # - 11.2 38 | # - 11.3 39 | #- name: Fedora 40 | # versions: 41 | # - all 42 | # - 16 43 | # - 17 44 | # - 18 45 | # - 19 46 | # - 20 47 | # - 21 48 | # - 22 49 | # - 23 50 | #- name: Windows 51 | # versions: 52 | # - all 53 | # - 2012R2 54 | #- name: SmartOS 55 | # versions: 56 | # - all 57 | # - any 58 | #- name: opensuse 59 | # versions: 60 | # - all 61 | # - 12.1 62 | # - 12.2 63 | # - 12.3 64 | # - 13.1 65 | # - 13.2 66 | #- name: Amazon 67 | # versions: 68 | # - all 69 | # - 2013.03 70 | # - 2013.09 71 | #- name: GenericBSD 72 | # versions: 73 | # - all 74 | # - any 75 | #- name: FreeBSD 76 | # versions: 77 | # - all 78 | # - 10.0 79 | # - 10.1 80 | # - 10.2 81 | # - 8.0 82 | # - 8.1 83 | # - 8.2 84 | # - 8.3 85 | # - 8.4 86 | # - 9.0 87 | # - 9.1 88 | # - 9.1 89 | # - 9.2 90 | # - 9.3 91 | - name: Ubuntu 92 | versions: 93 | - all 94 | # - lucid 95 | # - maverick 96 | # - natty 97 | # - oneiric 98 | # - precise 99 | # - quantal 100 | # - raring 101 | # - saucy 102 | # - trusty 103 | # - utopic 104 | # - vivid 105 | # - wily 106 | #- name: SLES 107 | # versions: 108 | # - all 109 | # - 10SP3 110 | # - 10SP4 111 | # - 11 112 | # - 11SP1 113 | # - 11SP2 114 | # - 11SP3 115 | #- name: GenericLinux 116 | # versions: 117 | # - all 118 | # - any 119 | - name: Debian 120 | versions: 121 | - all 122 | # - etch 123 | # - jessie 124 | # - lenny 125 | # - squeeze 126 | # - wheezy categories: 127 | # 128 | # List tags for your role here, one per line. A tag is 129 | # a keyword that describes and categorizes the role. 130 | # Users find roles by searching for tags. Be sure to 131 | # remove the '[]' above if you add tags to this list. 132 | # 133 | # NOTE: A tag is limited to a single word comprised of 134 | # alphanumeric characters. Maximum 20 tags per role. 135 | galaxy_tags: 136 | - system 137 | - users 138 | - user 139 | - ssh 140 | # List your role dependencies here, one per line. Only 141 | # dependencies available via galaxy should be listed here. 142 | # Be sure to remove the '[]' above if you add dependencies 143 | # to this list. 144 | dependencies: [] 145 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | sudo: required 3 | language: python 4 | services: 5 | - docker 6 | env: 7 | global: 8 | - role: weareinteractive.users 9 | matrix: 10 | - distribution: Ubuntu 11 | distribution_version: "22.04" 12 | init: /lib/systemd/systemd 13 | run_opts: "'--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro'" 14 | before_test: "'apt-get update && apt-get install -y python openssh-client'" 15 | - distribution: Ubuntu 16 | distribution_version: "20.04" 17 | init: /lib/systemd/systemd 18 | run_opts: "'--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro'" 19 | before_test: "'apt-get update && apt-get install -y python openssh-client'" 20 | - distribution: Ubuntu 21 | distribution_version: "18.04" 22 | init: /lib/systemd/systemd 23 | run_opts: "'--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro'" 24 | before_test: "'apt-get update && apt-get install -y python openssh-client'" 25 | - distribution: Ubuntu 26 | distribution_version: "16.04" 27 | init: /lib/systemd/systemd 28 | run_opts: "'--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro'" 29 | before_test: "'apt-get update && apt-get install -y openssh-client'" 30 | - distribution: Debian 31 | distribution_version: "11" 32 | init: /lib/systemd/systemd 33 | run_opts: "'--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro'" 34 | before_test: "'apt-get update && apt-get install -y openssh-client'" 35 | - distribution: Debian 36 | distribution_version: "10" 37 | init: /lib/systemd/systemd 38 | run_opts: "'--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro'" 39 | before_test: "'apt-get update && apt-get install -y openssh-client'" 40 | - distribution: Debian 41 | distribution_version: "9" 42 | init: /lib/systemd/systemd 43 | run_opts: "'--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro'" 44 | before_test: "'apt-get update && apt-get install -y openssh-client'" 45 | - distribution: Debian 46 | distribution_version: "8" 47 | init: /lib/systemd/systemd 48 | run_opts: "'--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro'" 49 | before_test: "'apt-get update && apt-get install -y openssh-client'" 50 | - distribution: Centos 51 | distribution_version: "7" 52 | init: /lib/systemd/systemd 53 | run_opts: "'--privileged --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro'" 54 | before_test: "'yum makecache && yum install -y openssh-clients'" 55 | 56 | before_install: 57 | - sudo apt-get update 58 | - sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce 59 | - docker pull ansiblecheck/ansiblecheck:"${distribution,,}"-"${distribution_version}" 60 | 61 | script: 62 | - container_id=$(mktemp) 63 | # Start The Built Container In The Background 64 | - docker run -d -v "${PWD}":/etc/ansible/roles/${role}:ro ${run_opts} ansiblecheck/ansiblecheck:"${distribution,,}"-"${distribution_version}" "${init}" > "${container_id}" 65 | 66 | # Print ansible version 67 | - docker exec -t "$(cat ${container_id})" env TERM=xterm ansible --version 68 | 69 | # Ansible syntax check. 70 | - 'docker exec -t "$(cat ${container_id})" env TERM=xterm ansible-playbook /etc/ansible/roles/${role}/tests/main.yml --syntax-check' 71 | 72 | # Install dependencies 73 | - docker exec -t "$(cat ${container_id})" env TERM=xterm sh -c "${before_test}" 74 | 75 | # Test role. 76 | - 'docker exec "$(cat ${container_id})" env ANSIBLE_FORCE_COLOR=1 ansible-playbook /etc/ansible/roles/${role}/tests/main.yml' 77 | 78 | # Test Idempotence 79 | - idempotence=$(mktemp) 80 | - docker exec "$(cat ${container_id})" ansible-playbook /etc/ansible/roles/${role}/tests/main.yml | tee -a ${idempotence} 81 | - > 82 | tail ${idempotence} 83 | | grep -q 'failed=0' 84 | && (echo 'Idempotence test: pass' && exit 0) 85 | || (echo 'Idempotence test: fail' && exit 1) 86 | 87 | notifications: 88 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ansible weareinteractive.users role 2 | 3 | [![Build Status](https://img.shields.io/travis/weareinteractive/ansible-users.svg)](https://travis-ci.org/weareinteractive/ansible-users) 4 | [![Galaxy](http://img.shields.io/badge/galaxy-weareinteractive.users-blue.svg)](https://galaxy.ansible.com/weareinteractive/users) 5 | [![GitHub tag](https://img.shields.io/github/tag/weareinteractive/ansible-users.svg)](https://github.com/weareinteractive/ansible-users/releases) 6 | [![GitHub stars](https://img.shields.io/github/stars/weareinteractive/ansible-users.svg?style=social&label=Star)](https://github.com/weareinteractive/ansible-users) 7 | 8 | > `weareinteractive.users` is an [Ansible](http://www.ansible.com) role which: 9 | > 10 | > * manages users and groups membership 11 | > * manages user's private key 12 | > * manages user's authorized keys 13 | 14 | **Note:** 15 | 16 | > Since Ansible Galaxy switched all role names to the organization name, this role has moved from `franklinkim.users` to `weareinteractive.users`! 17 | 18 | ## Installation 19 | 20 | Using `ansible-galaxy`: 21 | 22 | ```shell 23 | $ ansible-galaxy install weareinteractive.users 24 | ``` 25 | 26 | Using `requirements.yml`: 27 | 28 | ```yaml 29 | - src: weareinteractive.users 30 | ``` 31 | 32 | Using `git`: 33 | 34 | ```shell 35 | $ git clone https://github.com/weareinteractive/ansible-users.git weareinteractive.users 36 | ``` 37 | 38 | ## Dependencies 39 | 40 | * Ansible >= 2.4 41 | 42 | ## Variables 43 | 44 | Here is a list of all the default variables for this role, which are also available in `defaults/main.yml`. 45 | 46 | ```yaml 47 | --- 48 | # This role takes advantage of Ansible's user module. 49 | # All user related properties will fall back to Ansible's default values. 50 | # @see https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html 51 | # 52 | # users: 53 | # - username: foobar (required) 54 | # name: Foo Bar 55 | # uid: 1000 56 | # group: staff 57 | # password: xxxxx (a hash created with: mkpasswd) 58 | # groups: ["adm", "www-data"] 59 | # append: no (only append groups, leave others) 60 | # home_mode: "0750" 61 | # home_create: yes 62 | # home: /path/to/user/home 63 | # home_files: 64 | # - "/path/to/user/home/.bashrc" 65 | # - "/path/to/user/home/.bash_profile" 66 | # system: no 67 | # authorized_keys: 68 | # - "xxx" 69 | # - "{{ lookup('file', '/path/to/id_rsa.pub') }}" 70 | # authorized_keys_exclusive: yes 71 | # ssh_key_type: rsa 72 | # ssh_key_bits: 2048 73 | # ssh_key_password: "" 74 | # ssh_key_generate: no 75 | # ssh_key: "xxx" or "{{ lookup('file', '/path/to/id_rsa') }}" 76 | # ssh_keys: 77 | # id_rsa_1: "xxx" or "{{ lookup('file', '/path/to/id_rsa') }}" 78 | # id_rsa_2: "xxx" or "{{ lookup('file', '/path/to/id_rsa') }}" 79 | # shell: /bin/bash 80 | # update_password: always 81 | # user_create: yes 82 | # 83 | # users_remove: 84 | # - foobar 85 | # - { username: foobar, remove: no } 86 | 87 | # list of users to add 88 | users: [] 89 | # create the users 90 | users_user_create: yes 91 | # default user's dotfiles 92 | users_home_files: [] 93 | # users home directory 94 | users_home: /home 95 | # create user's home directory 96 | users_home_create: yes 97 | # default user's primary group for users 98 | users_group: 99 | # default user's secondary groups 100 | users_groups: [] 101 | # default user's home directory permissions 102 | users_home_mode: "0755" 103 | # default user login shell 104 | #users_shell: 105 | # default user's ssh key type 106 | users_ssh_key_type: rsa 107 | # default user's ssh key bits 108 | users_ssh_key_bits: 2048 109 | # default user's setting for authorized keys exclusive 110 | users_authorized_keys_exclusive: no 111 | # list of users to be removed 112 | users_remove: [] 113 | 114 | ``` 115 | 116 | 117 | ## Usage 118 | 119 | This is an example playbook: 120 | 121 | ```yaml 122 | --- 123 | 124 | - hosts: all 125 | become: yes 126 | roles: 127 | - weareinteractive.users 128 | vars: 129 | users: 130 | - username: root 131 | home: /root 132 | group: root 133 | authorized_keys: 134 | - "{{ lookup('file', 'tests/id_rsa.pub') }}" 135 | user_create: no 136 | - username: foobar 137 | name: Foo Bar 1 138 | - username: foobar_authorized_keys 139 | authorized_keys: 140 | - "{{ lookup('file', 'tests/id_rsa.pub') }}" 141 | home_create: yes 142 | - username: foobar_nohome 143 | home_create: no 144 | - username: foobar_groups 145 | groups: 146 | - users 147 | append: yes 148 | - username: foobar_groups_reset 149 | groups: [] 150 | group: foobar_groups_reset 151 | - username: foobar_home_mode 152 | home_mode: "0750" 153 | - username: foobar_key 154 | ssh_key: "{{ lookup('file', 'tests/id_rsa') }}" 155 | - username: foobar_keys 156 | ssh_keys: 157 | id_rsa_1: "{{ lookup('file', 'tests/id_rsa') }}" 158 | id_rsa_2: "{{ lookup('file', 'tests/id_rsa') }}" 159 | - username: foobar_key_generate 160 | ssh_key_generate: yes 161 | ssh_key_password: secret 162 | - username: foobar_system 163 | system: yes 164 | - username: foobar_file 165 | home_files: 166 | - "tests/.bashrc" 167 | users_group: staff 168 | users_groups: 169 | - www-data 170 | users_authorized_keys_exclusive: yes 171 | users_remove: 172 | - foobar 173 | - { username: foobar_key, remove: no } 174 | - { username: foobar_authorized_keys, remove: yes } 175 | 176 | 177 | ``` 178 | 179 | 180 | ## Testing 181 | 182 | ```shell 183 | $ git clone https://github.com/weareinteractive/ansible-users.git 184 | $ cd ansible-users 185 | $ make test 186 | ``` 187 | 188 | ## Contributing 189 | In lieu of a formal style guide, take care to maintain the existing coding style. Add unit tests and examples for any new or changed functionality. 190 | 191 | 1. Fork it 192 | 2. Create your feature branch (`git checkout -b my-new-feature`) 193 | 3. Commit your changes (`git commit -am 'Add some feature'`) 194 | 4. Push to the branch (`git push origin my-new-feature`) 195 | 5. Create new Pull Request 196 | 197 | *Note: To update the `README.md` file please install and run `ansible-role`:* 198 | 199 | ```shell 200 | $ gem install ansible-role 201 | $ ansible-role docgen 202 | ``` 203 | 204 | ## License 205 | Copyright (c) We Are Interactive under the MIT license. 206 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ## 1.17.0 (2020-11-06) 3 | 4 | 5 | #### Features 6 | 7 | * add `users_user_create` and `user.user_create` option ([daa876ee](https://github.com/weareinteractive/ansible-users/commit/daa876ee0c9d9839a899668ebe65a5504a7bf2b0)) 8 | 9 | 10 | 11 | 12 | ## 1.16.0 (2020-06-21) 13 | 14 | 15 | #### Features 16 | 17 | * ignore root user ([55d3c48f](https://github.com/weareinteractive/ansible-users/commit/55d3c48fd011eb37c51492714ff3bb4d6a232c4a)) 18 | 19 | 20 | 21 | 22 | ## 1.15.0 (2020-04-04) 23 | 24 | 25 | #### Features 26 | 27 | * allow to keep user directories on delete ([cd363ce7](https://github.com/weareinteractive/ansible-users/commit/cd363ce78d13cf8e641b1fa743f88da627935239)) 28 | 29 | 30 | 31 | 32 | ### 1.14.1 (2020-03-17) 33 | 34 | 35 | #### Features 36 | 37 | * set no_log on private key ([b31ba4c7](https://github.com/weareinteractive/ansible-users/commit/b31ba4c7e4dce1b3a0250fa70d0d7f8257403b6e)) 38 | 39 | 40 | 41 | 42 | ## 1.14.0 (2020-02-04) 43 | 44 | 45 | #### Features 46 | 47 | * add `ssh_keys` option for mutiple keys 48 | 49 | 50 | 51 | ### 1.13.1 (2019-10-17) 52 | 53 | 54 | #### Features 55 | 56 | * test and document centos7 support ([bda06a8c](https://github.com/weareinteractive/ansible-users/commit/bda06a8cf77f198bf659b1c795a4e5a759a04b5e)) 57 | 58 | 59 | 60 | 61 | ## 1.13.0 (2019-07-10) 62 | 63 | 64 | #### Features 65 | 66 | * add default values ([b5bc7116](https://github.com/weareinteractive/ansible-users/commit/b5bc7116ab64e9e01c972a8bf944e0d4def837c3)) 67 | 68 | 69 | 70 | 71 | ## 1.12.0 (2019-06-17) 72 | 73 | 74 | #### Bug Fixes 75 | 76 | * fix directory not found in check mode ([57d10aa7](https://github.com/weareinteractive/ansible-users/commit/57d10aa765331429f91e3e1c6210f15ff5f0a1dc)) 77 | 78 | 79 | 80 | 81 | ### 1.11.2 (2019-03-16) 82 | 83 | 84 | #### Bug Fixes 85 | 86 | * remove comment in private key file ([24ca28a7](https://github.com/weareinteractive/ansible-users/commit/24ca28a79b69d138e136d302452aa1a4a9a88d34)) 87 | 88 | 89 | 90 | 91 | ### 1.11.1 (2019-02-10) 92 | 93 | 94 | 95 | 96 | 97 | ## 1.11.0 (2018-12-11) 98 | 99 | 100 | #### Features 101 | 102 | * adopt galaxy role name ([55a97e7d](https://github.com/weareinteractive/ansible-users/commit/55a97e7da4444af230a1621e7cd68ed80ec41a3a)) 103 | 104 | 105 | 106 | 107 | ## 1.10.0 (2018-09-13) 108 | 109 | 110 | #### Features 111 | 112 | * add home_files to user ([43d50f22](https://github.com/weareinteractive/ansible-users/commit/43d50f2265958889b1f73dd4fd8da3fbaeb42d1b)) 113 | 114 | #### Bug Fixes 115 | 116 | * add skip for missing attributes ([11db5434](https://github.com/weareinteractive/ansible-users/commit/11db5434588e868b76d16404b242d2731333b966)) 117 | 118 | 119 | 120 | 121 | ### 1.9.3 (2018-05-13) 122 | 123 | 124 | 125 | 126 | 127 | ### 1.9.2 (2018-01-25) 128 | 129 | 130 | #### Features 131 | 132 | * change gitignore rules ([6e50c90e](https://github.com/weareinteractive/ansible-users/commit/6e50c90e2d7a43392492bb0a9e662dd5f3da6188)) 133 | * add makefile format ([5c51d0fe](https://github.com/weareinteractive/ansible-users/commit/5c51d0fe1d99240a95dbfa791da62de3e2c57ab6)) 134 | 135 | 136 | 137 | 138 | ### 1.9.1 (2017-11-10) 139 | 140 | 141 | 142 | 143 | 144 | ## 1.8.0 (2017-06-21) 145 | 146 | 147 | #### Features 148 | 149 | * bump ansible version to 2.0 ([b4c39b06](https://github.com/weareinteractive/ansible-users/commit/b4c39b0653ac425a34b5162af0309465cd7284c8)) 150 | * add append flag to users ([c4bffe1b](https://github.com/weareinteractive/ansible-users/commit/c4bffe1b7cc44d557b2b88ac1925f19c92f85f6d)) 151 | 152 | 153 | 154 | 155 | ### 1.7.1 (2017-02-14) 156 | 157 | 158 | #### Features 159 | 160 | * add update_password flag ([d3511ffe](https://github.com/weareinteractive/ansible-users/commit/d3511ffee448b691965ad4b976a7b32e7dc8824d)) 161 | 162 | 163 | 164 | 165 | ## 1.7.0 (2016-08-02) 166 | 167 | 168 | #### Features 169 | 170 | * add `users_remove` ([d06f860d](https://github.com/weareinteractive/ansible-users/commit/d06f860d064da9115331224ec16fcfe5db91fa82)) 171 | * optimize authorized keys management ([382d7c2e](https://github.com/weareinteractive/ansible-users/commit/382d7c2e9f7edc987c2f8b0679fc27cdfdc9c6b6)) 172 | 173 | 174 | 175 | 176 | ### 1.6.1 (2016-05-30) 177 | 178 | 179 | 180 | 181 | 182 | ## 1.6.0 (2016-05-09) 183 | 184 | 185 | #### Features 186 | 187 | * add password and shell variables ([93b48f0e](https://github.com/weareinteractive/ansible-users/commit/93b48f0eb0e9c547717a5679f9dbc14a18d32b17)) 188 | 189 | 190 | 191 | 192 | ## 1.5.0 (2016-04-18) 193 | 194 | 195 | #### Bug Fixes 196 | 197 | * fix 'when' clause when adding the primary user group ([9fec282d](https://github.com/weareinteractive/ansible-users/commit/9fec282d4635eeb808837c4ce9ddfed25ce7bffd)) 198 | * fix deprecation warnings in ansible 2.0 199 | 200 | 201 | 202 | ## 1.4.0 (2016-04-14) 203 | 204 | 205 | #### Features 206 | 207 | * make sure groups are available ([232fe41b](https://github.com/weareinteractive/ansible-users/commit/232fe41b47372177492789e7a9f1ee5bb851de2e)) 208 | 209 | 210 | 211 | 212 | ## 1.3.0 (2015-12-11) 213 | 214 | 215 | #### Breaking Changes 216 | 217 | * move config.yml tasks to manage.yml since it belongs in that context ([a1edf947](https://github.com/weareinteractive/ansible-users/commit/a1edf94719275b4f204105807ee32d21dd3319d2)) 218 | 219 | #### Features 220 | 221 | * adds galaxy_tags ([082d43cd](https://github.com/weareinteractive/ansible-users/commit/082d43cd4cadbfacb9e6c57e54dfdf3d17f31db8)) 222 | * move config.yml tasks to manage.yml since it belongs in that context ([a1edf947](https://github.com/weareinteractive/ansible-users/commit/a1edf94719275b4f204105807ee32d21dd3319d2)) 223 | * adds CHANGELOG ([3a39f74c](https://github.com/weareinteractive/ansible-users/commit/3a39f74cb6ba1bea4fda7483122bae889ac6251e)) 224 | * using ansible-role docgen for README geneartion ([7c16c027](https://github.com/weareinteractive/ansible-users/commit/7c16c02716a65af4e90916bf88bf0083a5a902d1)) 225 | * use `authorized_key` module instead of template ([a6d96f43](https://github.com/weareinteractive/ansible-users/commit/a6d96f4358e601c9c634b43629e8e9304f0e395e), closes [#5](https://github.com/weareinteractive/ansible-users/issues/5)) 226 | --------------------------------------------------------------------------------