BIND Infrastructure DNS Records Deployment

1. Overview

This runbook adds ALL infrastructure DNS records to the existing bind-01 BIND server. Execute sequentially - each phase depends on the previous.

1.1. Scope

Item Count

A Records

43 hosts

PTR Records

43 reverse entries

CNAME Records

9 aliases

SRV Records

Already configured (AD/Kerberos)

1.2. Infrastructure Records

Hostname IP Category Status

vyos-01

10.50.1.2

VyOS HA (MASTER)

Active

vyos-02

10.50.1.3

VyOS HA (BACKUP)

Active

vyos

10.50.1.1

VyOS VIP

Active

kvm-01

10.50.1.110

Hypervisor

Active

kvm-02

10.50.1.111

Hypervisor

Active

ipmi-01

10.50.1.200

IPMI/OOB

Active

ipmi-02

10.50.1.201

IPMI/OOB

Planned

home-dc01

10.50.1.50

AD Domain Controller

Active

home-dc02

10.50.1.51

AD Domain Controller

Planned

keycloak-01

10.50.1.80

Identity Provider

Active

keycloak-02

10.50.1.81

Identity Provider

Planned

ipa-01

10.50.1.100

FreeIPA

Active

ipa-02

10.50.1.101

FreeIPA

Planned

vault-01

10.50.1.60

Vault PKI/SSH CA

Active

vault-02

10.50.1.61

Vault HA

Planned

vault-03

10.50.1.62

Vault HA

Planned

ise-01

10.50.1.20

ISE (PAN/MnT/PSN)

Active

ise-02

10.50.1.21

ISE HA Secondary

Active

ipsk-mgr-01

10.50.1.30

iPSK Manager

Active

ipsk-mgr-02

10.50.1.31

iPSK Manager HA

Planned

ipsk-mgr

10.50.1.32

iPSK VIP

Planned

bind-01

10.50.1.90

BIND DNS

Active

bind-02

10.50.1.91

BIND DNS HA

Planned

9800-wlc-01

10.50.1.40

Wireless LAN Controller

Active

9800-wlc-02

10.50.1.41

WLC HA Standby

Active

3560-cx

10.50.1.10

Access Switch

Active

c9300-01

10.50.1.11

Core Switch

Active

nas-01

10.50.1.70

Synology NAS

Active

nas-02

10.50.1.71

NAS HA

Planned

gitea-01

10.50.1.72

Git Server

Active

minio-01

10.50.1.73

S3 Storage

Planned

k3s-master-01

10.50.1.120

k3s Control Plane

Active

k3s-master-02

10.50.1.121

k3s Control Plane

Planned

k3s-master-03

10.50.1.122

k3s Control Plane

Planned

k3s-worker-01

10.50.1.123

k3s Worker

Planned

k3s-worker-02

10.50.1.124

k3s Worker

Planned

k3s-worker-03

10.50.1.125

k3s Worker

Planned

traefik

10.50.1.130

Ingress VIP

Active

wazuh-indexer

10.50.1.131

SIEM Indexer

Active

wazuh-dashboard

10.50.1.132

SIEM Dashboard

Active

wazuh-workers

10.50.1.133

SIEM Workers

Active

wazuh-manager

10.50.1.134

SIEM Manager

Active

zabbix-01

10.50.1.135

Monitoring

Planned

Table 1. CNAME Aliases
Alias Target

dc

home-dc01

vault

vault-01

ise

ise-01

wlc

9800-wlc-01

nas

nas-01

wazuh

wazuh-manager

prometheus

traefik

grafana

traefik

alertmanager

traefik

1.3. Prerequisites

  • SSH access to bind-01 (Vault SSH CA cert valid)

  • bind-01 running and responding to queries

  • Zone files exist: /var/named/inside.domusdigitalis.dev.zone, /var/named/10.50.1.rev

2. Phase 0: Session Variables

Set these ONCE at the start of your session:

