crossplane-contrib / provider-upjet-aws

AWS Provider for Crossplane.
https://marketplace.upbound.io/providers/upbound/provider-family-aws/
Apache License 2.0
146 stars 123 forks source link

[Bug]: API Gateway Deployment: refuse to update the external resource because the following update requires replacing it #1432

Open marmol-dev opened 3 months ago

marmol-dev commented 3 months ago

Is there an existing issue for this?

Affected Resource(s)

Resource MRs required to reproduce the bug

apiVersion: apigateway.aws.upbound.io/v1beta1
kind: RestAPI
metadata:
  labels:
    api: int-sandbox-dev-demo
  name: int-sandbox-dev-demo
spec:
  forProvider:
    body: >-
      ${jsonencode({
          openapi = "3.0.1"
          info = {
            title   = "demo"
            version = "1.0"
          }
          paths = {}

        })}
    name: int-sandbox-dev-demo
    region: eu-west-3
---
apiVersion: apigateway.aws.upbound.io/v1beta1
kind: Deployment
metadata:
  labels:
    deployment: int-sandbox-dev-demo
  name: int-sandbox-dev-demo
spec:
  forProvider:
    region: eu-west-3
    restApiIdSelector:
      matchLabels:
        api: int-sandbox-dev-demo
    triggers:
      version: "1"
---
apiVersion: apigateway.aws.upbound.io/v1beta1
kind: Stage
metadata:
  labels:
    stage: int-sandbox-dev-demo
  name: int-sandbox-dev-demo
spec:
  forProvider:
    region: eu-west-3
    restApiIdSelector:
      matchLabels:
        api: int-sandbox-dev-demo
    stageName: int-sandbox-dev-demo
    deploymentIdSelector:
      matchLabels:
        deployment: int-sandbox-dev-demo

Steps to Reproduce

  1. Deploy the submited MRs: kubectl apply resources.yaml
  2. Change the deployment trigger's field: version: "2"
  3. Deploy the MRs: 'kubectl apply resources.yaml`

What happened?

The Deployment MR is expected to reconcile with AWS but a error is obtained: refuse to update the external resource because the following update requires replacing it: cannot change the value of the argument "triggers.version" from "1" to "2"

I expect that the trigger property of the Deployment MR works exactly doing this: force a replacement of the underlying Terraform and AWS resource.

Relevant Error Output Snippet

Conditions:
    Last Transition Time:  2024-08-01T08:55:43Z
    Reason:                Available
    Status:                True
    Type:                  Ready
    Last Transition Time:  2024-08-01T08:56:16Z
    Message:               update failed: async update failed: refuse to update the external resource because the following update requires replacing it: cannot change the value of the argument "triggers.version" from "1" to "2"
    Reason:                ReconcileError
    Status:                False
    Type:                  Synced
    Last Transition Time:  2024-08-01T08:56:16Z
    Message:               async update failed: refuse to update the external resource because the following update requires replacing it: cannot change the value of the argument "triggers.version" from "1" to "2"
    Reason:                AsyncUpdateFailure
    Status:                False 
    Type:                  LastAsyncOperation
Events:
  Type     Reason                        Age               From                                                        Message
  ----     ------                        ----              ----                                                        -------
  Normal   CreatedExternalResource       43s               managed/apigateway.aws.upbound.io/v1beta1, kind=deployment  Successfully requested creation of external resource
  Normal   UpdatedExternalResource       9s                managed/apigateway.aws.upbound.io/v1beta1, kind=deployment  Successfully requested update of external resource
  Warning  CannotUpdateExternalResource  2s (x10 over 9s)  managed/apigateway.aws.upbound.io/v1beta1, kind=deployment  async update failed: refuse to update the external resource because the following update requires replacing it: cannot change the value of the argument "triggers.version" from "1" to "2"

Crossplane Version

1.16.0

Provider Version

1.9.0

Kubernetes Version

v1.30.2-eks-db838b0

Kubernetes Distribution

EKS

Additional Info

The reason I use "triggers" is to create a new Deployment on AWS with the changes of the RestAPI resource. I want to simulate the "Deploy" button on the AWS console.

blakeromano commented 3 months ago

I don't think this is a bug from what I understand...

Crossplane Providers will not update a resource if it requires a re-creation (or at least in my experience upjet ones do not for sure). I think you'd have to create a new resource, then delete this resource (or however TF deals with replacements of this resource assuming you feel that makes sense).

marmol-dev commented 3 months ago

Thanks @blakeromano , I understand the challenge for Crossplane with recreation.

But, what is the purpose of the "triggers" attribute of "deployment.apigateway.aws.upbound.io/v1beta1" ? It will always force recreation when it changes.

blakeromano commented 3 months ago

I am not an API Gateway expert by assumption is a deployment is essentially "immutable" where once you create a deployment your path forward is to create a new deployment not update existing. Upjet providers use Terraform under the hood with some customizations to make it K8s native so there's other resources which are pretty "immutable" that you can deploy with Crossplane.

github-actions[bot] commented 1 week ago

This provider repo does not have enough maintainers to address every issue. Since there has been no activity in the last 90 days it is now marked as stale. It will be closed in 14 days if no further activity occurs. Leaving a comment starting with /fresh will mark this issue as not stale.