Search code examples
amazon-web-servicesaws-cloudformationaws-api-gatewayaws-serverless

AWS SAM: Stage already exists error during deployment


I'm trying to deploy a simple API Gateway integrated with a Lambda function. I'm using GitLab CICD to deploy the resource but even after trying out so many fixes, I can't seem to get it to deploy successfully. Below is the YAML template I'm using.

Resources:
  MyFunction: 
    Type: AWS::Serverless::Function 
      FunctionName : MyFunctionName
      CodeUri: MyFunctionName/
      Handler: app.lambda_handler
      Role: MyRole
      Tags: 
        env : dev
      Architectures:
        - x86_64
      Events:
        MyAPI:
          Type: Api
          Properties:
            Path: /dev
            Method: POST
            RestApiId: 
              Ref: MyAPI
      VpcConfig:
        SecurityGroupIds: <sec grp id>
        SubnetIds: <subnet id>

  MyAPI: 
    Type: AWS::Serverless::Api
    Properties:
      DefinitionBody: 
        swagger: 2.0
        info:
          title: MyAPIName
        host: "xxxxx.execute-api.ap-south-1.amazonaws.com"
        schemes:
          - https        
        basePath: /dev
        paths:
          /:
            post:
              responses: {}
              x-amazon-apigateway-integration:
                type: "aws_proxy"
                httpMethod: "POST"
                uri: "arn:aws:apigateway:ap-south-1:lambda:path/2015-03-31/functions/<MyFunction ARN>/invocations"
                responses:
                  default:
                    statusCode: "200"
                passthroughBehavior: "when_no_match"
                contentHandling: "CONVERT_TO_TEXT"      
        x-amazon-apigateway-policy:
          Version: '2012-10-17'
          Statement:
          - Effect: Deny
            Principal: "*"
            Action: execute-api:Invoke
            Resource: "*"
            Condition:
              StringNotEquals:
                aws:sourceVpce:
                - vpce-xxxxxx
          - Effect: Allow
            Principal: "*"
            Action: execute-api:Invoke
            Resource: "*"
      EndpointConfiguration:
        Type: PRIVATE
      StageName: dev

  MyAPIDeployment:  
    Type: AWS::ApiGateway::Deployment
    Properties: 
      RestApiId: 
        Ref: MyAPI
      StageName: dev

When I try to deploy the above script, the error I am receiving is: (using GitLab CI)

dev already exists in stack arn:aws:cloudformation:ap-south-1:xxxx:stack/stackname/xxxx

I checked the API GW on console and found a stage by the name Stage(from an older deployment). But no "dev". Thought that this was causing the issue, I deleted the stage and tried deploying again. But it is still giving me the same error. I have been stuck with this issue for few days now and any kind of help would be appreciated.


Solution

  • Edit

    I didn't correctly associate this issue - this is a one of possible ways: CloudFormation doesn't deploy to API gateway stages on update (it's quite complex with pure CFN, but CDK provides some constructs for easy implementation of custom resources, if it is possible I recommend to migrate your code to CDK)

    A second way, I see here is to create a lambda function, that will wait until the update is complete and then request deploy API. This lambda should be invoked by the Cloudformation template.