Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Immutable fields should reject changes #78

Open
muvaf opened this issue Aug 24, 2022 · 7 comments
Open

Immutable fields should reject changes #78

muvaf opened this issue Aug 24, 2022 · 7 comments
Assignees
Labels
enhancement New feature or request is:triaged
Milestone

Comments

@muvaf
Copy link
Member

muvaf commented Aug 24, 2022

What problem are you facing?

Terraform has ForceNew attribute on fields that represents the immutability but we don't account it at the moment. Changing those fields causes Terraform errors that don't really seem to be related since TF tries to re-create the resource for changes in those fields.

How could Terrajet help solve your problem?

We can invest in crossplane/crossplane-tools#40 and then add that marker to the fields, similar to how we generate reference resolvers. Though it's also worth investigating whether Common Expression Language (CEL) stuff merged in upstream would help here. Though that may require kubebuilder changes since it requires changes on the CRD manifests.

@muvaf muvaf added the enhancement New feature or request label Aug 24, 2022
@luebken
Copy link

luebken commented Aug 24, 2022

Re CEL and Validation Rules: I found this upcoming blogpost informative.

@muvaf
Copy link
Member Author

muvaf commented Aug 30, 2022

Another one specifically about immutability. We might be able to get away with a kubebuilder marker but we need to be sure about the semantics. Specifically, nil values should not be considered immutable till a value is assigned. kubernetes/website#36032

@ulucinar
Copy link
Collaborator

ulucinar commented Sep 9, 2022

@muvaf
Copy link
Member Author

muvaf commented Apr 20, 2023

Adding the following is now supported in kubebuilder. Should be straight-forward to add this to our code gen pipeline.

// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"

https://kubernetes.io/blog/2022/09/29/enforce-immutability-using-cel/

@Hronom
Copy link

Hronom commented Jun 20, 2023

Hello, we need what described here crossplane/terrajet#158 (comment)
basically lifecycle.prevent_destroy

@jrote1
Copy link

jrote1 commented Oct 9, 2023

Hi, is there any update on this?

@jeanduplessis
Copy link
Collaborator

@jrote1 there are no plans to invest in this right now. The Upbound team is focused on improving the performance at the moment and won't be able to look at this in the near term. If someone is interested in picking this up, we would happily support them.

For posterity, here's a high-level overview of the situation:

Terraform marks certain configuration arguments in its schema as ForceNew. In that case, if the argument's value in the Terraform configuration differs from what's available in the Terraform state, the plan generator generates a plan in which the existing external resource is deleted and a new one with the desired argument value is provisioned, and hence forces a new resource to satisfy the new desired state.

Crossplane providers, by convention (referring to the Crossplane Resource Model), never delete external resources unless the corresponding MR is deleted under an appropriate management policy. So in the Terraform configurations that we generate while reconciling the managed resources, we unconditionally include the prevent-destroy lifecycle meta-argument to prevent Terraform from destroying the existing external resource and provisioning a new one.

However, the API server does not know anything about those parameters with the underlying ForceNew indication in the corresponding resource and thus accepts modifications to those spec.forProvider parameters. This results in the Terraform layer complaining with a cryptic `a change to this field has been requested but I cannot do it because of the prevent-destroy lifecycle meta-argument) message.

A possible solution is to add some validation rules to the (generated) OpenAPI v3 schema of the CRDs that will ask the API server to reject changes to such fields if they have already been set.

We can also consider improving the error reported in status conditions (and elsewhere) by explaining that the field should be treated as an immutable one (by parsing the error message from the Terraform layer).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request is:triaged
Projects
None yet
Development

No branches or pull requests

6 participants