【问题标题】:CloudFormation deploy Method already exists for this resource此资源已存在 CloudFormation 部署方法
【发布时间】:2021-06-12 01:06:47
【问题描述】:

我有一个创建 APIGateway 的 CloudFormation 模板,但是当我再次部署以添加 APIGateway 方法(运行更新堆栈)时,我得到:

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

我尝试向所有资源添加更新/删除策略,但这似乎不起作用:

    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain

我有一种预感,这可能是由于没有正确指定资源造成的,我的资源路径有问题吗?两个资源都是在根资源上创建的还是什么?

我的最终目标

声明两个单独的资源(具有单独的 URL)例如

https://xxx/post-note

https://xxx/deleteNote

都与 lambda 函数相关

我的模板:

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

【问题讨论】:

    标签: aws-lambda amazon-cloudformation aws-api-gateway


    【解决方案1】:

    两个cloudformation资源AWS::ApiGateway::Method指向同一个API网关资源,POST方法相同。

    我们有两种选择

    选项 1:更改其中一种方法的方法名称。

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

    选项 2:为每种方法使用不同的根资源。因此,如果我们需要两个 POST 端点 /postNote 和 /deleteNote,我们必须有两个来自根路径的独立资源,并将这些资源用于 lambdas。

    例如:

    /postNote 以 Parent 作为根资源。

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

    方法ResourceId指向!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
    

    同样我们需要添加删除资源。

      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
    

    【讨论】:

    • 感谢您的详细回答,但我正在尝试声明两个单独的资源(具有单独的 URL),例如:xxx/post-notexxx/deleteNote 我更新了我的帖子,希望能更清楚地说明这一点跨度>
    • 知道了!然后我们需要两个不同的资源,让我尝试更新答案。
    • 我更新了答案,详细说明了为每种方法创建不同的资源。
    猜你喜欢
    • 2020-01-04
    • 1970-01-01
    • 1970-01-01
    • 2019-08-21
    • 2020-03-31
    • 1970-01-01
    • 2018-08-30
    • 2017-08-03
    • 2020-09-30
    相关资源
    最近更新 更多