Skip to content

Commit 47baa57

Browse files
authored
Allow to specify an own IPv6 IPAM pool (#1573)
* Allow to specify an own IPv6 IPAM pool. * Add intergration test for ipam pool. * Provide type for IPAM pool config. * Add documentation * Make generate * Address review comments.
1 parent a34252c commit 47baa57

12 files changed

Lines changed: 238 additions & 11 deletions

File tree

docs/usage/ipv6.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,31 @@ To create an IPv6 shoot cluster or a dual-stack shoot within your own Virtual Pr
153153
![bring your own vpc](./images/bring-your-own-vpc.png)
154154
An egress-only internet gateway is required for outbound internet traffic (IPv6) from the instances within your VPC. Please create one egress-only internet gateway and attach it to the VPC. Please also make sure that the VPC has an attached internet gateway and the following attributes set: `enableDnsHostnames` and `enableDnsSupport` as described under [usage](usage.md#infrastructureConfig).
155155

156+
### Configuring a Custom IPv6 IPAM Pool
157+
158+
By default, AWS will assign an Amazon-provided IPv6 CIDR block to a newly created VPC for IPv6 / dual-stack shoot clusters. If you want to control from which pool the VPC IPv6 CIDR is allocated (for example to ensure consistent addressing across multiple clusters or accounts), you can reference an existing AWS IPAM pool via the `infrastructureConfig.networks.vpc.ipv6IpamPool` field.
159+
160+
```yaml
161+
provider:
162+
type: aws
163+
infrastructureConfig:
164+
apiVersion: aws.provider.extensions.gardener.cloud/v1alpha1
165+
kind: InfrastructureConfig
166+
networks:
167+
vpc:
168+
ipv6IpamPool:
169+
id: ipam-pool-0123456789abcdef0
170+
...
171+
```
172+
173+
Requirements & notes:
174+
* The referenced pool must exist in the same AWS account & region as the shoot infrastructure.
175+
* The pool must be IPv6 and have available capacity for a /56 CIDR; otherwise VPC creation will fail.
176+
* Only the pool ID is used; the extension currently always requests an IPv6 netmask length of /56 (not configurable yet).
177+
* Changing the pool after creation is not supported (VPC IPv6 CIDRs are immutable once associated).
178+
179+
Use this option when you operate centralized IP address management and need deterministic allocation ranges across shoots.
180+
156181
### Migration of IPv4-only Shoot Clusters to Dual-Stack
157182

158183
To migrate an IPv4-only shoot cluster to Dual-Stack simply change the `.spec.networking.ipFamilies` field in the `Shoot` resource from `IPv4` to `IPv4, IPv6` as shown below.

hack/api-reference/api.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,37 @@ string
959959
</tr>
960960
</tbody>
961961
</table>
962+
<h3 id="aws.provider.extensions.gardener.cloud/v1alpha1.IPAMPool">IPAMPool
963+
</h3>
964+
<p>
965+
(<em>Appears on:</em>
966+
<a href="#aws.provider.extensions.gardener.cloud/v1alpha1.VPC">VPC</a>)
967+
</p>
968+
<p>
969+
<p>IPAMPool represents an AWS IPAM pool referenced for IPv6 address allocation of the VPC.
970+
Currently only the ID is required; future fields may extend configuration.</p>
971+
</p>
972+
<table>
973+
<thead>
974+
<tr>
975+
<th>Field</th>
976+
<th>Description</th>
977+
</tr>
978+
</thead>
979+
<tbody>
980+
<tr>
981+
<td>
982+
<code>id</code></br>
983+
<em>
984+
string
985+
</em>
986+
</td>
987+
<td>
988+
<p>ID is the IPAM pool id.</p>
989+
</td>
990+
</tr>
991+
</tbody>
992+
</table>
962993
<h3 id="aws.provider.extensions.gardener.cloud/v1alpha1.IgnoreTags">IgnoreTags
963994
</h3>
964995
<p>
@@ -1839,6 +1870,22 @@ string
18391870
<p>GatewayEndpoints service names to configure as gateway endpoints in the VPC.</p>
18401871
</td>
18411872
</tr>
1873+
<tr>
1874+
<td>
1875+
<code>ipv6IpamPool</code></br>
1876+
<em>
1877+
<a href="#aws.provider.extensions.gardener.cloud/v1alpha1.IPAMPool">
1878+
IPAMPool
1879+
</a>
1880+
</em>
1881+
</td>
1882+
<td>
1883+
<em>(Optional)</em>
1884+
<p>Ipv6IpamPool references an AWS IPv6 IPAM pool used to allocate the VPC&rsquo;s IPv6 CIDR block.
1885+
If specified, the extension will request the VPC&rsquo;s IPv6 CIDR from this pool instead of
1886+
letting AWS auto-assign one. The pool must already exist in the target account/region.</p>
1887+
</td>
1888+
</tr>
18421889
</tbody>
18431890
</table>
18441891
<h3 id="aws.provider.extensions.gardener.cloud/v1alpha1.VPCStatus">VPCStatus

pkg/apis/aws/types_infrastructure.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ type VPC struct {
115115
CIDR *string
116116
// GatewayEndpoints service names to configure as gateway endpoints in the VPC.
117117
GatewayEndpoints []string
118+
// Ipv6IpamPool references an AWS IPv6 IPAM pool used to allocate the VPC's IPv6 CIDR block.
119+
Ipv6IpamPool *IPAMPool
120+
}
121+
122+
// IPAMPool references an AWS IPAM pool that should be used to allocate the VPC's CIDR.
123+
type IPAMPool struct {
124+
// ID is the IPAM pool id.
125+
ID *string
118126
}
119127

120128
// VPCStatus contains information about a generated VPC or resources inside an existing VPC.

pkg/apis/aws/v1alpha1/types_infrastructure.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,18 @@ type VPC struct {
127127
// GatewayEndpoints service names to configure as gateway endpoints in the VPC.
128128
// +optional
129129
GatewayEndpoints []string `json:"gatewayEndpoints,omitempty"`
130+
// Ipv6IpamPool references an AWS IPv6 IPAM pool used to allocate the VPC's IPv6 CIDR block.
131+
// If specified, the extension will request the VPC's IPv6 CIDR from this pool instead of
132+
// letting AWS auto-assign one. The pool must already exist in the target account/region.
133+
// +optional
134+
Ipv6IpamPool *IPAMPool `json:"ipv6IpamPool,omitempty"`
135+
}
136+
137+
// IPAMPool represents an AWS IPAM pool referenced for IPv6 address allocation of the VPC.
138+
// Currently only the ID is required; future fields may extend configuration.
139+
type IPAMPool struct {
140+
// ID is the IPAM pool id.
141+
ID *string `json:"id"`
130142
}
131143

132144
// VPCStatus contains information about a generated VPC or resources inside an existing VPC.

pkg/apis/aws/v1alpha1/zz_generated.conversion.go

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/apis/aws/v1alpha1/zz_generated.deepcopy.go

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/apis/aws/zz_generated.deepcopy.go

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/aws/client/client.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,8 @@ func (c *Client) CreateVpc(ctx context.Context, desired *VPC) (*VPC, error) {
801801
AmazonProvidedIpv6CidrBlock: aws.Bool(desired.AssignGeneratedIPv6CidrBlock),
802802
TagSpecifications: desired.ToTagSpecifications(ec2types.ResourceTypeVpc),
803803
InstanceTenancy: desired.InstanceTenancy,
804+
Ipv6IpamPoolId: desired.Ipv6IpamPoolId,
805+
Ipv6NetmaskLength: desired.Ipv6NetmaskLength,
804806
}
805807
output, err := c.EC2.CreateVpc(ctx, input)
806808
if err != nil {

pkg/aws/client/types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,8 @@ type VPC struct {
234234
EnableDnsSupport bool
235235
EnableDnsHostnames bool
236236
AssignGeneratedIPv6CidrBlock bool
237+
Ipv6IpamPoolId *string
238+
Ipv6NetmaskLength *int32
237239
DhcpOptionsId *string
238240
InstanceTenancy ec2types.Tenancy
239241
State *string

pkg/controller/infrastructure/infraflow/reconcile.go

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ import (
3131
)
3232

3333
const (
34-
defaultTimeout = 90 * time.Second
35-
defaultLongTimeout = 3 * time.Minute
36-
allIPv4 = "0.0.0.0/0"
37-
allIPv6 = "::/0"
38-
nat64Prefix = "64:ff9b::/96"
34+
defaultTimeout = 90 * time.Second
35+
defaultLongTimeout = 3 * time.Minute
36+
allIPv4 = "0.0.0.0/0"
37+
allIPv6 = "::/0"
38+
nat64Prefix = "64:ff9b::/96"
39+
defaultIPv6NetmaskSize = 56
3940
)
4041

4142
// Reconcile creates and runs the flow to reconcile the AWS infrastructure.
@@ -198,12 +199,21 @@ func (c *FlowContext) ensureManagedVpc(ctx context.Context) error {
198199
instanceTenancy = ec2types.TenancyDedicated
199200
}
200201
desired := &awsclient.VPC{
201-
Tags: c.commonTags,
202-
EnableDnsSupport: true,
203-
EnableDnsHostnames: true,
204-
AssignGeneratedIPv6CidrBlock: (c.config.DualStack != nil && c.config.DualStack.Enabled) || isIPv6(c.getIpFamilies()),
205-
DhcpOptionsId: c.state.Get(IdentifierDHCPOptions),
206-
InstanceTenancy: instanceTenancy,
202+
Tags: c.commonTags,
203+
EnableDnsSupport: true,
204+
EnableDnsHostnames: true,
205+
DhcpOptionsId: c.state.Get(IdentifierDHCPOptions),
206+
InstanceTenancy: instanceTenancy,
207+
}
208+
209+
if (c.config.DualStack != nil && c.config.DualStack.Enabled) || isIPv6(c.getIpFamilies()) {
210+
if c.config.Networks.VPC.Ipv6IpamPool != nil && c.config.Networks.VPC.Ipv6IpamPool.ID != nil {
211+
desired.AssignGeneratedIPv6CidrBlock = false
212+
desired.Ipv6IpamPoolId = c.config.Networks.VPC.Ipv6IpamPool.ID
213+
desired.Ipv6NetmaskLength = ptr.To(int32(defaultIPv6NetmaskSize))
214+
} else {
215+
desired.AssignGeneratedIPv6CidrBlock = true
216+
}
207217
}
208218

209219
if c.config.Networks.VPC.CIDR == nil {

0 commit comments

Comments
 (0)