Skip to content

Commit 91d6092

Browse files
authored
Merge pull request #3741 from Skarlso/suspend_asg_processes
Suspend and Resume ASG Processes
2 parents 13c0c2e + 2afb7e8 commit 91d6092

13 files changed

+633
-50
lines changed

config/crd/bases/infrastructure.cluster.x-k8s.io_awsmachinepools.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,37 @@ spec:
846846
type: string
847847
type: object
848848
type: array
849+
suspendProcesses:
850+
description: SuspendProcesses defines a list of processes to suspend
851+
for the given ASG. This is constantly reconciled. If a process is
852+
removed from this list it will automatically be resumed.
853+
properties:
854+
all:
855+
type: boolean
856+
processes:
857+
description: Processes defines the processes which can be enabled
858+
or disabled individually.
859+
properties:
860+
addToLoadBalancer:
861+
type: boolean
862+
alarmNotification:
863+
type: boolean
864+
azRebalance:
865+
type: boolean
866+
healthCheck:
867+
type: boolean
868+
instanceRefresh:
869+
type: boolean
870+
launch:
871+
type: boolean
872+
replaceUnhealthy:
873+
type: boolean
874+
scheduledActions:
875+
type: boolean
876+
terminate:
877+
type: boolean
878+
type: object
879+
type: object
849880
required:
850881
- awsLaunchTemplate
851882
- maxSize
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Suspend ASG Processes
2+
3+
- **Feature status:** Experimental
4+
- **Feature gate:** MachinePool=true
5+
6+
MachinePool allows users to manage many machines as a single entity. Infrastructure providers implement a separate CRD that handles infrastructure side of the feature.
7+
8+
## Suspend Processes
9+
10+
It's possible to suspend certain processes for ASG. The list of processes can be found [here](https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_SuspendProcesses.html).
11+
12+
To utilize this feature, simply denote the list of processes that are desired to be suspended.
13+
14+
```yaml
15+
---
16+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
17+
kind: AWSMachinePool
18+
metadata:
19+
name: capa-mp-0
20+
spec:
21+
minSize: 1
22+
maxSize: 10
23+
availabilityZones:
24+
- "${AWS_AVAILABILITY_ZONE}"
25+
awsLaunchTemplate:
26+
instanceType: "${AWS_CONTROL_PLANE_MACHINE_TYPE}"
27+
sshKeyName: "${AWS_SSH_KEY_NAME}"
28+
suspendProcesses:
29+
processes:
30+
launch: true
31+
alarmNotification: true
32+
azRebalance: true
33+
---
34+
```
35+
36+
## Resume Processes
37+
38+
If a service is desired to be resumed, simply remove it from the list of suspended processes. The reconciler will then
39+
resume any process that is not part of the desired suspended processes list.
40+
41+
```yaml
42+
---
43+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
44+
kind: AWSMachinePool
45+
metadata:
46+
name: capa-mp-0
47+
spec:
48+
minSize: 1
49+
maxSize: 10
50+
availabilityZones:
51+
- "${AWS_AVAILABILITY_ZONE}"
52+
awsLaunchTemplate:
53+
instanceType: "${AWS_CONTROL_PLANE_MACHINE_TYPE}"
54+
sshKeyName: "${AWS_SSH_KEY_NAME}"
55+
suspendProcesses:
56+
processes:
57+
launch: true
58+
---
59+
```
60+
61+
_Note_ that now `AlarmNotification` and `AZRebalance` will be resumed, but the reconciler will not try to suspend
62+
`Launch` again. So it doesn't incur additional expensive, redundant API calls.
63+
64+
## Optional `All`
65+
66+
An option is also provided to suspend all processes without having to set each of them to `true`. Simply use `all` like
67+
this:
68+
69+
```yaml
70+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
71+
kind: AWSMachinePool
72+
metadata:
73+
name: capa-mp-0
74+
spec:
75+
minSize: 1
76+
maxSize: 10
77+
availabilityZones:
78+
- "${AWS_AVAILABILITY_ZONE}"
79+
awsLaunchTemplate:
80+
instanceType: "${AWS_CONTROL_PLANE_MACHINE_TYPE}"
81+
sshKeyName: "${AWS_SSH_KEY_NAME}"
82+
suspendProcesses:
83+
all: true
84+
```
85+
86+
To exclude individual processes from `all` simply add them with value `false`:
87+
88+
```yaml
89+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
90+
kind: AWSMachinePool
91+
metadata:
92+
name: capa-mp-0
93+
spec:
94+
minSize: 1
95+
maxSize: 10
96+
availabilityZones:
97+
- "${AWS_AVAILABILITY_ZONE}"
98+
awsLaunchTemplate:
99+
instanceType: "${AWS_CONTROL_PLANE_MACHINE_TYPE}"
100+
sshKeyName: "${AWS_SSH_KEY_NAME}"
101+
suspendProcesses:
102+
all: true
103+
processes:
104+
launch: false
105+
```

