Skip to content

Immutable fields broken under certain operations #1543

@embano1

Description

@embano1

As per a discussion with @a-hilaly and @jaypipes here's a description of how immutable fields are currently broken under some circumstances and what we should do to fix them on the long term.

Describe the bug

Scenario: As a user, I want to make the name field of my resource immutable after object creation in the Kubernetes API.
Example:

resources:
  EventBus:
    fields:
      Name:
        is_immutable: true

When I do kubectl edit eventbus ... and change the name I was expecting that the controller sets a terminal condition because an immutable field change has been detected (the field code change detection is actually generated correctly).

However, what happens is that sdk.ReadOne makes a DescribeResource call with spec.name as input, which of course returns ResourceNotFoundException because that resource does not exist. That leads to the code entering the Create path instead of failing during Update. A new resource is created with that new spec.name and the result is zombie resources in AWS (the old resource), i.e. resource leaks.

{"level":"debug","ts":"2022-11-08T14:51:24.907+0100","logger":"ackrt","msg":">> rm.ReadOne","account":"331505801289","role":"","region":"eu-central-1","kind":"Rule","namespace":"default","name":"rule-01","is_adopted":false,"generation":2}
{"level":"debug","ts":"2022-11-08T14:51:24.907+0100","logger":"ackrt","msg":">>> rm.sdkFind","account":"331505801289","role":"","region":"eu-central-1","kind":"Rule","namespace":"default","name":"rule-01","is_adopted":false,"generation":2}
{"level":"debug","ts":"2022-11-08T14:51:25.021+0100","logger":"ackrt","msg":"<<< rm.sdkFind","account":"331505801289","role":"","region":"eu-central-1","kind":"Rule","namespace":"default","name":"rule-01","is_adopted":false,"generation":2,"error":"resource not found"}
{"level":"debug","ts":"2022-11-08T14:51:25.021+0100","logger":"ackrt","msg":"<< rm.ReadOne","account":"331505801289","role":"","region":"eu-central-1","kind":"Rule","namespace":"default","name":"rule-01","is_adopted":false,"generation":2,"error":"resource not found"}
{"level":"debug","ts":"2022-11-08T14:51:25.021+0100","logger":"ackrt","msg":">> r.createResource","account":"331505801289","role":"","region":"eu-central-1","kind":"Rule","namespace":"default","name":"rule-01","is_adopted":false,"generation":2}

Steps to reproduce

See above.

Expected outcome

The controller should respect field immutability.

Environment

Every ACK/K8s/Resource version is affected.

Solution

Because the way controller runtime (and as such code gen in ACK) works (level-triggered vs. edge), we do not have access to any previous state during Reconcile() (unless we perform list operations against K8s and AWS control planes, which is very expensive for such a feature and has edges with caching and consistency/concurrency).

A common approach is validation webhooks in the admission chain as here we have access to the current and desired state. Since Kubernetes v1.25 an alternative solution is available though using CRD Validation Rules (beta):

The CEL expression is a one-liner: self == oldSelf | Validate that a required field is immutable once it is set

Going forward, ACK should generate both, an admission controller (for Kubernetes <1.25) but also CRD CEL expressions (older K8s API servers simply ignore this new object). A Helm chart can have logic to deploy the validation webhook in K8s versions <1.25.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/code-generationIssues or PRs as related to controllers or docs code generationhelp wantedDenotes an issue that needs help from a contributor. Must meet "help wanted" guidelines.kind/enhancementCategorizes issue or PR as related to existing feature enhancements.lifecycle/frozenIndicates that an issue or PR should not be auto-closed due to staleness.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions