Git Product home page Git Product logo

ansible-role-users's Issues

Make role work well with usernames containing a '.' (dot) sign.

Proposed feature

Make role work well with usernames containing a '.' (dot) sign.
Currently it doesn't work for such users.

Rationale

This is from sudoers(5) manual:

 The #includedir directive can be used to create a sudoers.d directory that the system package manager can drop sudoers file rules into as part of package installation.  For example, given:
     #includedir /etc/sudoers.d

 sudo will suspend processing of the current file and read each file in /etc/sudoers.d, skipping file names that end in ‘~’ or contain a ‘.’ character to avoid causing problems with package manager or editor temporary/backup
 files.  Files are parsed in sorted lexical order.  That is, /etc/sudoers.d/01_first will be parsed before /etc/sudoers.d/10_second.  Be aware that because the sorting is lexical, not numeric, /etc/sudoers.d/1_whoops would be
 loaded after /etc/sudoers.d/10_second.  Using a consistent number of leading zeroes in the file names can be used to avoid such problems.  After parsing the files in the directory, control returns to the file that contained the
 #includedir directive.

Additional context

I'll do some code changes right away with a PR.

Allow disabling deployment of /etc/cron.allow

Describe the bug
When deploying users with this role (without setting cron_allow: true), an empty file /etc/cron.allow is created (except the ansible_managed header).

Quoting crontab(8):

If the /etc/cron.allow file exists, then you must be listed (one user per line) therein in order to be allowed to use this command.

This means that after using this role, no (other) user is allowed to run cron.

Expected behavior
It should be possible to disable the deployment of /etc/cron.allow. Maybe setting a variable like users_cron_allow: false could do the trick. The default could be true, but I am also fine with false.

Environment

  • Control node OS: Debian 9 (Debian/stretch)
  • Control node Ansible version: 2.8.0
  • Managed node OS: Debian 9 (Debian/stretch)

no test named 'boolean'

Describe the bug

Using AWX 19.3.0 with this EE https://github.com/tomoliveri/ansible_aio_ee, and running this role returns an error:

template error while templating string: no test named 'boolean'

The role works fine for me normally, this is the first time I've tried to use the role in AWX however.

Playbook

---
- hosts: all
  become: yes
  become_user: root
  vars:
    users_user_list:
        <snip>    
  roles:
    - robertdebock.users

Output

{
  "msg": "The conditional check 'users_cron_allow is boolean' failed. The error was: template error while templating string: no test named 'boolean'. String: {% if users_cron_allow is boolean %} True {% else %} False {% endif %}",
  "_ansible_no_log": false
}

Environment

  • Control node OS: AWX 19.3.0
  • Ansible version: 2.11.6rc1.post0
  • Managed node OS: Oracle Linux 8.4

Also, this looks to be a similar problem to here: robertdebock/ansible-role-tomcat#37

Let this role create a key pair

It would be great if this role could create a key pair and send the private key to the user.

Both .pub and .ppk

Describe the solution you'd like
Create a key pair on the controlenode, send the private key to the user.

The passphrase should either be generated, or it should be possible to set a passphase.

Descriptions of more scary variable names

Proposed feature

Some of the variable names suggest (to me as N00B) that they might be risky.
Can I add some descriptions, or a link to a main doc?

Rationale

As a newcomer, I was about to install the minikube role and I noticed a reference to this role. It seems really cool and there is some ninja $#@! going on in the user settings which I would love to understand.

Perhaps there is a comprehensive doc somewhere. I could not immediately tell what module the groups variable related to.

Additional context

      users_user_list:
        - name: root                         # What if I already have a root account with a passwd ?
          cron_allow: yes
          unauthorized_keys:          # required? Is this a known-bad key?
            - "ssh-rsa ZYX54321"
        - name: blaise
          comment: Blaise Pabon
          uid: 1024
          group: blaise
          groups: users                  # how do I list more than one group? `users, wheel, libvirt` ? Also the word `groups` means something in Ansible...
          cron_allow: yes
          sudo_options: "ALL=(ALL) NOPASSWD: ALL"
          authorized_keys:
            - "ssh-rsa ABC123"
          expires: -1                                        # Does this mean the account never expires?
          password_validity_days: 9
        - name: notuser                               # Does this remove pre-existing users from the host?
          state: absent

and also:

        - name: remotekey                       # Who is Shaan and why do I add his key?
          authorized_keys:
            - "https://raw.githubusercontent.com/shaanr/smdb/master/file.pub"
        - name: systemuser
          system: yes
        - name: multisudo                       # This seems interesting, is this for a service account?
          sudo_options:
            - "ALL= NOPASSWD: /usr/bin/systemctl restart httpd"
            - "ALL= NOPASSWD: /usr/bin/systemctl start httpd"

Please consider sponsoring me.

