Skip to content

Commit 4e989ab

Browse files
Merge branch 'master' into issue-4989-add-helm-unit-test
* master: feat(aws): always create AAAA alias records in route53 (kubernetes-sigs#5111) feat(aws): fetch zones with tags batching (kubernetes-sigs#5058)
2 parents 7b9fd47 + 7c23e01 commit 4e989ab

18 files changed

+759
-459
lines changed

docs/sources/gateway.md

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,19 +83,18 @@ The targets from each parent Gateway matching the \*Route are then combined and
8383

8484
## Dualstack Routes
8585

86-
Gateway resources may be served from an external-loadbalancer which may support both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces.
87-
External DNS Controller uses the `external-dns.alpha.kubernetes.io/dualstack` annotation to determine this. If this annotation is
88-
set to `true` then ExternalDNS will create two records (one A record
89-
and one AAAA record) for each hostname associated with the Route resource.
86+
Gateway resources may be served from an external-loadbalancer which may support
87+
both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces. When using the AWS
88+
Route53 provider, External DNS Controller will always create both A and AAAA
89+
alias DNS records by default, regardless of whether the load balancer is dual
90+
stack or not.
9091

91-
Example:
92+
## Example
9293

9394
```yaml
9495
apiVersion: gateway.networking.k8s.io/v1
9596
kind: HTTPRoute
9697
metadata:
97-
annotations:
98-
external-dns.alpha.kubernetes.io/dualstack: "true"
9998
name: echo
10099
spec:
101100
hostnames:
@@ -112,7 +111,3 @@ spec:
112111
type: PathPrefix
113112
value: /echo
114113
```
115-
116-
The above HTTPRoute resource is backed by a dualstack Gateway.
117-
ExternalDNS will create both an A `echoserver.example.org` record and
118-
an AAAA record of the same name, that each are aliases for the same LB.

docs/tutorials/aws-filters.md

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# AWS Filters
2+
3+
This document provides guidance on filtering AWS zones using various strategies and flags.
4+
5+
## Strategies for Scoping Zones
6+
7+
> Without specifying these flags, management applies to all zones.
8+
9+
In order to manage specific zones, there is a possibility to combine multiple options
10+
11+
| Argument | Description | Flow Control |
12+
|:---------------------------|:-----------------------------------------------------------|:------------:|
13+
| `--zone-id-filter` | Specify multiple times if needed | OR |
14+
| `--domain-filter` | By domain suffix - specify multiple times if needed | OR |
15+
| `--regex-domain-filter` | By domain suffix but as a regex - overrides domain-filter | AND |
16+
| `--exclude-domains` | To exclude a domain or subdomain | OR |
17+
| `--regex-domain-exclusion` | Subtracts its matches from `regex-domain-filter`'s matches | AND |
18+
| `--aws-zone-type` | Only sync zones of this type `[public\|private]` | OR |
19+
| `--aws-zone-tags` | Only sync zones with this tag | AND |
20+
21+
Minimum required configuration
22+
23+
```sh
24+
args:
25+
--provider=aws
26+
--registry=txt
27+
--source=service
28+
```
29+
30+
### Filter by Zone Type
31+
32+
> If this flag is not specified, management applies to both public and private zones.
33+
34+
```sh
35+
args:
36+
--aws-zone-type=private|public # choose between public or private
37+
...
38+
```
39+
40+
### Filter by Domain
41+
42+
> Specify multiple times if needed.
43+
44+
```sh
45+
args:
46+
--domain-filter=example.com
47+
--domain-filter=.paradox.example.com
48+
...
49+
```
50+
51+
Example `--domain-filter=example.com` will allow for zone `example.com` and any zones that end in `.example.com`, including `an.example.com`, i.e., the subdomains of example.com.
52+
53+
When there are multiple domains, filter `--domain-filter=example.com` will match domains `example.com`, `ex.par.example.com`, `par.example.com`, `x.par.eu-west-1.example.com`.
54+
55+
And if the filter is prepended with `.` e.g., `--domain-filter=.example.com` it will allow *only* zones that end in `.example.com`, i.e., the subdomains of example.com but not the `example.com` zone itself. Example result: `ex.par.eu-west-1.example.com`, `ex.par.example.com`, `par.example.com`.
56+
57+
> Note: if you prepend the filter with ".", it will not attempt to match parent zones.
58+
59+
### Filter by Zone ID
60+
61+
> Specify multiple times if needed, the flow logic is OR
62+
63+
```sh
64+
args:
65+
--zone-id-filter=ABCDEF12345678
66+
--zone-id-filter=XYZDEF12345888
67+
...
68+
```
69+
70+
### Filter by Tag
71+
72+
> Specify multiple times if needed, the flow logic is AND
73+
74+
Keys only
75+
76+
```sh
77+
args:
78+
--aws-zone-tags=owner
79+
--aws-zone-tags=vertical
80+
```
81+
82+
Or specify keys with values
83+
84+
```sh
85+
args:
86+
--aws-zone-tags=owner=k8s
87+
--aws-zone-tags=vertical=k8s
88+
```
89+
90+
Can't specify multiple or separate values with commas: `key1=val1,key2=val2` at the moment.
91+
Filter only by value `--aws-zone-tags==tag-value` is not supported.
92+
93+
```sh
94+
args:
95+
--aws-zone-tags=team=k8s,vertical=platform # this is not supported
96+
--aws-zone-tags==tag-value # this is not supported
97+
```
98+
99+
## Filtering Workflows
100+
101+
***Filtering Sequence***
102+
103+
The diagram describes the sequence for filtering AWS zones.
104+
105+
```mermaid
106+
flowchart TD
107+
A["zones"] --> B{"Is zonesCache valid?"}
108+
B -- Yes --> C["Return cached zones"]
109+
B -- No --> D["Initialize zones map"]
110+
D --> E["For each profile and client"]
111+
E --> F["Create paginator"]
112+
F --> G{"Has more pages?"}
113+
G -- Yes --> H["Get next page"]
114+
H --> I["For each zone in page"]
115+
I --> J{"Match zoneIDFilter?"}
116+
J -- No --> G
117+
J -- Yes --> K{"Match zoneTypeFilter?"}
118+
K -- No --> G
119+
K -- Yes --> L{"Match domainFilter?"}
120+
L -- No --> M{"zoneMatchParent?"}
121+
M -- No --> G
122+
M -- Yes --> N{"Match domainFilter parent?"}
123+
N -- No --> G
124+
N -- Yes --> O{"zoneTagFilter specified?"}
125+
O -- Yes --> P["Add zone to zonesToValidate"]
126+
O -- No --> Q["Add zone to zones map"]
127+
P --> Q
128+
Q --> G
129+
G -- No --> R{"zonesToValidate not empty?"}
130+
R -- Yes --> S["Get tags for zones"]
131+
S --> T["For each zone and tags"]
132+
T --> U{"Match zoneTagFilter?"}
133+
U -- No --> V["Delete zone from zones map"]
134+
U -- Yes --> W["Keep zone in zones map"]
135+
V --> W
136+
W --> R
137+
R -- No --> X["Update zonesCache"]
138+
X --> Y["Return zones"]
139+
```
140+
141+
***Filtering Flow***
142+
143+
The is a sequence diagram that describes the interaction between `external-dns`, `AWSProvider`, and `Route53Client`
144+
during the filtering process. Here is a high-level description:
145+
146+
```mermaid
147+
sequenceDiagram
148+
participant external-dns
149+
participant AWSProvider
150+
participant Route53Client
151+
152+
external-dns->>AWSProvider: zones
153+
alt Cache is valid
154+
AWSProvider-->>external-dns: return cached zones
155+
else
156+
157+
AWSProvider->>Route53Client: ListHostedZonesPaginator
158+
loop While paginator.HasMorePages
159+
Route53Client->>AWSProvider: paginator.NextPage
160+
alt ThrottlingException
161+
AWSProvider->>external-dns: error
162+
else
163+
AWSProvider-->>external-dns: return error
164+
end
165+
AWSProvider->>AWSProvider: Filter zones
166+
alt Tags need validation
167+
AWSProvider->>Route53Client: ListTagsForResources
168+
Route53Client->>AWSProvider: return tags
169+
AWSProvider->>AWSProvider: Validate tags
170+
end
171+
end
172+
alt Cache duration > 0
173+
AWSProvider->>AWSProvider: Update cache
174+
end
175+
AWSProvider-->>external-dns: return zones
176+
end
177+
```

docs/tutorials/aws-load-balancer-controller.md

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,17 @@ spec:
101101
The above should result in the creation of an (ipv4) ALB in AWS which will forward
102102
traffic to the echoserver application.
103103

104-
If the `source=ingress` argument is specified, then ExternalDNS will create DNS
105-
records based on the hosts specified in ingress objects. The above example would
106-
result in two alias records being created, `echoserver.mycluster.example.org` and
107-
`echoserver.example.org`, which both alias the ALB that is associated with the
108-
Ingress object.
104+
If the `--source=ingress` argument is specified, then ExternalDNS will create
105+
DNS records based on the hosts specified in ingress objects. The above example
106+
would result in two alias records (A and AAAA) being created for each of the
107+
domains: `echoserver.mycluster.example.org` and `echoserver.example.org`. All
108+
four records alias the ALB that is associated with the Ingress object. As the
109+
ALB is IPv4 only, the AAAA alias records have no effect.
110+
111+
If you would like ExternalDNS to not create AAAA records at all, you can add the
112+
following command line parameter: `--exclude-record-types=AAAA`. Please be
113+
aware, this will disable AAAA record creation even for dualstack enabled load
114+
balancers.
109115

110116
Note that the above example makes use of the YAML anchor feature to avoid having
111117
to repeat the http section for multiple hosts that use the exact same paths. If
@@ -138,15 +144,17 @@ In the above example we create a default path that works for any hostname, and
138144
make use of the `external-dns.alpha.kubernetes.io/hostname` annotation to create
139145
multiple aliases for the resulting ALB.
140146

141-
## Dualstack ALBs
147+
## Dualstack Load Balancers
142148

143-
AWS [supports][4] both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces for ALBs.
144-
The AWS Load Balancer Controller uses the `alb.ingress.kubernetes.io/ip-address-type`
145-
annotation (which defaults to `ipv4`) to determine this. If this annotation is
146-
set to `dualstack` then ExternalDNS will create two alias records (one A record
147-
and one AAAA record) for each hostname associated with the Ingress object.
149+
AWS [supports both IPv4 and "dualstack" (both IPv4 and IPv6) interfaces for ALBs][4]
150+
and [NLBs][5]. The AWS Load Balancer Controller uses the `alb.ingress.kubernetes.io/ip-address-type`
151+
annotation (which defaults to `ipv4`) to determine this. ExternalDNS creates
152+
both A and AAAA alias DNS records by default, regardless of this annotation.
153+
It's possible to create only A records with the following command line
154+
parameter: `--exclude-record-types=AAAA`
148155

149156
[4]: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#ip-address-type
157+
[5]: https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html#ip-address-type
150158

151159
Example:
152160

@@ -174,5 +182,4 @@ spec:
174182
```
175183

176184
The above Ingress object will result in the creation of an ALB with a dualstack
177-
interface. ExternalDNS will create both an A `echoserver.example.org` record and
178-
an AAAA record of the same name, that each are aliases for the same ALB.
185+
interface.

0 commit comments

Comments
 (0)