feat(bind9): support systemd drop-ins

Keep role configuration namespaced and allow hosts to customize systemd startup.

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
volker.raschekandCopilot committed 2026-10-24 16:45:32 +02:00
1 parent 65e088cdd5
commit d7826d46a1
14 files changed
+121 -68

No files matched your search

+4
View File
@@ -110,6 +110,10 @@ bind9_statics:
acls: acls:
- "localhost" - "localhost"
bind9_systemd_dropin: ~
# [Service]
# ExecStart=
# ExecStart={{ bind9_binary }} -f -u {{ bind9_unix_user }} -4
bind9_tsigkeys: [] bind9_tsigkeys: []
# - name: "name" # - name: "name"
+1 -1
View File
@@ -2,6 +2,6 @@
- name: Restart named - name: Restart named
ansible.builtin.systemd: ansible.builtin.systemd:
name: "{{ bind_service_name }}" name: "{{ bind9_service_name }}"
state: restarted state: restarted
daemon_reload: true daemon_reload: true
+4 -4
View File
@@ -4,8 +4,8 @@
ansible.builtin.copy: ansible.builtin.copy:
dest: "{{ item.private.filename }}" dest: "{{ item.private.filename }}"
content: "{{ item.private.content }}" content: "{{ item.private.content }}"
owner: "{{ bind_unix_user }}" owner: "{{ bind9_unix_user }}"
group: "{{ bind_unix_group }}" group: "{{ bind9_unix_group }}"
mode: "0600" mode: "0600"
no_log: true no_log: true
with_items: with_items:
@@ -16,8 +16,8 @@
ansible.builtin.copy: ansible.builtin.copy:
dest: "{{ item.public.filename }}" dest: "{{ item.public.filename }}"
content: "{{ item.public.content }}" content: "{{ item.public.content }}"
owner: "{{ bind_unix_user }}" owner: "{{ bind9_unix_user }}"
group: "{{ bind_unix_group }}" group: "{{ bind9_unix_group }}"
mode: "0644" mode: "0644"
no_log: true no_log: true
with_items: with_items:
+56 -20
View File
@@ -17,22 +17,22 @@
ansible.builtin.package: ansible.builtin.package:
name: "{{ item }}" name: "{{ item }}"
state: present state: present
with_items: "{{ bind_package_names }}" with_items: "{{ bind9_package_names }}"
- name: Create logging directory - name: Create logging directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ bind_log_directory }}" path: "{{ bind9_log_directory }}"
owner: "{{ bind_unix_user }}" owner: "{{ bind9_unix_user }}"
group: "{{ bind_unix_group }}" group: "{{ bind9_unix_group }}"
mode: "0755" mode: "0755"
state: directory state: directory
recurse: true recurse: true
- name: Create config directory - name: Create config directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ bind_config_directory }}" path: "{{ bind9_config_directory }}"
owner: "{{ bind_unix_user }}" owner: "{{ bind9_unix_user }}"
group: "{{ bind_unix_group }}" group: "{{ bind9_unix_group }}"
mode: "0755" mode: "0755"
state: directory state: directory
recurse: true recurse: true
@@ -41,7 +41,7 @@
block: block:
- name: Find existing journal files - name: Find existing journal files
ansible.builtin.find: ansible.builtin.find:
path: "{{ bind_config_directory }}" path: "{{ bind9_config_directory }}"
recurse: true recurse: true
patterns: "*.jnl" patterns: "*.jnl"
register: files_to_delete register: files_to_delete
@@ -55,7 +55,7 @@
block: block:
- name: Find existing signed zone files - name: Find existing signed zone files
ansible.builtin.find: ansible.builtin.find:
path: "{{ bind_config_directory }}" path: "{{ bind9_config_directory }}"
recurse: true recurse: true
patterns: "*.signed" patterns: "*.signed"
register: files_to_delete register: files_to_delete
@@ -80,8 +80,8 @@
- name: Create DNSSEC key directory - name: Create DNSSEC key directory
ansible.builtin.file: ansible.builtin.file:
path: "{{ bind9_options.key_directory }}" path: "{{ bind9_options.key_directory }}"
owner: "{{ bind_unix_user }}" owner: "{{ bind9_unix_user }}"
group: "{{ bind_unix_group }}" group: "{{ bind9_unix_group }}"
mode: "0700" mode: "0700"
state: directory state: directory
@@ -102,18 +102,18 @@
- name: Create main configuration file - name: Create main configuration file
ansible.builtin.template: ansible.builtin.template:
src: "etc/named.conf.j2" src: "etc/named.conf.j2"
dest: "{{ bind_main_config }}" dest: "{{ bind9_main_config }}"
owner: "{{ bind_unix_user }}" owner: "{{ bind9_unix_user }}"
group: "{{ bind_unix_group }}" group: "{{ bind9_unix_group }}"
mode: "0644" mode: "0644"
notify: Restart named notify: Restart named
- name: Create excluded configuration files - name: Create excluded configuration files
ansible.builtin.template: ansible.builtin.template:
src: "{{ item }}.j2" src: "{{ item }}.j2"
dest: "{{ item | replace('etc/named', bind_config_directory) }}" dest: "{{ item | replace('etc/named', bind9_config_directory) }}"
owner: "{{ bind_unix_user }}" owner: "{{ bind9_unix_user }}"
group: "{{ bind_unix_group }}" group: "{{ bind9_unix_group }}"
mode: "0644" mode: "0644"
with_items: with_items:
- etc/named.conf - etc/named.conf
@@ -124,9 +124,45 @@
- etc/named/named.conf.views - etc/named/named.conf.views
notify: Restart named notify: Restart named
- name: Create systemd drop-in
when: bind9_systemd_dropin | default('', true) | length > 0
block:
- name: Create systemd drop-in directory
ansible.builtin.file:
path: "{{ bind9_systemd_dropin_dir }}"
owner: "root"
group: "root"
mode: "0755"
state: "directory"
- name: Template systemd drop-in
ansible.builtin.template:
src: etc/systemd/system/named.service.d/override.conf.j2
dest: "{{ bind9_systemd_dropin_dir }}/override.conf"
owner: "root"
group: "root"
mode: "0644"
register: _bind9_systemd_drop_in
- name: Systemd reload
ansible.builtin.systemd:
daemon_reload: true
when: _bind9_systemd_drop_in.changed
- name: Remove systemd drop-in
when: bind9_systemd_dropin | default('', true) | length == 0
block:
- name: Remove systemd drop-in file
ansible.builtin.file:
path: "{{ bind9_systemd_dropin_dir }}/override.conf"
state: "absent"
register: _bind9_systemd_drop_in
- name: Systemd reload
ansible.builtin.systemd:
daemon_reload: true
when: _bind9_systemd_drop_in.changed
- name: Start and enabled named - name: Start and enabled named
ansible.builtin.systemd: ansible.builtin.systemd:
name: named name: "{{ bind9_service_name }}"
state: started state: started
enabled: true enabled: true
@@ -134,8 +170,8 @@
ansible.builtin.template: ansible.builtin.template:
src: etc/rndc.key.j2 src: etc/rndc.key.j2
dest: /etc/rndc.key dest: /etc/rndc.key
owner: "{{ bind_unix_user }}" owner: "{{ bind9_unix_user }}"
group: "{{ bind_unix_group }}" group: "{{ bind9_unix_group }}"
mode: "0600" mode: "0600"
when: bind9_rndc_key.name | length > 0 and when: bind9_rndc_key.name | length > 0 and
bind9_rndc_key.algorithm | length > 0 and bind9_rndc_key.algorithm | length > 0 and
+5 -5
View File
@@ -15,14 +15,14 @@
_dnssec_cmd: "{{ dnssec_cmd + ['-o', zone.config.origin] }}" _dnssec_cmd: "{{ dnssec_cmd + ['-o', zone.config.origin] }}"
- name: "Extend dnssec command of zone file" - name: "Extend dnssec command of zone file"
ansible.builtin.set_fact: ansible.builtin.set_fact:
_dnssec_cmd: "{{ _dnssec_cmd + [bind_config_directory + '/' + zone.file] }}" _dnssec_cmd: "{{ _dnssec_cmd + [bind9_config_directory + '/' + zone.file] }}"
- name: "Sign zone {{ zone.config.origin }}" - name: "Sign zone {{ zone.config.origin }}"
ansible.builtin.command: ansible.builtin.command:
argv: "{{ _dnssec_cmd }}" argv: "{{ _dnssec_cmd }}"
creates: "{{ bind_config_directory + '/' + zone.file }}.signed" creates: "{{ bind9_config_directory + '/' + zone.file }}.signed"
- name: Adapt signed zone file permissions - name: Adapt signed zone file permissions
ansible.builtin.file: ansible.builtin.file:
path: "{{ bind_config_directory + '/' + zone.file }}.signed" path: "{{ bind9_config_directory + '/' + zone.file }}.signed"
owner: "{{ bind_unix_user }}" owner: "{{ bind9_unix_user }}"
group: "{{ bind_unix_group }}" group: "{{ bind9_unix_group }}"
mode: "0644" mode: "0644"
+6 -6
View File
@@ -2,9 +2,9 @@
- name: "Create config directory of DNS zones" - name: "Create config directory of DNS zones"
ansible.builtin.file: ansible.builtin.file:
path: "{{ bind_config_directory }}/{{ zone.file | dirname }}" path: "{{ bind9_config_directory }}/{{ zone.file | dirname }}"
owner: "{{ bind_unix_user }}" owner: "{{ bind9_unix_user }}"
group: "{{ bind_unix_group }}" group: "{{ bind9_unix_group }}"
mode: "0755" mode: "0755"
state: directory state: directory
with_items: with_items:
@@ -17,9 +17,9 @@
- name: "Template view {{ view.name }}" - name: "Template view {{ view.name }}"
ansible.builtin.template: ansible.builtin.template:
src: "{{ inventory_hostname }}/etc/named/{{ zone.file }}.j2" src: "{{ inventory_hostname }}/etc/named/{{ zone.file }}.j2"
dest: "{{ bind_config_directory + '/' + zone.file }}" dest: "{{ bind9_config_directory + '/' + zone.file }}"
owner: "{{ bind_unix_user }}" owner: "{{ bind9_unix_user }}"
group: "{{ bind_unix_group }}" group: "{{ bind9_unix_group }}"
mode: "0644" mode: "0644"
with_items: with_items:
- "{{ view.zones }}" - "{{ view.zones }}"
+3 -3
View File
@@ -2,12 +2,12 @@
- name: "Read the last character of DNS zone: {{ zone.config.origin }}" - name: "Read the last character of DNS zone: {{ zone.config.origin }}"
ansible.builtin.command: ansible.builtin.command:
cmd: "tail --bytes 1 {{ bind_config_directory + '/' + zone.file }}" cmd: "tail --bytes 1 {{ bind9_config_directory + '/' + zone.file }}"
register: _bind9_zone_last_character register: _bind9_zone_last_character
changed_when: _bind9_zone_last_character.rc == 0 changed_when: _bind9_zone_last_character.rc == 0
failed_when: _bind9_zone_last_character.rc > 0 failed_when: _bind9_zone_last_character.rc > 0
- name: "Fail when the last character of DNS zone file is not a newline: {{ bind_config_directory + '/' + zone.file }}" - name: "Fail when the last character of DNS zone file is not a newline: {{ bind9_config_directory + '/' + zone.file }}"
ansible.builtin.fail: ansible.builtin.fail:
msg: "Last character of DNS zone file is not a newline: {{ bind_config_directory + '/' + zone.file }}" msg: "Last character of DNS zone file is not a newline: {{ bind9_config_directory + '/' + zone.file }}"
when: _bind9_zone_last_character.stdout != '' when: _bind9_zone_last_character.stdout != ''
+5 -5
View File
@@ -7,8 +7,8 @@
# file "named.ca"; # file "named.ca";
# }; # };
include "{{ bind_config_directory }}/named.conf.acl"; include "{{ bind9_config_directory }}/named.conf.acl";
include "{{ bind_config_directory }}/named.conf.logging"; include "{{ bind9_config_directory }}/named.conf.logging";
include "{{ bind_config_directory }}/named.conf.options"; include "{{ bind9_config_directory }}/named.conf.options";
include "{{ bind_config_directory }}/named.conf.tsigkeys"; include "{{ bind9_config_directory }}/named.conf.tsigkeys";
include "{{ bind_config_directory }}/named.conf.views"; include "{{ bind9_config_directory }}/named.conf.views";
+1 -1
View File
@@ -184,7 +184,7 @@ options {
# allow-update-forwarding {}; # allow-update-forwarding {};
{% endif %} {% endif %}
directory "{{ bind_config_directory }}"; directory "{{ bind9_config_directory }}";
# This accepts expired signatures when verifying DNSSEC signatures. The default is no. Setting this option to yes # This accepts expired signatures when verifying DNSSEC signatures. The default is no. Setting this option to yes
# leaves named vulnerable to replay attacks. # leaves named vulnerable to replay attacks.
+2 -2
View File
@@ -148,11 +148,11 @@ view "{{ view.name }}" {
# contact the Master, ffor whatever reason, the zone may be left with # contact the Master, ffor whatever reason, the zone may be left with
# no effective Authoritative Name Servers. # no effective Authoritative Name Servers.
{% if zone.file is defined and zone.file | length > 0 and not zone.file.startswith('/') %} {% if zone.file is defined and zone.file | length > 0 and not zone.file.startswith('/') %}
file "{{ bind_config_directory }}/{{ zone.config.file }}"; file "{{ bind9_config_directory }}/{{ zone.config.file }}";
{% elif zone.file is defined and zone.file | length > 0 and zone.file.startswith('/')%} {% elif zone.file is defined and zone.file | length > 0 and zone.file.startswith('/')%}
file "{{ zone.config.file }}"; file "{{ zone.config.file }}";
{% else %} {% else %}
# file "{{ bind_config_directory }}/..."; # file "{{ bind9_config_directory }}/...";
{% endif %} {% endif %}
# This option is only meaningful if the forwarders list is not empty. A # This option is only meaningful if the forwarders list is not empty. A
@@ -0,0 +1,4 @@
#
# {{ ansible_managed }}
#
{{ bind9_systemd_dropin }}
+10 -7
View File
@@ -1,13 +1,16 @@
--- ---
bind_main_config: /etc/named.conf bind9_binary: /usr/bin/named
bind_config_directory: /etc/named
bind_log_directory: /var/log/named
bind_package_names: bind9_main_config: /etc/named.conf
bind9_config_directory: /etc/named
bind9_log_directory: /var/log/named
bind9_package_names:
- bind - bind
bind_service_name: named bind9_service_name: named
bind9_systemd_dropin_dir: "/etc/systemd/system/{{ bind9_service_name }}.service.d"
bind_unix_user: named bind9_unix_user: named
bind_unix_group: named bind9_unix_group: named
+10 -7
View File
@@ -1,13 +1,16 @@
--- ---
bind_main_config: /etc/bind/named.conf bind9_binary: /usr/sbin/named
bind_config_directory: /etc/bind
bind_log_directory: /var/log/bind
bind_package_names: bind9_main_config: /etc/bind/named.conf
bind9_config_directory: /etc/bind
bind9_log_directory: /var/log/bind
bind9_package_names:
- bind9 - bind9
bind_service_name: named bind9_service_name: named
bind9_systemd_dropin_dir: "/etc/systemd/system/{{ bind9_service_name }}.service.d"
bind_unix_user: bind bind9_unix_user: bind
bind_unix_group: bind bind9_unix_group: bind
+10 -7
View File
@@ -1,14 +1,17 @@
--- ---
bind_main_config: /etc/named.conf bind9_binary: /usr/sbin/named
bind_config_directory: /etc/named
bind_log_directory: /var/log/named
bind_package_names: bind9_main_config: /etc/named.conf
bind9_config_directory: /etc/named
bind9_log_directory: /var/log/named
bind9_package_names:
- bind - bind
- bind-utils # for dig and tsig-keygen and so on - bind-utils # for dig and tsig-keygen and so on
bind_service_name: named bind9_service_name: named
bind9_systemd_dropin_dir: "/etc/systemd/system/{{ bind9_service_name }}.service.d"
bind_unix_user: named bind9_unix_user: named
bind_unix_group: named bind9_unix_group: named