8. August 2026 · 6 Min. Lesezeit
Zwei DNS-Schichten, die identisch aussehen, wenn beide grün sind
Pods in der VPC eines Accounts bekamen fortlaufend NXDOMAIN für Namen in einer privaten Hosted Zone, die einem anderen Account gehörte. Der Fehler hatte eine sehr spezifische Form: Er trat nur von dieser einen fremden VPC aus auf. Fragte man dieselben Namen aus der Heimat-VPC der Zone ab, lösten sie sofort auf. Das war also keine kaputte Zone, kein falscher Record, keine Propagierungsverzögerung. Es war auf genau eine VPC beschränkt, die Art von Detail, die mir hätte sagen sollen, was falsch war, und mir stattdessen nichts sagte, weil ich es durch die falsche Schicht las.
Die Peering-Verbindung zwischen den beiden VPCs war gesund. Routen waren auf beiden Seiten vorhanden. Security Groups erlaubten den Traffic. Und die allow_remote_vpc_dns_resolution-Option der Peering-Verbindung war gesetzt, also genau die Einstellung, deren Name am ehesten nach “lass diese VPC DNS über das Peering auflösen” klingt. Jedes Signal, das ich zu prüfen wusste, war grün. Die Namen lösten trotzdem nicht auf.
Die zwei Schichten
Der Grund, warum keines dieser grünen Signale half, ist, dass DNS über ein gepeertes, account-übergreifendes Setup auf zwei unabhängigen Mechanismen läuft, und die sehen von außen gleich aus.
Der erste ist die DNS-Auflösung der Peering-Verbindung. Dieses allow_remote_vpc_dns_resolution-Flag tut eine einzige, enge Sache: Es erlaubt Instanzen auf einer Seite des Peerings, die provider-vergebenen privaten DNS-Namen der Instanzen auf der anderen Seite aufzulösen, die ip-10-x-x-x.region.compute.internal-Hostnamen, die AWS automatisch vergibt. Das ist der gesamte Umfang des Flags. Es geht um das interne Standard-DNS, das jede VPC kostenlos bekommt.
Der zweite ist die Mitgliedschaft in einer privaten Hosted Zone. Eine private Hosted Zone beantwortet Anfragen nur von den VPCs, die mit ihr assoziiert sind. Assoziation ist ein eigener, expliziter Akt: Man hängt eine bestimmte VPC an eine bestimmte Zone, und erst dann taucht diese Zone im Resolver dieser VPC auf. Eine Zone, die nicht mit deiner VPC assoziiert ist, existiert für den Resolver deiner VPC nicht, und die ehrliche, korrekte Antwort auf eine Anfrage nach einem ihrer Namen ist NXDOMAIN.
Diese beiden Schichten haben nichts miteinander zu tun. Die Peering-DNS-Auflösung betrifft die automatischen compute.internal-Namen; die Zonen-Mitgliedschaft betrifft deine eigene Zone. Das Peering-Häkchen zu setzen ändert das Erste und tut absolut nichts für das Zweite. Meine fremde VPC konnte die compute.internal-Hostnamen der Gegenseite perfekt auflösen, genau das, was das Flag verspricht, und dieser Erfolg sagte mir nichts darüber, ob meine eigene Zone antworten würde, denn das war nie die Aufgabe des Flags.
Warum es einen täuscht
Jeder diagnostische Reflex, den ich hatte, zeigte auf die Peering-Schicht. Ist das Peering aktiv? Sind die Routen da? Erlauben die Security Groups es? Ist die DNS-Auflösung auf der Verbindung aktiviert? Das sind die Fragen, die man zur Cross-VPC-Konnektivität stellt, und jede einzelne Antwort kam korrekt zurück, weil die Peering-Schicht wirklich korrekt war. Das Problem war, dass eine korrekte Peering-Schicht kein Beleg für die Zonen-Mitgliedschaft ist. Ich sammelte weiter grüne Häkchen von einem Mechanismus und behandelte sie als Beruhigung über einen anderen.
Nichts auf dieser ganzen Oberfläche sagt “diese VPC ist kein Mitglied der Zone”. Es gibt kein rotes Licht dafür. Die Peering-Konsole ist zufrieden, die Route-Tabellen sind zufrieden, die Security Groups sind zufrieden, und die fehlende Assoziation lebt in einer völlig anderen Ressource, die man nur findet, wenn man sie bereits vermutet. Der Fehler sitzt in der Lücke zwischen zwei Schichten, die beide grün melden, und die Form des Bugs ist, dass das Grün der Schicht, die du sehen kannst, dich überzeugt, die Schicht, die du nicht sehen kannst, sei auch in Ordnung.
Die Lösung, und warum sie zwei Schritte hat
Die Lösung ist, die fremde VPC zu einem tatsächlichen Mitglied der Zone zu machen. Weil Zone und VPC in verschiedenen Accounts leben, ist diese Assoziation ein zweistufiger Handshake, ein Aufruf in jedem Account:
# Im Zonen-Owner-Account: die fremde VPC autorisieren.
aws route53 create-vpc-association-authorization \
--hosted-zone-id "$ZONE_ID" \
--vpc VPCRegion="$REGION",VPCId="$FOREIGN_VPC_ID" \
--profile zone-owner
# Im VPC-Owner-Account: durch Assoziieren annehmen.
aws route53 associate-vpc-with-hosted-zone \
--hosted-zone-id "$ZONE_ID" \
--vpc VPCRegion="$REGION",VPCId="$FOREIGN_VPC_ID" \
--profile vpc-owner
Der Split ist keine Zeremonie. Die Autorisierung ist die Entscheidung des Zonen-Owners, also läuft sie unter dessen Credentials; die Assoziation hängt die Zone an eine VPC, die dem anderen Account gehört, also läuft sie unter dessen Credentials. Jede Hälfte läuft dort, wo ihre Ressource lebt. Führt man sie in dieser Reihenfolge aus, beginnt der Resolver der fremden VPC sofort, für die Zone zu antworten. Der Autorisierungs-Record bleibt nach Abschluss der Assoziation bestehen, also sind beide Hälften dauerhaft und später beide importierbar in das, was deine Infrastructure as Code verwaltet.
Die Audit-Falle
Sobald man weiß, dass die Assoziation das Entscheidende ist, wartet eine zweite Überraschung: Es gibt kein einzelnes Kommando, das dir sagt, ob eine VPC eine Zone auflösen kann. Es gibt zwei, und sie beantworten verschiedene Fragen.
# Was tatsächlich assoziiert ist (die Resolver-Wahrheit):
aws route53 get-hosted-zone --id "$ZONE_ID"
# Was nur autorisiert wurde (eine stehende Einladung):
aws route53 list-vpc-association-authorizations --hosted-zone-id "$ZONE_ID"
get-hosted-zone listet die tatsächlich assoziierten VPCs, also die Menge, die auflösen kann. list-vpc-association-authorizations listet die autorisierten VPCs, also nur die Erlaubnis zu assoziieren, nicht die Assoziation selbst. Sie sind sich regelmäßig uneinig. Ein Audit einer Zone förderte eine VPC zutage, die autorisiert, aber nie assoziiert worden war: Von der Infrastructure-as-Code-Seite sah es erledigt aus, die Autorisierungs-Ressource existierte, und die Auflösung aus dieser VPC war weiterhin kaputt. Der umgekehrte Fall passiert auch: Dieselbe Zone trug eine Assoziation zu einer VPC, die in keinem Account mehr existierte, ein Überbleibsel einer abgebauten Umgebung, harmlos, aber leicht mit einem lebenden Peer zu verwechseln. Autorisiert ist nicht assoziiert, und assoziiert ist nicht unbedingt noch real.
Die Lektion, die bleibt
Die bleibende Lektion handelt nicht von Route53. Sie lautet: Wenn zwei Schichten dasselbe grüne Licht zeigen, ist ein gesundes Signal von der einen kein Beleg über die andere, egal wie selbstsicher ihr Name etwas anderes suggeriert. allow_remote_vpc_dns_resolution klingt, als regelte es alles DNS über das Peering. Es regelt einen engen Ausschnitt, und der Ausschnitt, den ich tatsächlich brauchte, lag in einer ganz anderen Ressource.
Wenn also ein Signal grün ist und die Sache trotzdem nicht funktioniert, ist die nützliche Frage nicht “warum lügt mich dieses grüne Ding an”. Das grüne Ding sagt meist die Wahrheit über seine eigene Schicht. Die Frage ist, in welcher Schicht der Fehler tatsächlich lebt, und ob das beruhigende Grün, auf das du starrst, dort überhaupt irgendeine Autorität hat. Meistens hat es die nicht, und die echte Antwort liegt eine Ressource weiter, an einem Ort, an den du nie geschaut hast, weil dich nichts dorthin wies.