kubevela/terraform-controller

Have configuration resources A and B that both configure the same backend,when configuration resource A is deleted, if there are other configuration resources like B referencing this backend, the terraformDestroy method should not be executed.

wujiuye opened this issue · 14 comments

When we try to specify a backend for a configuration resource, due to the controller not performing duplicate validation, suppose we have configuration resources A and B that both configure the same backend. After apply A, the infrastructure is provisioned successfully, and the tfstate is generated. When apply B, it will not request new infrastructure resources, and the tfstate is shared. However, if either A or B is deleted, it will lead to the removal of the underlying infrastructure resources, and the other configuration resource will not be aware of this.

We use the same backend for the following reason: Since kubevela does not support a shared-resources-like strategy for infrastructure components sharing, we use specifying the same backend for components to achieve infrastructure sharing among applications.

The expected result is: If the terraform-controller does not perform uniqueness validation on the backend, we expect that when configuration resource A is deleted, if there are other configuration resources like B referencing this backend, the terraformDestroy method should not be executed.

Then how to deal with the Configuration which has been marked as deleted (by set DeleteTimestamp)?

The Configuration resource is deleted normally, but if there are other Configuration resources that reference the same Backend, the terraformDestroy logic is skipped and only the resources other than tfstate are cleaned up.

So if we create the same configuration again, how this behavior will effect the consistency? Is is possible to patially delete the state in the backend?

If a newly created configuration references an existing backend (configured by other configurations), then the terraform apply executed by the newly created configuration will actually do nothing because it uses the existing tfstate for execution. If the input parameters are different, it can indeed lead to consistency issues, but the users who use it should be aware of how to handle them. Just like allowing users to specify a backend, users should be aware of the issues they may face when using the same backend.

How do you think if we disallow user to specify the same backend as others. By adding a validation.

I agree with this approach:“By adding a validation”.

Reason: From the perspective of the terraform-controller, one configuration resource corresponds to the provisioning of one infrastructure resource. The backend should ideally be unique or isolated, and the tfstate of one configuration should not affect others.

The reason we proposed the shared backend approach is mainly because kubevela does not allow multiple apps to declare components with the same name, which means we cannot achieve our goal of sharing infrastructure components.

Can kubevela provide a strategy called "shared-component" and implement a reference counter, so that the shared component is only uninstalled after the last referencing application is uninstalled, similar to the "shared-resources" strategy?

The literal meaning of "shared-resources" is to share Kubernetes resource objects. However, kubevela only knows the corresponding Kubernetes resources after rendering the components. For the "user," when I write the application.yaml, I don't know what this component will be rendered into, which means I don't know the definition of the component. This creates a high barrier for users.

The concept of a "component" is from OAM. Users directly edit the OAM component, not the Kubernetes resource after the component is rendered. Therefore, I think it would be more appropriate to provide a strategy called "shared-component".

That's a good idea! I've convert it to a kubevela issue. Before "shared-component" I think adding validation to prevent user from creating the same Configuration is not reasonable because you want to share infra between apps.

I just realized specifying componentNames in shared-resource policy may solve your problem. Can you check that? @wujiuye

At the beginning, we also believed that, because the componentName is indeed the name of the configuration resource, many of our designs were based on this assumption. However, kubevela has a webhook that prevents us from using it in this way, so we only learned about "shared-resources". However, "shared-resources" is not suitable, so we ultimately changed our approach to using a shared backend.

This restriction has been removed.

Can you tell me from which version it started to be removed? We are currently using version 1.8.2.

I'm not sure the version. But it is removed. Check the release note please.

I just realized specifying componentNames in shared-resource policy may solve your problem. Can you check that? @wujiuye

I misunderstood your intention here. We have actually tried this approach, and the conclusion is that it doesn't work. My colleague also raised an issue regarding this matter: https://github.com/kubevela/kubevela/issues/6260