After external resource is created, changes to `initProvider` shouldn't take effect
- Dominant language
- Go
- Stars
- 481
- Forks
- 131
- Avg merge
- 2d 1h
- Merged PRs (30d)
- 11
Description
Note: This issue was [originally reported in provider-aws repository](https://github.com/upbound/provider-aws/issues/946).
### What happened?
I discovered this bug, while working on supporting management policies in [no-fork external client](https://github.com/upbound/provider-aws/pull/938). To summarize, changes to `initProvider` after resource has been created take effect, in certain circumstances, contrary to [`initProvider`'s documented behavior](https://github.com/crossplane/docs/blob/c819ac2ce3b4c212553a09bc9907486cc73d869a/content/v1.13/concepts/managed-resources.md?plain=1#L277-L279).
### How can we reproduce it?
1. Create an AWS VPC resource with the following configuration:
```yaml
apiVersion: ec2.aws.upbound.io/v1beta1
kind: VPC
metadata:
name: test-initprovider-bug
spec:
initProvider:
cidrBlock: 172.16.0.0/16
tags:
foo: bar
forProvider:
region: us-west-1
tags:
Name: test-initprovider-bug
```
2. [From AWS Console](https://us-west-1.console.aws.amazon.com/vpcconsole/home?region=us-west-1#vpcs:search=test-initprovider;tag:crossplane-name=test-initprovider-bug), verify that resource has been created with tag “foo”.
3. Apply the following configuration that removes `initProvider.tags` from the initial configuration:
```yaml
apiVersion: ec2.aws.upbound.io/v1beta1
kind: VPC
metadata:
name: test-initprovider-bug
spec:
initProvider:
cidrBlock: 172.16.0.0/16
forProvider:
region: us-west-1
tags:
Name: test-initprovider-bug
```
4. [From AWS Console](https://us-west-1.console.aws.amazon.com/vpcconsole/home?region=us-west-1#vpcs:search=test-initprovider;tag:crossplane-name=test-initprovider-bug), verify that tag “foo” has been deleted from external resource. Expected behavior is to have no changes, i.e., still have tag “foo”.
The problem is because of how Terraform's [`ignore_changes` is computed](https://github.com/crossplane/upjet/blob/main/pkg/terraform/files.go#L85). `ignore_changes` consists of fields exclusive to `initProvider`. If a field doesn't exist in `initProvider` — `tags.foo` in the above example — it cannot be added to `ignore_changes`.
Given how `initProvider` is designed to work, handling such cases seems to be difficult. We might consider an update to the design, so as to allow leaving ownership of a field to external controllers.
Note that if we had removed `cidrBlock`, instead of `tags.foo`, in the example above, `cidrBlock` wouldn't have been deleted from the external resource — conforming to documented behavior. I'm not sure why, but one explanation could be that Terraform doesn't detect drift, because local configuration doesn't specify any value for `cidrBlock`. The fact that `cidrBlock` is a top-level field, as opposed to `tags.foo`, could also be important.
### What environment did it happen in?
* Crossplane Version: 1.13.2-up.1
* Provider Version: main (a0bfa2617ad5d497d727df0be31c774667a94936)
* Kubernetes Version: v1.26.0
* Kubernetes Distribution: kind
Contributor guide
Assessment
This issue has not been assessed yet.