Skip to content

Commit 40cf298

Browse files
authored
Merge pull request #3247 from Ankitasw/externally-managed-clusters
Documentation for usage of externally managed clusters
2 parents fb12a8b + d7b7297 commit 40cf298

File tree

2 files changed

+75
-20
lines changed

2 files changed

+75
-20
lines changed

docs/book/src/SUMMARY_PREFIX.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
- [Using EKS Addons](./topics/eks/addons.md)
2121
- [Enabling Encryption](./topics/eks/encryption.md)
2222
- [Cluster Upgrades](./topics/eks/cluster-upgrades.md)
23-
- [Consuming Existing AWS Infrastructure](./topics/consuming-existing-aws-infrastructure.md)
23+
- [Bring Your Own AWS Infrastructure](./topics/bring-your-own-aws-infrastructure.md)
2424
- [Specifying the IAM Role to use for Management Components](./topics/specify-management-iam-role.md)
2525
- [Using external cloud provider with EBS CSI driver](./topics/external-cloud-provider-with-ebs-csi-driver.md)
2626
- [Restricting Cluster API to certain namespaces](./topics/restricting-cluster-api-to-certain-namespaces.md)

docs/book/src/topics/consuming-existing-aws-infrastructure.md renamed to docs/book/src/topics/bring-your-own-aws-infrastructure.md

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
1-
# Consuming Existing AWS Infrastructure
1+
# Bring Your Own AWS Infrastructure
22

3-
Normally, Cluster API will create infrastructure on AWS when standing up a new workload cluster. However, it is possible to have Cluster API re-use existing AWS infrastructure instead of creating its own infrastructure. Follow the instructions below to configure Cluster API to consume existing AWS infrastructure.
3+
Normally, Cluster API will create infrastructure on AWS when standing up a new workload cluster. However, it is possible to have Cluster API re-use external AWS infrastructure instead of creating its own infrastructure.
44

5-
## Prerequisites
5+
There are two possible ways to do this:
6+
* By consuming existing AWS infrastructure
7+
* By using externally managed AWS infrastructure
8+
> **IMPORTANT NOTE**: This externally managed AWS infrastructure should not be confused with EKS-managed clusters.
9+
10+
Follow the instructions below to configure Cluster API to consume existing AWS infrastructure.
11+
12+
## Consuming Existing AWS Infrastructure
13+
14+
### Overview
15+
16+
CAPA supports using existing AWS resources while creating AWS Clusters which gives flexibility to the users to bring their own existing resources into the cluster instead of creating new resources again.
17+
18+
Follow the instructions below to configure Cluster API to consume existing AWS infrastructure.
19+
20+
### Prerequisites
621

722
In order to have Cluster API consume existing AWS infrastructure, you will need to have already created the following resources:
823

@@ -22,7 +37,7 @@ If you want to use existing security groups, these can be specified and new ones
2237

2338
If you want to use an existing control load load balancer, specify its name.
2439

25-
## Tagging AWS Resources
40+
### Tagging AWS Resources
2641

2742
Cluster API itself does tag AWS resources it creates. The `sigs.k8s.io/cluster-api-provider-aws/cluster/<cluster-name>` (where `<cluster-name>` matches the `metadata.name` field of the Cluster object) tag, with a value of `owned`, tells Cluster API that it has ownership of the resource. In this case, Cluster API will modify and manage the lifecycle of the resource.
2843

@@ -32,7 +47,7 @@ However, the built-in Kubernetes AWS cloud provider _does_ require certain tags
3247

3348
Finally, if the controller manager isn't started with the `--configure-cloud-routes: "false"` parameter, the route table(s) will also need the `kubernetes.io/cluster/<cluster-name>` tag. (This parameter can be added by customizing the `KubeadmConfigSpec` object of the `KubeadmControlPlane` object.)
3449

35-
## Configuring the AWSCluster Specification
50+
### Configuring the AWSCluster Specification
3651

3752
Specifying existing infrastructure for Cluster API to use takes place in the specification for the AWSCluster object. Specifically, you will need to add an entry with the VPC ID and the IDs of all applicable subnets into the `network` field. Here is an example:
3853

@@ -59,7 +74,7 @@ spec:
5974
6075
When you use `kubectl apply` to apply the Cluster and AWSCluster specifications to the management cluster, Cluster API will use the specified VPC ID and subnet IDs, and will not create a new VPC, new subnets, or other associated resources. It _will_, however, create a new ELB and new security groups.
6176

62-
## Placing EC2 Instances in Specific AZs
77+
### Placing EC2 Instances in Specific AZs
6378

6479
To distribute EC2 instances across multiple AZs, you can add information to the Machine specification. This is optional and only necessary if control over AZ placement is desired.
6580

@@ -81,7 +96,7 @@ spec:
8196

8297
Note that all replicas within a MachineDeployment will reside in the same AZ.
8398

84-
## Placing EC2 Instances in Specific Subnets
99+
### Placing EC2 Instances in Specific Subnets
85100

86101
To specify that an EC2 instance should be placed in a specific subnet, add this to the AWSMachine specification:
87102

@@ -103,7 +118,7 @@ spec:
103118

104119
Users may either specify `failureDomain` on the Machine or MachineDeployment objects, _or_ users may explicitly specify subnet IDs on the AWSMachine or AWSMachineTemplate objects. If both are specified, the subnet ID is used and the `failureDomain` is ignored.
105120

106-
## Security Groups
121+
### Security Groups
107122

108123
To use existing security groups for instances for a cluster, add this to the AWSCluster specification:
109124

