'AWS::ApiGateway::Method is delete in every deployment

I had a codepipeline with a cloudformation template. I'm creating a AWS::ApiGateway::Resource and AWS::ApiGateway::Method to access S3 bucket. First time it creates the method with the API. But when I push a change to the repo and it does a redeploy the method is deleted.

I can't which is the reason. Somebody has any clue! Thanks!

QrResource:
    Type: "AWS::ApiGateway::Resource"
    Properties:
      ParentId:
        Fn::GetAtt:
          - "myApi"
          - "RootResourceId"
      RestApiId: !Ref myApi
      PathPart: "qr"
  QrItemResource:
    Type: "AWS::ApiGateway::Resource"
    Properties:
      ParentId: !Ref QrResource
      RestApiId: !Ref myApi
      PathPart: "{item}"
  Qr:
    Type: "AWS::ApiGateway::Method"
    Properties:
      HttpMethod: GET
      ApiKeyRequired: false
      AuthorizationType: NONE
      RequestParameters:
        method.request.header.Content-Disposition: false
        method.request.header.Content-Type: false
        method.request.header.Accept: false
        method.request.path.item: true
      MethodResponses:
        - StatusCode: 200
          ResponseParameters:
            method.response.header.Content-Type: integration.response.header.Content-Type
            method.response.header.Content-Disposition: integration.response.header.Content-Disposition
            method.response.header.Accept-Ranges: integration.response.header.Accept-Ranges
          ResponseModels:
            "application/json": EmptyModel
        - StatusCode: 403
          ResponseModels:
            "application/json": ErrorModel
      RestApiId: !Ref myApi
      ResourceId: !Ref QrItemResource
      Integration:
        Type: AWS
        Credentials: !Ref RoleApi
        IntegrationHttpMethod: GET
        PassthroughBehavior: WHEN_NO_MATCH
        IntegrationResponses:
          - StatusCode: 200
            SelectionPattern: 200
            ContentHandling: CONVERT_TO_BINARY
            ResponseParameters:
              method.response.header.Content-Type: integration.response.header.Content-Type
              method.response.header.Accept-Ranges: "'bytes'"
              method.response.header.Content-Disposition: "'inline'"
            ResponseTemplates:
              "application/json": ""
        RequestParameters:
          integration.request.header.Content-Disposition: method.request.header.Content-Disposition
          integration.request.header.Content-Type: method.request.header.Content-Type
          integration.request.header.Accept: method.request.header.Accept
          integration.request.path.item: method.request.path.item
        Uri: arn:aws:apigateway:us-east-1:s3:path/s3-bucket/{item}


Solution 1:[1]

I had the same issue, so I opened a ticket in AWS Support. This was their answer:

Customer is using Serverless Application Model(SAM) (AWS::Serverless::Api+AWS::Serverless::Function) resources along with API Gateway CFN Resources (AWS::ApiGateway::Method) to define their API. 
This can have unpredictable situation where first can overwrite the second. We highly recommend customer to define this new resources in SAM directly under AWS::Serverless::Api as part of OpenApi. 

First, I considered this a bug since having unpredictable situations where first can overwrite the second doesn't seem like the desired behaviour for anyone.

But later on, they explained to me that the AWS::Serverless::Api creates all the necessary resources (like AWS::APIGateway::RestApi) to wire everything up.

So, if you're pushing a change where all the resources (AWS::Serverless::Api, AWS::ApiGateway::Resource and AWS::ApiGateway::Method) are being modified, Cloudformation will apply these changes in the OpenAPI definition, and everything will work as expected.

On the other hand, if you're pushing a change in the AWS::Serverless::Api (like adding an AWS::Serverless::Function attached to the AWS::Serverless::Api), Cloudformation will detect no changes on the AWS::ApiGateway::Resource and AWS::ApiGateway::Method (so the AWS::Serverless::Api OpenAPI definition will overwrite your standalone methods and path).

It seems like they have no way to check these conflicts on their side, which makes a little more sense.

So, in the end, the solution is not to mix AWS::Serverless::Api with standalone AWS::ApiGateway resources (like AWS::ApiGateway::Method and AWS::ApiGateway::Resource).

In fact, they told me they're about to update their documentation to add this recommendation. (it seems like it's not been pushed yet, but we can find the documentation history here)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Professor