diff --git a/docs/annotations/annotations.md b/docs/annotations/annotations.md index 24f90dd0f..9784a3ab6 100644 --- a/docs/annotations/annotations.md +++ b/docs/annotations/annotations.md @@ -27,7 +27,7 @@ The following table documents which sources support which annotations: [^1]: Unless the `--ignore-hostname-annotation` flag is specified. [^2]: Only behaves differently than `hostname` for `Service`s of type `ClusterIP` or `LoadBalancer`. [^3]: Also supported on `Pods` referenced from a headless `Service`'s `Endpoints`. -[^4]: The annotation must be on the `Gateway`. +[^4]: For Gateway API sources, annotation placement differs by type. See [Gateway API Annotation Placement](#gateway-api-annotation-placement) for details. [^5]: The annotation must be on the listener's `VirtualService`. ## external-dns.alpha.kubernetes.io/access @@ -210,3 +210,13 @@ Specifies the set identifier for DNS records generated by the resource. A set identifier differentiates among multiple DNS record sets that have the same combination of domain and type. Which record set or sets are returned to queries is then determined by the configured routing policy. + +## Gateway API Annotation Placement + +When using Gateway API sources (`gateway-httproute`, `gateway-grpcroute`, `gateway-tlsroute`, etc.), annotations +are read from different resources: **Gateway resource** reads only `target` annotation, while **Route resources** +(HTTPRoute, GRPCRoute, TLSRoute, etc.) read all other annotations (`hostname`, `ttl`, `controller`, and +provider-specific annotations like `cloudflare-*`, `aws-*`, `scw-*`). + +For more details and comprehensive examples, see the +[Gateway API documentation](../sources/gateway-api.md#annotations). diff --git a/docs/sources/gateway-api.md b/docs/sources/gateway-api.md index 1333ffa00..1ed779c2d 100644 --- a/docs/sources/gateway-api.md +++ b/docs/sources/gateway-api.md @@ -35,6 +35,112 @@ for HTTPRoutes and TLSRoutes by ExternalDNS, but it's _strongly_ recommended tha specs to provide all intended hostnames, since the Gateway that ultimately routes their requests/connections won't recognize additional hostnames from the annotation. +## Annotations + +### Annotation Placement + +ExternalDNS reads different annotations from different Gateway API resources: + +- **Gateway annotations**: Only `external-dns.alpha.kubernetes.io/target` is read from Gateway resources +- **Route annotations**: All other annotations (hostname, ttl, controller, provider-specific) are read from Route + resources (HTTPRoute, GRPCRoute, TLSRoute, TCPRoute, UDPRoute) + +This separation aligns with Gateway API architecture where Gateway defines infrastructure (IP addresses, listeners) +and Routes define application-level DNS records. + +### Examples + +#### Example: Cloudflare Proxied Records + +```yaml +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: my-gateway + namespace: default + annotations: + # ✅ Correct: target annotation on Gateway + external-dns.alpha.kubernetes.io/target: "203.0.113.1" +spec: + gatewayClassName: cilium + listeners: + - name: https + hostname: "*.example.com" + protocol: HTTPS + port: 443 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: my-route + annotations: + # ✅ Correct: provider-specific annotations on HTTPRoute + external-dns.alpha.kubernetes.io/cloudflare-proxied: "true" + external-dns.alpha.kubernetes.io/ttl: "300" +spec: + parentRefs: + - name: my-gateway + namespace: default + hostnames: + - api.example.com + rules: + - backendRefs: + - name: api-service + port: 8080 +``` + +#### Example: AWS Route53 with Routing Policies + +```yaml +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: aws-gateway + annotations: + # ✅ Correct: target annotation on Gateway + external-dns.alpha.kubernetes.io/target: "alb-123.us-east-1.elb.amazonaws.com" +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: weighted-route + annotations: + # ✅ Correct: AWS-specific annotations on HTTPRoute + external-dns.alpha.kubernetes.io/aws-weight: "100" + external-dns.alpha.kubernetes.io/set-identifier: "backend-v1" +spec: + parentRefs: + - name: aws-gateway + hostnames: + - app.example.com +``` + +### Common Mistakes + +❌ **Incorrect**: Placing provider-specific annotations on Gateway + +```yaml +kind: Gateway +metadata: + annotations: + # ❌ These annotations are ignored on Gateway + external-dns.alpha.kubernetes.io/cloudflare-proxied: "true" + external-dns.alpha.kubernetes.io/ttl: "300" +``` + +❌ **Incorrect**: Placing target annotation on HTTPRoute + +```yaml +kind: HTTPRoute +metadata: + annotations: + # ❌ This annotation is ignored on Routes + external-dns.alpha.kubernetes.io/target: "203.0.113.1" +``` + +For a complete list of supported annotations, see the +[annotations documentation](../annotations/annotations.md#gateway-api-annotation-placement). + ## Manifest with RBAC ```yaml