kubernetes/kops · error

reconcile is not supported with terraform

Error message

reconcile is not supported with terraform

What it means

RunReconcileCluster rejects the terraform target up front: `kops reconcile cluster` performs a sequence of live updates and rolling restarts against the running cluster, which is incompatible with generating terraform output. When CoreUpdateClusterOptions.Target is cloudup.TargetTerraform (i.e. `--target terraform` was effectively set) the command returns this error instead of running. It is an intentional, unconditional guard, not a runtime failure.

Source

Thrown at cmd/kops/reconcile_cluster.go:126

	// viper.BindPFlag("lifecycle-overrides", cmd.Flags().Lookup("lifecycle-overrides"))
	// viper.BindEnv("lifecycle-overrides", "KOPS_LIFECYCLE_OVERRIDES")
	// cmd.RegisterFlagCompletionFunc("lifecycle-overrides", completeLifecycleOverrides)
	// cmd.Flags().BoolVar(&options.Prune, "prune", options.Prune, "Delete old revisions of cloud resources that were needed during an upgrade")
	// cmd.Flags().BoolVar(&options.IgnoreKubeletVersionSkew, "ignore-kubelet-version-skew", options.IgnoreKubeletVersionSkew, "Setting this to true will force updating the kubernetes version on all instance groups, regardles of which control plane version is running")

	// cmd.Flags().BoolVar(&options.Reconcile, "reconcile", options.Reconcile, "Reconcile the cluster by rolling the control plane and nodes sequentially")

	return cmd
}

// ReconcileCluster updates the cluster to the desired state, including rolling updates where necessary.
// To respect skew policy, it updates the control plane first, then updates the nodes.
// "update" is probably now smart enough to automatically not update the control plane if it is already at the desired version,
// but we do it explicitly here to be clearer / safer.
func RunReconcileCluster(ctx context.Context, f *util.Factory, out io.Writer, options *ReconcileClusterOptions) error {
	c := &options.CoreUpdateClusterOptions
	if c.Target == cloudup.TargetTerraform {
		return fmt.Errorf("reconcile is not supported with terraform")
	}

	if !c.Yes {
		// A reconcile without --yes is the same as a dry run
		opt := *c
		if _, err := RunCoreUpdateCluster(ctx, f, out, &opt); err != nil {
			return err
		}
		return nil
	}

	fmt.Fprintf(out, "Updating control plane configuration\n")
	{
		opt := *c
		opt.InstanceGroupRoles = []string{
			string(kops.InstanceGroupRoleAPIServer),
			string(kops.InstanceGroupRoleControlPlane),
		}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Remove the terraform target (set Target to "direct" or leave it empty) in the ReconcileClusterOptions before calling RunReconcileCluster.
  2. If you need terraform-managed infrastructure, run `kops update cluster --target terraform` instead of reconcile, and apply the plan with terraform; use reconcile only for direct in-place updates.
  3. In wrapper scripts, ensure flags meant for `kops update` (especially --target) are not forwarded to `kops reconcile cluster`.
  4. If reconcile must support terraform in your workflow, file/upvote an upstream kOps feature request — it is explicitly unsupported today.

Example fix

// before
opt := &ReconcileClusterOptions{}
opt.CoreUpdateClusterOptions.Target = cloudup.TargetTerraform
err := RunReconcileCluster(ctx, f, out, opt) // "reconcile is not supported with terraform"
// after
opt := &ReconcileClusterOptions{}
opt.CoreUpdateClusterOptions.Target = "direct"
err := RunReconcileCluster(ctx, f, out, opt)
Defensive patterns

Strategy: validation

Validate before calling

if options.CoreUpdateClusterOptions.Target == cloudup.TargetTerraform {
    return errors.New("use `kops update cluster --target terraform` instead of reconcile")
}
err := RunReconcileCluster(ctx, f, out, options)

Try / catch

err := RunReconcileCluster(ctx, f, out, options)
if err != nil && strings.Contains(err.Error(), "reconcile is not supported with terraform") {
    // fall back to update flow for terraform users
    return RunCoreUpdateCluster(ctx, f, out, &options.CoreUpdateClusterOptions)
}
return err

Prevention

When it happens

Trigger: Invoking reconcile with a configuration whose update target is terraform — e.g. programmatically building ReconcileClusterOptions with CoreUpdateClusterOptions.Target = cloudup.TargetTerraform, or wrapping/reusing update flags that had `--target terraform` set. Note the reconcile CLI currently does not expose a --target flag, so this mainly occurs in code that embeds the options.

Common situations: Scripts or tooling that construct shared update options (defaulting Target to terraform) and then call RunReconcileCluster; refactored automation reusing the update command's flag set for reconcile; copying update-command invocation patterns (update --target terraform) onto the reconcile command.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/019ff55f78793454. Report an issue: GitHub.