diff --git a/roles/ansible/vars/main.yml b/roles/ansible/vars/main.yml index e986c65..cae4b75 100644 --- a/roles/ansible/vars/main.yml +++ b/roles/ansible/vars/main.yml @@ -30,6 +30,11 @@ __ansible__config: apt_key: uniques: ['keyserver', 'url', 'id', 'file' ,'data'] aliases: {} + community: + general: + sudoers: + required: ['name'] + uniques: ['name'] ansible_builtin_apt: uniques: ['name'] aliases: diff --git a/roles/auth/defaults/main.yml b/roles/auth/defaults/main.yml index f9cc390..aaed167 100644 --- a/roles/auth/defaults/main.yml +++ b/roles/auth/defaults/main.yml @@ -4,18 +4,33 @@ auth__manage_groups: false auth__manage_users: false auth__manage_authorized_keys: false auth__manage_ssh_config: false +auth__manage_sudoers: false +##### BEGIN - SSH Config ##### auth__ssh_config_dir: /etc/ssh/ssh_config.d auth__ssh_config_file: "{{ auth__ssh_config_dir }}/50-ansible.conf" -auth__ssh_config_template: etc/ssh/ssh_config.d/custom.conf.j2 +auth__ssh_config_template: etc/ssh/ssh_config.d/50-ansible.conf.j2 auth__ssh_config_backup: true -# module can be systemd_service or service +# module can be 'systemd_service' or 'service' # module can be left empty to skip the service restart # when can be immediate or at the end of the play auth__ssh_config_change_strategy: module: systemd_service when: immediate +# Uncomment the following line to validate the sshd config # auth__sshd_validate: "/usr/sbin/sshd -t -f %s" +##### END - SSH Config ##### + +##### BEGIN - SSH Config ##### +auth__sudoers_dir: /etc/sudoers.d +auth__sudoers_file: "{{ auth__sudoers_dir }}/50-ansible" +auth__sudoers_template: etc/sudoers.d/50-ansible.j2 +auth__sudoers_backup: true +# Set false to prevent consolidation of sudoers files for community.general.sudoers module +# (Merges all sudoers module entries' name (basename of auth__sudoers_file) and sudoers_path (dirname of auth__sudoers_file) as provided above) +# Consult https://docs.ansible.com/ansible/latest/collections/community/general/sudoers_module.html +auth__sudoers_consolidate: true +##### END - SSH Config ##### auth__default: [] auth__group: [] diff --git a/roles/auth/handlers/main.yml b/roles/auth/handlers/main.yml index 5e51599..7c94989 100644 --- a/roles/auth/handlers/main.yml +++ b/roles/auth/handlers/main.yml @@ -13,21 +13,21 @@ state: "{{ change_strategy.state | default(omit) }}" vars: change_strategy: "{{ (__ansible__config is defined) | - ternary(auth__ssh_config_change_strategy | aybarsm.helper.replace_aliases(__ansible__config.modules.ansible.builtin.systemd_service.aliases), - auth__ssh_config_change_strategy) - ) }}" + ternary( + (auth__ssh_config_change_strategy | aybarsm.helper.replace_aliases(__ansible__config.modules.ansible.builtin.systemd_service.aliases)), + auth__ssh_config_change_strategy) }}" register: auth__ssh_config_apply_changes_systemd_service listen: "auth__ssh_config_apply_changes" when: - - change_strategy.module is defined - - change_strategy.module == 'systemd_service' + - auth__ssh_config_change_strategy.module is defined + - auth__ssh_config_change_strategy.module == 'systemd_service' - name: Effect service for ssh config changes become: true ansible.builtin.service: arguments: "{{ change_strategy.arguments | default(omit) }}" enabled: "{{ change_strategy.enabled | default(omit) }}" - name: "{{ change_strategy.name }}" + name: "{{ change_strategy.name | default('ssh.service') }}" pattern: "{{ change_strategy.pattern | default(omit) }}" runlevel: "{{ change_strategy.runlevel | default(omit) }}" sleep: "{{ change_strategy.sleep | default(omit) }}" @@ -35,11 +35,11 @@ use: "{{ change_strategy.use | default(omit) }}" vars: change_strategy: "{{ (__ansible__config is defined) | - ternary(auth__ssh_config_change_strategy | aybarsm.helper.replace_aliases(__ansible__config.modules.ansible.builtin.service.aliases), - auth__ssh_config_change_strategy) - ) }}" + ternary( + (auth__ssh_config_change_strategy | aybarsm.helper.replace_aliases(__ansible__config.modules.ansible.builtin.service.aliases)), + auth__ssh_config_change_strategy) }}" register: auth__ssh_config_apply_changes_service listen: "auth__ssh_config_apply_changes" when: - - change_strategy.module is defined - - change_strategy.module == 'service' \ No newline at end of file + - auth__ssh_config_change_strategy.module is defined + - auth__ssh_config_change_strategy.module == 'service' \ No newline at end of file diff --git a/roles/auth/tasks/authorized_keys.yml b/roles/auth/tasks/authorized_keys.yml index 84f9ae6..ce60e91 100644 --- a/roles/auth/tasks/authorized_keys.yml +++ b/roles/auth/tasks/authorized_keys.yml @@ -1,4 +1,14 @@ --- +- name: Retrieve passwd database in check mode for authorized keys + become: true + ansible.builtin.getent: + database: passwd + register: auth__authorized_keys_test_user_existence + when: + - auth__authorized_keys_all | type_debug == 'list' + - auth__authorized_keys_all | length > 0 + - ansible_check_mode | bool + - name: Apply authorized keys configuration become: true ansible.posix.authorized_key: @@ -17,3 +27,4 @@ when: - auth__authorized_keys_all | type_debug == 'list' - auth__authorized_keys_all | length > 0 + - not ansible_check_mode | bool or (ansible_check_mode and (item.user in ansible_facts['getent_passwd'] or item.path is defined)) diff --git a/roles/auth/tasks/main.yml b/roles/auth/tasks/main.yml index f4d5594..351ba0d 100644 --- a/roles/auth/tasks/main.yml +++ b/roles/auth/tasks/main.yml @@ -1,32 +1,32 @@ --- # Require for configuration management - name: Load aybarsm ansible role main variables - ansible.builtin.include_vars: "../ansible/vars/main.yml" + ansible.builtin.include_vars: ../ansible/vars/main.yml -- name: Include groups tasks - ansible.builtin.include_tasks: - file: groups.yml - when: - - auth__role_enabled | default(false) | bool - - auth__manage_groups | default(false) | bool +# - name: Include groups tasks +# ansible.builtin.include_tasks: +# file: groups.yml +# when: +# - auth__role_enabled | default(false) | bool +# - auth__manage_groups | default(false) | bool -- name: Include users tasks - ansible.builtin.include_tasks: - file: users.yml - when: - - auth__role_enabled | default(false) | bool - - auth__manage_users | default(false) | bool +# - name: Include users tasks +# ansible.builtin.include_tasks: +# file: users.yml +# when: +# - auth__role_enabled | default(false) | bool +# - auth__manage_users | default(false) | bool -- name: Include authroized keys tasks - ansible.builtin.include_tasks: - file: authorized_keys.yml - when: - - auth__role_enabled | default(false) | bool - - auth__manage_authorized_keys | default(false) | bool +# - name: Include authroized keys tasks +# ansible.builtin.include_tasks: +# file: authorized_keys.yml +# when: +# - auth__role_enabled | default(false) | bool +# - auth__manage_authorized_keys | default(false) | bool -- name: Include ssh config tasks - ansible.builtin.include_tasks: - file: ssh_config.yml - when: - - auth__role_enabled | default(false) | bool - - auth__manage_ssh_config | default(false) | bool \ No newline at end of file +# - name: Include ssh config tasks +# ansible.builtin.include_tasks: +# file: ssh_config.yml +# when: +# - auth__role_enabled | default(false) | bool +# - auth__manage_ssh_config | default(false) | bool \ No newline at end of file diff --git a/roles/auth/tasks/sudoers.yml b/roles/auth/tasks/sudoers.yml new file mode 100644 index 0000000..3ac8593 --- /dev/null +++ b/roles/auth/tasks/sudoers.yml @@ -0,0 +1,34 @@ +--- +- name: Apply sudoers configuration template + become: true + ansible.builtin.template: + src: "{{ auth__ssh_config_template }}" + dest: "{{ auth__ssh_config_file }}" + backup: "{{ auth__ssh_config_backup | default(omit) | bool }}" + validate: "{{ auth__sshd_validate | default(omit) }}" + register: auth__sudoers_apply + when: + - auth__sudoers_all | type_debug == 'list' + - auth__sudoers_all | length > 0 + +- name: Apply sudoers configuration via community.general.sudoers module + become: true + community.general.sudoers: + commands: "{{ item.commands | default(omit) }}" + groups: "{{ item.groups | default(omit) }}" + host: "{{ item.host | default(omit) }}" + name: "{{ item.name }}" + noexec: "{{ item.noexec | default(omit) | bool }}" + nopassword: "{{ item.nopassword | default(omit) | bool }}" + runas: "{{ item.runas | default(omit) }}" + setenv: "{{ item.setenv | default(omit) | bool }}" + state: "{{ item.state | default(omit) }}" + sudoers_path: "{{ item.sudoers_path | default(omit) }}" + user: "{{ item.user | default(omit) }}" + validation: "{{ item.validation | default(omit) }}" + loop: "{{ auth__sudoers_module_all }}" + register: auth__sudoers_module_apply + when: + - auth__sudoers_module_all | type_debug == 'list' + - auth__sudoers_module_all | length > 0 + \ No newline at end of file diff --git a/roles/auth/templates/etc/ssh/ssh_config.d/custom.conf.j2 b/roles/auth/templates/etc/ssh/ssh_config.d/50-ansible.conf.j2 similarity index 100% rename from roles/auth/templates/etc/ssh/ssh_config.d/custom.conf.j2 rename to roles/auth/templates/etc/ssh/ssh_config.d/50-ansible.conf.j2 diff --git a/roles/auth/templates/etc/sudoers.d/50-ansible.conf.j2 b/roles/auth/templates/etc/sudoers.d/50-ansible.conf.j2 new file mode 100644 index 0000000..5c02948 --- /dev/null +++ b/roles/auth/templates/etc/sudoers.d/50-ansible.conf.j2 @@ -0,0 +1 @@ +{{ ansible_managed | comment }} diff --git a/roles/auth/vars/main.yml b/roles/auth/vars/main.yml index 0e36c02..d0437a5 100644 --- a/roles/auth/vars/main.yml +++ b/roles/auth/vars/main.yml @@ -2,32 +2,36 @@ __auth__config: authorized_keys: selectattr: - - when: + - when: - ['type', 'defined'] - ['type', 'equalto', 'authorized_key'] - ['user', 'defined'] - ['key', 'defined'] groups: - selectattr: - - when: - - ['type', 'defined'] - - ['type', 'equalto', 'group'] - - when: "{{ __ansible__config.modules.ansible_builtin_group.uniques | product(['defined']) | list }}" - logic: or + selectattr: + - when: + - ['type', 'defined'] + - ['type', 'equalto', 'group'] + - when: "{{ __ansible__config.modules.ansible_builtin_group.uniques | product(['defined']) | list }}" + logic: or users: selectattr: - - when: + - when: - ['type', 'defined'] - ['type', 'equalto', 'user'] - - when: "{{ __ansible__config.modules.ansible_builtin_user.uniques | product(['defined']) | list }}" - logic: or + - when: "{{ __ansible__config.modules.ansible_builtin_user.uniques | product(['defined']) | list }}" + logic: or ssh_config: selectattr: - - when: + - when: - ['type', 'defined'] - ['type', 'equalto', 'ssh_config'] - ['name', 'defined'] - ['value', 'defined'] + sudoers_module: + selectattr: + - when: "{{ [['type', 'defined'], ['type', 'equalto', 'sudoers_module']] + + ([['name', 'defined']] if (auth__sudoers_consolidate | default(true) | bool) else []) }}" auth__authorized_keys_all: "{{ auth__all | aybarsm.helper.selectattr(__auth__config.authorized_keys.selectattr) | @@ -35,12 +39,12 @@ auth__authorized_keys_all: "{{ auth__all | default([]) }}" auth__groups_all: "{{ auth__all | - aybarsm.helper.selectattr(__auth__config.packages.selectattr) | + aybarsm.helper.selectattr(__auth__config.groups.selectattr) | aybarsm.helper.unique_recursive(__ansible__config.modules.ansible_builtin_group.uniques) | default([]) }}" auth__users_all: "{{ auth__all | - aybarsm.helper.selectattr(__auth__config.packages.selectattr) | + aybarsm.helper.selectattr(__auth__config.users.selectattr) | aybarsm.helper.replace_aliases(__ansible__config.modules.ansible_builtin_user.aliases) | aybarsm.helper.unique_recursive(__ansible__config.modules.ansible_builtin_user.uniques) | default([]) }}" @@ -49,4 +53,9 @@ auth__ssh_config_all: "{{ auth__all | aybarsm.helper.selectattr(__auth__config.ssh_config.selectattr) | aybarsm.helper.replace_aliases(__ansible__config.modules.ansible_builtin_user.aliases) | aybarsm.helper.unique_recursive('name', 'children') | + default([]) }}" + +auth__sudoers_module_all: "{{ auth__all | + aybarsm.helper.selectattr(__auth__config.sudoers_module.selectattr) | + aybarsm.helper.unique_recursive('name') | default([]) }}" \ No newline at end of file