ERROR! this task 'ansible.builtin.import_tasks' has extra params... when running playbook with the role

Describe the bug

Error using the role in my playbook

Playbook

playbook:

---
- hosts: redacted

  tags:
    - user

  vars:
    ansible_user: "{{ base_user }}"
    ansible_password: "{{ base_user_password }}"
    ansible_sudo_pass: "{{ base_sudo_pass }}"

  become: true

  roles:
    - robertdebock.users

  tasks:
    - name: "Change password for {{ default_user }}"
      user:
        name: "{{ default_user }}"
        password: "{{ default_user_password | string | password_hash('sha512', 'A512') }}"

requirements.yml (excerpt)

- src: robertdebock.users
  version: 5.4.0
# ansible-galaxy list -p ./roles/ | grep 'robertdebock.users'
- robertdebock.users, 5.4.0

Output

# ansible-playbook playbook.yml -i inventories/redacted/ --vault-password-file ~/.vault_pass.txt
ERROR! this task 'ansible.builtin.import_tasks' has extra params, which is only allowed in the following modules: ansible.windows.win_command, shell, win_shell, include_vars, ansible.windows.win_shell, import_role, script, meta, include, include_tasks, group_by, raw, include_role, command, import_tasks, win_command, add_host, set_fact

The error appears to be in '/git/ansible/roles/robertdebock.users/tasks/main.yml': line 4, column 3, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:


- name: import assert.yml
  ^ here

vscode linter of extension Ansible v0.7.1 JSON Schema Ansible Tasks File on the main.yml (lines):

4 - name: import assert.yml
5   ansible.builtin.import_tasks: assert.yml
6   run_once: yes
7   delegate_to: localhost

4: Missing property "action".yaml-schema: TaskModel | BeremothTaskModel
5: Property ansible.builtin.import_tasks is not allowed.yaml-schema: TaskModel
6: Incorrect type. Expected "boolean".yaml-schema: Run Once | BeremothTaskModel

Environment

  • Control node OS: 18.04.6 LTS (Bionic Beaver)
  • Control node Ansible version: 2.10.2
  • Managed node OS: 20.04.2 LTS (Focal Fossa)

Ansible group management

Hello everyone

I'm trying to use the robertdebock.users role to create sudoers for my virtualization infrastructure, using the following principle: if the VM is in the "robert" Ansible group, then I create a "robert" account for it.
But the "ansible_group in group_names" condition is not taken into account and the account is created for all users. Certain tasks are avoided but, alas, account creations are carried out correctly.

Here is the role dedicated to this task:

# roles/users/tasks/sudoers.yml
- name: Include variables from sudoers.yml
  include_vars:
    file: "{{ role_path }}/defaults/sudoers.yml"
- name: Creation of Unix groups in a loop on the group dictionary
  include_role:
    name: robertdebock.users
  vars:
    name: "{{ group_item.name }}"
    system: "{{ group_item.system | default(false) }}"
    ansible_group: "{{ group_item.ansible_group }}"
  loop: "{{ users_groups }}"
  loop_control:
    loop_var: group_item
  when:
     - group_item.ansible_group is defined and group_item.ansible_group in group_names
- name: Create accounts in a loop on the user dictionary
  include_role:
    name: robertdebock.users
  vars:
    name: "{{ user_item.name }}"
    password: "{{ user_item.password }}"
    update_password: on_create
    group: "{{ user_item.group }}"
    sudo_options: "{{ user_item.sudo_options }}"
    ansible_group: "{{ user_item.ansible_group }}"
  loop: "{{ users }}"
  loop_control:
    loop_var: user_item
  when:
    - user_item is defined and user_item.ansible_group is defined and user_item.ansible_group in group_names

Below is a sample of my user data.

# roles/users/defaults/sudoers.yml
users_groups:
  - name: almina
    ansible_group: almina
  - name: chfalcon
    ansible_group: chfalcon

users:
  - name: almina
    comment: Marie-Almina Gindre
    group: almina
    password: "$6$9...TVg/"
    cron_allow: no
    sudo_options: "ALL=(ALL) NOPASSWD: ALL"
    ansible_group: almina

  - name: chfalcon
    comment: "Charles-Henri Falconnet"
    group: chfalcon
    password: "$y$j9...dNA"
    cron_allow: yes
    sudo_options: "ALL=(ALL) NOPASSWD: ALL"
    ansible_group: chfalcon

Extract from my_hosts showing that the VM is zuri is only a member of the Almina group

[almina]
zuri.inframshe.univ-fcomte.fr
[chfalcon]

Finally, here's the output of the playbook execution, in which we can see that one task has been skipped, while the others have been completed.