# DNS Server
DNS_SERVER="bind-01"
DNS_IP="10.50.1.90"
DOMAIN="inside.domusdigitalis.dev"

# Zone files
FORWARD_ZONE="/var/named/inside.domusdigitalis.dev.zone"
REVERSE_ZONE="/var/named/10.50.1.rev"

# Verify variables
echo "DNS Server: $DNS_SERVER ($DNS_IP)"
echo "Domain: $DOMAIN"

3. Phase 1: Pre-Deployment Validation

3.1. 1.1 Verify SSH Connectivity

echo "=== PRE-DEPLOYMENT: BIND Connectivity ==="
ssh bind-01 "hostname && uptime"
Expected Output
bind-01
 10:30:00 up 45 days, ...

3.2. 1.2 Verify BIND Service

ssh $DNS_SERVER "systemctl is-active named"
Expected Output
active

3.3. 1.3 Current Zone Status

echo "=== PRE-DEPLOYMENT: Current Zone Status ==="
ssh bind-01 "sudo rndc zonestatus inside.domusdigitalis.dev | grep -E 'serial|expires'"
Expected Output (example)
serial: 2026021401
expires: ...

3.4. 1.4 Current Record Count

echo "=== PRE-DEPLOYMENT: Current Record Count ==="
ssh bind-01 "sudo grep -cE '^[a-z]' /var/named/inside.domusdigitalis.dev.zone"

Record the count:

3.5. 1.5 Test DNS Resolution (Baseline)

dig @$DNS_IP ise-01.$DOMAIN +short
Expected Output
10.50.1.20

3.6. 1.6 Validate All Existing A Records

Parse zone file with awk and verify each record resolves:

ssh $DNS_SERVER "sudo awk '/IN[[:space:]]+A[[:space:]]+/ {print \$1, \$NF}' $FORWARD_ZONE" | while read host ip; do
  result=$(dig @$DNS_IP ${host}.$DOMAIN +short)
  if [[ "$result" == "$ip" ]]; then
    echo "✓ $host → $result"
  else
    echo "✗ $host: expected $ip, got '$result'"
  fi
done
Expected Output (sample)
✓ vyos (VIP) → 10.50.1.1
✓ ise-01 → 10.50.1.20
✓ vault-01 → 10.50.1.60
✓ bind-01 → 10.50.1.90
✓ k3s-master-01 → 10.50.1.120
...

CNAMEs may show discrepancy: If grafana, prometheus, alertmanager show different IPs, they’re likely CNAMEs pointing to traefik VIP - this is correct behavior.

3.7. 1.7 Validate All Existing PTR Records

ssh $DNS_SERVER "sudo awk '/IN[[:space:]]+PTR[[:space:]]+/ {print \$1, \$NF}' $REVERSE_ZONE" | while read octet fqdn; do
  result=$(dig @$DNS_IP -x 10.50.1.$octet +short)
  if [[ "$result" == "$fqdn" ]]; then
    echo "✓ 10.50.1.$octet → $result"
  else
    echo "✗ 10.50.1.$octet: expected $fqdn, got '$result'"
  fi
done
Expected Output (sample)
✓ 10.50.1.1 → vyos.inside.domusdigitalis.dev.
✓ 10.50.1.20 → ise-01.inside.domusdigitalis.dev.
✓ 10.50.1.60 → vault-01.inside.domusdigitalis.dev.
✓ 10.50.1.90 → bind-01.inside.domusdigitalis.dev.
✓ 10.50.1.120 → k3s-master-01.inside.domusdigitalis.dev.
...

4. Phase 2: Backup Zone Files

CRITICAL: Always backup before modifications.

4.1. 2.1 Backup Forward Zone

ssh bind-01 "sudo cp /var/named/inside.domusdigitalis.dev.zone /var/named/inside.domusdigitalis.dev.zone.bak.$(date +%Y%m%d%H%M)"

4.2. 2.2 Backup Reverse Zone

