GithubHelp home page GithubHelp logo

ryandaniels / ansible-role-create-users Goto Github PK

View Code? Open in Web Editor NEW
100.0 6.0 59.0 55 KB

Manage users on Linux using Ansible

Home Page: https://galaxy.ansible.com/ryandaniels/create_users

License: MIT License

ansible ansible-role

ansible-role-create-users's Introduction

ansible-role-create-users

CI

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. all is also supported to apply to every host in an inventory file.

More detailed example can be found in the blog post: User Management with Ansible

Note: Deleting users is not done on purpose.

Distros tested

  • Ubuntu 22.04, 20.04, 18.04, 16.04
  • CentOS / RHEL: 9.1, 8.x, 7.x, 6.5, 5.9

Dependencies

Requires Ansible 2.6 (due to previous bug 20096 with un-expiring users)

ansible-vault

Use ansible-vault to encrypt sensitive info from git.

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

vi .gitignore
#Insert the following lines
.vaultpass
.retry
secret
*.secret

How to generate password

  • on Ubuntu - Install "whois" package
mkpasswd --method=SHA-512
  • on RedHat - Use Python
python -c 'import crypt,getpass; print(crypt.crypt(getpass.getpass(), crypt.mksalt(crypt.METHOD_SHA512)))'

Default Settings

---
# 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
default_generate_ssh_key_comment: "{{ item.username }}@{{ ansible_hostname }}"

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: Add authorized 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.
  • generate_ssh_key_comment: Specify the comment for the generated SSH key (optional). If not specified, will use default_generate_ssh_key_comment from defaults yaml.
  • 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

[webserver]
webserver1
webserver2
webserver3

[database]
db1
db2
db3

[monitoring]
monitor1

Example config file (vars/secret)

---
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
      - all

  - 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
    generate_ssh_key: yes
    generate_ssh_key_comment: custom comment for generated ssh key
    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

---
- 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

ansible-playbook create-users.yml --ask-vault-pass --extra-vars "inventory=all-dev" -i hosts

ansible-role-create-users's People

Contributors

baprx avatar eahlstrom avatar ryandaniels avatar vuzdemav avatar ziegenberg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

ansible-role-create-users's Issues

Have generate_ssh_key include the username

Is there any way to have generate_ssh_key include the username after the generated key (like ssh-keygen does)?

Reason for this requirement:

I have servers that can ssh to other servers under another username, and it's very confusing not to be able see which user the generated ssh key is for.

Creation of groups via comma separated list does not seem to work

Destination server: Ubuntu 18:04 LTS.

When trying to create group membership via this module, error messages like:
groupadd: '['users', 'sudo']' is not a valid group name\n are shown.

I tried adding the comma separated list with all the groups multiple ways, but it always reverts to this error, looking to me like Ansible is not understanding the format of the comma separated input. There is no example in the documentation stating the correct input format. and i have too little experience with ansible yet, to be able to reverse engineer this.

My apologies for this.

lock users

Hi there,

did you get this snippet to work?

- name: Lock users | Lock password & ssh key authentication
  user:
    name: "{{ item.0.username }}"
    expires: 0 #lock account if not locked
    #  command: change -E 0 {{ item.0.username }} #Alternative lock password & ssh key authentication
    #  register: user_results
    when: item.0.user_state == 'lock' and item.1 in groups
    with_subelements:
      - "{{ users }}"
      - servers
    loop_control:
      label: "username: {{ item.0.username }}, user_state: {{ item.0.user_state }}"

Documentation is not clear in how to setup server variables

I tried to use this Ansible Role, but ran into some issues. You might want to update the documentation about this. With errors like below, it took me a while to find the sentence "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." in the README. However it is not stated how to declare those variables, in what format or so.

At this moment running the role, will result in a message like this.
fatal: [HOSTNAME]: FAILED! => {"msg": "The conditional check '(item.0.user_state == 'present' or item.0.user_state == 'lock') and item.1 in group_names' failed. The error was: error while evaluating conditional ((item.0.user_state == 'present' or item.0.user_state == 'lock') and item.1 in group_names): 'dict object' has no attribute 'user_state'\n\nThe error appears to have been in '/home/ansible/ansible/roles/create_users/tasks/main.yml': line 19, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Add users | create users, shell, home dirs\n ^ here\n"}

Cannot ssh using created users

Hi, when I create a user and assign it an ssh key, I expect that I can ssh to the server using that user account. Could you add that feature? Maybe just simply modify the /etc/ssh/sshd_config file?

Removing a group from the "servers" list does not delete the user from those servers

Suppose there is a user joebloggs with the following permissions:

- username: joebloggs
  user_state: present
  # ...
  servers:
    - www-dev
    - www-prod

Running this role will create the user on the "www-dev" and "www-prod" hosts.