TASK [Create accounts in a loop on the user dictionary] ***********************************************************************************************************************************************************
skipping: [zuri.inframshe.univ-fcomte.fr] => (item={'name': 'chfalcon', 'comment': 'Charles-Henri Falconnet', 'group': 'chfalcon', 'password': '$y$j...dNA', 'cron_allow': True, 'sudo_options': 'ALL=(ALL) NOPASSWD: ALL', 'ansible_group': 'chfalcon'}) 

TASK [robertdebock.users : assert | Test users_ssh_key_directory] *************************************************************************************************************************************************
ok: [zuri.inframshe.univ-fcomte.fr -> localhost]

TASK [robertdebock.users : assert | Test users_shell] *************************************************************************************************************************************************************
ok: [zuri.inframshe.univ-fcomte.fr -> localhost]

TASK [robertdebock.users : assert | Test users_cron_allow] ********************************************************************************************************************************************************
ok: [zuri.inframshe.univ-fcomte.fr -> localhost]

TASK [robertdebock.users : assert | Test users_create_home] *******************************************************************************************************************************************************
ok: [zuri.inframshe.univ-fcomte.fr -> localhost]

I really don't see what the problem is.

Please note that if I use the ansible.builtin.group role, then the "when" clause is taken into account when creating groups. But that's not the case with robertdebock.users... and ansible.builtin.user doesn't exist yet.

Any help would be appreciated, thanks in advance.

Ernest.

Add update_password option

Is your feature request related to a problem? Please describe.
When setting a password for a user (on creation) we usually don't want to revert the password once it was changed.

Describe the solution you'd like
The Ansible user module has an update_password parameter which allows to only set the password on_create. It would be nice if we could add this option in user.yml.
I am not sure if we should default to always though, I would vote for on_create, but I would like to hear your opinon.

Option to copy SSH keys into authorized_keys from GitHub

Is your feature request related to a problem? Please describe.
Listing all of the keys for multiple users seems a bit tiresome. We could, instead, copy the keys from GitHub to a users authorized_keys file.

Describe the solution you'd like
GitHub exposes the users public key at https://github.com/username.keys. If we could pass GitHub username as a variable then we can copy the keys over to the users authorized_keys file. I believe the authorized_keys module has provision for this (https://docs.ansible.com/ansible/latest/modules/authorized_key_module.html#examples)

Describe alternatives you've considered
Alternative is to list all the keys for the users, as we do now.

Additional context
N/A

My users are not created

Describe the bug

When I run my playbooks it does not create my users and also in the /etc/ssh/sshd_config file the ALLOW USERS section does it as follows, the name separated by spaces. Example:

AllowUsers f e r n a n d o

Requirements

run command:
ansible-galaxy install -r requirements.yml

---
roles:
- name: robertdebock.bootstrap
- name: robertdebock.core_dependencies
- name: robertdebock.epel
- name: robertdebock.fail2ban
- name: robertdebock.firewall
- name: robertdebock.openssh
- name: robertdebock.selinux
- name: robertdebock.software
- name: robertdebock.sysctl
- name: robertdebock.users
- name: robertdebock.ntp

collections:
- name: community.general
- name: ansible.posix

Playbook 1

run command:
ansible-playbook -K create_user.yml

---
- hosts: localhost
  become: yes
  become_user: root
  gather_facts: yes

  roles:
    - role: robertdebock.bootstrap
    - role: robertdebock.core_dependencies

    - role: robertdebock.users
      users_group_list:
        - name: root

      users_user_list:
        - name: user_name
          group: root
          password: "{{'123456x' |  password_hash('sha512')}}"
          update_password: on_create
          cron_allow: no
          sudo_options: "ALL=(ALL) ALL"
          authorized_keys:
            - "https://gitlab.com/path/path/-/raw/master/playbooks/keys.pub"

Playbook 2

run command:
ansible-playbook -K site.yml

---
---
- hosts: localhost
  become: yes
  become_user: root
  gather_facts: yes

  roles:
  - role: robertdebock.bootstrap
  - role: robertdebock.core_dependencies
  - role: robertdebock.epel

  - role: openpyme.ius

  - role: robertdebock.selinux
    selinux_reboot: false
    selinux_state: enforcing
    selinux_booleans:
    - name: httpd_can_network_connect
      state: true
      persistent: true
    - name: httpd_enable_homedirs
      state: true
      persistent: true
    - name: httpd_read_user_content
      state: true
      persistent: true

  - role: robertdebock.sysctl
    sysctl_items:
    - name: vm.swappiness
      value: 10
    - name: vm.vfs_cache_pressure
      value: 50

  - role: robertdebock.openssh
    openssh_allow_users: user_name
    openssh_permit_root_login: "no"
    openssh_password_authentication: "no"

  - role: robertdebock.firewall
    firewall_services:
    - name: ssh
    - name: http
    - name: https

  - role: robertdebock.fail2ban
  
  - role: robertdebock.ntp
    ntp_timezone: America/Mexico_City

  - role: robertdebock.software
    software_packages:
    - name: byobu

  - role: robertdebock.users
    users_group_list:
      - name: no_root

    users_user_list:
      - name: user_name2
        group: no_root
        password: "{{'123456x' | password_hash('sha512')}}"
        update_password: on_create
        cron_allow: yes