ssh $DNS_SERVER "sudo cp $REVERSE_ZONE ${REVERSE_ZONE}.bak.$(date +%Y%m%d%H%M)"

4.3. 2.3 Verify Backups

ssh $DNS_SERVER "ls -la /var/named/*.bak.*"

5. Phase 3: Add Forward (A) Records

5.1. 3.1 Add All Infrastructure A Records

ssh bind-01 << 'EOF'
sudo tee -a /var/named/inside.domusdigitalis.dev.zone << 'RECORDS'
; === VyOS Firewall HA ===
vyos-01         IN A    10.50.1.2
vyos-02         IN A    10.50.1.3
vyos            IN A    10.50.1.1

; === Hypervisors ===
kvm-01          IN A    10.50.1.110
kvm-02          IN A    10.50.1.111
ipmi-01         IN A    10.50.1.200
ipmi-02         IN A    10.50.1.201

; === Identity ===
home-dc01       IN A    10.50.1.50
home-dc02       IN A    10.50.1.51
keycloak-01     IN A    10.50.1.80
keycloak-02     IN A    10.50.1.81
ipa-01          IN A    10.50.1.100
ipa-02          IN A    10.50.1.101

; === Security ===
vault-01        IN A    10.50.1.60
vault-02        IN A    10.50.1.61
vault-03        IN A    10.50.1.62
ise-01          IN A    10.50.1.20
ise-02          IN A    10.50.1.21
ipsk-mgr-01     IN A    10.50.1.30
ipsk-mgr-02     IN A    10.50.1.31
ipsk-mgr        IN A    10.50.1.32

; === DNS ===
bind-01         IN A    10.50.1.90
bind-02         IN A    10.50.1.91

; === Network ===
9800-wlc-01     IN A    10.50.1.40
9800-wlc-02     IN A    10.50.1.41
3560-cx         IN A    10.50.1.10
c9300-01        IN A    10.50.1.11

; === Storage ===
nas-01          IN A    10.50.1.70
nas-02          IN A    10.50.1.71
gitea-01        IN A    10.50.1.72
minio-01        IN A    10.50.1.73

; === k3s Cluster ===
k3s-master-01   IN A    10.50.1.120
k3s-master-02   IN A    10.50.1.121
k3s-master-03   IN A    10.50.1.122
k3s-worker-01   IN A    10.50.1.123
k3s-worker-02   IN A    10.50.1.124
k3s-worker-03   IN A    10.50.1.125

; === Monitoring VIPs (MetalLB/Traefik) ===
traefik         IN A    10.50.1.130
wazuh-indexer   IN A    10.50.1.131
wazuh-dashboard IN A    10.50.1.132
wazuh-workers   IN A    10.50.1.133
wazuh-manager   IN A    10.50.1.134
zabbix-01       IN A    10.50.1.135

; === CNAMEs for convenience ===
dc              IN CNAME home-dc01
vault           IN CNAME vault-01
ise             IN CNAME ise-01
wlc             IN CNAME 9800-wlc-01
nas             IN CNAME nas-01
wazuh           IN CNAME wazuh-manager
prometheus      IN CNAME traefik
grafana         IN CNAME traefik
alertmanager    IN CNAME traefik
RECORDS
EOF

5.2. 3.2 Verify Records Added

ssh bind-01 "sudo tail -50 /var/named/inside.domusdigitalis.dev.zone"

6. Phase 4: Increment Serial Number

CRITICAL: Serial MUST increment or changes won’t propagate.

6.1. 4.1 Check Current Serial

ssh bind-01 "grep -E '^[[:space:]]+[0-9]{10}' /var/named/inside.domusdigitalis.dev.zone"

6.2. 4.2 Edit Serial Manually

ssh bind-01 "sudo vi /var/named/inside.domusdigitalis.dev.zone"

Format: YYYYMMDDNN (e.g., 2026030201)

  • Find the line with the 10-digit serial

  • Increment the last two digits (NN)

  • If NN=99, increment the date and reset to 01

  • Save and exit (:wq)

