--- - name: Group hosts by platform hosts: all tags: - always pre_tasks: - include_tasks: tasks/meta/runtime-group-determination.yaml - name: Bootstrap remote ansible environment hosts: linux gather_facts: false tags: - always tasks: - include_tasks: tasks/meta/bootstrap-remote-env.yaml - name: Update system hosts: linux tags: - packages vars_files: - vars/packages.yaml tasks: - name: Update system packages via DNF when: ansible_distribution == "Rocky" or ansible_distribution == "Fedora" become: true ansible.builtin.dnf: name: "*" state: latest - name: Install global bash config become: true ansible.builtin.copy: src: global.sh dest: /etc/profile.d/ZZ-skylab-global.sh owner: root group: "{{ ansible_user }}" mode: 0644 - name: Install universal packages on Rocky when: ansible_distribution == "Rocky" become: true ansible.builtin.dnf: name: "{{ skylab_packages_global + skylab_packages_rocky }}" state: present update_cache: true - name: Install universal packages on Fedora when: ansible_distribution == "Fedora" become: true ansible.builtin.dnf: name: "{{ skylab_packages_global + skylab_packages_fedora }}" state: present update_cache: true - name: Update unix accounts hosts: linux tags: - accounts - access vars_files: - vars/access.yaml - vars/sshkeys.yaml tasks: - name: Create management groups become: true ansible.builtin.group: name: "{{ item.name }}" gid: "{{ item.gid }}" state: present loop: - "{{ skylab_group }}" - "{{ skylab_group_admin }}" - "{{ skylab_group_automation }}" loop_control: label: "{{ item.name }},{{ item.gid }}" - name: Determine existing skylab users changed_when: false ansible.builtin.shell: cmd: 'grep "{{ skylab_group.name }}:" /etc/group | cut --delimiter : --fields 4 | tr "," "\n"' register: _existing_skylab_accounts - name: Determine deleted skylab users vars: _deleted_accounts: [] when: item not in (skylab_accounts | items2dict(key_name='name', value_name='uid')) ansible.builtin.set_fact: _deleted_accounts: "{{ _deleted_accounts + [item] }}" loop: "{{ _existing_skylab_accounts.stdout_lines }}" - name: Delete accounts when: _deleted_accounts | default(false) block: - name: Delete removed user accounts become: true ansible.builtin.user: name: "{{ item }}" state: absent loop: "{{ _deleted_accounts }}" - name: Delete removed user groups become: true ansible.builtin.group: name: "{{ item }}" state: absent loop: "{{ _deleted_accounts }}" - name: Delete removed user home directories become: true ansible.builtin.file: path: "/home/{{ item }}" state: absent loop: "{{ _deleted_accounts }}" - name: Determine active users when: item.targets | default([]) | intersect(skylab_targets) vars: _active_accounts: [] ansible.builtin.set_fact: _active_accounts: "{{ _active_accounts + [item] }}" loop: "{{ skylab_accounts }}" loop_control: label: "{{ item.uid }},{{ item.name }}" - name: Create account groups become: true ansible.builtin.group: name: "{{ item.name }}" gid: "{{ item.uid }}" state: present loop: "{{ _active_accounts }}" loop_control: label: "{{ item.uid }},{{ item.name }}" - name: Determine account groups ansible.builtin.set_fact: _determined_member_groups: "{{ _determined_member_groups | default({}) | combine({item.name: [ skylab_group.name, 'wheel' if (item.admin | default(false) and ansible_os_family == 'RedHat') else '', 'sudo' if (item.admin | default(false) and ansible_os_family == 'Debian') else '', skylab_group_admin.name if item.admin | default(false) else '', skylab_group_automation.name if item.service | default(false) else '', ]}) }}" loop: "{{ _active_accounts }}" loop_control: label: "{{ item.uid }},{{ item.name }}" - name: Create accounts become: true ansible.builtin.user: name: "{{ item.name }}" state: present uid: "{{ item.uid }}" group: "{{ item.name }}" groups: "{{ _determined_member_groups[item.name] }}" comment: "{{ item.fullname | default('') }}" system: "{{ item.service | default(false) }}" generate_ssh_key: true ssh_key_bits: 4096 ssh_key_passphrase: "{{ item.password }}" ssh_key_comment: "{{ item.name }}@{{ inventory_hostname }}" ssh_key_type: ed25519 password: "{{ item.password }}" loop: "{{ _active_accounts }}" loop_control: label: "{{ item.uid }},{{ item.name }}" - name: Ensure proper ownership of user home directories become: true ansible.builtin.file: path: /home/{{ item.name }} state: directory group: "{{ item.name }}" owner: "{{ item.name }}" mode: 0700 loop: "{{ _active_accounts }}" loop_control: label: "{{ item.uid }},{{ item.name }}" - name: Create SSH directory become: true ansible.builtin.file: path: /home/{{ item.name }}/.ssh owner: "{{ item.name }}" group: "{{ item.name }}" state: directory mode: 0700 loop: "{{ _active_accounts }}" loop_control: label: "{{ item.uid }},{{ item.name }}" - name: Update authorized keys become: true ansible.builtin.authorized_key: user: "{{ item.name }}" key: "{{ skylab_ssh_keys[item.name] | join('\n') }}" state: present exclusive: true loop: "{{ _active_accounts }}" loop_control: label: "{{ item.uid }},{{ item.name }}" - name: Enforce ownership of authorized keys become: true ansible.builtin.file: path: /home/{{ item.name }}/.ssh/authorized_keys state: file owner: "{{ item.name }}" group: "{{ item.name }}" mode: 0400 loop: "{{ _active_accounts }}" loop_control: label: "{{ item.uid }},{{ item.name }}" - name: Enforce root password become: true ansible.builtin.user: name: root password: "{{ skylab_root_password }}" state: present