@@ -130,7 +145,7 @@ spec:
130145
- ...
131146
```
132147

133-
## Control Plane Load Balancer
148+
### Control Plane Load Balancer
134149

135150
The cluster control plane is accessed through a Classic ELB. By default, Cluster API creates the Classic ELB. To use an existing Classic ELB, add its name to the AWSCluster specification:
136151

@@ -142,20 +157,60 @@ spec:
142157

143158
As control plane instances are added or removed, Cluster API will register and deregister them, respectively, with the Classic ELB.
144159

145-
<aside class="note warning">
160+
> **WARNING:** Using an existing Classic ELB is an advanced feature. **If you use an existing Classic ELB, you must correctly configure it, and attach subnets to it.**
161+
>
162+
>An incorrectly configured Classic ELB can easily lead to a non-functional cluster. We strongly recommend you let Cluster API create the Classic ELB.
146163

147-
<h1>Warning</h1>
164+
### Caveats/Notes
148165

149-
Using an existing Classic ELB is an advanced feature. **If you use an existing Classic ELB, you must correctly configure it, and attach subnets to it.**
166+
* When both public and private subnets are available in an AZ, CAPI will choose the private subnet in the AZ over the public subnet for placing EC2 instances.
167+
* If you configure CAPI to use existing infrastructure as outlined above, CAPI will _not_ create an SSH bastion host. Combined with the previous bullet, this means you must make sure you have established some form of connectivity to the instances that CAPI will create.
150168

151-
An incorrectly configured Classic ELB can easily lead to a non-functional cluster. We strongly recommend you let Cluster API create the Classic ELB.
169+
## Using Externally managed AWS Clusters
152170

153-
</aside>
171+
### Overview
154172

155-
## Caveats/Notes
173+
Alternatively, CAPA supports externally managed cluster infrastructure which is useful for scenarios where a different persona is managing the cluster infrastructure out-of-band(external system) while still wanting to use CAPI for automated machine management.
174+
Users can make use of existing AWSCluster CRDs in their externally managed clusters.
156175

157-
* When both public and private subnets are available in an AZ, CAPI will choose the private subnet in the AZ over the public subnet for placing EC2 instances.
158-
* If you configure CAPI to use existing infrastructure as outlined above, CAPI will _not_ create an SSH bastion host. Combined with the previous bullet, this means you must make sure you have established some form of connectivity to the instances that CAPI will create.
176+
### How to use externally managed clusters?
177+
178+
Users have to use `cluster.x-k8s.io/managed-by: "<name-of-system>"` annotation to depict that AWS resources are managed externally. If CAPA controllers come across this annotation in any of the AWS resources while reconciliation, then it will ignore the resource and not perform any reconciliation(including creating/modifying any of the AWS resources, or it's status).
159179
160-
Alternatively CAPA supports [externally managed cluster infrastructure](https://github.com/kubernetes-sigs/cluster-api/blob/10d89ceca938e4d3d94a1d1c2b60515bcdf39829/docs/proposals/20210203-externally-managed-cluster-infrastructure.md).
161-
If the `AWSCluster` resource includes a "cluster.x-k8s.io/managed-by" annotation then the [controller will skip any reconciliation](https://cluster-api.sigs.k8s.io/developer/providers/cluster-infrastructure.html#normal-resource).
180+
A predicate `ResourceIsNotExternallyManaged` is exposed by Cluster API which allows CAPA controllers to differentiate between externally managed vs CAPA managed resources. For example:
181+
```go
182+
c, err := ctrl.NewControllerManagedBy(mgr).
183+
For(&providerv1.InfraCluster{}).
184+
Watches(...).
185+
WithOptions(options).
186+
WithEventFilter(predicates.ResourceIsNotExternallyManaged(ctrl.LoggerFrom(ctx))).
187+
Build(r)
188+
if err != nil {
189+
return errors.Wrap(err, "failed setting up with a controller manager")
190+
}
191+
```
192+
The external system must provide all required fields within the spec of the AWSCluster and must adhere to the CAPI provider contract and set the AWSCluster status to be ready when it is appropriate to do so.
193+
194+
> **IMPORTANT NOTE**: Users should take care of skipping reconciliation in external controllers within mapping function while enqueuing requests. For example:
195+
> ```go
196+
> err := c.Watch(
197+
> &source.Kind{Type: &infrav1.AWSCluster{}},
198+
> handler.EnqueueRequestsFromMapFunc(func(a client.Object) []reconcile.Request {
199+
> if annotations.IsExternallyManaged(awsCluster) {
200+
> log.Info("AWSCluster is externally managed, skipping mapping.")
201+
> return nil
202+
> }
203+
> return []reconcile.Request{
204+
> {
205+
> NamespacedName: client.ObjectKey{Namespace: c.Namespace, Name: c.Spec.InfrastructureRef.Name},
206+
> },
207+
> }}))
208+
> if err != nil {
209+
> // handle it
210+
> }
211+
> ```
212+
213+
### Caveats
214+
Once the user has created externally managed AWSCluster, it is not allowed to convert it to CAPA managed cluster. However, converting from managed to externally managed is allowed.
215+
216+
User should only use this feature if their cluster infrastructure lifecycle management has constraints that the reference implementation does not support. See [user stories](https://github.com/kubernetes-sigs/cluster-api/blob/10d89ceca938e4d3d94a1d1c2b60515bcdf39829/docs/proposals/20210203-externally-managed-cluster-infrastructure.md#user-stories) for more details.

0 commit comments

Comments
 (0)