提问者:小点点

CDKAPI网关堆栈分成2个小堆栈


我试图创建一个CDK堆栈,以创建API网关。如果我在“小块”(注释部分资源)中创建堆栈,一切都将例外,但是当我试图创建完整的堆栈时,我得到了这个异常:

 Number of resources, 224, is greater than maximum allowed, 200

因此,我尝试将我的大堆栈拆分为2个较小的堆栈,一个堆栈创建资源并创建一半的资源,另一个堆栈填充相关数据。

代码片段:


const api = new apigateway.RestApi(this, 'ApiGWEndPoint', {
  restApiName: 'API_NAME,
  deployOptions: {
    stageName: 'STAGE_NAME',
  },
  description: "MyDescription",
  endpointTypes: [apigateway.EndpointType.REGIONAL]
});

我试图创建交叉堆栈嵌套堆栈并将API数据传递给它,但到目前为止还没有运气。

我的目标是创建一个包含两个小堆栈的堆栈——它们都指向同一个API。或者,如果可能的话,为资源限制创建一个解决方法。

任何帮助将不胜感激。

更新1.10.2020:

目前,没有解决这个问题的方法,最终将API网关分成许多API网关。

更新10.24.2020:

AWS云形成现在支持增加对五个服务配额的限制——模板大小、资源、参数、映射和输出。可以在S3对象中传递的模板的最大大小现在是1MB(以前是450KB)。每个模板的最大资源数量的新限制是500(以前是200)。

更多信息可以在这里找到。


共3个答案

匿名用户

这就是我们现在正在做的事情。我们基本上有多个堆栈共享同一个API网关类(RestApi)

class MultipleStackConstruct extends Construct {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    // Main stack with shared components
    const commonStack = new CommonStack(
      scope,
      `common-stack`
    );

    // Module 1
    const moduleOneStack = new ModulOneStack(
      scope,
      `module-one`,
      {
        apiGatewayRestApi: commonStack.apiGatewayRestApi
      }
    );

    // Module 2, 3, etc.....
  }
}

该接口用于将props传递给模块堆栈:

export interface CommonProps extends cdk.StackProps {
  apiGatewayRestApi: apigw.RestApi;
}

公共模块将创建API网关对象:

export class CommonStack extends cdk.Stack {
  public readonly apiGatewayRestApi: apigw.RestApi;

  constructor(scope: cdk.Construct, id: string, props?: CommonProps) {
    super(scope, id, props);

    /******** SETUP API ********/
    this.apiGatewayRestApi = new apigw.RestApi(this, "MyAPI", {
      // Options here
    });
}

所以模块堆栈本身将是这样的:

export class ModuleOneStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: CommonProps) {
    super(scope, id, props);

    if (props && props.apiGatewayRestApi) {
      const apiGatewayRestApi = props.apiGatewayRestApi;

      // associate lambda with api gateway
    }
  }
}

在这种情况下,我们只使用一个API网关,其中包含多个Lambda,这些Lambda被分成多个堆栈,因为我们也遇到了限制问题。

AWS有一个留档,使用VPC做同样的事情:https://docs.aws.amazon.com/cdk/api/latest/docs/aws-ec2-readme.html#sharing-vpcs-between-stacks

从我的评论中复制粘贴:https://github.com/aws/aws-cdk/issues/1477#issuecomment-568652807

匿名用户

我认为你可以通过将资源分成更小的堆栈来实现你的目标。你似乎不需要跨栈引用或嵌套堆栈。

以下是一个示例(Python),其中295个资源在两个堆栈之间拆分。

#!/usr/bin/env python3

from aws_cdk import core

from lambda_api.lambda_api_stack import APIStack
from lambda_api.lambda_api_stack import LambdasStack


app = core.App()
lambdas_stack = LambdasStack(app, 'lambdasstack')
APIStack(app, 'apistack', lambdas=lambdas_stack.lambdas)


app.synth()
from aws_cdk import (
    aws_apigateway as apigateway,
    aws_lambda as _lambda,
    aws_s3 as s3,
    core
)


class LambdasStack(core.Stack):

    @property
    def lambdas(self):
        return self._lambdas

    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        self._lambdas = list()
        for i in range(48):
            handler = _lambda.Function(
                self, f'Handler_{i}',
                function_name=f'Handler_{i}',
                runtime=_lambda.Runtime.PYTHON_3_8,
                code=_lambda.Code.from_asset('resources'),
                handler='handler.main'
            )
            self._lambdas.append(handler)


class APIStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, lambdas: list,
            **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        api = apigateway.RestApi(
            self, 'lambdas-api',
            rest_api_name='Lambdas Service',
            description='This service serves lambdas.'
        )

        for i in range(len(lambdas)):
            get_lambda_integration = apigateway.LambdaIntegration(
                lambdas[i],
                request_templates={
                    'application/json':
                    '{ "statusCode": "200" }'
                }
            )
            model = api.root.add_resource(f'Resource_{i}')
            model.add_method('GET', get_lambda_integration)

对于此示例,API资源Lambda集成生成的资源最多。以下是创建的资源的概要。

97个资源是在lambdasack中创建的。

  • 1AWS::CDK::元数据
  • 48 x 2资源
    • 1AWS::bda::F函数
    • 1AWS::IAM::角色

    198个资源在apistack中创建。

    • 1AWS::CDK::元数据
    • AWS::ApiGateway::Account
    • 1AWS::IAM::角色
    • 1AWS::ApiGateway::RestApi
    • AWS::ApiGateway::De部署 AWS::ApiGateway::阶段
    • 48 x 4资源
        AWS::ApiGateway::资源 AWS::ApiGateway::方法
      • 2AWS::IAM::角色

匿名用户

只需使用属性传递数据。

这需要在提供输出变量的堆栈上定义公共属性,并创建一个扩展StackProperties并传入所需属性的接口。

结果可能如下所示:

const domain = new DomainStack(app, 'domain', {
  env: env,
  domainName: domainName,
  hostedZoneId: hostedZoneId
});

new WebsiteStack(app, 'website', {
  env: env,
  domainName: domainName,
  certificate: domain.certificate,
  hostedZone: domain.hostedZone,
});