Compare commits

3 Commits

Author SHA1 Message Date
0a8ea77c63 Merge pull request 'feature/role-improvements' (#2) from feature/role-improvements into main
Reviewed-on: https://gitea/daniel/ansible-bind9-role/pulls/2
2025-12-07 20:22:40 +00:00
Daniel Akulenok
986b33df21 fix: explicit boolean checks for Ansible 12 compatibility 2025-12-07 20:28:26 +01:00
Daniel Akulenok
192747e438 refactor: Rename leaf config to site config
feat: Add argument specs and atomic validation
2025-12-07 20:24:22 +01:00
4 changed files with 122 additions and 18 deletions

View File

@@ -38,7 +38,7 @@ named.conf
bind configuration is set through the various bind9_*_config parameters. These are, in order of precedence:
1. bind9_default_config
2. bind9_group_config
3. bind9_leaf_config
3. bind9_site_config
4. bind9_host_config
All these configuration parameters are merged in a way where each successing config supercedes the previous one at a config-file level. To illustrate:
@@ -59,7 +59,7 @@ bind9_group_config:
- name: "."
type: mirror
bind9_leaf_config:
bind9_site_config:
- name: named.conf.local
zone:
- name: "."
@@ -81,7 +81,7 @@ bind9_config:
file: /etc/share/dns/root.hints
```
The `named.conf.options` block in `bind9_default_config` got completely overwritten by the `bind9_group_config`, and the `bind9_leaf_config` completely overwrote `named.conf.local`, however, `named.conf.options` was left intact after merging with `bind9_leaf_config`.
The `named.conf.options` block in `bind9_default_config` got completely overwritten by the `bind9_group_config`, and the `bind9_site_config` completely overwrote `named.conf.local`, however, `named.conf.options` was left intact after merging with `bind9_site_config`.
Configuration Grammar
---------------------

View File

@@ -14,7 +14,7 @@ bind9_debug_config: false
bind9_config_indent: 4
bind9_group_config: []
bind9_leaf_config: []
bind9_site_config: []
bind9_host_config: []
bind9_default_config:
@@ -30,7 +30,7 @@ bind9_default_config:
bind9_config: "{{ [bind9_default_config,
bind9_group_config,
bind9_leaf_config,
bind9_site_config,
bind9_host_config] |
community.general.lists_mergeby('name',
recursive=true,

55
meta/argument_specs.yml Normal file
View File

@@ -0,0 +1,55 @@
---
argument_specs:
main:
short_description: The main entry point for the bind9 role.
options:
bind9_config:
type: list
elements: dict
description:
- A list of configuration dictionaries that are merged to produce the final configuration.
- Each element must have a 'name' key (filename).
bind9_default_config:
type: list
elements: dict
description: Default configuration.
bind9_group_config:
type: list
elements: dict
description: Group-level configuration.
bind9_site_config:
type: list
elements: dict
description: Site/Leaf-level configuration.
bind9_host_config:
type: list
elements: dict
description: Host-level configuration.
bind9_backup_config:
type: bool
default: true
description: Whether to backup configuration files before overwriting.
bind9_debug_config:
type: bool
default: false
description: Whether to print the merged configuration during execution.
bind9_config_indent:
type: int
default: 4
description: Indentation level for generated configuration files.
bind9_packages:
type: list
elements: str
description: List of packages to install.
bind9_cfgdir:
type: str
description: Directory for configuration files.
bind9_working_directory:
type: str
description: Working directory for BIND.
bind9_libdir:
type: str
description: Library directory for BIND.
bind9_backup_dir:
type: str
description: Directory for backups.

View File

@@ -16,20 +16,69 @@
owner: root
group: root
mode: 0750
when: bind9_backup_config is defined and bind9_backup_config
when: bind9_backup_config is defined and bind9_backup_config | bool
- name: Template named.conf.generator
ansible.builtin.template:
src: named.conf.generator.j2
dest: "{{ bind9_cfgdir }}/{{ item.name }}"
owner: root
group: bind
mode: 0640
backup: "{{ item.backup | default('false') | bool }}"
# validate: 'named-checkconf -z -j %s'
loop: "{{ bind9_config }}"
loop_control:
label: "{{ item.name }}"
- name: Deploy and Validate Configuration
block:
- name: Create backup of current config
ansible.builtin.copy:
src: "{{ bind9_cfgdir }}/{{ item.name }}"
dest: "{{ bind9_cfgdir }}/{{ item.name }}.bak"
remote_src: true
owner: root
group: bind
mode: 0640
failed_when: false # It's okay if the file doesn't exist yet
# We do this for every file in the loop
loop: "{{ bind9_config }}"
loop_control:
label: "{{ item.name }}"
- name: Template named.conf.generator
ansible.builtin.template:
src: named.conf.generator.j2
dest: "{{ bind9_cfgdir }}/{{ item.name }}"
owner: root
group: bind
mode: 0640
loop: "{{ bind9_config }}"
loop_control:
label: "{{ item.name }}"
register: _template_result
- name: Validate configuration using named-checkconf
ansible.builtin.command:
cmd: "named-checkconf -z {{ bind9_cfgdir }}/named.conf"
changed_when: false
rescue:
- name: Restore configuration from backup
ansible.builtin.copy:
src: "{{ bind9_cfgdir }}/{{ item.name }}.bak"
dest: "{{ bind9_cfgdir }}/{{ item.name }}"
remote_src: true
owner: root
group: bind
mode: 0640
loop: "{{ bind9_config }}"
loop_control:
label: "{{ item.name }}"
failed_when: false # Best effort restore
- name: Fail due to invalid configuration
ansible.builtin.fail:
msg: "Configuration validation failed. Changes have been reverted. Check the logs for named-checkconf errors."
always:
- name: Remove backup files
ansible.builtin.file:
path: "{{ bind9_cfgdir }}/{{ item.name }}.bak"
state: absent
loop: "{{ bind9_config }}"
loop_control:
label: "{{ item.name }}"
when: bind9_backup_config | bool is false # Keep if backup is forced, otherwise cleanup temporary atomic backup
tags:
- bind9
- template