diff options
| author | Ahmed Abdelhalim <[email protected]> | 2025-08-11 00:32:00 +0200 |
|---|---|---|
| committer | Ahmed Abdelhalim <[email protected]> | 2025-08-11 00:32:00 +0200 |
| commit | 20ab3adb6b08944235c707490449c8906394564f (patch) | |
| tree | 8f0bded9360fde2cb6779d4e8cd50d41a3741c4c | |
| parent | b837d1af24552836cf85a17013ca7b210e1b727c (diff) | |
Add network role
| -rw-r--r-- | group_vars/all.yml.example | 2 | ||||
| -rw-r--r-- | molecule/default/Dockerfile.archlinux.j2 | 24 | ||||
| -rw-r--r-- | molecule/default/Dockerfile.raspberrypi.j2 | 24 | ||||
| -rw-r--r-- | molecule/default/Dockerfile.ubuntu.j2 | 29 | ||||
| -rw-r--r-- | molecule/default/converge.yml | 9 | ||||
| -rw-r--r-- | molecule/default/molecule.yml | 41 | ||||
| -rw-r--r-- | roles/network/README.md | 12 | ||||
| -rw-r--r-- | roles/network/defaults/main.yml | 3 | ||||
| -rw-r--r-- | roles/network/handlers/main.yml | 13 | ||||
| -rw-r--r-- | roles/network/meta/argument_specs.yml | 29 | ||||
| -rw-r--r-- | roles/network/meta/main.yml | 19 | ||||
| -rw-r--r-- | roles/network/tasks/install-archlinux.yml | 15 | ||||
| -rw-r--r-- | roles/network/tasks/install-debian.yml | 15 | ||||
| -rw-r--r-- | roles/network/tasks/main.yml | 89 | ||||
| -rw-r--r-- | roles/network/templates/NetworkManager.conf.j2 | 22 | ||||
| -rw-r--r-- | roles/network/templates/eth0-connection.nmconnection.j2 | 16 | ||||
| -rw-r--r-- | roles/network/templates/wifi-connection.nmconnection.j2 | 23 | ||||
| -rw-r--r-- | roles/network/vars/archlinux.yml | 11 | ||||
| -rw-r--r-- | roles/network/vars/debian.yml | 13 | ||||
| -rw-r--r-- | site.yml | 2 |
20 files changed, 411 insertions, 0 deletions
diff --git a/group_vars/all.yml.example b/group_vars/all.yml.example index ed97d539..e0529a63 100644 --- a/group_vars/all.yml.example +++ b/group_vars/all.yml.example @@ -1 +1,3 @@ --- +network_wifi_ssid: "TEST_WIFI_SSID" +network_wifi_pass: "TEST_WIFI_PASS" diff --git a/molecule/default/Dockerfile.archlinux.j2 b/molecule/default/Dockerfile.archlinux.j2 new file mode 100644 index 00000000..1d5a1cd5 --- /dev/null +++ b/molecule/default/Dockerfile.archlinux.j2 @@ -0,0 +1,24 @@ +FROM docker.io/library/archlinux + +ENV container docker + +RUN pacman -Syu --noconfirm --needed python3 \ + && pacman -Scc --noconfirm + +RUN (cd /lib/systemd/system/sysinit.target.wants/; \ + for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \ + rm -f /lib/systemd/system/multi-user.target.wants/*;\ + rm -f /etc/systemd/system/*.wants/*;\ + rm -f /lib/systemd/system/local-fs.target.wants/*; \ + rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ + rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ + rm -f /lib/systemd/system/basic.target.wants/*;\ + rm -f /lib/systemd/system/anaconda.target.wants/*; + +# Workaround archlinux not including any non-indo-european locales +# https://gitlab.archlinux.org/archlinux/archlinux-docker/-/issues/59 +RUN cp -r /usr/share/i18n/locales/en_US /usr/share/i18n/locales/de_DE; + +VOLUME ["/sys/fs/cgroup"] + +CMD ["/lib/systemd/systemd"] diff --git a/molecule/default/Dockerfile.raspberrypi.j2 b/molecule/default/Dockerfile.raspberrypi.j2 new file mode 100644 index 00000000..1b1133f4 --- /dev/null +++ b/molecule/default/Dockerfile.raspberrypi.j2 @@ -0,0 +1,24 @@ +# Based on the amazing work of geerlingguy <3 +# FROM docker.io/geerlingguy/docker-debian12-ansible +FROM docker.io/library/debian:bookworm + +ARG DEBIAN_FRONTEND=noninteractive + +ENV container docker + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + systemd python3 avahi-daemon \ + && rm -Rf /var/lib/apt/lists/* \ + && rm -Rf /usr/share/doc \ + && rm -Rf /usr/share/man \ + && apt-get clean + +RUN rm -f /lib/systemd/system/multi-user.target.wants/getty.target + +# Mimic Raspberry OS default boot (for testing) +RUN systemctl enable avahi-daemon + +VOLUME ["/sys/fs/cgroup", "/tmp", "/run", "/opt"] + +CMD ["/lib/systemd/systemd"] diff --git a/molecule/default/Dockerfile.ubuntu.j2 b/molecule/default/Dockerfile.ubuntu.j2 new file mode 100644 index 00000000..4cf904ed --- /dev/null +++ b/molecule/default/Dockerfile.ubuntu.j2 @@ -0,0 +1,29 @@ +# Based on the amazing work of geerlingguy <3 +# FROM docker.io/geerlingguy/docker-ubuntu2404-ansible +FROM docker.io/library/ubuntu:noble + +ARG DEBIAN_FRONTEND=noninteractive + +ENV container docker + +RUN apt-get update \ + && apt-get install -y --no-install-recommends locales systemd avahi-daemon python3 \ + && apt-get clean \ + && rm -Rf /var/lib/apt/lists/* \ + && rm -Rf /usr/share/doc \ + && rm -Rf /usr/share/man + +# Fix potential UTF-8 errors with ansible-test. +RUN locale-gen en_US.UTF-8 + +# Remove unnecessary getty and udev targets that result in high CPU usage when using +# multiple containers with Molecule (https://github.com/ansible/molecule/issues/1104) +RUN rm -f /lib/systemd/system/systemd*udev* \ + && rm -f /lib/systemd/system/getty.target + +# Mimic Ubuntu OS default boot (for testing) +RUN systemctl enable avahi-daemon + +VOLUME ["/sys/fs/cgroup", "/tmp", "/run", "/opt"] + +CMD ["/lib/systemd/systemd"] diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml new file mode 100644 index 00000000..d0c2418d --- /dev/null +++ b/molecule/default/converge.yml @@ -0,0 +1,9 @@ +--- +- name: Converge + hosts: instance + vars: + ansible_become_method: su + network_wifi_ssid: "TEST_WIFI_SSID" + network_wifi_pass: "TEST_WIFI_PASS" + roles: + - role: network diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml new file mode 100644 index 00000000..c0ec4e96 --- /dev/null +++ b/molecule/default/molecule.yml @@ -0,0 +1,41 @@ +--- +role_name_check: 1 +dependency: + name: galaxy + options: + ignore-errors: true +driver: + name: podman +platforms: + - name: instance + image: ${MOLECULE_DISTRO:-archlinux} + dockerfile: Dockerfile.${MOLECULE_DISTRO:-archlinux}.j2 + platform: "${MOLECULE_PLATFORM:-linux/amd64}" + pre_build_image: false + privileged: true + command: ${MOLECULE_COMMAND:-"/lib/systemd/systemd"} + tmpfs: + "/tmp": "rw" + "/run": "rw,exec" + volumes: + - "/sys/fs/cgroup:/sys/fs/cgroup:rw" + cgroupns_mode: host +provisioner: + name: ansible + inventory: + links: + host_vars: "../../host_vars/" + group_vars: "../../group_vars/" + env: + MOLECULE_DISTRO: "${MOLECULE_DISTRO:-archlinux}" + ANSIBLE_ROLES_PATH: "../../roles" + config_options: + defaults: + callback_result_format: yaml + interpreter_python: /usr/bin/python3 + ssh_connection: + pipelining: true + playbooks: + converge: converge.yml +verifier: + name: ansible diff --git a/roles/network/README.md b/roles/network/README.md new file mode 100644 index 00000000..ef0a566d --- /dev/null +++ b/roles/network/README.md @@ -0,0 +1,12 @@ +# Ansible Role: network + +This role configure the basic networking functionality of a linux distro + +## Role Variables + +- `hostname` the hostname to be configure if provided. +- `network_wifi_ssid` the name of the WIFI network to be configured (default: ""). +- `network_wifi_pass` the passphrase of the WIFI network to be configure (default: ""). +- `network_packages` the packages to install for a distro (default in distro vars). +- `network_packages_removed` the packages to remove from a distro (default in distro vars). +- `network_services` the services names to start/enable for a distro (default in distro vars). diff --git a/roles/network/defaults/main.yml b/roles/network/defaults/main.yml new file mode 100644 index 00000000..5e1076a7 --- /dev/null +++ b/roles/network/defaults/main.yml @@ -0,0 +1,3 @@ +--- +network_wifi_ssid: "" +network_wifi_pass: "" diff --git a/roles/network/handlers/main.yml b/roles/network/handlers/main.yml new file mode 100644 index 00000000..df50d41d --- /dev/null +++ b/roles/network/handlers/main.yml @@ -0,0 +1,13 @@ +--- +- name: "Reload systemd" + become: true + ansible.builtin.systemd_service: + daemon_reload: true + when: not ansible_is_chroot + +- name: "Restart NetworkManager" + become: true + ansible.builtin.systemd_service: + name: "NetworkManager" + state: "restarted" + when: not ansible_is_chroot diff --git a/roles/network/meta/argument_specs.yml b/roles/network/meta/argument_specs.yml new file mode 100644 index 00000000..cd30b69c --- /dev/null +++ b/roles/network/meta/argument_specs.yml @@ -0,0 +1,29 @@ +--- +argument_specs: + main: + options: + hostname: + type: "str" + description: "The distro linux network hostname to be used" + network_wifi_ssid: + type: "str" + description: "The WIFI SSID to be configure when provided" + required: false + default: "" + network_wifi_pass: + type: "str" + description: "The WIFI Passphrase to be configure when provided" + required: false + default: "" + network_packages: + type: "list" + description: "The network packages to install" + elements: "str" + network_packages_removed: + type: "list" + description: "The network packages to remove" + elements: "str" + network_services: + type: "list" + description: "The network services to enable" + elements: "str" diff --git a/roles/network/meta/main.yml b/roles/network/meta/main.yml new file mode 100644 index 00000000..a129a772 --- /dev/null +++ b/roles/network/meta/main.yml @@ -0,0 +1,19 @@ +--- +dependencies: [] +galaxy_info: + role_name: network + author: a14m + description: "Configure basic distro networking features" + company: "kartoffeln.work GmbH." + license: "license MIT" + min_ansible_version: "2.18" + platforms: + - name: ArchLinux + versions: + - all + - name: Ubuntu + versions: + - noble + - name: Debian + versions: + - bookworm diff --git a/roles/network/tasks/install-archlinux.yml b/roles/network/tasks/install-archlinux.yml new file mode 100644 index 00000000..94384c5a --- /dev/null +++ b/roles/network/tasks/install-archlinux.yml @@ -0,0 +1,15 @@ +--- +- name: "Ensure network_packages are installed" + become: true + community.general.pacman: + name: "{{ network_packages }}" + state: "present" + tags: [required_for_boot] + +- name: "Ensrue network_packages_removed are removed" + become: true + community.general.pacman: + name: "{{ network_packages_removed }}" + state: "absent" + extra_args: "-n" # Removes config files too + # Not required for boot diff --git a/roles/network/tasks/install-debian.yml b/roles/network/tasks/install-debian.yml new file mode 100644 index 00000000..057a4d0f --- /dev/null +++ b/roles/network/tasks/install-debian.yml @@ -0,0 +1,15 @@ +--- +- name: "Ensure network_packages are installed" + become: true + ansible.builtin.apt: + pkg: "{{ network_packages }}" + state: "present" + tags: [required_for_boot] + +- name: "Ensrue network_packages_removed are removed" + become: true + ansible.builtin.apt: + name: "{{ network_packages_removed }}" + state: "absent" + purge: true + # Not required for boot diff --git a/roles/network/tasks/main.yml b/roles/network/tasks/main.yml new file mode 100644 index 00000000..44a9e300 --- /dev/null +++ b/roles/network/tasks/main.yml @@ -0,0 +1,89 @@ +--- +- name: "Configure /etc/hostname" + become: true + ansible.builtin.copy: + dest: "/etc/hostname" + mode: "0644" + content: | + {{ hostname }} + when: hostname is defined + tags: [required_for_boot] + +- name: "Configure /etc/hosts" + become: true + ansible.builtin.copy: + dest: "/etc/hosts" + mode: "0644" + content: | + 127.0.0.1 localhost + 127.0.1.1 {{ hostname }} + ::1 localhost ip6-localhost ip6-loopback + ff02::1 ip6-allnodes + ff02::2 ip6-allrouters + when: hostname is defined + # Not required for boot + +- name: "Include OS-specific variables" + ansible.builtin.include_vars: "{{ ansible_os_family | lower }}.yml" + tags: [required_for_boot] + +- name: "Install OS-specific packages" + ansible.builtin.include_tasks: "install-{{ ansible_os_family | lower }}.yml" + tags: [required_for_boot] + +- name: "(chroot): Ensure network_services are enabled" + ansible.builtin.command: + cmd: "systemctl enable {{ item }}" + changed_when: true + with_items: "{{ network_services }}" + when: ansible_is_chroot + # noqa: command-instead-of-module module doesn't work inside chroot + tags: [required_for_boot] + +- name: "Ensure network_services are enabled" + become: true + ansible.builtin.systemd_service: + name: "{{ item }}" + enabled: true + state: "started" + with_items: "{{ network_services }}" + when: not ansible_is_chroot + # Not required for boot + +- name: "Configure NetworkManager" + become: true + tags: [required_for_boot] + notify: + - "Restart NetworkManager" + - "Reload systemd" + block: + - name: "Configure NetworkManager" + ansible.builtin.template: + src: "NetworkManager.conf.j2" + dest: "/etc/NetworkManager/NetworkManager.conf" + mode: "0644" + + - name: "Configure NetworkManager Captive Portals" + ansible.builtin.get_url: + dest: "/etc/NetworkManager/dispatcher.d/90-open_captive_portal" + # yamllint disable-line + url: "https://raw.githubusercontent.com/Seme4eg/captive-portal-sh/04751034437b6abd92647cab1b22cef586c86f4e/90-open_captive_portal" + checksum: "sha1:75f4c827939e7dd433357ab4776c787be02c485b" + mode: "0750" + + - name: "Configure ethernet connection" + ansible.builtin.template: + src: "eth0-connection.nmconnection.j2" + dest: "/etc/NetworkManager/system-connections/ethernet.nmconnection" + mode: "0600" + owner: "root" + group: "root" + + - name: "Configure wifi connection" + ansible.builtin.template: + src: "wifi-connection.nmconnection.j2" + dest: "/etc/NetworkManager/system-connections/{{ network_wifi_ssid }}.nmconnection" + mode: "0600" + owner: "root" + group: "root" + when: network_wifi_ssid != "" diff --git a/roles/network/templates/NetworkManager.conf.j2 b/roles/network/templates/NetworkManager.conf.j2 new file mode 100644 index 00000000..32d8a442 --- /dev/null +++ b/roles/network/templates/NetworkManager.conf.j2 @@ -0,0 +1,22 @@ +[connectivity] +uri=https://ping.archlinux.org + +[main] +dhcp=dhcpcd + +[device-mac-randomization] +wifi.scan-rand-mac-address=yes + +[connection-mac-randomization] +# Random MAC on every Ethernet connection +ethernet.cloned-mac-address=random +# Random (but permanent) MAC on every wifi network +wifi.cloned-mac-address=stable + +[connection] +ipv6.ip6-privacy=2 +ipv6.dhcp-duid=stable-uuid +wifi.powersave=2 + +[logging] +level=INFO diff --git a/roles/network/templates/eth0-connection.nmconnection.j2 b/roles/network/templates/eth0-connection.nmconnection.j2 new file mode 100644 index 00000000..b5cbe276 --- /dev/null +++ b/roles/network/templates/eth0-connection.nmconnection.j2 @@ -0,0 +1,16 @@ +[connection] +id=ethernet +type=ethernet +autoconnect=true +interface-name=eth0 + +[ethernet] + +[ipv4] +method=auto + +[ipv6] +addr-gen-mode=default +method=auto + +[proxy] diff --git a/roles/network/templates/wifi-connection.nmconnection.j2 b/roles/network/templates/wifi-connection.nmconnection.j2 new file mode 100644 index 00000000..9fffbd12 --- /dev/null +++ b/roles/network/templates/wifi-connection.nmconnection.j2 @@ -0,0 +1,23 @@ +[connection] +id={{ network_wifi_ssid }} +uuid={{ network_wifi_ssid | to_uuid }} +type=wifi +autoconnect=true + +[wifi] +mode=infrastructure +ssid={{ network_wifi_ssid }} + +[wifi-security] +auth-alg=open +key-mgmt=wpa-psk +psk={{ network_wifi_pass }} + +[ipv4] +method=auto + +[ipv6] +addr-gen-mode=default +method=auto + +[proxy] diff --git a/roles/network/vars/archlinux.yml b/roles/network/vars/archlinux.yml new file mode 100644 index 00000000..c3732716 --- /dev/null +++ b/roles/network/vars/archlinux.yml @@ -0,0 +1,11 @@ +--- +network_packages: + - "dhcpcd" + - "networkmanager" + +network_packages_removed: [] + +network_services: + - "dhcpcd" + - "systemd-resolved" + - "NetworkManager" diff --git a/roles/network/vars/debian.yml b/roles/network/vars/debian.yml new file mode 100644 index 00000000..5a9e8797 --- /dev/null +++ b/roles/network/vars/debian.yml @@ -0,0 +1,13 @@ +--- +network_packages: + - "dhcpcd" + - "network-manager" + - "systemd-resolved" + +network_packages_removed: + - "avahi-daemon" + +network_services: + - "dhcpcd" + - "systemd-resolved" + - "NetworkManager" @@ -4,3 +4,5 @@ hosts: - homelab - chroot + roles: + - role: "network" |