Output playbook requirements.yml

[root@localhost playbooks]# ansible-galaxy install -r requirements.yml
Starting galaxy role install process

Output playbook create_user.yml

[root@localhost playbooks]# ansible-playbook -K create_user.yml
BECOME password:
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] ***********************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.bootstrap : Validating arguments against arg spec 'main' - Prepare a system to be managed by Ansible.] **************************************************************
ok: [localhost]

TASK [robertdebock.bootstrap : assert | Test bootstrap_wait_for_host] ******************************************************************************************************************
ok: [localhost]

TASK [robertdebock.bootstrap : assert | Test bootstrap_timeout] ************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.bootstrap : assert | Test bootstrap_become] *************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.bootstrap : Wait for port to be available] **************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.bootstrap : Test connection] ****************************************************************************************************************************************
[WARNING]: Reset is not implemented for this connection
ok: [localhost]

TASK [robertdebock.bootstrap : Test sudo] **********************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.bootstrap : Gather ansible facts] ***********************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.bootstrap : Install bootstrap packages (package)] *******************************************************************************************************************
ok: [localhost] => (item=python3)
ok: [localhost] => (item=sudo)

TASK [robertdebock.core_dependencies : Remove conflicting packages] ********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.core_dependencies : Install packages] *******************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.core_dependencies : Flush handlers] *********************************************************************************************************************************

TASK [robertdebock.users : assert | Test users_ssh_key_directory] **********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.users : assert | Test users_shell] **********************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.users : assert | Test users_cron_allow] *****************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.users : assert | Test users_create_home] ****************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.users : assert | Test users_groups] *********************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.name in users_groups] ********************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.gid in users_groups] *********************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.state in users_groups] *******************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.system in users_groups] ******************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.name in users] ***************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.cron_allow in users] *********************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.uid in users] ****************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.authorized_keys in users] ****************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.manage_ssh_key in users] *****************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.update_password in users] ****************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.exipres in users] ************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.password_validity_days in users] *********************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.system in users] *************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : Install required software] **********************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : Loop over users_groups] *************************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : Ensure the /etc/sudoers.d directory is included] ************************************************************************************************************
ok: [localhost]

TASK [robertdebock.users : Loop over users] ********************************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : Manage cron permission] *************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.users : Check existence of /etc/cron.allow] *************************************************************************************************************************
skipping: [localhost]

PLAY RECAP *****************************************************************************************************************************************************************************
localhost : ok=17 changed=0 unreachable=0 failed=0 skipped=19 rescued=0 ignored=0

Output playbook site.yml

[root@localhost playbooks]# ansible-playbook -K site.yml
BECOME password:
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] ***********************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.bootstrap : Validating arguments against arg spec 'main' - Prepare a system to be managed by Ansible.] **************************************************************
ok: [localhost]

TASK [robertdebock.bootstrap : assert | Test bootstrap_wait_for_host] ******************************************************************************************************************
ok: [localhost]

TASK [robertdebock.bootstrap : assert | Test bootstrap_timeout] ************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.bootstrap : assert | Test bootstrap_become] *************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.bootstrap : Wait for port to be available] **************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.bootstrap : Test connection] ****************************************************************************************************************************************
[WARNING]: Reset is not implemented for this connection
ok: [localhost]

TASK [robertdebock.bootstrap : Test sudo] **********************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.bootstrap : Gather ansible facts] ***********************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.bootstrap : Install bootstrap packages (package)] *******************************************************************************************************************
ok: [localhost] => (item=python3)
ok: [localhost] => (item=sudo)

TASK [robertdebock.core_dependencies : Remove conflicting packages] ********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.core_dependencies : Install packages] *******************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.core_dependencies : Flush handlers] *********************************************************************************************************************************

TASK [robertdebock.epel : Install epel gpg key] ****************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.epel : Install epel-release] ****************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.epel : Install epel-next-release] ***********************************************************************************************************************************
skipping: [localhost]

TASK [openpyme.ius : install ius] ******************************************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.selinux : assert | Test selinux_state] ******************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.selinux : assert | Test selinux_policy] *****************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.selinux : assert | Test selinux_reboot] *****************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.selinux : assert | Test selinux_booleans] ***************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.selinux : assert | Test item.name in selinux_booleans] **************************************************************************************************************
ok: [localhost] => (item=httpd_can_network_connect)
ok: [localhost] => (item=httpd_enable_homedirs)
ok: [localhost] => (item=httpd_read_user_content)