exp/api/v1beta1/conversion.go

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
infrav1beta1 "sigs.k8s.io/cluster-api-provider-aws/api/v1beta1"
2222
infrav1 "sigs.k8s.io/cluster-api-provider-aws/api/v1beta2"
2323
infrav1exp "sigs.k8s.io/cluster-api-provider-aws/exp/api/v1beta2"
24+
utilconversion "sigs.k8s.io/cluster-api/util/conversion"
2425
"sigs.k8s.io/controller-runtime/pkg/conversion"
2526
)
2627

@@ -30,7 +31,17 @@ func (src *AWSMachinePool) ConvertTo(dstRaw conversion.Hub) error {
3031
if err := Convert_v1beta1_AWSMachinePool_To_v1beta2_AWSMachinePool(src, dst, nil); err != nil {
3132
return err
3233
}
33-
34+
35+
// Manually restore data.
36+
restored := &infrav1exp.AWSMachinePool{}
37+
if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok {
38+
return err
39+
}
40+
41+
if restored.Spec.SuspendProcesses != nil {
42+
dst.Spec.SuspendProcesses = restored.Spec.SuspendProcesses
43+
}
44+
3445
return nil
3546
}
3647

@@ -41,8 +52,8 @@ func (r *AWSMachinePool) ConvertFrom(srcRaw conversion.Hub) error {
4152
if err := Convert_v1beta2_AWSMachinePool_To_v1beta1_AWSMachinePool(src, r, nil); err != nil {
4253
return err
4354
}
44-
45-
return nil
55+
56+
return utilconversion.MarshalData(src, r)
4657
}
4758

4859
// ConvertTo converts the v1beta1 AWSMachinePoolList receiver to a v1beta2 AWSMachinePoolList.
@@ -75,7 +86,7 @@ func (r *AWSManagedMachinePool) ConvertFrom(srcRaw conversion.Hub) error {
7586
if err := Convert_v1beta2_AWSManagedMachinePool_To_v1beta1_AWSManagedMachinePool(src, r, nil); err != nil {
7687
return err
7788
}
78-
89+
7990
return nil
8091
}
8192

@@ -147,3 +158,20 @@ func Convert_v1beta1_Instance_To_v1beta2_Instance(in *infrav1beta1.Instance, out
147158
func Convert_v1beta2_AWSLaunchTemplate_To_v1beta1_AWSLaunchTemplate(in *infrav1exp.AWSLaunchTemplate, out *AWSLaunchTemplate, s apiconversion.Scope) error {
148159
return autoConvert_v1beta2_AWSLaunchTemplate_To_v1beta1_AWSLaunchTemplate(in, out, s)
149160
}
161+
162+
func Convert_v1beta1_AWSMachinePoolSpec_To_v1beta2_AWSMachinePoolSpec(in *AWSMachinePoolSpec, out *infrav1exp.AWSMachinePoolSpec, s apiconversion.Scope) error {
163+
return autoConvert_v1beta1_AWSMachinePoolSpec_To_v1beta2_AWSMachinePoolSpec(in, out, s)
164+
}
165+
166+
func Convert_v1beta2_AWSMachinePoolSpec_To_v1beta1_AWSMachinePoolSpec(in *infrav1exp.AWSMachinePoolSpec, out *AWSMachinePoolSpec, s apiconversion.Scope) error {
167+
return autoConvert_v1beta2_AWSMachinePoolSpec_To_v1beta1_AWSMachinePoolSpec(in, out, s)
168+
}
169+
170+
func Convert_v1beta1_AutoScalingGroup_To_v1beta2_AutoScalingGroup(in *AutoScalingGroup, out *infrav1exp.AutoScalingGroup, s apiconversion.Scope) error {
171+
return autoConvert_v1beta1_AutoScalingGroup_To_v1beta2_AutoScalingGroup(in, out, s)
172+
}
173+
174+
func Convert_v1beta2_AutoScalingGroup_To_v1beta1_AutoScalingGroup(in *infrav1exp.AutoScalingGroup, out *AutoScalingGroup, s apiconversion.Scope) error {
175+
// explicitly ignore CurrentlySuspended.
176+
return autoConvert_v1beta2_AutoScalingGroup_To_v1beta1_AutoScalingGroup(in, out, s)
177+
}

exp/api/v1beta1/zz_generated.conversion.go

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

0 commit comments

Comments
 (0)