7. Phase 5: Validate Forward Zone

ssh bind-01 "sudo named-checkzone inside.domusdigitalis.dev /var/named/inside.domusdigitalis.dev.zone"
Expected Output
zone inside.domusdigitalis.dev/IN: loaded serial 2026030201
OK

If validation fails, DO NOT proceed. Fix syntax errors first.

8. Phase 6: Add Reverse (PTR) Records

8.1. 6.1 Add All PTR Records

ssh bind-01 << 'EOF'
sudo tee -a /var/named/10.50.1.rev << 'PTR'
; === VyOS ===
1    IN PTR  vyos.inside.domusdigitalis.dev.
2    IN PTR  vyos-01.inside.domusdigitalis.dev.
3    IN PTR  vyos-02.inside.domusdigitalis.dev.

; === Switches ===
10   IN PTR  3560-cx.inside.domusdigitalis.dev.
11   IN PTR  c9300-01.inside.domusdigitalis.dev.

; === ISE ===
20   IN PTR  ise-01.inside.domusdigitalis.dev.
21   IN PTR  ise-02.inside.domusdigitalis.dev.

; === iPSK HA ===
30   IN PTR  ipsk-mgr-01.inside.domusdigitalis.dev.
31   IN PTR  ipsk-mgr-02.inside.domusdigitalis.dev.
32   IN PTR  ipsk-mgr.inside.domusdigitalis.dev.

; === WLC HA ===
40   IN PTR  9800-wlc-01.inside.domusdigitalis.dev.
41   IN PTR  9800-wlc-02.inside.domusdigitalis.dev.

; === Identity ===
50   IN PTR  home-dc01.inside.domusdigitalis.dev.
51   IN PTR  home-dc02.inside.domusdigitalis.dev.

; === Vault ===
60   IN PTR  vault-01.inside.domusdigitalis.dev.
61   IN PTR  vault-02.inside.domusdigitalis.dev.
62   IN PTR  vault-03.inside.domusdigitalis.dev.

; === Storage HA ===
70   IN PTR  nas-01.inside.domusdigitalis.dev.
71   IN PTR  nas-02.inside.domusdigitalis.dev.
72   IN PTR  gitea-01.inside.domusdigitalis.dev.
73   IN PTR  minio-01.inside.domusdigitalis.dev.

; === Keycloak HA ===
80   IN PTR  keycloak-01.inside.domusdigitalis.dev.
81   IN PTR  keycloak-02.inside.domusdigitalis.dev.

; === DNS ===
90   IN PTR  bind-01.inside.domusdigitalis.dev.
91   IN PTR  bind-02.inside.domusdigitalis.dev.

; === FreeIPA ===
100  IN PTR  ipa-01.inside.domusdigitalis.dev.
101  IN PTR  ipa-02.inside.domusdigitalis.dev.

; === Hypervisors ===
110  IN PTR  kvm-01.inside.domusdigitalis.dev.
111  IN PTR  kvm-02.inside.domusdigitalis.dev.

; === k3s ===
120  IN PTR  k3s-master-01.inside.domusdigitalis.dev.
121  IN PTR  k3s-master-02.inside.domusdigitalis.dev.
122  IN PTR  k3s-master-03.inside.domusdigitalis.dev.
123  IN PTR  k3s-worker-01.inside.domusdigitalis.dev.
124  IN PTR  k3s-worker-02.inside.domusdigitalis.dev.
125  IN PTR  k3s-worker-03.inside.domusdigitalis.dev.

; === Monitoring VIPs ===
130  IN PTR  traefik.inside.domusdigitalis.dev.
131  IN PTR  wazuh-indexer.inside.domusdigitalis.dev.
132  IN PTR  wazuh-dashboard.inside.domusdigitalis.dev.
133  IN PTR  wazuh-workers.inside.domusdigitalis.dev.
134  IN PTR  wazuh-manager.inside.domusdigitalis.dev.
135  IN PTR  zabbix-01.inside.domusdigitalis.dev.

