terraform-provider-awscc icon indicating copy to clipboard operation
terraform-provider-awscc copied to clipboard

JSON Patch remove operations should consider and predict the item location on the list

Open wellsiau-aws opened this issue 4 months ago • 5 comments

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment
  • The resources and data sources in this provider are generated from the CloudFormation schema, so they can only support the actions that the underlying schema supports. For this reason submitted bugs should be limited to defects in the generation and runtime code of the provider. Customizing behavior of the resource, or noting a gap in behavior are not valid bugs and should be submitted as enhancements to AWS via the CloudFormation Open Coverage Roadmap.

Description

AWSCC uses JSON patch to create delta changes between old and new state.

In the event when the new state will remove certain items for Attribute list, then it will produce multiple patch document such as:

## in this example, the patch will remove Tags on index 0, 4 and 6
[
  {"op":"remove","path":"/Tags/0"},
  {"op":"remove","path":"/Tags/4"},
  {"op":"remove","path":"/Tags/6"}
]

In the AWS Cloud Control API (CCAPI), the patch operations is applied sequentially in the order that they appear in the patch document. Ref

As such, the patch document sent by the AWSCC provider to the CCAPI should be aware of relative positions of each item after subsequent patch operations.

Now imagine a situation where we have resource as follow

Resource before changes

resource "awscc_s3_bucket" "example" {
  bucket_name = "exmaple-bucket-202410231857"
  tags = [
    {
    key   = "Name"
    value = "My bucket"
    },
    {
      key   = "Environment"
      value = "Dev"
    },
    {
      key   = "Modified By"
      value = "AWSCC"
    },
    {
      key   = "Department"
      value = "Engineering"
    },
    {
      key   = "Project"
      value = "wellsiau"
    },
    {
      key   = "Owner"
      value = "wellsiau"
    },
    {
      key   = "Managed By"
      value = "Terraform"
    }
  ]
}

Resource after changes

And let's assume we will remove / comment the first 3 tags

resource "awscc_s3_bucket" "example" {
  bucket_name = "exmaple-bucket-202410231857"
  tags = [
    # {
    # key   = "Name"
    # value = "My bucket"
    # },
    # {
    #   key   = "Environment"
    #   value = "Dev"
    # },
    # {
    #   key   = "Modified By"
    #   value = "AWSCC"
    # },
    {
      key   = "Department"
      value = "Engineering"
    },
    {
      key   = "Project"
      value = "wellsiau"
    },
    {
      key   = "Owner"
      value = "wellsiau"
    },
    {
      key   = "Managed By"
      value = "Terraform"
    }
  ]
}

State file before changes

And assume the current state file as follows (redacted for brevity). Noticed that the order of the tags are a bit different from the HCL.

      "instances": [
        {
          "schema_version": 1,
          "attributes": {
            "bucket_name": "exmaple-bucket-202410231857",
            . . .
            "tags": [
              {
                "key": "Modified By",
                "value": "AWSCC"
              },
              {
                "key": "Project",
                "value": "wellsiau"
              },
              {
                "key": "Department",
                "value": "Engineering"
              },
              {
                "key": "Owner",
                "value": "wellsiau"
              },
              {
                "key": "Environment",
                "value": "Dev"
              },
              {
                "key": "Managed By",
                "value": "Terraform"
              },
              {
                "key": "Name",
                "value": "My bucket"
              }
            ],
            "versioning_configuration": null,
            "website_configuration": null,
            "website_url": "http://exmaple-bucket-202410231857.s3-website-us-east-1.amazonaws.com"
          },
          "sensitive_attributes": []
        }
      ]
    }
  ],

Order of patch operations

Using the earlier example of the patch order:

[
  {"op":"remove","path":"/Tags/0"},
  {"op":"remove","path":"/Tags/4"},
  {"op":"remove","path":"/Tags/6"}
]
  1. After the first patch operation completed ( {"op":"remove","path":"/Tags/0"} ) there are only 5 Tags remaining in the list.
  2. After the second patch operations completed ( {"op":"remove","path":"/Tags/4"} ), there are only 4 tags remaining in the list.
  3. The third patch operations will fail due to index out of bounds ( {"op":"remove","path":"/Tags/6"})

Example error logs:

awscc_s3_bucket.example: Modifying... [id=exmaple-bucket-202410231857]
╷
│ Error: AWS SDK Go Service Operation Unsuccessful
│ 
│   with awscc_s3_bucket.example,
│   on main.tf line 1, in resource "awscc_s3_bucket" "example":
│    1: resource "awscc_s3_bucket" "example" {
│ 
│ Calling Cloud Control API service UpdateResource operation returned: operation error CloudControl: UpdateResource, https response error StatusCode: 400, RequestID:
│ 87fdad5d-54d2-4890-bc39-8772b8b7d696, api error ValidationException: index Out of bound, index is greater than 4

New or Affected Resource(s)

  • All resources

References

  • #0000

wellsiau-aws avatar Oct 24 '24 05:10 wellsiau-aws