infra/ansible/roles/base/tasks/users.yml
Graham McIntire fb5803c866
add FreeBSD bootstrap, irc servers, hostname overrides, and cleanups
- bootstrap.yml: support pkg for FreeBSD sudo/python3 install
- base role: FreeBSD package sets, sudoers paths, host key regen, admin group, usermod process-in-use tolerance
- freebsd role: pkg update/upgrade tasks
- general role: standalone hostname tasks (ungated from network.skip), hostname_override support
- inspircd role: deploy configs for ca/us manero.org irc servers with vault-backed secrets
- uisp role: download and run installer on fresh hosts, skip if already running
- netbox role: stop services before usermod to avoid process-in-use failures
- hosts: add irc_servers group, ca/us.manero.org (Tailscale), drop staging.towerops.net
- all.yml: graham user gets static ed25519 key alongside github keys
2026-06-19 17:19:29 -05:00

124 lines
4.4 KiB
YAML

# User and group management tasks
- name: Ensure admin group exists when defined
ansible.builtin.group:
name: "{{ admin_group }}"
when: admin_group | default('') | length > 0
- name: Ensure managed groups exist
ansible.builtin.group:
name: "{{ item.name }}"
gid: "{{ item.gid | default(omit) }}"
state: "{{ item.state | default('present') }}"
loop: "{{ managed_groups | default([]) }}"
loop_control:
label: "{{ item.name }}"
- name: Ensure primary groups for managed users exist
ansible.builtin.group:
name: "{{ item.primary_group }}"
gid: "{{ item.primary_gid | default(omit) }}"
state: present
loop: "{{ managed_users | default([]) }}"
loop_control:
label: "{{ item.name }}"
when: item.primary_group is defined
- name: Ensure managed users are present
ansible.builtin.user:
name: "{{ item.name }}"
uid: "{{ item.uid | default(omit) }}"
shell: "{{ item.shell | default('/bin/bash') }}"
home: "{{ item.home | default(omit) }}"
group: "{{ item.primary_group | default(omit) }}"
groups: "{{ (user_groups | join(',')) if user_groups else omit }}"
append: "{{ true if user_groups else omit }}"
create_home: "{{ item.create_home | default(true) }}"
state: "{{ item.state | default('present') }}"
vars:
user_groups: >-
{{ ((item.groups | default([])) +
([admin_group] if item.admin | default(false) and admin_group | default('') | length > 0 else []))
| unique }}
loop: "{{ managed_users | default([]) }}"
loop_control:
label: "{{ item.name }}"
when: item.state | default('present') != 'absent'
register: user_result
failed_when:
- user_result is failed
- '"currently used by process" not in user_result.msg'
- name: Remove managed users marked absent
ansible.builtin.user:
name: "{{ item.name }}"
state: absent
remove: "{{ item.remove | default(false) }}"
loop: "{{ managed_users | default([]) }}"
loop_control:
label: "{{ item.name }}"
when: item.state | default('present') == 'absent'
- name: Install authorized keys from GitHub
ansible.posix.authorized_key:
user: "{{ item.0.name }}"
state: "{{ item.1.state | default('present') }}"
key: "https://github.com/{{ item.1.value }}.keys"
manage_dir: "{{ item.1.manage_dir | default(true) }}"
exclusive: "{{ item.1.exclusive | default(false) }}"
loop: "{{ managed_users | default([]) | subelements('authorized_keys', skip_missing=True) }}"
loop_control:
label: "{{ item.0.name }} (github: {{ item.1.value }})"
when:
- item.1.type | default('github') == 'github'
- item.0.state | default('present') != 'absent'
- name: Install authorized keys from files
ansible.posix.authorized_key:
user: "{{ item.0.name }}"
state: "{{ item.1.state | default('present') }}"
key: "{{ lookup('file', item.1.value) }}"
manage_dir: "{{ item.1.manage_dir | default(true) }}"
exclusive: "{{ item.1.exclusive | default(false) }}"
loop: "{{ managed_users | default([]) | subelements('authorized_keys', skip_missing=True) }}"
loop_control:
label: "{{ item.0.name }} (file: {{ item.1.value }})"
when:
- item.1.type | default('github') == 'file'
- item.0.state | default('present') != 'absent'
- name: Install authorized keys from inline strings
ansible.posix.authorized_key:
user: "{{ item.0.name }}"
state: "{{ item.1.state | default('present') }}"
key: "{{ item.1.value }}"
manage_dir: "{{ item.1.manage_dir | default(true) }}"
exclusive: "{{ item.1.exclusive | default(false) }}"
loop: "{{ managed_users | default([]) | subelements('authorized_keys', skip_missing=True) }}"
loop_control:
label: "{{ item.0.name }} (string key)"
when:
- item.1.type | default('github') == 'string'
- item.0.state | default('present') != 'absent'
- name: Configure sudo for ansible user
ansible.builtin.template:
src: sudoers_ansible.j2
dest: "{{ sudoers_dir }}/ansible"
mode: '0440'
validate: "{{ visudo_path }} -cf %s"
- name: Configure sudo for graham user
ansible.builtin.template:
src: sudoers_graham.j2
dest: "{{ sudoers_dir }}/graham"
mode: '0440'
validate: "{{ visudo_path }} -cf %s"
- name: Enable passwordless sudo for admin group
ansible.builtin.lineinfile:
path: "{{ sudoers_path }}"
state: present
regexp: '^%{{ admin_group }}'
line: '{{ admin_group }} ALL=(ALL) NOPASSWD: ALL'
validate: "{{ visudo_path }} -cf %s"