TASK [robertdebock.selinux : assert | Test item.state in selinux_booleans] *************************************************************************************************************
ok: [localhost] => (item=httpd_can_network_connect)
ok: [localhost] => (item=httpd_enable_homedirs)
ok: [localhost] => (item=httpd_read_user_content)

TASK [robertdebock.selinux : assert | Test item.persistent in selinux_booleans] ********************************************************************************************************
ok: [localhost] => (item=httpd_can_network_connect)
ok: [localhost] => (item=httpd_enable_homedirs)
ok: [localhost] => (item=httpd_read_user_content)

TASK [robertdebock.selinux : Install required packages] ********************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.selinux : Flush handlers] *******************************************************************************************************************************************

TASK [robertdebock.selinux : Manage selinux] *******************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.selinux : Manage selinux booleans] **********************************************************************************************************************************
ok: [localhost] => (item=httpd_can_network_connect)
ok: [localhost] => (item=httpd_enable_homedirs)
ok: [localhost] => (item=httpd_read_user_content)

TASK [robertdebock.sysctl : assert | Test sysctl_set] **********************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.sysctl : assert | Test sysctl_reload] *******************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.sysctl : Install requirements] **************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.sysctl : Set sysctl setting] ****************************************************************************************************************************************
ok: [localhost] => (item=vm.swappiness)
ok: [localhost] => (item=vm.vfs_cache_pressure)

TASK [robertdebock.openssh : assert | Test ssh_port] ***********************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_address_family] *********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_listen_addresses] *******************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_host_keys] **************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_rekey_limit] ************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_syslog_facility] ********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_loglevel] ***************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_login_grace_time] *******************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_permit_root_login] ******************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_strict_modes] ***********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_max_auth_tries] *********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_max_sessions] ***********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_pub_key_authentication] *************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_authorized_key_file] ****************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_authorized_prinicpals_file] *********************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_authorized_keys_command] ************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_authorized_keys_command_user] *******************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_host_based_authentication] **********************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_ignore_user_known_hosts] ************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_ignore_rhosts] **********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_permit_empty_passwords] *************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_password_authentication] ************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_challenge_response_authentication] **************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_gssapi_authentication] **************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_gssapi_cleanup_credentials] *********************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_gssapi_strict_acceptor_check] *******************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_gssapi_key_exchange] ****************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_gssaip_enable_k5_users] *************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_use_pam] ****************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_allow_agent_forwarding] *************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_allow_tcp_forwarding] ***************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_gateway_ports] **********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_x11_forwarding] *********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_x11_display_offset] *****************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_x11_use_localhost] ******************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_permit_tty] *************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_print_motd] *************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_print_last_log] *********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_tcp_keep_alive] *********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_permit_user_environment] ************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_compression] ************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_client_alive_interval] **************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_client_alive_count_max] *************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_show_patch_level] *******************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_use_dns] ****************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_pid_file] ***************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_max_startups] ***********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_permit_tunnel] **********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_chroot_directory] *******************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_version_addendum] *******************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_banner] *****************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_accept_envs] ************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_subsystem] **************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_trusted_user_ca_keys] ***************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_allow_users] ************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : assert | Test openssh_allow_groups] ***********************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.openssh : Install openssh] ******************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : Configure selinux to allow openssh_port] ******************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : Generate host key] ****************************************************************************************************************************************
ok: [localhost] => (item=rsa)
ok: [localhost] => (item=ecdsa)
ok: [localhost] => (item=ed25519)

TASK [robertdebock.openssh : Make run directory] ***************************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.openssh : Configure openssh] ****************************************************************************************************************************************
changed: [localhost]

TASK [robertdebock.openssh : Start and enable openssh] *********************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.openssh : Flush handlers] *******************************************************************************************************************************************

RUNNING HANDLER [robertdebock.openssh : Restart openssh] *******************************************************************************************************************************
changed: [localhost]

TASK [robertdebock.firewall : assert | Test firewall_default_protocol] *****************************************************************************************************************
ok: [localhost]

TASK [robertdebock.firewall : assert | Test firewall_default_rule] *********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.firewall : assert | Test firewall_services] *************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.firewall : assert | Test non-numeric item in firewall_services] *****************************************************************************************************
ok: [localhost] => (item=ssh)
ok: [localhost] => (item=http)
ok: [localhost] => (item=https)

TASK [robertdebock.firewall : assert | Test numeric item in firewall_services] *********************************************************************************************************
skipping: [localhost] => (item=ssh)
skipping: [localhost] => (item=http)
skipping: [localhost] => (item=https)
skipping: [localhost]

TASK [robertdebock.firewall : assert | Test item with state in firewall_services] ******************************************************************************************************
skipping: [localhost] => (item=unset)
skipping: [localhost] => (item=unset)
skipping: [localhost] => (item=unset)
skipping: [localhost]

