Rilcon42
Rilcon42

Reputation: 9763

CloudFormation deploy Method already exists for this resource

I have a CloudFormation template that creates an APIGateway, but when I deploy again to add APIGateway methods (running update stack) I get:

Method already exists for this resource (Service: AmazonApiGateway; Status Code: 409; 
Error Code: ConflictException; Request ID: 7058deed-14e1-46bc-863d-efba23cd668b; Proxy: null)

I attempted to add an update/delete policy to all resources but that doesn't seem to have worked:

    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain

I have a hunch it may be caused by not specifying the resources correctly, do I have something wrong with my resource paths? Are both resources being created at the root resource or something?

My End Goal

To declare two separate resources (with seperate URLS) eg

https://xxx/post-note

https://xxx/deleteNote

that are both tied to lambda functions

My template:

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
# above two lines necessary to convert SAM template to CloudFormation template
Description: Resource definitions for my site
Globals: # any parameters you want available to all your resources
  Api:
    Cors:
      AllowMethods: "'OPTIONS,POST,GET'"
      AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
      AllowOrigin: "'*'"

  Function:
    Runtime: nodejs14.x # language used at runtime
    Timeout: 35 # timeout seconds for a given lambda function execution
    Environment:
      Variables: # these will be important later
        DYNAMO_TABLE: !Ref DynamoNotesTable
        DB_ENDPOINT: http://dynamodb.us-east-1.amazonaws.com
        REGION_NAME: us-east-1

Resources:
  # #############################################################################
  # # BACK END LAMBDAS
  # #############################################################################
  postNote:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::Serverless::Function
    Properties:
      Handler: backend/dynamo/postNote.postNote
      CodeUri: s3://backend/xxx
      Policies:
        - AmazonDynamoDBFullAccess

  deleteNote:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::Serverless::Function
    Properties:
      Handler: backend/dynamo/deleteNote.deleteNote
      CodeUri: s3://backend/xxx
      Policies:
        - AmazonDynamoDBFullAccess

  #############################################################################
  # api-gateway (with cognito auth)
  # https://bl.ocks.org/magnetikonline/c314952045eee8e8375b82bc7ec68e88
  #############################################################################
  apiGateway:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Description: API Gateway
      EndpointConfiguration:
        Types:
          - REGIONAL
      Name: my-api

  postNoteGatewayMethod:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::ApiGateway::Method
    Properties:
      HttpMethod: POST
      Integration:
        IntegrationHttpMethod: POST
        Type: AWS_PROXY
        Uri: !Sub
          - arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/${lambdaArn}/invocations
          - lambdaArn: !GetAtt postNote.Arn
      ResourceId: !GetAtt apiGateway.RootResourceId
      RestApiId: !Ref apiGateway

  deleteNoteGatewayMethod:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::ApiGateway::Method
    Properties:
      HttpMethod: POST
      Integration:
        IntegrationHttpMethod: POST
        Type: AWS_PROXY
        Uri: !Sub
          - arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/${lambdaArn}/invocations
          - lambdaArn: !GetAtt deleteNote.Arn
      ResourceId: !GetAtt apiGateway.RootResourceId
      RestApiId: !Ref apiGateway

  apiGatewayDeployment:
    Type: AWS::ApiGateway::Deployment
    DependsOn:
      - postNoteGatewayMethod
      - deleteNoteGatewayMethod
    Properties:
      RestApiId: !Ref apiGateway
      StageName: Prod

  lambdaApiGatewayInvoke:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !GetAtt postNote.Arn
      Principal: apigateway.amazonaws.com
      SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/Prod/POST/PATH_PART

Upvotes: 3

Views: 4763

Answers (1)

Balu Vyamajala
Balu Vyamajala

Reputation: 10333

Both cloudformation resources AWS::ApiGateway::Method pointing to same api gateway resource with same method POST.

We have two options

Option 1: Change Method Name for one of the methods.

  deleteNoteGatewayMethod:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::ApiGateway::Method
    Properties:
      HttpMethod: POST   <--- should be DELETE
      AuthorizationType: "NONE"

Option 2: have a different root resource for each methods. so, if we need two POST endpoints /postNote and /deleteNote, we must have two separate resources from the root path and use these resources for the lambdas.

Ex:

/postNote with Parent as root resource.

  noteResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      ParentId: !GetAtt apiGateway.RootResourceId
      PathPart: "postNote"
      RestApiId: !Ref apiGateway

and method ResourceId pointing to !Ref noteResource

  postNoteGatewayMethod:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::ApiGateway::Method
    DependsOn:
      - noteResource
    Properties:
      HttpMethod: POST
      AuthorizationType: NONE
      Integration:
        IntegrationHttpMethod: POST
        Type: AWS_PROXY
        Uri: !Sub
          - arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/${lambdaArn}/invocations
          - lambdaArn: !GetAtt postNote.Arn
      ResourceId: !Ref noteResource
      RestApiId: !Ref apiGateway

Similarly we need to add delete resource.

  deleteResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      ParentId: !GetAtt apiGateway.RootResourceId
      PathPart: "deleteNote"
      RestApiId: !Ref apiGateway

  deleteNoteGatewayMethod:
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Type: AWS::ApiGateway::Method
    DependsOn:
      - deleteResource
    Properties:
      HttpMethod: POST
      AuthorizationType: "NONE"
      Integration:
        IntegrationHttpMethod: POST
        Type: AWS_PROXY
        Uri: !Sub
          - arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/${lambdaArn}/invocations
          - lambdaArn: !GetAtt deleteNote.Arn
      ResourceId: !Ref deleteResource
      RestApiId: !Ref apiGateway

Upvotes: 3

Related Questions