feat: add dhcpd server role

This commit is contained in:
Clément Désiles 2026-02-03 22:07:40 +01:00
parent 5fb027c446
commit 1f758deb82
No known key found for this signature in database
8 changed files with 147 additions and 0 deletions

29
roles/dhcpd/README.md Normal file
View File

@ -0,0 +1,29 @@
# dhcpd
ISC DHCP server role for Arch Linux and Debian/Ubuntu.
## Requirements
- `dhcpd_interface` must be defined in inventory
## Configuration
See [defaults/main.yml](defaults/main.yml) for all available variables.
## Example
```yaml
dhcpd_interface: "lan0"
dhcpd_subnet: "192.168.1.0"
dhcpd_range_start: "192.168.1.20"
dhcpd_range_end: "192.168.1.200"
dhcpd_gateway: "192.168.1.1"
dhcpd_dns_servers:
- "192.168.1.2"
dhcpd_domain_name: "home.lan"
dhcpd_reservations:
- hostname: printer
mac: "aa:bb:cc:dd:ee:ff"
ip: "192.168.1.10"
```

View File

@ -0,0 +1,27 @@
# Network configuration
dhcpd_subnet: "192.168.1.0"
dhcpd_netmask: "255.255.255.0"
dhcpd_range_start: "192.168.1.20"
dhcpd_range_end: "192.168.1.200"
dhcpd_gateway: "192.168.1.1"
dhcpd_dns_servers:
- "1.1.1.1"
# Lease times (in seconds)
dhcpd_default_lease_time: 86400 # 24 hours
dhcpd_max_lease_time: 172800 # 48 hours
# Interface to listen on (required)
# dhcpd_interface: "lan0"
# Domain name (optional)
# dhcpd_domain_name: "home.lan"
# Static reservations
# dhcpd_reservations:
# - hostname: printer
# mac: "aa:bb:cc:dd:ee:ff"
# ip: "192.168.1.10"
# - hostname: nas
# mac: "11:22:33:44:55:66"
# ip: "192.168.1.2"

View File

@ -0,0 +1,5 @@
---
- name: Restart dhcpd
ansible.builtin.systemd:
name: "{{ dhcpd_service }}"
state: restarted

View File

@ -0,0 +1,46 @@
---
- name: Validate required variables
ansible.builtin.assert:
that:
- dhcpd_interface is defined
- dhcpd_interface | length > 0
fail_msg: |
dhcpd_interface is required.
See roles/dhcpd/defaults/main.yml for configuration instructions.
success_msg: "Variable validation passed"
- name: Load OS-specific variables
ansible.builtin.include_vars: "{{ item }}"
with_first_found:
- "{{ ansible_facts['os_family'] | lower }}.yml"
- "debian.yml"
- name: Install DHCP server
ansible.builtin.package:
name: "{{ dhcpd_package }}"
state: present
- name: Deploy DHCP server configuration
ansible.builtin.template:
src: dhcpd.conf.j2
dest: "{{ dhcpd_config_path }}"
owner: root
group: root
mode: "0644"
notify: Restart dhcpd
- name: Configure interface for DHCP server (Debian)
ansible.builtin.template:
src: isc-dhcp-server.j2
dest: "{{ dhcpd_defaults_path }}"
owner: root
group: root
mode: "0644"
when: ansible_facts['os_family'] | lower == 'debian'
notify: Restart dhcpd
- name: Enable and start DHCP server
ansible.builtin.systemd:
name: "{{ dhcpd_service }}"
enabled: true
state: started

View File

@ -0,0 +1,28 @@
# {{ ansible_managed }}
# Global options
default-lease-time {{ dhcpd_default_lease_time }};
max-lease-time {{ dhcpd_max_lease_time }};
authoritative;
{% if dhcpd_domain_name is defined %}
option domain-name "{{ dhcpd_domain_name }}";
{% endif %}
option domain-name-servers {{ dhcpd_dns_servers | join(', ') }};
# Subnet configuration
subnet {{ dhcpd_subnet }} netmask {{ dhcpd_netmask }} {
range {{ dhcpd_range_start }} {{ dhcpd_range_end }};
option routers {{ dhcpd_gateway }};
}
# Static reservations
{% if dhcpd_reservations is defined %}
{% for host in dhcpd_reservations %}
host {{ host.hostname }} {
hardware ethernet {{ host.mac }};
fixed-address {{ host.ip }};
}
{% endfor %}
{% endif %}

View File

@ -0,0 +1,5 @@
# {{ ansible_managed }}
# Defaults for isc-dhcp-server
INTERFACESv4="{{ dhcpd_interface }}"
INTERFACESv6=""

View File

@ -0,0 +1,3 @@
dhcpd_package: dhcp
dhcpd_service: dhcpd4
dhcpd_config_path: /etc/dhcpd.conf

View File

@ -0,0 +1,4 @@
dhcpd_package: isc-dhcp-server
dhcpd_service: isc-dhcp-server
dhcpd_config_path: /etc/dhcp/dhcpd.conf
dhcpd_defaults_path: /etc/default/isc-dhcp-server