TASK [robertdebock.firewall : Remove conflicting software] *****************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.firewall : Install required software] *******************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.firewall : Start and enable firewall service] ***********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.firewall : Open ports (ufw)] ****************************************************************************************************************************************
ok: [localhost] => (item=ssh)
ok: [localhost] => (item=http)
ok: [localhost] => (item=https)

TASK [robertdebock.firewall : Close ports (ufw)] ***************************************************************************************************************************************
skipping: [localhost] => (item=ssh)
skipping: [localhost] => (item=http)
skipping: [localhost] => (item=https)
skipping: [localhost]

TASK [robertdebock.firewall : Open ports (firewalld-port)] *****************************************************************************************************************************
skipping: [localhost] => (item=ssh)
skipping: [localhost] => (item=http)
skipping: [localhost] => (item=https)
skipping: [localhost]

TASK [robertdebock.firewall : Close ports (firewalld-port)] ****************************************************************************************************************************
skipping: [localhost] => (item=ssh)
skipping: [localhost] => (item=http)
skipping: [localhost] => (item=https)
skipping: [localhost]

TASK [robertdebock.firewall : Open ports (firewalld-service)] **************************************************************************************************************************
skipping: [localhost] => (item=ssh)
skipping: [localhost] => (item=http)
skipping: [localhost] => (item=https)
skipping: [localhost]

TASK [robertdebock.firewall : Close ports (firewalld-service)] *************************************************************************************************************************
skipping: [localhost] => (item=ssh)
skipping: [localhost] => (item=http)
skipping: [localhost] => (item=https)
skipping: [localhost]

TASK [robertdebock.firewall : Enable ufw] **********************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.firewall : Configure iptables] **************************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.fail2ban : assert | Test fail2ban_loglevel] *************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.fail2ban : assert | Test fail2ban_logtarget] ************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.fail2ban : assert | Test fail2ban_ignoreself] ***********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.fail2ban : assert | Test fail2ban_ignoreips] ************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.fail2ban : assert | Test fail2ban_bantime] **************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.fail2ban : assert | Test fail2ban_findtime] *************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.fail2ban : assert | Test fail2ban_maxretry] *************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.fail2ban : assert | Test fail2ban_destemail] ************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.fail2ban : assert | Test fail2ban_sender] ***************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.fail2ban : assert | Test fail2ban_configuration] ********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.fail2ban : assert | Test item in fail2ban_configuration] ************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.fail2ban : assert | Test fail2ban_jail_configuration] ***************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.fail2ban : assert | Test item in fail2ban_filterd_path] *************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.fail2ban : Install fail2ban] ****************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.fail2ban : Copy filters in filter.d] ********************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.fail2ban : Configure fail2ban.local] ********************************************************************************************************************************
ok: [localhost] => (item=loglevel)
ok: [localhost] => (item=logtarget)
ok: [localhost] => (item=ignoreip)

TASK [robertdebock.fail2ban : Configure jail.local] ************************************************************************************************************************************
ok: [localhost] => (item=ignoreself)
ok: [localhost] => (item=bantime)
ok: [localhost] => (item=findtime)
ok: [localhost] => (item=maxretry)
ok: [localhost] => (item=destemail)
ok: [localhost] => (item=sender)

TASK [robertdebock.fail2ban : Stat auth log file] **************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.fail2ban : Touch auth log file] *************************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.fail2ban : Start and enable fail2ban] *******************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.ntp : Validating arguments against arg spec 'main' - Install and configure ntp on your system.] *********************************************************************
ok: [localhost]

TASK [robertdebock.ntp : assert | Test ntp_state] **************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.ntp : assert | Test ntp_enabled] ************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.ntp : assert | Test ntp_interfaces] *********************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.ntp : assert | Test item in ntp_interfaces] *************************************************************************************************************************
ok: [localhost] => (item=127.0.0.1)

TASK [robertdebock.ntp : assert | Test ntp_pool] ***************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.ntp : assert | Test item in ntp_pool] *******************************************************************************************************************************
ok: [localhost] => (item=0.pool.ntp.org iburst)
ok: [localhost] => (item=1.pool.ntp.org iburst)
ok: [localhost] => (item=2.pool.ntp.org iburst)
ok: [localhost] => (item=3.pool.ntp.org iburst)

TASK [robertdebock.ntp : assert | Test ntp_server] *************************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.ntp : assert | Test item in ntp_server] *****************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.ntp : assert | Test ntp_timezone] ***********************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.ntp : Install packages] *********************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.ntp : Configure /etc/chrony.conf] ***********************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.ntp : Install timezone information] *********************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.ntp : Configure timezone] *******************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.ntp : Manage chronyd] ***********************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.software : assert | Test software_packages] *************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.software : assert | Test item.name in software_packages] ************************************************************************************************************
ok: [localhost] => (item=byobu)

