hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.86k stars 9.21k forks source link

[Bug]: aws_api_gateway_rest_api.body ignores x-amazon-apigateway-policy changes #38515

Open t0yv0 opened 4 months ago

t0yv0 commented 4 months ago

Terraform Core Version

1.6.3

AWS Provider Version

5.9.0

Affected Resource(s)

Expected Behavior

When updating x-amazon-apigateway-policy inside body, expect the policy output and the cloud state to get updated accordingly.

Actual Behavior

When updating x-amazon-apigateway-policy inside body, body gets updated but the cloud state and policy are retained from the previous state.

Relevant Error/Panic Output Snippet

No errors or panics

Terraform Configuration Files

infra.tf:

resource "aws_api_gateway_rest_api" "example" {
  body = file("${path.module}/policy.json") # change this to policy2.json for step2
  name = "example"
  endpoint_configuration {
    types = ["REGIONAL"]
  }
}

policy.json:

{
  "openapi": "3.0.3",
  "info": {
    "title": "test-api",
    "version": "0.1.0"
  },
  "paths": {
    "/test": {
      "post": {
        "responses": {
          "200": {
            "description": "200 response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccesfulReturn"
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorModel"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "SuccesfulReturn": {
        "type": "object",
        "required": [
          "message",
          "body",
          "statusCode"
        ],
        "properties": {
          "message": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "statusCode": {
            "type": "integer",
            "minimum": 200,
            "maximum": 300,
            "default": 200
          }
        }
      },
      "ErrorModel": {
        "type": "object",
        "required": [
          "message",
          "statusCode"
        ],
        "properties": {
          "message": {
            "type": "string"
          },
          "statusCode": {
            "type": "integer",
            "minimum": 100,
            "maximum": 600,
            "default": 500
          }
        }
      }
    }
  },
  "x-amazon-apigateway-policy": {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Deny",
        "Action": "execute-api:Invoke",
        "Resource": "execute-api:/*/POST/*",
        "Principal": {
          "AWS": "*"
        },
        "Condition": {
          "NotIpAddress": {
            "aws:SourceIp": "10.0.0.3"
          }
        }
      },
      {
        "Effect": "Allow",
        "Action": "execute-api:Invoke",
        "Resource": "execute-api:/*/POST/*",
        "Principal": {
          "AWS": "*"
        }
      }
    ]
  }
}

policy2.json is the same except aws:SourceIp: "10.0.0.3" is replaced with aws:SourceIp: "10.0.0.4".

Steps to Reproduce

Observe in terraform state show aws_api_gateway_rest_api.example:

    policy                       = jsonencode(
        {
            Statement = [
                {
                    Action    = "execute-api:Invoke"
                    Condition = {
                        NotIpAddress = {
                            "aws:SourceIp" = "10.0.0.3"
                        }
                    }
                    Effect    = "Deny"
                    Principal = {
                        AWS = "*"
                    }
                    Resource  = "arn:aws:execute-api:us-west-2:616138583583:sixx4k2q3g/*/POST/*"
                },
                {
                    Action    = "execute-api:Invoke"
                    Effect    = "Allow"
                    Principal = {
                        AWS = "*"
                    }
                    Resource  = "arn:aws:execute-api:us-west-2:616138583583:sixx4k2q3g/*/POST/*"
                },
            ]
            Version   = "2012-10-17"
        }
    )

Note that "aws:SourceIp" = "10.0.0.3" did not get updated.

Debug Output

N/A

Panic Output

N/A

Important Factoids

N/A

References

N/A

Would you like to implement a fix?

None

github-actions[bot] commented 4 months ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

MatthewMazaika commented 2 months ago

I spent a good bit of time bumping up against this bug - during the apply, we tracked the actual API calls to AWS and had the following 4 calls executed:

    1.  2024-09-09T20:16:57.046Z - PutRestApi
    2.  2024-09-09T20:17:12.005Z - CreateDeployment
    3.  2024-09-09T20:17:19.403Z - UpdateStage
    4.  2024-09-09T20:17:19.945Z - UpdateRestApi

The first PutRestApi properly applied the policy, but moments later, the UpdateRestApi call came in and reverted the policy to some old version.

klutzer commented 3 weeks ago

I'm facing the same issue here. Do we have any updates on that?