diff --git a/api/v1alpha2/terraform_types.go b/api/v1alpha2/terraform_types.go index 9998bda2b..599a235e6 100644 --- a/api/v1alpha2/terraform_types.go +++ b/api/v1alpha2/terraform_types.go @@ -286,6 +286,12 @@ type Remediation struct { // retries. // +optional Retries int64 `json:"retries,omitempty"` + + // RemediateLastFailure tells the controller to remediate the last failure, when + // no retries remain. Defaults to 'false' unless 'Retries' is greater than 0. + // +optional + RemediateLastFailure *bool `json:"remediateLastFailure,omitempty"` + } type CloudSpec struct { @@ -954,6 +960,15 @@ func (in *Terraform) GetRetries() int64 { return in.Spec.Remediation.Retries } +// MustRemediateLastFailure returns whether to remediate the last failure when +// no retries remain. +func (in *Terraform) MustRemediateLastFailure() bool { + if in.Spec.Remediation.RemediateLastFailure == nil { + return false + } + return *in.Spec.Remediation.RemediateLastFailure +} + func (in *Terraform) GetReconciliationFailures() int64 { return in.Status.ReconciliationFailures } diff --git a/charts/tofu-controller/crds/crds.yaml b/charts/tofu-controller/crds/crds.yaml index 2f6cd7245..0921dc607 100644 --- a/charts/tofu-controller/crds/crds.yaml +++ b/charts/tofu-controller/crds/crds.yaml @@ -5581,6 +5581,12 @@ spec: retries. format: int64 type: integer + remediateLastFailure: + default: false + description: |- + remediateLastFailure instructs the controller to remediate the last failure + when no retries remain. Defaults to false + type: boolean type: object retryInterval: description: |- diff --git a/controllers/tf_controller.go b/controllers/tf_controller.go index a6ee7ef6e..9665efc03 100644 --- a/controllers/tf_controller.go +++ b/controllers/tf_controller.go @@ -443,6 +443,16 @@ func (r *TerraformReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( terraform.GetGeneration(), )) + if terraform.MustRemediateLastFailure() { + log.Info("RemediateLastFailure is true, reseting retries, requeue after interval", "interval", terraform.Spec.Interval.Duration.String()) + terraform = infrav1.TerraformResetRetry(terraform) + if err := r.patchStatus(ctx, req.NamespacedName, terraform.Status); err != nil { + log.Error(err, "unable to update status after maximum number of retries reached") + return ctrl.Result{Requeue: true}, err + } + return ctrl.Result{RequeueAfter: terraform.Spec.Interval.Duration}, nil + } + terraform = infrav1.TerraformReachedLimit(terraform) traceLog.Info("Patch the status of the Terraform resource") diff --git a/docs/References/terraform.md b/docs/References/terraform.md index b447fe30a..560e05679 100644 --- a/docs/References/terraform.md +++ b/docs/References/terraform.md @@ -702,6 +702,19 @@ before bailing. Defaults to ‘0’, a negative integer denotes unlimite retries.

+ + +remediateLastFailure
+ +bool + + + +(Optional) +

RemediateLastFailure tells the controller to remediate the last failure, when +no retries remain. Defaults to ‘false’ unless ‘Retries’ is greater than 0.

+ +