@@ -142,10 +142,11 @@ func (r *AWSMachineReconciler) getObjectStoreService(scope scope.S3Scope) servic
142142 return s3 .NewService (scope )
143143}
144144
145- // +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsmachines,verbs=get;list;watch;update;patch;delete
146- // +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsmachines/status,verbs=get;update;patch
147145// +kubebuilder:rbac:groups=controlplane.cluster.x-k8s.io,resources=*,verbs=get;list;watch
148- // +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=machines;machines/status,verbs=get;list;watch
146+ // +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsmachines,verbs=create;get;list;watch;update;patch;delete
147+ // +kubebuilder:rbac:groups=infrastructure.cluster.x-k8s.io,resources=awsmachines/status,verbs=get;update;patch
148+ // +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=machines,verbs=get;list;watch;delete
149+ // +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=machines/status,verbs=get;list;watch
149150// +kubebuilder:rbac:groups="",resources=secrets;,verbs=get;list;watch
150151// +kubebuilder:rbac:groups="",resources=namespaces,verbs=get;list;watch
151152// +kubebuilder:rbac:groups="",resources=events,verbs=get;list;watch;create;update;patch
@@ -458,6 +459,7 @@ func (r *AWSMachineReconciler) findInstance(machineScope *scope.MachineScope, ec
458459 return instance , nil
459460}
460461
462+ //nolint:gocyclo
461463func (r * AWSMachineReconciler ) reconcileNormal (_ context.Context , machineScope * scope.MachineScope , clusterScope cloud.ClusterScoper , ec2Scope scope.EC2Scope , elbScope scope.ELBScope , objectStoreScope scope.S3Scope ) (ctrl.Result , error ) {
462464 machineScope .Trace ("Reconciling AWSMachine" )
463465
@@ -481,7 +483,7 @@ func (r *AWSMachineReconciler) reconcileNormal(_ context.Context, machineScope *
481483 }
482484
483485 // Make sure bootstrap data is available and populated.
484- if machineScope .Machine .Spec .Bootstrap .DataSecretName == nil {
486+ if ! machineScope . IsMachinePoolMachine () && machineScope .Machine .Spec .Bootstrap .DataSecretName == nil {
485487 machineScope .Info ("Bootstrap data secret reference is not yet available" )
486488 conditions .MarkFalse (machineScope .AWSMachine , infrav1 .InstanceReadyCondition , infrav1 .WaitingForBootstrapDataReason , clusterv1 .ConditionSeverityInfo , "" )
487489 return ctrl.Result {}, nil
@@ -496,6 +498,12 @@ func (r *AWSMachineReconciler) reconcileNormal(_ context.Context, machineScope *
496498 conditions .MarkUnknown (machineScope .AWSMachine , infrav1 .InstanceReadyCondition , infrav1 .InstanceNotFoundReason , "%s" , err .Error ())
497499 return ctrl.Result {}, err
498500 }
501+ if instance == nil && machineScope .IsMachinePoolMachine () {
502+ err = errors .New ("no instance found for machine pool" )
503+ machineScope .Error (err , "unable to find instance" )
504+ conditions .MarkUnknown (machineScope .AWSMachine , infrav1 .InstanceReadyCondition , infrav1 .InstanceNotFoundReason , "%s" , err .Error ())
505+ return ctrl.Result {}, err
506+ }
499507
500508 // If the AWSMachine doesn't have our finalizer, add it.
501509 if controllerutil .AddFinalizer (machineScope .AWSMachine , infrav1 .MachineFinalizer ) {
@@ -585,9 +593,18 @@ func (r *AWSMachineReconciler) reconcileNormal(_ context.Context, machineScope *
585593 conditions .MarkTrue (machineScope .AWSMachine , infrav1 .InstanceReadyCondition )
586594 case infrav1 .InstanceStateShuttingDown , infrav1 .InstanceStateTerminated :
587595 machineScope .SetNotReady ()
588- machineScope .Info ("Unexpected EC2 instance termination" , "state" , instance .State , "instance-id" , * machineScope .GetInstanceID ())
589- r .Recorder .Eventf (machineScope .AWSMachine , corev1 .EventTypeWarning , "InstanceUnexpectedTermination" , "Unexpected EC2 instance termination" )
590- conditions .MarkFalse (machineScope .AWSMachine , infrav1 .InstanceReadyCondition , infrav1 .InstanceTerminatedReason , clusterv1 .ConditionSeverityError , "" )
596+
597+ if machineScope .IsMachinePoolMachine () {
598+ // In an auto-scaling group, instance termination is perfectly normal on scale-down
599+ // and therefore should not be reported as error.
600+ machineScope .Info ("EC2 instance of machine pool was terminated" , "state" , instance .State , "instance-id" , * machineScope .GetInstanceID ())
601+ r .Recorder .Eventf (machineScope .AWSMachine , corev1 .EventTypeNormal , infrav1 .InstanceTerminatedReason , "EC2 instance termination" )
602+ conditions .MarkFalse (machineScope .AWSMachine , infrav1 .InstanceReadyCondition , infrav1 .InstanceTerminatedReason , clusterv1 .ConditionSeverityInfo , "" )
603+ } else {
604+ machineScope .Info ("Unexpected EC2 instance termination" , "state" , instance .State , "instance-id" , * machineScope .GetInstanceID ())
605+ r .Recorder .Eventf (machineScope .AWSMachine , corev1 .EventTypeWarning , "InstanceUnexpectedTermination" , "Unexpected EC2 instance termination" )
606+ conditions .MarkFalse (machineScope .AWSMachine , infrav1 .InstanceReadyCondition , infrav1 .InstanceTerminatedReason , clusterv1 .ConditionSeverityError , "" )
607+ }
591608 default :
592609 machineScope .SetNotReady ()
593610 machineScope .Info ("EC2 instance state is undefined" , "state" , instance .State , "instance-id" , * machineScope .GetInstanceID ())
@@ -598,14 +615,18 @@ func (r *AWSMachineReconciler) reconcileNormal(_ context.Context, machineScope *
598615 }
599616
600617 // reconcile the deletion of the bootstrap data secret now that we have updated instance state
601- if deleteSecretErr := r .deleteBootstrapData (machineScope , clusterScope , objectStoreScope ); deleteSecretErr != nil {
602- r .Log .Error (deleteSecretErr , "unable to delete secrets" )
603- return ctrl.Result {}, deleteSecretErr
604- }
618+ if ! machineScope .IsMachinePoolMachine () {
619+ if deleteSecretErr := r .deleteBootstrapData (machineScope , clusterScope , objectStoreScope ); deleteSecretErr != nil {
620+ r .Log .Error (deleteSecretErr , "unable to delete secrets" )
621+ return ctrl.Result {}, deleteSecretErr
622+ }
605623
606- if instance .State == infrav1 .InstanceStateTerminated {
607- machineScope .SetFailureReason ("UpdateError" )
608- machineScope .SetFailureMessage (errors .Errorf ("EC2 instance state %q is unexpected" , instance .State ))
624+ // For machine pool machines, it is expected that the ASG terminates instances at any time,
625+ // so no error is logged for those.
626+ if instance .State == infrav1 .InstanceStateTerminated {
627+ machineScope .SetFailureReason ("UpdateError" )
628+ machineScope .SetFailureMessage (errors .Errorf ("EC2 instance state %q is unexpected" , instance .State ))
629+ }
609630 }
610631
611632 // tasks that can take place during all known instance states
@@ -875,9 +896,13 @@ func getIgnitionVersion(scope *scope.MachineScope) string {
875896}
876897
877898func (r * AWSMachineReconciler ) deleteBootstrapData (machineScope * scope.MachineScope , clusterScope cloud.ClusterScoper , objectStoreScope scope.S3Scope ) error {
878- _ , userDataFormat , err := machineScope .GetRawBootstrapDataWithFormat ()
879- if client .IgnoreNotFound (err ) != nil {
880- return errors .Wrap (err , "failed to get raw userdata" )
899+ var userDataFormat string
900+ var err error
901+ if machineScope .Machine .Spec .Bootstrap .DataSecretName != nil {
902+ _ , userDataFormat , err = machineScope .GetRawBootstrapDataWithFormat ()
903+ if client .IgnoreNotFound (err ) != nil {
904+ return errors .Wrap (err , "failed to get raw userdata" )
905+ }
881906 }
882907
883908 if machineScope .UseSecretsManager (userDataFormat ) {
0 commit comments