Now suppose that the user should no longer have access to production hosts, so the users entry is changed to:

- username: joebloggs
  user_state: present
  # ...
  servers:
    - www-dev

(i.e. www-prod is removed). The joebloggs user will not be deleted from existing www-prod hosts.

The role fails on check mode when adding a new user

Hey @ryandaniels, thank you for this useful role, I have an issue when creating new users if they have configured SSH public keys:

failed: [vm-1] (item=username: my-user, ssh_key: True, exclusive_ssh_key: True) => {"ansible_loop_var": "item", "changed": false, "item": {"exclusive_ssh_key": true, "servers": ["all"], "ssh_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFyipFv98/Zp0e2pljNVVvtm1dHdYCx0njinKOuVZL [email protected]\n", "use_sudo": false, "use_sudo_nopass": true, "user_state": "present", "username": "my-user"}, "msg": "Either user must exist or you must provide full path to key file in check mode"}

Our workflow fails if the check mode wasn't successful so we really need it to complete.

I've creating the following PR to address this issue: #29

I'm providing the default path /home/<username>/.ssh/authorized_keys only if the check mode is enabled, nothing when running without it.

Please tell me if you have a suggestion or any other comment about it, thank you.

couldn't resolve module/action 'authorized_key'

Playing my configuration using /ryandaniels.create_users gives me

ERROR! couldn't resolve module/action 'authorized_key'. This often indicates a misspelling, missing collection, or incorrect module path.

The error appears to be in '[...]/roles/ryandaniels.create_users/tasks/main.yml': line 119, column 3, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

- name: SSH Keys | Add authorized key for ssh key authentication
  ^ here

I found this thread on GitHub which made me think I can fix it by replacing authorized_key by ansible.posix.authorized_key, but then I get the same error for ansible.posix.authorized_key. I don't know how to fix it, and tbh I don't even know where the root cause actually is. Used to work a few months ago. Any help appreciated.

ansible --version gives me:

ansible [core 2.12.10]
  config file = /home/jenkins/workspace/Ansible Server Setup/ansible.cfg
  configured module search path = ['/home/jenkins/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/jenkins/workspace/Ansible Server Setup/collections:/home/jenkins/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.8.10 (default, Jun 22 2022, 20:18:18) [GCC 9.4.0]
  jinja version = 2.10.1
  libyaml = True

invalid key specified when using SSH keys

Hello everyone,

The execution of my playbook fails when users have SSH key(s). This is the error message (sorry for the layout, but github seems to have degraded the possibilities to write clean code...).

"msg": "invalid key specified: ['ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDNtoEXORkQPe92V60dfz5YdkKG/eXmK/kaCboh06UuGwCDhEZxXCRFtXTfleUlD2fygXrkr+w9KWWbp82XufDWZOxXCnfyJhxjstdMIljkBqg9ZxQY+D+N+bV7OhdFEGqycqX6y8/tKySf2x+i79gIq4V/mrnc8ME9iX/WMZA1Doscvhhbob0OWl3WLEjMDe1WENUbbHB23mQOI4ZF5GWV7JBX+HPYX6Gi1vWNUtw1WfEk2fAesIMbsDIemETWWZLiO+fL95TKybn7izakQobZX23Kem+7gK5iJqKIt9sDpWKcgymTL0RIE2WyAoVL7ShUVY2dkQiY9WUcGXJDAHQT matt@mshe']

However, this key is perfectly valid, as shown by the ssh-keygen -l command below.

root@pbs14200:~ # cat id_rsa_matt.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDNtoEXORkQPe92V60dfz5YdkKG/eXmK/kaCboh06UuGwCDhEZxXCRFtXTfleUlD2fygXrkr+w9KWWbp82XufDWZOxXCnfyJhxjstdMIljkBqg9ZxQY+D+N+bV7OhdFEGqycqX6y8/tKySf2x+i79gIq4V/mrnc8ME9iX/WMZA1Doscvhhbob0OWl3WLEjMDe1WENUbbHB23mQOI4ZF5GWV7JBX+HPYX6Gi1vWNUtw1WfEk2fAesIMbsDIemETWWZLiO+fL95TKybn7izakQobZX23Kem+7gK5iJqKIt9sDpWKcgymTL0RIE2WyAoVL7ShUVY2dkQiY9WUcGXJDAHQT matt@mshe

root@pbs14200:~ # ssh-keygen -l -f id_rsa_matt.pub
2048 SHA256:wxvifLRrl8wP6QUE3PMYZ0ISZXVHbZ9IgHWgjJu3VA8 matt@mshe (RSA)

I wrote the following role to create users.

- name: Include variables from sudoers.yml
  include_vars:
    file: "{{ role_path }}/defaults/sudoers.yml"

- name: Create accounts in a loop on the user dictionary
  include_role:
    name: ryandaniels.create_users
  vars:
    comment:           "{{ user_item.comment }}"
    password:          "{{ user_item.password }}"
    primarygroup:      "{{ user_item.primarygroup }}"
    ssh_key:           "{{ user_item.ssh_key }}"
    exclusive_ssh_key: "{{ user_item.exclusive_ssh_key | default(yes) }}"
    user_state:        "{{ user_item.user_state }}"
    update_password:   "{{ user_item.update_password   | default(on_create) }}"
    username:          "{{ user_item.username }}"
    use_sudo:          "{{ user_item.use_sudo }}"
    use_sudo_nopass:   "{{ user_item.use_sudo_nopass }}"
  with_items: "{{ users }}"
  loop_control:
    loop_var: user_item

the data has been organized in accordance with the documentation and the previous role, in the users dictionary.

users:
  - username: matt
    user_state: present
    comment: Mattieu Latroy
    primarygroup: matt
    password: "$6$...EhO."
    cron_allow: yes
    use_sudo: yes
    use_sudo_nopass: yes
    servers:
      - linux

    exclusive_ssh_key: yes

    ssh_key:
      - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDNtoEXORkQPe92V60dfz5YdkKG/eXmK/kaCboh06UuGwCDhEZxXCRFtXTfleUlD2fygXrkr+w9KWWbp82XufDWZOxXCnfyJhxjstdMIljkBqg9ZxQY+D+N+bV7OhdFEGqycqX6y8/tKySf2x+i79gIq4V/mrnc8ME9iX/WMZA1Doscvhhbob0OWl3WLEjMDe1WENUbbHB23mQOI4ZF5GWV7JBX+HPYX6Gi1vWNUtw1WfEk2fAesIMbsDIemETWWZLiO+fL95TKybn7izakQobZX23Kem+7gK5iJqKIt9sDpWKcgymTL0RIE2WyAoVL7ShUVY2dkQiY9WUcGXJDAHQT matt@mshe"

The debug mode shows that the data is correctly managed by the role:

        {
            "comment": "Mattieu Latroy",
            "cron_allow": true,
            "exclusive_ssh_key": true,
            "password": "$6$...EhO.",
            "primarygroup": "matt",
            "servers": [
                "linux"
            ],
            "ssh_key": [
                "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDNtoEXORkQPe92V60dfz5YdkKG/eXmK/kaCboh06UuGwCDhEZxXCRFtXTfleUlD2fygXrkr+w9KWWbp82XufDWZOxXCnfyJhxjstdMIljkBqg9ZxQY+D+N+bV7OhdFEGqycqX6y8/tKySf2x+i79gIq4V/mrnc8ME9iX/WMZA1Doscvhhbob0OWl3WLEjMDe1WENUbbHB23mQOI4ZF5GWV7JBX+HPYX6Gi1vWNUtw1WfEk2fAesIMbsDIemETWWZLiO+fL95TKybn7izakQobZX23Kem+7gK5iJqKIt9sDpWKcgymTL0RIE2WyAoVL7ShUVY2dkQiY9WUcGXJDAHQT matt@mshe"
            ],
            "use_sudo": true,
            "use_sudo_nopass": true,
            "user_state": "present",
            "username": "matt"
        },

I don't know what the problem is and I'd like to know if I've forgotten something or if there's a bug somewhere.

Thanks in advance for your feedback.

Ernest.

Allow to specify url with SSH public keys for a user

Some websites (such as GitHub and GitLab) provide users' public SSH keys in a plain-text format via a public link.

Example:

Is it possible to add a parameter to provide an URL with this info instead of ssh keys themselves, so the task would download keys from the provided link? It would facilitate key management for teams with established github/gitlab organizations or other key distribution methods and remove unneeded secrets file updates if keys change.

How to give access to all the inventory without putting all the group host in the servers variable

Hi,

By default, is it possible to give a user access to all the hosts in the inventory?
For example, by putting in the 'servers' variable:

- global
or
- all

Instead of listing the host list like this :

   primarygroup: testgroup104primary
    ssh_key: ssh-rsa AAAB.... test103@server
   exclusive_ssh_key: no
   use_sudo: no
   user_state: present
   servers:
     - webserver
    - monitoring
    - group1
    - group2
    - group3
    - group4

shell is not validated/enforced

changing a users shell (disable login for existing user) does not seem to work

  - username: debian
    password: "!"
    update_password: always
    comment: Debian Default account
    shell: /bin/false

the playbook completes without altering the user shell.

edit: caused by typo in user_state: locked, instaed of user_state: lock. No warning on my misstake though.

Specify SSH Key path

hi,

I'm a beginer with Ansible and your module is the first I use :-) Is it possible to specify the SSH key path, for example /etc/ssh/keys/ ?

cu denny and thanks :-)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.