; === IPMI ===
200  IN PTR  ipmi-01.inside.domusdigitalis.dev.
201  IN PTR  ipmi-02.inside.domusdigitalis.dev.
PTR
EOF

8.2. 6.2 Edit Reverse Zone Serial

ssh $DNS_SERVER "sudo vi $REVERSE_ZONE"

Increment serial (same format: YYYYMMDDNN)

9. Phase 7: Validate Reverse Zone

ssh bind-01 "sudo named-checkzone 1.50.10.in-addr.arpa /var/named/10.50.1.rev"
Expected Output
zone 1.50.10.in-addr.arpa/IN: loaded serial 2026030201
OK

10. Phase 8: Reload Zones

10.1. 8.1 Reload Forward Zone

ssh bind-01 "sudo rndc reload inside.domusdigitalis.dev"
Expected Output
zone reload queued

10.2. 8.2 Reload Reverse Zone

ssh bind-01 "sudo rndc reload 1.50.10.in-addr.arpa"
Expected Output
zone reload queued

11. Phase 9: Post-Deployment Validation

11.1. 9.1 Validate ALL A Records

echo "=== POST-DEPLOYMENT: Validating ALL Records ==="
DOMAIN="inside.domusdigitalis.dev"
DNS="10.50.1.90"
FAILED=0

# All infrastructure hosts
HOSTS=(
  "vyos-01:10.50.1.2"
  "vyos-02:10.50.1.3"
  "vyos:10.50.1.1"
  "kvm-01:10.50.1.110"
  "kvm-02:10.50.1.111"
  "vault-01:10.50.1.60"
  "vault-02:10.50.1.61"
  "vault-03:10.50.1.62"
  "ise-01:10.50.1.20"
  "ise-02:10.50.1.21"
  "home-dc01:10.50.1.50"
  "home-dc02:10.50.1.51"
  "keycloak-01:10.50.1.80"
  "keycloak-02:10.50.1.81"
  "ipa-01:10.50.1.100"
  "ipa-02:10.50.1.101"
  "bind-01:10.50.1.90"
  "bind-02:10.50.1.91"
  "9800-wlc-01:10.50.1.40"
  "9800-wlc-02:10.50.1.41"
  "nas-01:10.50.1.70"
  "nas-02:10.50.1.71"
  "gitea-01:10.50.1.72"
  "minio-01:10.50.1.73"
  "ipsk-mgr-01:10.50.1.30"
  "ipsk-mgr-02:10.50.1.31"
  "ipsk-mgr:10.50.1.32"
  "3560-cx:10.50.1.10"
  "c9300-01:10.50.1.11"
  "ipmi-01:10.50.1.200"
  "ipmi-02:10.50.1.201"
  "k3s-master-01:10.50.1.120"
  "k3s-master-02:10.50.1.121"
  "k3s-master-03:10.50.1.122"
  "k3s-worker-01:10.50.1.123"
  "k3s-worker-02:10.50.1.124"
  "k3s-worker-03:10.50.1.125"
  "traefik:10.50.1.130"
  "wazuh-indexer:10.50.1.131"
  "wazuh-dashboard:10.50.1.132"
  "wazuh-workers:10.50.1.133"
  "wazuh-manager:10.50.1.134"
  "zabbix-01:10.50.1.135"
)

for entry in "${HOSTS[@]}"; do
  HOST="${entry%%:*}"
  EXPECTED="${entry##*:}"
  RESULT=$(dig @$DNS $HOST.$DOMAIN +short)
  if [[ "$RESULT" == "$EXPECTED" ]]; then
    echo "✓ $HOST → $RESULT"
  else
    echo "✗ $HOST: expected $EXPECTED, got $RESULT"
    ((FAILED++))
  fi
done

