From e3d93ca4c805b4d83b3bc849adaa53923f9faa59 Mon Sep 17 00:00:00 2001 From: ilia Date: Thu, 28 Aug 2025 14:06:22 -0400 Subject: [PATCH] Refactor dev-playbook.yml to use role tags for improved task organization. Update README.md to include prerequisites and examples for selective execution with tags. Enhance applications role to check for existing installations and manage Brave browser setup. Modify base role to streamline UFW handling and add mailutils. Update docker role to include checks for existing installations and improve repository management. Add reboot check in maintenance tasks to ensure system changes are applied correctly. --- README.md | 21 ++++++++ collections/requirements.yml | 6 +++ dev-playbook.yml | 19 ++++--- roles/applications/tasks/main.yml | 53 +++++++++++++++++++ roles/base/handlers/main.yml | 3 +- roles/base/tasks/main.yml | 6 +-- roles/docker/tasks/main.yml | 84 ++++++++++++++++++++++++++++--- roles/maintenance/tasks/main.yml | 12 +++-- roles/ssh/handlers/main.yml | 5 +- roles/ssh/tasks/main.yml | 5 ++ 10 files changed, 188 insertions(+), 26 deletions(-) create mode 100644 collections/requirements.yml diff --git a/README.md b/README.md index f861b69..1f5386a 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,12 @@ This Ansible playbook automates the setup of development environments across mul ## 🚀 Usage +### Prerequisites +```bash +# Install required collections +ansible-galaxy collection install -r collections/requirements.yml +``` + ### Basic Setup ```bash # Run on all development machines @@ -40,6 +46,21 @@ ansible-playbook dev-playbook.yml --limit devVM ansible-playbook dev-playbook.yml --limit bottom ``` +### Selective Execution with Tags +```bash +# Security-related roles only +ansible-playbook dev-playbook.yml --tags security + +# Development tools only +ansible-playbook dev-playbook.yml --tags development,docker + +# Applications only +ansible-playbook dev-playbook.yml --tags apps + +# Skip maintenance +ansible-playbook dev-playbook.yml --skip-tags maintenance +``` + ### Skip Reboots Add `skip_reboot=true` to host variables: ```ini diff --git a/collections/requirements.yml b/collections/requirements.yml new file mode 100644 index 0000000..2ea3420 --- /dev/null +++ b/collections/requirements.yml @@ -0,0 +1,6 @@ +--- +collections: + - name: community.general + version: ">=6.0.0" + - name: ansible.posix + version: ">=1.4.0" diff --git a/dev-playbook.yml b/dev-playbook.yml index 964a2b3..12b6136 100644 --- a/dev-playbook.yml +++ b/dev-playbook.yml @@ -2,21 +2,20 @@ become: true roles: - - maintenance - - base - - development - - shell - - docker - - ssh - - user - - applications - - snap + - { role: maintenance, tags: ['maintenance'] } + - { role: base, tags: ['base', 'security'] } + - { role: user, tags: ['user'] } + - { role: ssh, tags: ['ssh', 'security'] } + - { role: shell, tags: ['shell'] } + - { role: development, tags: ['development', 'dev'] } + - { role: docker, tags: ['docker'] } + - { role: applications, tags: ['applications', 'apps'] } + - { role: snap, tags: ['snap', 'apps'] } pre_tasks: - name: Update apt cache apt: update_cache: yes - run_once: true tasks: # Additional tasks can be added here if needed diff --git a/roles/applications/tasks/main.yml b/roles/applications/tasks/main.yml index 46d7555..066b896 100644 --- a/roles/applications/tasks/main.yml +++ b/roles/applications/tasks/main.yml @@ -1,4 +1,14 @@ --- +- name: Check if desktop applications are installed + apt: + list: "{{ item }}" + register: app_check + loop: + - redshift + - libreoffice + - evince + changed_when: false + - name: Install desktop applications apt: name: @@ -6,20 +16,63 @@ - libreoffice - evince state: present + when: + - app_check.results[0].installed is not defined or + - app_check.results[1].installed is not defined or + - app_check.results[2].installed is not defined + +- name: Check if Brave is already installed + command: brave-browser --version + register: brave_check + ignore_errors: true + changed_when: false + +- name: Check if Brave package is installed via apt + apt: + list: brave-browser + register: brave_apt_check + changed_when: false + +- name: Remove old Brave repository files + file: + path: "{{ item }}" + state: absent + loop: + - /etc/apt/sources.list.d/brave-browser.list + - /etc/apt/sources.list.d/brave-browser-release.sources + when: brave_check.rc != 0 or brave_apt_check.results[0].installed is not defined - name: Download Brave APT key get_url: url: https://brave-browser-apt-release.s3.brave.com/brave-browser-archive-keyring.gpg dest: /usr/share/keyrings/brave-browser-archive-keyring.gpg mode: '0644' + when: brave_check.rc != 0 or brave_apt_check.results[0].installed is not defined - name: Add Brave repo (all Debian family) apt_repository: repo: "deb [signed-by=/usr/share/keyrings/brave-browser-archive-keyring.gpg] https://brave-browser-apt-release.s3.brave.com/ stable main" filename: brave-browser state: present + when: brave_check.rc != 0 or brave_apt_check.results[0].installed is not defined + +- name: Update apt cache after Brave repo add + apt: + update_cache: yes + when: brave_check.rc != 0 or brave_apt_check.results[0].installed is not defined - name: Install Brave browser apt: name: brave-browser state: present + when: brave_check.rc != 0 or brave_apt_check.results[0].installed is not defined + +- name: Display application status + debug: + msg: + - "Redshift installed: {{ 'Yes' if app_check.results[0].installed is defined else 'No' }}" + - "LibreOffice installed: {{ 'Yes' if app_check.results[1].installed is defined else 'No' }}" + - "Evince installed: {{ 'Yes' if app_check.results[2].installed is defined else 'No' }}" + - "Brave already installed: {{ brave_check.stdout if brave_check.rc == 0 else 'Not found' }}" + - "Brave package installed: {{ 'Yes' if brave_apt_check.results[0].installed is defined else 'No' }}" + - "Actions taken: {{ 'None - All apps already present' if app_check.results[0].installed is defined and app_check.results[1].installed is defined and app_check.results[2].installed is defined and brave_check.rc == 0 and brave_apt_check.results[0].installed is defined else 'Some applications installed/updated' }}" diff --git a/roles/base/handlers/main.yml b/roles/base/handlers/main.yml index e38df8a..13dc1ea 100644 --- a/roles/base/handlers/main.yml +++ b/roles/base/handlers/main.yml @@ -7,5 +7,4 @@ state: restarted - name: reload ufw - ufw: - state: reloaded + command: ufw reload diff --git a/roles/base/tasks/main.yml b/roles/base/tasks/main.yml index da83d22..3826f97 100644 --- a/roles/base/tasks/main.yml +++ b/roles/base/tasks/main.yml @@ -16,6 +16,7 @@ - net-tools - ufw - fail2ban + - mailutils state: present - name: Install monitoring tools @@ -33,10 +34,7 @@ mode: '0644' notify: restart fail2ban -- name: Enable UFW - ufw: - state: enabled - policy: deny +# UFW enablement moved to ssh role to avoid lockout - name: Set timezone timezone: diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml index 74bfd86..620bdf8 100644 --- a/roles/docker/tasks/main.yml +++ b/roles/docker/tasks/main.yml @@ -1,4 +1,24 @@ --- +- name: Debug distribution information + debug: + msg: + - "Distribution: {{ ansible_facts['distribution'] }}" + - "Distribution Release: {{ ansible_facts['distribution_release'] }}" + - "Distribution Version: {{ ansible_facts['distribution_version'] }}" + - "OS Family: {{ ansible_facts['os_family'] }}" + +- name: Check if Docker is already installed + command: docker --version + register: docker_check + ignore_errors: true + changed_when: false + +- name: Check if Docker packages are installed via apt + apt: + list: docker-ce + register: docker_apt_check + changed_when: false + - name: Install Docker requirements apt: name: @@ -10,15 +30,57 @@ state: present update_cache: yes -- name: Add Docker's official GPG key - apt_key: - url: https://download.docker.com/linux/ubuntu/gpg - state: present +- name: Remove old Docker repository files + file: + path: "{{ item }}" + state: absent + loop: + - /etc/apt/sources.list.d/docker.list + - /etc/apt/sources.list.d/docker-ce.list + when: docker_check.rc != 0 or docker_apt_check.results[0].installed is not defined -- name: Add Docker repository +- name: Create keyrings directory + file: + path: /etc/apt/keyrings + state: directory + mode: '0755' + when: docker_check.rc != 0 or docker_apt_check.results[0].installed is not defined + +- name: Download Docker's official GPG key + get_url: + url: https://download.docker.com/linux/ubuntu/gpg + dest: /etc/apt/keyrings/docker.gpg + mode: '0644' + when: docker_check.rc != 0 or docker_apt_check.results[0].installed is not defined + +- name: Add Docker repository for Ubuntu apt_repository: - repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable" + repo: "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable" state: present + when: + - ansible_facts['distribution'] == "Ubuntu" + - docker_check.rc != 0 or docker_apt_check.results[0].installed is not defined + +- name: Add Docker repository for Debian + apt_repository: + repo: "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian {{ ansible_distribution_release }} stable" + state: present + when: + - ansible_facts['distribution'] == "Debian" + - docker_check.rc != 0 or docker_apt_check.results[0].installed is not defined + +- name: Add Docker repository for Linux Mint + apt_repository: + repo: "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable" + state: present + when: + - ansible_facts['distribution'] == "Linux Mint" + - docker_check.rc != 0 or docker_apt_check.results[0].installed is not defined + +- name: Update apt cache after Docker repo add + apt: + update_cache: yes + when: docker_check.rc != 0 or docker_apt_check.results[0].installed is not defined - name: Install Docker CE apt: @@ -30,16 +92,26 @@ - docker-compose-plugin state: present update_cache: yes + when: docker_check.rc != 0 or docker_apt_check.results[0].installed is not defined - name: Start and enable Docker service systemd: name: docker state: started enabled: yes + when: docker_check.rc != 0 or docker_apt_check.results[0].installed is not defined - name: Add user to docker group user: name: "{{ ansible_user }}" groups: docker append: yes + when: docker_check.rc != 0 or docker_apt_check.results[0].installed is not defined + +- name: Display Docker status + debug: + msg: + - "Docker already installed: {{ docker_check.stdout if docker_check.rc == 0 else 'Not found' }}" + - "Docker CE package installed: {{ 'Yes' if docker_apt_check.results[0].installed is defined else 'No' }}" + - "Actions taken: {{ 'None - Docker already present' if docker_check.rc == 0 and docker_apt_check.results[0].installed is defined else 'Docker installation/configuration performed' }}" diff --git a/roles/maintenance/tasks/main.yml b/roles/maintenance/tasks/main.yml index b0a5aed..cebd7bf 100644 --- a/roles/maintenance/tasks/main.yml +++ b/roles/maintenance/tasks/main.yml @@ -15,9 +15,15 @@ apt: autoclean: yes -- name: Reboot if tasks changed things +- name: Check if reboot is required + stat: + path: /var/run/reboot-required + register: reboot_required + +- name: Reboot if required reboot: msg: "Reboot triggered by Ansible after system changes." - when: + when: - ansible_facts['pkg_mgr'] == "apt" - - skip_reboot is not defined or skip_reboot != "true" \ No newline at end of file + - reboot_required.stat.exists + - skip_reboot | default(false) | bool == false \ No newline at end of file diff --git a/roles/ssh/handlers/main.yml b/roles/ssh/handlers/main.yml index 7e51bf6..c567a5b 100644 --- a/roles/ssh/handlers/main.yml +++ b/roles/ssh/handlers/main.yml @@ -1,2 +1,5 @@ --- -# handlers file for ssh +- name: restart ssh + systemd: + name: ssh + state: restarted \ No newline at end of file diff --git a/roles/ssh/tasks/main.yml b/roles/ssh/tasks/main.yml index 40fd4c1..d3c7818 100644 --- a/roles/ssh/tasks/main.yml +++ b/roles/ssh/tasks/main.yml @@ -9,3 +9,8 @@ rule: allow name: OpenSSH +- name: Enable UFW with deny default policy + ufw: + state: enabled + policy: deny +