声明式管理 Proxmox API 对象与 Samba DNS 上游
This commit is contained in:
@@ -1,4 +1,13 @@
|
||||
---
|
||||
# Shared authentication for typed community.proxmox API modules. Secrets are
|
||||
# runtime inputs; never put them in inventory or vars files.
|
||||
pve_api_host: "{{ lookup('env', 'PROXMOX_HOST') }}"
|
||||
pve_api_user: "{{ lookup('env', 'PROXMOX_USER') }}"
|
||||
pve_api_token_id: "{{ lookup('env', 'PROXMOX_TOKEN_ID') }}"
|
||||
pve_api_token_secret: "{{ lookup('env', 'PROXMOX_TOKEN_SECRET') }}"
|
||||
pve_api_validate_certs: true
|
||||
pve_api_python_interpreter: "{{ lookup('env', 'PVE_API_PYTHON') | default(ansible_playbook_python, true) }}"
|
||||
|
||||
ansible_user: root
|
||||
ansible_python_interpreter: /usr/bin/python3
|
||||
|
||||
|
||||
@@ -19,20 +19,13 @@ all:
|
||||
|
||||
pve2:
|
||||
ansible_host: 192.168.10.7
|
||||
# ThinkCentre, Ryzen 2400GE (Raven Ridge), 8G. THIS is the node that
|
||||
# randomly froze. Kernel workaround below; also set BIOS
|
||||
# "Power Supply Idle Control" -> "Typical Current Idle" (the more
|
||||
# reliable half of the fix, and it can only be done physically).
|
||||
pve_kernel_cmdline_extra: "idle=nomwait processor.max_cstate=1"
|
||||
# ThinkCentre, Ryzen 2400GE (Raven Ridge), 8G.
|
||||
pve_install_disk: nvme0n1
|
||||
pve_bulk_disk: sda
|
||||
|
||||
pve3:
|
||||
ansible_host: 192.168.10.9
|
||||
# Same Raven Ridge silicon as pve2 but has never frozen. Deliberately
|
||||
# left WITHOUT the C-state workaround: processor.max_cstate=1 blocks
|
||||
# deeper idle states and costs power, so it is not applied pre-emptively.
|
||||
# If pve3 ever freezes, set pve_kernel_cmdline_extra here too.
|
||||
# ThinkCentre, Ryzen 2400GE (Raven Ridge), 8G.
|
||||
pve_install_disk: nvme0n1
|
||||
pve_bulk_disk: sda
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
proxmoxer==2.3.0
|
||||
requests==2.34.2
|
||||
@@ -13,3 +13,5 @@ collections:
|
||||
- name: ansible.posix # mount, authorized_key
|
||||
- name: community.general # proxmox_kvm (guest lifecycle). NOTE: deb822_repository
|
||||
# is ansible.builtin, NOT community.general — see CLAUDE.md
|
||||
- name: community.proxmox
|
||||
version: 2.0.0 # typed PVE API modules for HA, SDN and guest lifecycle
|
||||
|
||||
@@ -14,12 +14,26 @@ pve_ha_resources:
|
||||
max_restart: 3
|
||||
max_relocate: 2
|
||||
|
||||
# pve3 is the normal home for the critical router. Non-strict preserves pve1
|
||||
# and pve2 as failover targets when pve3 is unavailable.
|
||||
pve_ha_rules:
|
||||
- name: prefer-vyos-pve3
|
||||
type: node-affinity
|
||||
resources: ["vm:100"]
|
||||
nodes: ["pve3:100", "pve1:10", "pve2:10"]
|
||||
strict: false
|
||||
comment: "Prefer critical VyOS router on pve3, away from CI nodes"
|
||||
|
||||
pve_ha_portable_vms:
|
||||
- vmid: 100
|
||||
node: pve3
|
||||
cpu: x86-64-v2-AES
|
||||
|
||||
# --- Watchdog ---------------------------------------------------------------
|
||||
# ⚠ WHY THIS MATTERS: adding ANY HA resource arms fencing cluster-wide. PVE's
|
||||
# default is `softdog`, a SOFTWARE watchdog — a kernel timer, which CANNOT fire if
|
||||
# the kernel itself is frozen. That is precisely the failure this cluster has
|
||||
# actually seen (pve2's Raven Ridge idle freeze). A hardware watchdog is
|
||||
# independent silicon and fires regardless.
|
||||
# the kernel itself is frozen. A hardware watchdog is independent silicon and
|
||||
# fires regardless.
|
||||
#
|
||||
# Verified available 2026-07-26:
|
||||
# pve1 (Intel i3-6100U) -> iTCO_wdt (timeout 30s)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Deliberately does NOT reboot. Swapping the watchdog under an armed cluster is a
|
||||
# manual, ordered operation (see ../../../README-ha.md); a surprise rolling reboot
|
||||
# of all three nodes is exactly what you do not want an idempotent play to do.
|
||||
- name: reboot required for watchdog
|
||||
- name: Reboot required for watchdog
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
Watchdog config changed on {{ inventory_hostname }}. It takes effect on the
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
---
|
||||
# Proxmox HA. Read roles/pve_ha/defaults/main.yml first — it explains why the
|
||||
# resource list is short and why the watchdog choice is not cosmetic.
|
||||
- name: Validate Proxmox API inputs
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- pve_api_host | length > 0
|
||||
- pve_api_user | length > 0
|
||||
- pve_api_token_id | length > 0
|
||||
- pve_api_token_secret | length > 0
|
||||
fail_msg: >-
|
||||
Export PROXMOX_HOST, PROXMOX_USER, PROXMOX_TOKEN_ID and
|
||||
PROXMOX_TOKEN_SECRET before running ha.yml.
|
||||
run_once: true
|
||||
delegate_to: localhost
|
||||
no_log: true
|
||||
tags: [ha]
|
||||
|
||||
# --- Watchdog ---------------------------------------------------------------
|
||||
# Done BEFORE registering resources: adding a resource arms fencing, and arming
|
||||
# fencing on a software watchdog is the weakest configuration.
|
||||
- name: Select the hardware watchdog module
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/default/pve-ha-manager
|
||||
@@ -12,13 +21,9 @@
|
||||
line: "WATCHDOG_MODULE={{ pve_ha_watchdog_module }}"
|
||||
create: false
|
||||
when: pve_ha_watchdog_module | length > 0
|
||||
notify: reboot required for watchdog
|
||||
notify: Reboot required for watchdog
|
||||
tags: [ha, watchdog]
|
||||
|
||||
# watchdog-mux opens /dev/watchdog, which belongs to whichever watchdog registered
|
||||
# FIRST. PVE loads softdog at boot, so it wins and the hardware module ends up as
|
||||
# an unused watchdog1. Blacklisting softdog is what actually makes the hardware
|
||||
# one take effect — setting WATCHDOG_MODULE alone does nothing.
|
||||
- name: Blacklist softdog so the hardware watchdog claims /dev/watchdog
|
||||
ansible.builtin.copy:
|
||||
dest: /etc/modprobe.d/pve-ha-watchdog.conf
|
||||
@@ -29,48 +34,147 @@
|
||||
# {{ pve_ha_watchdog_module }} register as watchdog0 and own /dev/watchdog.
|
||||
blacklist softdog
|
||||
when: pve_ha_watchdog_module | length > 0
|
||||
notify: reboot required for watchdog
|
||||
notify: Reboot required for watchdog
|
||||
tags: [ha, watchdog]
|
||||
|
||||
# ⚠ NOT DONE LIVE ON PURPOSE. Swapping the watchdog on a running node means
|
||||
# stopping watchdog-mux and unloading softdog while fencing is armed — get the
|
||||
# order wrong and the node self-fences (reboots). The safe live procedure is
|
||||
# documented in ../../README-ha.md; otherwise it simply takes effect on the next
|
||||
# reboot, which is why the handler only WARNS rather than rebooting anything.
|
||||
|
||||
# --- Resources ---------------------------------------------------------------
|
||||
- name: Read current HA resources
|
||||
ansible.builtin.command: ha-manager status
|
||||
register: pve_ha_status
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
- name: Read current HA VM configurations
|
||||
ansible.builtin.uri:
|
||||
url: >-
|
||||
https://{{ pve_api_host }}:8006/api2/json/nodes/{{ item.node }}/qemu/{{ item.vmid }}/config
|
||||
headers:
|
||||
Authorization: >-
|
||||
PVEAPIToken={{ pve_api_user }}!{{ pve_api_token_id }}={{ pve_api_token_secret }}
|
||||
ca_path: /etc/ssl/certs/ca-certificates.crt
|
||||
return_content: true
|
||||
loop: "{{ pve_ha_portable_vms }}"
|
||||
loop_control:
|
||||
label: "VM {{ item.vmid }}"
|
||||
register: pve_ha_vm_config
|
||||
run_once: true
|
||||
delegate_to: localhost
|
||||
no_log: true
|
||||
tags: [ha]
|
||||
|
||||
- name: Register HA resources
|
||||
ansible.builtin.command: >-
|
||||
ha-manager add {{ item.sid }}
|
||||
--state {{ item.state }}
|
||||
--max_restart {{ item.max_restart }}
|
||||
--max_relocate {{ item.max_relocate }}
|
||||
- name: Reconcile portable CPU models for HA VMs
|
||||
community.proxmox.proxmox_kvm:
|
||||
api_host: "{{ pve_api_host }}"
|
||||
api_user: "{{ pve_api_user }}"
|
||||
api_token_id: "{{ pve_api_token_id }}"
|
||||
api_token_secret: "{{ pve_api_token_secret }}"
|
||||
validate_certs: "{{ pve_api_validate_certs }}"
|
||||
ca_path: /etc/ssl/certs/ca-certificates.crt
|
||||
node: "{{ item.node }}"
|
||||
vmid: "{{ item.vmid }}"
|
||||
cpu: "{{ item.cpu }}"
|
||||
update: true
|
||||
state: present
|
||||
loop: "{{ pve_ha_portable_vms }}"
|
||||
loop_control:
|
||||
label: "VM {{ item.vmid }} -> {{ item.cpu }}"
|
||||
index_var: vm_index
|
||||
when: pve_ha_vm_config.results[vm_index].json.data.cpu != item.cpu
|
||||
run_once: true
|
||||
delegate_to: localhost
|
||||
no_log: true
|
||||
vars:
|
||||
ansible_python_interpreter: "{{ pve_api_python_interpreter }}"
|
||||
tags: [ha]
|
||||
|
||||
- name: Read current HA resources
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ pve_api_host }}:8006/api2/json/cluster/ha/resources"
|
||||
headers:
|
||||
Authorization: >-
|
||||
PVEAPIToken={{ pve_api_user }}!{{ pve_api_token_id }}={{ pve_api_token_secret }}
|
||||
ca_path: /etc/ssl/certs/ca-certificates.crt
|
||||
return_content: true
|
||||
register: pve_ha_resource_state
|
||||
run_once: true
|
||||
delegate_to: localhost
|
||||
no_log: true
|
||||
tags: [ha]
|
||||
|
||||
- name: Reconcile HA resources through the PVE API
|
||||
community.proxmox.proxmox_cluster_ha_resources:
|
||||
api_host: "{{ pve_api_host }}"
|
||||
api_user: "{{ pve_api_user }}"
|
||||
api_token_id: "{{ pve_api_token_id }}"
|
||||
api_token_secret: "{{ pve_api_token_secret }}"
|
||||
validate_certs: "{{ pve_api_validate_certs }}"
|
||||
ca_path: /etc/ssl/certs/ca-certificates.crt
|
||||
name: "{{ item.sid }}"
|
||||
state: present
|
||||
hastate: "{{ item.state }}"
|
||||
max_restart: "{{ item.max_restart }}"
|
||||
max_relocate: "{{ item.max_relocate }}"
|
||||
loop: "{{ pve_ha_resources }}"
|
||||
loop_control:
|
||||
label: "{{ item.sid }}"
|
||||
# `ha-manager add` errors if the resource already exists, so gate on the status
|
||||
# output. This is what keeps a second run at changed=0.
|
||||
when: "'service ' ~ item.sid not in (pve_ha_status.stdout | default(''))"
|
||||
when: >-
|
||||
_current_resource | length == 0 or
|
||||
_current_resource.state != item.state or
|
||||
_current_resource.max_restart | int != item.max_restart | int or
|
||||
_current_resource.max_relocate | int != item.max_relocate | int
|
||||
run_once: true
|
||||
delegate_to: localhost
|
||||
no_log: true
|
||||
vars:
|
||||
ansible_python_interpreter: "{{ pve_api_python_interpreter }}"
|
||||
_current_resource: >-
|
||||
{{ pve_ha_resource_state.json.data |
|
||||
selectattr('sid', 'equalto', item.sid) | first | default({}) }}
|
||||
tags: [ha]
|
||||
|
||||
- name: Verify HA is armed and the resource is known
|
||||
ansible.builtin.command: ha-manager status
|
||||
register: pve_ha_verify
|
||||
changed_when: false
|
||||
- name: Reconcile HA placement rules through the PVE API
|
||||
community.proxmox.proxmox_cluster_ha_rules:
|
||||
api_host: "{{ pve_api_host }}"
|
||||
api_user: "{{ pve_api_user }}"
|
||||
api_token_id: "{{ pve_api_token_id }}"
|
||||
api_token_secret: "{{ pve_api_token_secret }}"
|
||||
validate_certs: "{{ pve_api_validate_certs }}"
|
||||
ca_path: /etc/ssl/certs/ca-certificates.crt
|
||||
name: "{{ item.name }}"
|
||||
state: present
|
||||
type: "{{ item.type }}"
|
||||
resources: "{{ item.resources }}"
|
||||
nodes: "{{ item.nodes }}"
|
||||
strict: "{{ item.strict }}"
|
||||
comment: "{{ item.comment }}"
|
||||
disable: false
|
||||
loop: "{{ pve_ha_rules }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
run_once: true
|
||||
delegate_to: localhost
|
||||
no_log: true
|
||||
vars:
|
||||
ansible_python_interpreter: "{{ pve_api_python_interpreter }}"
|
||||
tags: [ha]
|
||||
|
||||
- name: Show HA state
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ pve_ha_verify.stdout_lines }}"
|
||||
- name: Read HA placement rules through the PVE API
|
||||
community.proxmox.proxmox_cluster_ha_rules_info:
|
||||
api_host: "{{ pve_api_host }}"
|
||||
api_user: "{{ pve_api_user }}"
|
||||
api_token_id: "{{ pve_api_token_id }}"
|
||||
api_token_secret: "{{ pve_api_token_secret }}"
|
||||
validate_certs: "{{ pve_api_validate_certs }}"
|
||||
ca_path: /etc/ssl/certs/ca-certificates.crt
|
||||
register: pve_ha_rule_state
|
||||
run_once: true
|
||||
delegate_to: localhost
|
||||
no_log: true
|
||||
vars:
|
||||
ansible_python_interpreter: "{{ pve_api_python_interpreter }}"
|
||||
tags: [ha]
|
||||
|
||||
- name: Assert declared placement rules exist
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- >-
|
||||
(pve_ha_rules | map(attribute='name') | list |
|
||||
difference(pve_ha_rule_state.rules | default([]) |
|
||||
map(attribute='rule') | list) | length) == 0
|
||||
fail_msg: A declared HA placement rule is absent after reconciliation
|
||||
run_once: true
|
||||
delegate_to: localhost
|
||||
tags: [ha]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
# Per-host kernel cmdline additions, driven by `pve_kernel_cmdline_extra` in the
|
||||
# inventory. Currently only pve2 sets it (Raven Ridge random-freeze workaround);
|
||||
# pve3 is identical silicon but is deliberately left alone -- see inventory.
|
||||
# inventory. No node currently sets it; keep the role for future kernel parameters.
|
||||
#
|
||||
# This is a no-op on hosts that do not define the variable.
|
||||
|
||||
|
||||
@@ -1,60 +1,81 @@
|
||||
---
|
||||
# SDN config is cluster-wide (/etc/pve/sdn/), so everything runs once.
|
||||
|
||||
- name: Read existing zones
|
||||
ansible.builtin.command:
|
||||
cmd: "pvesh get /cluster/sdn/zones --output-format json"
|
||||
register: _zones
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
- name: Validate Proxmox API inputs
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- pve_api_host | length > 0
|
||||
- pve_api_user | length > 0
|
||||
- pve_api_token_id | length > 0
|
||||
- pve_api_token_secret | length > 0
|
||||
fail_msg: Missing Proxmox API environment variables
|
||||
run_once: true
|
||||
delegate_to: localhost
|
||||
no_log: true
|
||||
|
||||
- name: Create the VLAN zone
|
||||
ansible.builtin.command:
|
||||
cmd: >-
|
||||
pvesh create /cluster/sdn/zones --zone {{ pve_sdn_zone }} --type vlan
|
||||
--bridge {{ pve_sdn_bridge }} --mtu {{ pve_sdn_mtu }}
|
||||
--nodes {{ groups['pve'] | join(',') }}
|
||||
when: pve_sdn_zone not in (_zones.stdout | from_json | map(attribute='zone') | list)
|
||||
- name: Read current PVE SDN zones
|
||||
ansible.builtin.uri:
|
||||
url: "https://{{ pve_api_host }}:8006/api2/json/cluster/sdn/zones"
|
||||
headers:
|
||||
Authorization: >-
|
||||
PVEAPIToken={{ pve_api_user }}!{{ pve_api_token_id }}={{ pve_api_token_secret }}
|
||||
ca_path: /etc/ssl/certs/ca-certificates.crt
|
||||
return_content: true
|
||||
register: pve_sdn_zone_state
|
||||
run_once: true
|
||||
delegate_to: localhost
|
||||
no_log: true
|
||||
|
||||
- name: Read existing vnets
|
||||
ansible.builtin.command:
|
||||
cmd: "pvesh get /cluster/sdn/vnets --output-format json"
|
||||
register: _vnets
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
- name: Reconcile the PVE VLAN zone
|
||||
community.proxmox.proxmox_zone:
|
||||
api_host: "{{ pve_api_host }}"
|
||||
api_user: "{{ pve_api_user }}"
|
||||
api_token_id: "{{ pve_api_token_id }}"
|
||||
api_token_secret: "{{ pve_api_token_secret }}"
|
||||
validate_certs: "{{ pve_api_validate_certs }}"
|
||||
ca_path: /etc/ssl/certs/ca-certificates.crt
|
||||
zone: "{{ pve_sdn_zone }}"
|
||||
type: vlan
|
||||
bridge: "{{ pve_sdn_bridge }}"
|
||||
mtu: "{{ pve_sdn_mtu }}"
|
||||
nodes: "{{ groups['pve'] | join(',') }}"
|
||||
update: true
|
||||
state: present
|
||||
when: >-
|
||||
_current_zone | length == 0 or
|
||||
_current_zone.type != 'vlan' or
|
||||
_current_zone.bridge != pve_sdn_bridge or
|
||||
_current_zone.mtu | int != pve_sdn_mtu | int or
|
||||
_current_zone.nodes != (groups['pve'] | join(','))
|
||||
run_once: true
|
||||
delegate_to: localhost
|
||||
no_log: true
|
||||
vars:
|
||||
ansible_python_interpreter: "{{ pve_api_python_interpreter }}"
|
||||
_current_zone: >-
|
||||
{{ pve_sdn_zone_state.json.data |
|
||||
selectattr('zone', 'equalto', pve_sdn_zone) | first | default({}) }}
|
||||
|
||||
- name: Create the VNets
|
||||
ansible.builtin.command:
|
||||
cmd: >-
|
||||
pvesh create /cluster/sdn/vnets --vnet {{ item.name }}
|
||||
--zone {{ pve_sdn_zone }} --tag {{ item.tag }}
|
||||
--alias '{{ item.alias }}'
|
||||
# The module owns the SDN global lock and applies pending configuration before
|
||||
# releasing it; a separate unconditional `pvesh set /cluster/sdn` is harmful
|
||||
# because it reports changed on every run.
|
||||
- name: Reconcile PVE VNets
|
||||
community.proxmox.proxmox_vnet:
|
||||
api_host: "{{ pve_api_host }}"
|
||||
api_user: "{{ pve_api_user }}"
|
||||
api_token_id: "{{ pve_api_token_id }}"
|
||||
api_token_secret: "{{ pve_api_token_secret }}"
|
||||
validate_certs: "{{ pve_api_validate_certs }}"
|
||||
ca_path: /etc/ssl/certs/ca-certificates.crt
|
||||
vnet: "{{ item.name }}"
|
||||
zone: "{{ pve_sdn_zone }}"
|
||||
tag: "{{ item.tag }}"
|
||||
alias: "{{ item.alias }}"
|
||||
update: true
|
||||
state: present
|
||||
loop: "{{ pve_sdn_vnets }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }} (vlan {{ item.tag }})"
|
||||
when: item.name not in (_vnets.stdout | from_json | map(attribute='vnet') | list)
|
||||
run_once: true
|
||||
|
||||
- name: Apply the SDN configuration
|
||||
# SDN changes stay PENDING until applied; without this the VNet bridges are
|
||||
# never actually created on the nodes.
|
||||
ansible.builtin.command:
|
||||
cmd: "pvesh set /cluster/sdn"
|
||||
register: _apply
|
||||
changed_when: true
|
||||
run_once: true
|
||||
|
||||
- name: Report
|
||||
ansible.builtin.shell:
|
||||
cmd: "pvesh get /cluster/sdn/vnets --output-format json | python3 -c \"import json,sys;[print(' ',v['vnet'],'vlan',v.get('tag'),'zone',v.get('zone')) for v in json.load(sys.stdin)]\""
|
||||
register: _rep
|
||||
changed_when: false
|
||||
run_once: true
|
||||
|
||||
- name: Show it
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ _rep.stdout_lines }}"
|
||||
label: "{{ item.name }} (VLAN {{ item.tag }})"
|
||||
run_once: true
|
||||
delegate_to: localhost
|
||||
no_log: true
|
||||
vars:
|
||||
ansible_python_interpreter: "{{ pve_api_python_interpreter }}"
|
||||
|
||||
@@ -28,6 +28,9 @@ pve_vms:
|
||||
description: "VyOS router: OSPF peer to the NEC IX, gateway for the SDN VNets."
|
||||
cores: 2
|
||||
memory: 2048
|
||||
# Portable across Intel pve1 and AMD pve2/pve3. `host` transferred memory
|
||||
# but failed target-side resume during the 2026-09-17 migration.
|
||||
cpu: x86-64-v2-AES
|
||||
disk: "pve-rg:8"
|
||||
# Headless by design: UEFI + serial console, NO emulated VGA. VyOS's own
|
||||
# kernel cmdline carries console=ttyS0, and the installer was answered with
|
||||
@@ -56,6 +59,7 @@ pve_vms:
|
||||
# are AMD.
|
||||
cores: 4
|
||||
memory: 4096
|
||||
cpu: host
|
||||
disk: "pve-rg:40"
|
||||
bios: ovmf
|
||||
machine: q35
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
--description '{{ item.item.description }}'
|
||||
--machine {{ item.item.machine | default('q35') }}
|
||||
--bios {{ item.item.bios | default('ovmf') }}
|
||||
--memory {{ item.item.memory }} --cores {{ item.item.cores }} --cpu host
|
||||
--memory {{ item.item.memory }} --cores {{ item.item.cores }} --cpu {{ item.item.cpu | default('x86-64-v2-AES') }}
|
||||
--scsihw virtio-scsi-single
|
||||
--scsi0 {{ item.item.disk }},discard=on,ssd=1
|
||||
--efidisk0 {{ item.item.disk.split(':')[0] }}:1,efitype=4m,pre-enrolled-keys=0
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: 更新现有 AD 域控 DNS 上游
|
||||
hosts: samba_dc
|
||||
become: true
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: 仅应用 DNS 转发器配置
|
||||
ansible.builtin.import_role:
|
||||
name: samba_ad_dc
|
||||
tasks_from: dns_forwarder
|
||||
@@ -7,7 +7,7 @@ samba_ad_realm: "AD.DDUPAN.TOP"
|
||||
samba_ad_domain: "DDUPAN"
|
||||
samba_ad_dc_hostname: "dc1"
|
||||
samba_ad_dc_ip: "192.168.10.5"
|
||||
samba_ad_dns_forwarder: "192.168.10.1"
|
||||
samba_ad_dns_forwarder: "192.168.10.127" # Blocky:DN42 条件转发及公网解析
|
||||
samba_ad_reverse_zone: "10.168.192.in-addr.arpa" # reverse of 192.168.10.0/24
|
||||
|
||||
# Static records now live in ../../dns/records.yml and are reconciled as complete
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: 更新 Samba DNS 转发器并校验配置
|
||||
ansible.builtin.lineinfile:
|
||||
path: /etc/samba/smb.conf
|
||||
regexp: '^\s*dns forwarder\s*='
|
||||
insertafter: '^\[global\]'
|
||||
line: "\tdns forwarder = {{ samba_ad_dns_forwarder }}"
|
||||
validate: '/usr/bin/testparm -s %s'
|
||||
backup: true
|
||||
notify: restart samba-ad-dc
|
||||
@@ -87,6 +87,9 @@
|
||||
creates: /var/lib/samba/private/sam.ldb
|
||||
no_log: true # keep the admin password out of logs
|
||||
|
||||
- name: 持续管理已初始化域控的 DNS 上游
|
||||
ansible.builtin.import_tasks: dns_forwarder.yml
|
||||
|
||||
- name: Install the generated krb5.conf system-wide
|
||||
ansible.builtin.copy:
|
||||
src: /var/lib/samba/private/krb5.conf
|
||||
|
||||
Reference in New Issue
Block a user