我试图创建一个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)。
更多信息可以在这里找到。
这就是我们现在正在做的事情。我们基本上有多个堆栈共享同一个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
中创建的。
AWS::CDK::元数据
AWS::bda::F函数
AWS::IAM::角色
198个资源在apistack
中创建。
AWS::CDK::元数据
AWS::IAM::角色
AWS::ApiGateway::RestApi
AWS::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,
});