echo ""
echo "=== SUMMARY ==="
echo "Total: ${#HOSTS[@]} records"
echo "Failed: $FAILED"
[[ $FAILED -eq 0 ]] && echo "STATUS: ALL RECORDS VALID" || echo "STATUS: VALIDATION FAILED"
Expected Output
✓ vyos-01 → 10.50.1.2
✓ vyos-02 → 10.50.1.3
...
=== SUMMARY ===
Total: 43 records
Failed: 0
STATUS: ALL RECORDS VALID

11.2. 9.2 Validate CNAMEs

echo "=== POST-DEPLOYMENT: Validating CNAMEs ==="
DOMAIN="inside.domusdigitalis.dev"
DNS="10.50.1.90"

CNAMES=(
  "dc:home-dc01"
  "vault:vault-01"
  "ise:ise-01"
  "wlc:9800-wlc-01"
  "nas:nas-01"
  "wazuh:wazuh-manager"
)

for entry in "${CNAMES[@]}"; do
  ALIAS="${entry%%:*}"
  TARGET="${entry##*:}"
  RESULT=$(dig @$DNS $ALIAS.$DOMAIN CNAME +short)
  if [[ "$RESULT" == "$TARGET.$DOMAIN." ]]; then
    echo "✓ $ALIAS → $TARGET"
  else
    echo "✗ $ALIAS: expected $TARGET.$DOMAIN., got $RESULT"
  fi
done

11.3. 9.3 Validate PTR Records (Sample)

echo "=== POST-DEPLOYMENT: Validating PTR Records (sample) ==="
DNS="10.50.1.90"

PTRS=(
  "10.50.1.1:vyos"
  "10.50.1.20:ise-01"
  "10.50.1.60:vault-01"
  "10.50.1.110:kvm-01"
  "10.50.1.120:k3s-master-01"
)

for entry in "${PTRS[@]}"; do
  IP="${entry%%:*}"
  EXPECTED="${entry##*:}"
  RESULT=$(dig @$DNS -x $IP +short)
  if [[ "$RESULT" == *"$EXPECTED"* ]]; then
    echo "✓ $IP → $RESULT"
  else
    echo "✗ $IP: expected *$EXPECTED*, got $RESULT"
  fi
done

11.4. 9.4 Confirm Serial Incremented

echo "=== POST-DEPLOYMENT: Confirm Serial Incremented ==="
ssh bind-01 "sudo rndc zonestatus inside.domusdigitalis.dev | grep serial"

12. Phase 10: Smoke Test

Test from your workstation using the new records:

12.1. 10.1 VyOS Resolution

for h in vyos-01 vyos-02 kvm-01 kvm-02 vault-01 ise-01; do
  echo -n "$h: "
  dig @10.50.1.90 $h.inside.domusdigitalis.dev +short
done

12.2. 10.2 k3s Cluster Resolution

for i in 01 02 03; do
  echo -n "k3s-master-$i: "
  dig @$DNS_IP k3s-master-$i.inside.domusdigitalis.dev +short
done

12.3. 10.3 Monitoring VIPs

for h in traefik wazuh-manager grafana prometheus; do
  echo -n "$h: "
  dig @$DNS_IP $h.inside.domusdigitalis.dev +short
done

13. Rollback Procedure

If something goes wrong:

13.1. Restore from Backup

# Find latest backups
ssh $DNS_SERVER "ls -la /var/named/*.bak.*"

# Restore forward zone (replace TIMESTAMP)
ssh $DNS_SERVER "sudo cp ${FORWARD_ZONE}.bak.TIMESTAMP $FORWARD_ZONE"

# Restore reverse zone
ssh $DNS_SERVER "sudo cp ${REVERSE_ZONE}.bak.TIMESTAMP $REVERSE_ZONE"

# Reload
ssh $DNS_SERVER "sudo rndc reload"

14. Milestone A Checkpoint

STOP HERE and validate before proceeding to VyOS Deployment (Milestone B).

