Files
puppet-prod/site/profiles/manifests/haproxy/dns.pp
T
unkinben 918c4f20e1 haproxy::dns: fully-qualify halb CNAME targets (#489)
## Why

The halb publishes service CNAMEs (`git.unkin.net`, `dashboard.ceph.unkin.net`, and every other halb-fronted name) with a **bare target label**, e.g.:
```
git.unkin.net.  300  IN  CNAME  au-syd1-prod-halb-vrrp.
```
`dns-updater` builds the RR with `dns.NewRR` and **no $ORIGIN**, so a bare value becomes root-absolute (`au-syd1-prod-halb-vrrp.`) and dead-ends in NXDOMAIN. Once the k8s bind became authoritative for these zones, that broke resolution of every halb-fronted service (git, the Ceph dashboard, ...). `au-syd1-prod-halb-vrrp.unkin.net` / `.main.unkin.net` resolve fine (198.18.19.17) — only the CNAME target was truncated.

## Change (`site/profiles/manifests/haproxy/dns.pp`)

Emit **fully-qualified** CNAME targets (trailing dot), the FQDN form `dns-updater` expects (per its own test fixture `au-syd1-prod-halb.main.unkin.net.`):
- vrrp cnames: `${location_environment}-halb-vrrp.${domain}.`
- non-vrrp cnames: `${location_environment}-halb.${domain}.`

The matching A records are already published in `main.unkin.net`/`unkin.net` just above, so the targets resolve to the VIP.

---------

Co-authored-by: benvin <neotheo@gmail.com>
Reviewed-on: #489
Co-authored-by: Ben Vincent <ben@unkin.net>
Co-committed-by: Ben Vincent <ben@unkin.net>
2026-07-19 01:37:06 +10:00

77 lines
3.0 KiB
Puppet

# profiles::haproxy::dns
class profiles::haproxy::dns (
Stdlib::IP::Address $ipaddr,
Array[Stdlib::Fqdn] $vrrp_cnames = [],
Array[Stdlib::Fqdn] $cnames = [],
Integer $order = 10,
){
# create an A record for each load balancer in a region
$location_environment = "${facts['country']}-${facts['region']}-${facts['environment']}"
profiles::dns::record { "${facts['networking']['fqdn']}_${location_environment}-halb_A":
value => $::facts['networking']['ip'],
type => 'A',
record => "${location_environment}-halb",
zone => $::facts['networking']['domain'],
order => $order,
}
# export cnames for haproxy applications
$cnames.each |$cname| {
$parts = split($cname, '\.')
$domain = join($parts[1, $parts.length], '.')
profiles::dns::record { "${::facts['networking']['fqdn']}_${cname}_CNAME":
# CNAME target must be a fully-qualified name (trailing dot): dns-updater
# parses the value with no $ORIGIN, so a bare label becomes root-absolute
# ("au-syd1-prod-halb.") and dead-ends in NXDOMAIN.
value => "${location_environment}-halb.${facts['networking']['domain']}.",
type => 'CNAME',
record => "${cname}.",
zone => $domain,
order => $order,
}
}
# if it is, find hosts, sort them so they dont cause changes every run
$servers_array = sort(puppetdb_query(
"facts[certname] {
name = 'enc_role' and value = '${facts['enc_role']}' and
certname in facts[certname] { name = 'country' and value = '${facts['country']}' } and
certname in facts[certname] { name = 'region' and value = '${facts['region']}' } and
certname in facts[certname] { name = 'environment' and value = '${facts['environment']}' }
}"
).map |$fact| { $fact['certname'] })
# give enough time for a few hosts to be provisioned
if length($servers_array) >= 3 {
# if this is the first host in the returned filter, export a/cnames for haproxy applications
if $servers_array[0] == $trusted['certname'] {
['main.unkin.net', 'unkin.net'].each |$domain| {
profiles::dns::record { "${facts['networking']['fqdn']}_vrrp_${domain}_${location_environment}-halb-vrrp":
value => $ipaddr,
type => 'A',
record => "${location_environment}-halb-vrrp",
zone => $domain,
order => $order,
}
}
$vrrp_cnames.each |$cname| {
$parts = split($cname, '\.')
$domain = join($parts[1, $parts.length], '.')
profiles::dns::record { "${::facts['networking']['fqdn']}_${cname}_CNAME":
# Fully-qualified target (trailing dot); see the note on the non-vrrp
# cnames above. The matching A record is published in main.unkin.net
# and unkin.net just above.
value => "${location_environment}-halb-vrrp.${facts['networking']['domain']}.",
type => 'CNAME',
record => "${cname}.",
zone => $domain,
order => $order,
}
}
}
}
}