TASK [robertdebock.software : assert | Test item.state in software_packages] ***********************************************************************************************************
skipping: [localhost] => (item=byobu)
skipping: [localhost]

TASK [robertdebock.software : Install packages] ****************************************************************************************************************************************
ok: [localhost] => (item=byobu)

TASK [robertdebock.users : assert | Test users_ssh_key_directory] **********************************************************************************************************************
ok: [localhost]

TASK [robertdebock.users : assert | Test users_shell] **********************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.users : assert | Test users_cron_allow] *****************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.users : assert | Test users_create_home] ****************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.users : assert | Test users_groups] *********************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.name in users_groups] ********************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.gid in users_groups] *********************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.state in users_groups] *******************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.system in users_groups] ******************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.name in users] ***************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.cron_allow in users] *********************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.uid in users] ****************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.authorized_keys in users] ****************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.manage_ssh_key in users] *****************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.update_password in users] ****************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.exipres in users] ************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.password_validity_days in users] *********************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : assert | Test item.system in users] *************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : Install required software] **********************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : Loop over users_groups] *************************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : Ensure the /etc/sudoers.d directory is included] ************************************************************************************************************
ok: [localhost]

TASK [robertdebock.users : Loop over users] ********************************************************************************************************************************************
skipping: [localhost]

TASK [robertdebock.users : Manage cron permission] *************************************************************************************************************************************
ok: [localhost]

TASK [robertdebock.users : Check existence of /etc/cron.allow] *************************************************************************************************************************
skipping: [localhost]

TASK [openpyme.nginx : create symbolic link for openssl] *******************************************************************************************************************************
skipping: [localhost]

TASK [openpyme.nginx : allow openperp reload nginx] ************************************************************************************************************************************
skipping: [localhost]

PLAY RECAP *****************************************************************************************************************************************************************************
localhost : ok=134 changed=2 unreachable=0 failed=0 skipped=41 rescued=0 ignored=0

Environment

  • Control node Ansible version: 2.15.8
  • OS: Rocky Linux 9.3 (Blue Onyx)

Please consider @robertdebock

syntax error near line 120

Looks like regression.
When I execute playbook with version 6.0.0, following error occurred:

[0;32m    packer.amazon-ebs.amazon_linux2: TASK [users : Ensure the /etc/sudoers.d directory is included] *****************[0m
[0;32m    packer.amazon-ebs.amazon_linux2: fatal: [127.0.0.1]: FAILED! => {"changed": false, "msg": "failed to validate: rc:1 error:>>> /root/.ansible/tmp/ansible-tmp-1694096904.2884834-4728-121955127142261/tmplp8wizy1: syntax error near line 120 <<<\n"}[0m

In version 5.6.0 work as expected

Environment

  • Control node OS: Amazon Linux 2
  • Control node Ansible version: [core 2.13.11]
  • Managed node OS: Amazon Linux 2

Option to copy public key or generate SSH keys only on instance

Proposed feature

Either add an option to copy the public key to the node or allow creation of SSH keys on the node itself.

Rationale

When provisioning a new development machine I want to generate an SSH key on the machine which can be uploaded to GitLab/GitHub.

Currently, it is only possible to copy the private key to the machine but not both.
And in the end, I don't need the generated keys on the controller but on the node itself.

Implementation option

The ansible.builtin.user module that is used has this option generate_ssh_key: true which would be enough for my needs.

Error in "Ensure the sudoers.d directory is checked..." ?

Describe the bug

Hi,
Ty for you're hard work.

I'm read you're code and, perhaps they have an mistake in tasks/user.yml near line 55 :

- name: user | Ensure the sudoers.d directory is checked for user sudoers files (will be put after EOF if not exists)
  ansible.builtin.lineinfile:
    path: /etc/sudoers
    state: present
    line: "#includedir /etc/sudoers.d"

is a comment, no ?

In my /etc/sudoers file on an debian 11, i have @includedir /etc/sudoers.d

is this an mistake or not ?

For root user wrong home directory is used

Describe the bug

When using this role to set root user configurations, the wrong home directory is used: Keys are placed in /home/root instead of /root

Playbook

---
users_user_list:
    - name: root
      authorized_keys: "{{ authorized_keys }}"
      private_keys:
        - name: id_ed25519
          content: "{{ lookup('hashi_vault', 'secret=credentials/keys/machine:private') }}"
---
- name: Bootstrap machines
  hosts: all
  roles:
    - name: robertdebock.core_dependencies
    - name: robertdebock.bootstrap
    - name: robertdebock.auto_update
    - name: robertdebock.locale
    - name: robertdebock.openssh
    - name: robertdebock.users

Output

$ find /root/.ssh/
/root/.ssh/
/root/.ssh/authorized_keys
/root/.ssh/known_hosts

$ find /home/root/.ssh/
/home/root/.ssh/
/home/root/.ssh/id_ed25519

Environment

Target: Fedora release 38 (Thirty Eight)
Role version: 5.5.0

Allow private key to be given and placed on a machine.

Proposed feature

It would be nice if this role can place a user-specified private key. Something like this:

users_user_list:
  - name: privkeyuser
    private_keys:
      - name: id_rsa
        content: >
        -----BEGIN RSA PRIVATE KEY-----
        MIIEowxyz
        -----END RSA PRIVATE KEY-----

Rationale

Provisioning a user with private key is user-friendly.

Please consider sponsoring me.

Remove sudo options for user if user.sudo_options is not defined

Describe the bug
When user.sudo_options is removed, /etc/suders.d/{{ user.name }} is not removed.

Expected behavior
When user.sudo_options is removed, we should make sure that /etc/suders.d/{{ user.name }} is removed.

Environment

  • Control node: Debian 9 (Debian/stretch)
  • Control node Ansible version: 2.8.0
  • Managed node OS: Debian 9 (Debian/stretch)

Refactor role for real idempotence and enhance users and ssh key features

Is your feature request related to a problem? Please describe.
Currently there is no real idempotence for adding cron.allow and bootstrapping in general.
Furthermore there is no support for managing users and multiple ssh keys over time.

Describe the solution you'd like

  • add support for bootstrap remote user
  • add support for more Ansible user attributes
  • add support for multiple authorized ssh keys per user
  • add management features for users and ssh keys (create & delete)
  • add support for openssh password authentication configuration (optional)
  • add real test case to playbooks

Describe alternatives you've considered
None.

Additional context
Build Status
GitHub Fork

Use task (filename) prefix for the task name

Proposed feature

Use task name prefix like - name: lsp | Install Cargo crates and enable_list: - name[prefix] in Ansible Lint.

Rationale

Because this role is organized into multiple files and can be imported in larger playbook it is important to provide observability for the users. It is common to rely on --list-tasks to quickly identify executable tasks and their locations in the roles.

$ molecule --base-config .config/molecule/config.yml converge -s dev -- --limit workstations --tags nvim --list-tasks
.......

 play #3 (workstations): PPE     TAGS: [ppe]
    tasks:
      namespace.generic.nodejs : prepare | Ensure Nodejs directory exists    TAGS: [deps, nodejs.prepare, nodejs.setup, nvim, ppe]
      namespace.generic.nodejs : prepare | Install unzip package    TAGS: [deps, nodejs.prepare, nodejs.setup, nvim, ppe]
      namespace.generic.nodejs : install | Download NodeJS release source   TAGS: [deps, nodejs.install, nodejs.setup, nvim, ppe]
      namespace.generic.nodejs : environment | Setup NodeJS environment     TAGS: [deps, nodejs.environment, nodejs.setup, nvim, ppe]
      namespace.generic.yarn : install | Install Yarn     TAGS: [deps, install, nvim, ppe, yarn, yarn.install]
      namespace.generic.yarn : config | Add environment     TAGS: [deps, nvim, ppe, yarn, yarn.config]
      namespace.generic.nvim : prepare | Install Neovim build prerequisites     TAGS: [deps, nvim, nvim.prepare, ppe]

As you can see, user is able easily identify the source of particular task.

Same goes to spot the source of failing tasks.

authorized_key(s) issue

Describe the bug
Perhaps I don't understand the intent but,

  1. Setting authorized_key without setting authorized_keys has no effect:
    "skip_reason": "Conditional result was False"
  2. Setting authorized_keys without setting authorized_key causes an error:
    "'dict object' has no attribute 'authorized_key'"
  3. Using both together work.

To Reproduce
Playbook fragment:

users_user_list:
  - name: fred
    uid: 1003
    group: fred
    groups: 'adm,sudo'
    authorized_key: "{{ lookup('file', '/home/fred/.ssh/id_rsa.pub') }}"
    authorized_keys:
      - "{{ lookup('file', '/home/fred/.ssh/id_rsa.pub') }}"
    shell: /bin/bash

local ssh_key_directory is created on every ansible (check) run

Describe the bug
Every (check) run of this role triggers a change at the task "create local ssh_key_directory".
The directory should either only be created when needed or should not trigger a change. (I prefer the former, but discussion welcome.. 😉)

To Reproduce

% ansible-playbook -D -C site.yml
[...]
TASK [robertdebock.users : create local ssh_key_directory] 
--- before
+++ after
@@ -1,4 +1,4 @@
 {
     "path": "ssh_keys",
-    "state": "absent"
+    "state": "directory"
 }

changed: [site.example.com]
[...]

Expected behavior
A change should not be triggered.

Environment

  • Control node OS: Debian 9 (Debian/stretch)
  • Control node Ansible version: 2.8.0
  • Managed node OS: Debian 9 (Debian/stretch)

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.