ALL checks below must pass. If any fail, do NOT proceed.

14.1. A.1 VyOS DNS Records

echo "=== VyOS DNS Records ==="
echo -n "vyos-01: " && dig @10.50.1.90 vyos-01.inside.domusdigitalis.dev +short
echo -n "vyos-02: " && dig @10.50.1.90 vyos-02.inside.domusdigitalis.dev +short
Expected Output
=== VyOS DNS Records ===
vyos-01: 10.50.1.2
vyos-02: 10.50.1.3

VyOS HA is COMPLETE - VRRP VIP active (2026-03-07).

The VIP (10.50.1.1) is now VyOS VRRP. pfSense was decommissioned 2026-03-07. The vyos CNAME pointing to VIP should exist in the zone file.

14.2. A.2 Core Infrastructure Records

echo "=== Core Infrastructure ==="
for h in kvm-01 kvm-02 vault-01 ise-01 bind-01 home-dc01; do
  echo -n "$h: " && dig @10.50.1.90 $h.inside.domusdigitalis.dev +short
done

14.3. A.3 k3s Cluster Records

echo "=== k3s Cluster ==="
for h in k3s-master-01 k3s-master-02 k3s-master-03 traefik; do
  echo -n "$h: " && dig @10.50.1.90 $h.inside.domusdigitalis.dev +short
done

14.4. A.4 Reverse DNS (PTR) Spot Check

echo "=== PTR Spot Check ==="
echo -n "10.50.1.3 (vyos-02): " && dig @10.50.1.90 -x 10.50.1.3 +short
echo -n "10.50.1.60 (vault-01): " && dig @10.50.1.90 -x 10.50.1.60 +short
echo -n "10.50.1.120 (k3s-master-01): " && dig @10.50.1.90 -x 10.50.1.120 +short

14.5. A.5 CNAME Resolution

echo "=== CNAMEs ==="
for alias in vault ise wlc nas dc; do
  echo -n "$alias → " && dig @10.50.1.90 $alias.inside.domusdigitalis.dev +short
done

14.6. Checkpoint Summary

echo ""
echo "=========================================="
echo "MILESTONE A CHECKPOINT SUMMARY"
echo "=========================================="
PASS=0
FAIL=0

# Critical VyOS records (VIP deferred until Milestone E)
for check in "vyos-01:10.50.1.2" "vyos-02:10.50.1.3"; do
  HOST="${check%%:*}"
  EXPECTED="${check##*:}"
  RESULT=$(dig @10.50.1.90 $HOST.inside.domusdigitalis.dev +short)
  if [[ "$RESULT" == "$EXPECTED" ]]; then
    echo "✓ $HOST = $RESULT"
    ((PASS++))
  else
    echo "✗ $HOST: expected $EXPECTED, got '$RESULT'"
    ((FAIL++))
  fi
done

# Core infrastructure spot check
for check in "vault-01:10.50.1.60" "ise-01:10.50.1.20" "bind-01:10.50.1.90"; do
  HOST="${check%%:*}"
  EXPECTED="${check##*:}"
  RESULT=$(dig @10.50.1.90 $HOST.inside.domusdigitalis.dev +short)
  if [[ "$RESULT" == "$EXPECTED" ]]; then
    echo "✓ $HOST = $RESULT"
    ((PASS++))
  else
    echo "✗ $HOST: expected $EXPECTED, got '$RESULT'"
    ((FAIL++))
  fi
done

echo ""
echo "Passed: $PASS | Failed: $FAIL"
echo "Note: vyos (VIP) deferred until Milestone E"
if [[ $FAIL -eq 0 ]]; then
  echo "STATUS: ✓ MILESTONE A COMPLETE - Ready for Milestone B"
else
  echo "STATUS: ✗ DO NOT PROCEED - Fix failures above"
fi
echo "=========================================="

Next Step: If all checks pass, proceed to VyOS Deployment and start at Session Variables.