diff --git a/README.md b/README.md index a5b04a9..19a8767 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # Ansible Collection -Opinionated set of roles to configure reasonable defaults for newly provisioned Debian / Ubuntu VMs running Docker. The repository provides a ready-to-use Ansible Collection (`studio.ansible`) containing reusable roles. +Opinionated set of roles to configure reasonable defaults for newly provisioned virtual machines. The repository provides a ready-to-use Ansible Collection (`studio.ansible`) containing reusable roles. + +Currently only supports Debian-based systems. diff --git a/galaxy.yml b/galaxy.yml index 9e0f03e..c79a793 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -3,8 +3,9 @@ namespace: studio name: ansible readme: README.md -version: 1.0.0 +version: 0.0.1 authors: - Studio Vitali description: Studio Ansible collection containing common roles -license: MIT +license: + - MIT diff --git a/meta/runtime.yml b/meta/runtime.yml new file mode 100644 index 0000000..1e85b01 --- /dev/null +++ b/meta/runtime.yml @@ -0,0 +1,2 @@ +--- +requires_ansible: ">=2.15.0" diff --git a/roles/base/tasks/main.yml b/roles/base/tasks/main.yml index c398fff..9535d89 100644 --- a/roles/base/tasks/main.yml +++ b/roles/base/tasks/main.yml @@ -10,7 +10,6 @@ update_cache: true upgrade: dist cache_valid_time: 3600 - when: ansible_facts['os_family'] == "Debian" ## only on Debian / Ubuntu systems become: true - name: Install essential system utilities @@ -26,7 +25,6 @@ - unattended-upgrades state: present update_cache: true - when: ansible_facts['os_family'] == "Debian" become: true # # - name: Enable unattended-upgrades @@ -37,5 +35,3 @@ # APT::Periodic::Unattended-Upgrade "1"; # mode: "0644" # when: ansible_facts['os_family'] == "Debian" - -## SCHEDULE REBOOTS 4 kernel upgrades: with cron, unattended-upgrades or action workflows? diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml index 4229019..a1f1d05 100644 --- a/roles/docker/tasks/main.yml +++ b/roles/docker/tasks/main.yml @@ -1,35 +1,76 @@ --- -- name: Install necessary Docker packages - ansible.builtin.apt: - name: - - docker.io - - docker-compose - state: present - when: ansible_facts['os_family'] == "Debian" ## Debian / Ubuntu +- name: Install Docker become: true + block: + - name: Install Docker prerequisites + ansible.builtin.apt: + name: + - ca-certificates + - curl + - python3-debian ## needed for the deb822 module + state: present + update_cache: true -- name: Ensure Docker service is running - ansible.builtin.service: - name: docker - state: started - enabled: true + - name: Add Docker official APT repository (DEB822 format) + ansible.builtin.deb822_repository: + name: docker + types: deb + uris: "https://download.docker.com/linux/{{ ansible_facts['distribution'] | lower }}" + suites: "{{ ansible_facts['distribution_release'] }}" + components: stable + signed_by: "https://download.docker.com/linux/{{ ansible_facts['distribution'] | lower }}/gpg" + state: present -- name: Create docker user for container execution - ansible.builtin.user: - name: docker - state: present - system: true - shell: /usr/sbin/nologin - groups: docker - append: true - create_home: false + - name: Install Docker CE packages + ansible.builtin.apt: + name: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-buildx-plugin + - docker-compose-plugin + state: present + update_cache: true + + - name: Ensure Docker service is running and enabled + ansible.builtin.service: + name: docker + state: started + enabled: true + +- name: Configure deployment user for Docker + when: deployment_public_ssh_key is defined become: true + block: + - name: Add deployment user to docker group + ansible.builtin.user: + name: deployment + groups: docker + append: true -- name: Create target for docker compose - ansible.builtin.file: - path: /opt/docker - state: directory - owner: deployment - group: deployment - mode: "0755" + - name: Create target for docker compose + ansible.builtin.file: + path: /opt/docker + state: directory + owner: deployment + group: deployment + mode: "0755" + +- name: Create app user for secure container execution become: true + block: + - name: Create appuser group + ansible.builtin.group: + name: appuser + state: present + gid: 9999 + + - name: Create appuser + ansible.builtin.user: + name: appuser + state: present + uid: 9999 + group: appuser + system: true + shell: /usr/sbin/nologin + create_home: false diff --git a/roles/security/handlers/main.yml b/roles/security/handlers/main.yml index 6998953..cad74d8 100644 --- a/roles/security/handlers/main.yml +++ b/roles/security/handlers/main.yml @@ -1,5 +1,5 @@ --- - name: Restart sshd ansible.builtin.service: - name: sshd + name: ssh state: restarted diff --git a/roles/security/tasks/main.yml b/roles/security/tasks/main.yml index a0b5b33..5d4c252 100644 --- a/roles/security/tasks/main.yml +++ b/roles/security/tasks/main.yml @@ -1,35 +1,35 @@ --- -- name: Create SSH drop-in directory - ansible.builtin.file: - path: /etc/ssh/sshd_config.d - state: directory - owner: root - group: root - mode: "0755" +- name: Harden SSH configuration become: true + block: + - name: Create SSH drop-in directory + ansible.builtin.file: + path: /etc/ssh/sshd_config.d + state: directory + owner: root + group: root + mode: "0755" -- name: Harden SSH configuration with drop-in template - ansible.builtin.template: - src: sshd.conf.j2 - dest: /etc/ssh/sshd_config.d/sshd.conf - owner: root - group: root - mode: "0644" - validate: "sshd -t -f %s" - notify: Restart sshd + - name: Harden SSH configuration with drop-in template + ansible.builtin.template: + src: sshd.conf.j2 + dest: /etc/ssh/sshd_config.d/sshd.conf + owner: root + group: root + mode: "0644" + notify: Restart sshd + +- name: Enable fail2ban become: true + block: + - name: Install fail2ban + ansible.builtin.apt: + name: + - fail2ban + state: present -- name: Install fail2ban - ansible.builtin.apt: - name: - - fail2ban - state: present - when: ansible_facts['os_family'] == "Debian" - become: true - -- name: Start fail2ban - ansible.builtin.service: - name: fail2ban - state: started - enabled: yes - when: ansible_facts['os_family'] == "Debian" + - name: Start fail2ban + ansible.builtin.service: + name: fail2ban + state: started + enabled: yes diff --git a/roles/users/tasks/main.yml b/roles/users/tasks/main.yml index 6628891..e416529 100644 --- a/roles/users/tasks/main.yml +++ b/roles/users/tasks/main.yml @@ -1,38 +1,42 @@ --- -# - name: Create primary admin user -# ansible.builtin.user: -# name: sysadmin -# groups: sudo -# append: yes -# shell: /bin/bash -# create_home: yes -# become: true - -# - name: Add SSH public key for sysadmin -# ansible.posix.authorized_key: -# user: sysadmin -# state: present -# key: "{{ sysadmin_public_ssh_key }}" -# become: true - -# - name: Allow passwordless sudo to sysadmin user -# ansible.builtin.copy: -# dest: /etc/sudoers.d/sysadmin -# content: "sysadmin ALL=(ALL) NOPASSWD: ALL" -# mode: "0440" -# validate: /usr/sbin/visudo -cf %s -# become: true - -- name: Create deployment user for CI/CD - ansible.builtin.user: - name: deployment - shell: /bin/bash - create_home: yes +- name: Set up primary sysadmin user + when: sysadmin_public_ssh_key is defined become: true + block: + - name: Create sysadmin user + ansible.builtin.user: + name: "{{ sysadmin_user }}" + groups: sudo + append: yes + shell: /bin/bash + create_home: yes -- name: Add SSH public key for deployment user - ansible.posix.authorized_key: - user: deployment - state: present - key: "{{ deployment_public_ssh_key }}" + - name: Add SSH public key + ansible.posix.authorized_key: + user: "{{ sysadmin_user }}" + state: present + key: "{{ sysadmin_public_ssh_key }}" + + - name: Allow passwordless sudo + ansible.builtin.copy: + dest: /etc/sudoers.d/sudo-nopasswd + content: "%sudo ALL=(ALL) NOPASSWD: ALL" + mode: "0440" + validate: /usr/sbin/visudo -cf %s + + +- name: Set up deployment user for CI/CD + when: deployment_public_ssh_key is defined become: true + block: + - name: Create deployment user + ansible.builtin.user: + name: deployment + shell: /bin/bash + create_home: yes + + - name: Add SSH public key + ansible.posix.authorized_key: + user: deployment + state: present + key: "{{ deployment_public_ssh_key }}"