Aws-cdk: API Gateway not working with custom Deployment/Stage resources

Created on 3 Feb 2020  ยท  7Comments  ยท  Source: aws/aws-cdk

Hey!

I'm having a problem with API Gateway and I think it's related to CDK.
I'll try to explain my problem but I don't know if I'll make myself clear... Here it is!

Instead of letting the apigateway.RestApi to handle the deployment/stage creation, we decided to do it by our selves, according to the documentation (https://docs.aws.amazon.com/cdk/api/latest/docs/aws-apigateway-readme.html#deployments).

const api = new apigateway.RestApi(scope, 'APIGateway', {
  deploy: false,
})

const deployment = new apigateway.Deployment(
  scope, 'APIGatewayDeployment', {
    api,
  }
)
const stage = new apigateway.Stage(scope, 'APIGatewayStage', {
  deployment,
  stageName: 'v1',
})
api.deploymentStage = stage

But, after doing that, fresh deployments fail to run (it works if you already have an API deployed before this change), with a message saying we need to define Methods before creating the Deployment (which we are already doing).

 14/78 | 3:04:55 PM | CREATE_FAILED        | AWS::ApiGateway::Deployment           | APIGatewayDeployment (APIGatewayDeploymentA02B6C11C61) The REST API doesn't contain any methods (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: c33281b2-0c01-442d-bd5a-ab8463321e4c)

Following some workarounds on the internet, it says you need to add a dependsOn in the Deployment resource to depends on the Method resource (https://stackoverflow.com/questions/56944526/cloudformation-stack-errors-with-rest-api-doesnt-contain-any-methods).
It's done by default if you don't choose to create the deployment yourself.

Here is the CloudFormation template when you let the RestAPI to create the Deployment.

"APIGatewayDeployment5333B9E1a111d7f8bb710c8cdaa1c47a7c775111": {
  "Type": "AWS::ApiGateway::Deployment",
  "Properties": {
    "RestApiId": {
      "Ref": "APIGateway621108CD"
    },
    "Description": "Automatically created by the RestApi construct"
  },
  "DependsOn": [
    "APIGatewaytokenPOSTC4C3ADA9",
    "APIGatewaytoken693561AD"
  ],
  "Metadata": {
    "aws:cdk:path": "AppDev/APIGateway/Deployment/Resource"
  }
},

And here is the CloudFormation template when you create the Deployment by yourself.

"APIGatewayDeploymentA02B6C11C61": {
  "Type": "AWS::ApiGateway::Deployment",
  "Properties": {
    "RestApiId": {
      "Ref": "APIGateway621108CD"
    }
  },
  "Metadata": {
    "aws:cdk:path": "AppDev/APIGatewayDeployment/Resource"
  }
},

I also tried to use the deployment.node.addDependency but it adds more resources than the default one and cyclical reference error happens.

const userResource = api.root.addResource('user')
deployment.node.addDependency(userResource)

Here is our the template looks like:

"APIGatewayDeployment002D66E1C53": {
  "Type": "AWS::ApiGateway::Deployment",
  "Properties": {
    "RestApiId": {
      "Ref": "APIGateway621108CD"
    }
  },
  "DependsOn": [
    "APIGatewaytokenPOSTApiPermissionAppDevAPIGateway819D1111POSTtoken21BCCACA",
    "APIGatewaytokenPOSTApiPermissionTestAppDevAPIGateway819D1222POSTtoken2AC3335B",
    "APIGatewaytokenPOSTCC435DA9",
    "APIGatewaytoken690562AC"
  ],
  "Metadata": {
    "aws:cdk:path": "AppDev/APIGatewayDeployment/Resource"
  }
},

And here is the error message:

โŒ  AppDev failed: Error [ValidationError]: Circular dependency between resources: [APIGatewayDeployment002D66E1C53, APIGatewayStageCB9034D3, APIGatewaytokenPOSTApiPermissionAppDevAPIGateway819D1439POSTtoken21BC5ECA, DomainMapAppDevAPIGateway819D14392E2E7BB0, UsagePlan5ECE7D2B, UsagePlanUsagePlanKeyResourceB99C6E7C]
    at Request.extractError (/Users/someone/project/node_modules/aws-sdk/lib/protocol/query.js:50:29)
    at Request.callListeners (/Users/someone/project/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
    at Request.emit (/Users/someone/project/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/Users/someone/project/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition (/Users/someone/project/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/Users/someone/project/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /Users/someone/project/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/Users/someone/project/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/Users/someone/project/node_modules/aws-sdk/lib/request.js:685:12)
    at Request.callListeners (/Users/someone/project/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
  message: 'Circular dependency between resources: ' +
    '[APIGatewayDeployment002D66E1C53, ' +
    'APIGatewayStageCB9034D3, ' +
    'APIGatewaytokenPOSTApiPermissionAppDevAPIGateway819D1439POSTtoken21BC5ECA, ' +
    'DomainMapAppDevAPIGateway819D14392E2E7BB0, ' +
    'UsagePlan5ECE7D2B, ' +
    'UsagePlanUsagePlanKeyResourceB99C6E7C]',
  code: 'ValidationError',
  time: 2020-02-03T14:17:42.429Z,
  requestId: '4888c05e-8259-43e9-80d9-f1c086895594',
  statusCode: 400,
  retryable: false,
  retryDelay: 220.94954181556952
}
Circular dependency between resources: [APIGatewayDeployment002D66E1C53, APIGatewayStageCB9034D3, APIGatewaytokenPOSTApiPermissionAppDevAPIGateway819D1439POSTtoken21BC5ECA, DomainMapAppDevAPIGateway819D14392E2E7BB0, UsagePlan5ECE7D2B, UsagePlanUsagePlanKeyResourceB99C6E7C]
error Command failed with exit code 1.

Environment

  • CDK version: 1.18.0
  • macOS Mojave: 10.14.6
  • Typescript: v8.5.4

This is :bug: Bug Report

@aws-cdaws-apigateway bug p1

All 7 comments

Does anyone know any workaround for this issue, if it'll really require a fix?

Thanks for reporting this @celiolatorraca. I acknowledge that this is a bug on the CDK side.

The workaround is to add the following line for every instance of Method -

(deployment.node.defaultChild! as CfnResource).addDependsOn(method.node.defaultChild as CfnResource);

Sorry for this late answer!

Just to update here... The workaround works, so I'm using it while we don't have a new version of the CDK!

Thanks @nija-at for the quicky fix!!

I faced also this issue on version 1.61.1

To my understanding, when another resource is created before adding methods to the API it will throw an error.

Example, this will fail:

const api = new RestApi(this, 'api');
const resource = api.root.addResource('resource');

const lamba = new Lambda(this, 'Lambda', lambdaProps)
const integration = new LambdaIntegration(lambda);

resource.addMethod('POST', integration);

While this would pass:

const lamba = new Lambda(this, 'Lambda', lambdaProps)
const integration = new LambdaIntegration(lambda);

const api = new RestApi(this, 'api');
const resource = api.root.addResource('resource');


resource.addMethod('POST', integration);

@nija-at How does #6165 fix this issue? The issue is still there ...

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nzspambot picture nzspambot  ยท  3Comments

abelmokadem picture abelmokadem  ยท  3Comments

eladb picture eladb  ยท  3Comments

PaulMaddox picture PaulMaddox  ยท  3Comments

sudoforge picture sudoforge  ยท  3Comments