Amazon web services 部署到不同阶段时出现无服务器共享API网关错误
我使用的是无服务器版本1.29.2 我已经创建了一个初始cloudformation脚本,该脚本创建了一个API网关REST API,其他服务将使用该API网关REST API。所以这里是负责它的cloudformation脚本Amazon web services 部署到不同阶段时出现无服务器共享API网关错误,amazon-web-services,serverless,api-gateway,Amazon Web Services,Serverless,Api Gateway,我使用的是无服务器版本1.29.2 我已经创建了一个初始cloudformation脚本,该脚本创建了一个API网关REST API,其他服务将使用该API网关REST API。所以这里是负责它的cloudformation脚本 { "AWSTemplateFormatVersion":"2010-09-09", "Description":"API", "Resources":{ "APIGw":{ "Type":"AWS::ApiGateway
{
"AWSTemplateFormatVersion":"2010-09-09",
"Description":"API",
"Resources":{
"APIGw":{
"Type":"AWS::ApiGateway::RestApi",
"Properties":{
"Name":"API-GW"
}
}
},
"Outputs":{
"ApiGwRestApiId":{
"Value":{
"Ref":"APIGw"
},
"Export":{
"Name":"apigw-restApiId"
}
},
"eyesApiGwRestApiRootResourceId":{
"Value":{
"Fn::GetAtt":[
"APIGw",
"RootResourceId"
]
},
"Export":{
"Name":"apigw-rootResourceId"
}
}
}
}
下面是我试图部署的应用程序的serverless.yml
service: template-test-service
provider:
name: aws
runtime: python3.6
region: eu-central-1
stage: ${self:custom.environment.stage}
environment:
stage: ${self:custom.environment.stage}
apiGateway:
restApiId:
'Fn::ImportValue': apigw-restApiId
restApiRootResourceId:
'Fn::ImportValue': apigw-rootResourceId
当我执行sls部署--stage dev
时,一切正常,但是当我执行另一个部署到sls部署--stage prod
这个错误出现了
Another resource with the same parent already has this name
你看了吗
似乎您必须创建公共资源路径组件,这些组件都是CloudFormed对象我已经为此挣扎了一周,问题在于如何使用资源和方法构建API网关。从文件中 在AmazonAPI网关中,您构建了一个RESTAPI,作为一个称为API网关资源的可编程实体的集合。例如,您可以使用RestApi资源来表示可以包含资源实体集合的API。每个资源实体可以依次拥有一个或多个方法资源。在请求参数和主体中表示的方法定义了客户端访问公开资源的应用程序编程接口,并表示客户端提交的传入请求 当您有一个由http事件触发的函数时,Serverless CLI将为您创建所有资源/方法
functions:
GetScenesInGame:
handler: handler.hello
layers: arn:aws:lambda:eu-west-1:xxxxxxxxx:layer:pynamodb-layer:1
events:
- http:
method: GET
path: api/v1/game/{gameId}/scene
根据上面的示例,这将创建五个资源(api、v1、game、gameIdParam、scene),并最终在最终资源上添加一个GET方法
不幸的是,如果您有两个独立的堆栈(就像在microservice设置中一样),如果它们是上述方法的任何一部分,则会出现错误,具有相同父级的另一个资源已经具有此名称
本文从serverless中重点介绍了该解决方案,尽管它不是很明确,而且很容易被忽略
首先,有一个顶级cloudformation模板,用于配置所需的资源
对于要添加无服务器微服务的资源,请将该资源的id导出为堆栈中的输出变量
然后在serverless.yml文件中导入api网关引用和apigateway资源id
然后,您可以部署每个服务,而不会在api结构中出现资源名称冲突
下面的模板显示了一组顶级资源
api/v1/game/{gameId}/page
api/v1/game/{gameId}/scene
然后将页面服务附加到页面资源,并将场景服务附加到场景资源
api-gateway.yml
serverless.yml(页面服务的无服务器Cli文件)
serverless.yml(用于场景服务的无服务器Cli文件)
希望这能帮助其他人解决这个问题,如果有人有更好的解决方法,我很想知道:-)您好,欢迎使用Stack Overflow!谢谢你的编辑。你能补充更多的信息吗?如果这一联系消失,这个答案仍然不够。解释如何创建公共资源路径组件,以及公共资源路径组件是如何成为CloudFormed对象的。我希望能举一个如何设置的示例。嗨@Alex Levitt,您是否曾使用
无服务器域管理器
尝试过此方法?我上次查看它已有一段时间了,但我记得无服务器域管理器是我尝试的解决方案之一,但它似乎没有我需要的控制来避免路由冲突。
AWSTemplateFormatVersion: "2010-09-09"
Description: "S3 template for deploying S3 to be used by ACS s3 connector."
Resources:
TestApiGw:
Type: AWS::ApiGateway::RestApi
Properties:
Name: !Sub 'test-apigw-throwaway'
ApiResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref TestApiGw
ParentId: !GetAtt
- TestApiGw
- RootResourceId
PathPart: "api"
VersionResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref TestApiGw
ParentId: !Ref ApiResource
PathPart: "v1"
GameResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref TestApiGw
ParentId: !Ref VersionResource
PathPart: "game"
GameParamResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref TestApiGw
ParentId: !Ref GameResource
PathPart: "{gameId}"
SceneResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref TestApiGw
ParentId: !Ref GameParamResource
PathPart: "scene"
PageResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref TestApiGw
ParentId: !Ref GameParamResource
PathPart: "page"
Outputs:
ApiRestApiId:
Value: !Ref TestApiGw
Export:
Name: !Sub ${AWS::StackName}-TestApiId
ApiRootResourceId:
Value:
Fn::GetAtt:
- TestApiGw
- RootResourceId
Export:
Name: !Sub ${AWS::StackName}-ApiRootResourceVar
ApiSceneResourceVar:
Value: !Ref SceneResource
Export:
# variable names are global so this will need more work to make it unique across stages.
Name: !Sub ${AWS::StackName}-ApiSceneResourceVar
ApiPageResourceVar:
Value: !Ref PageResource
Export:
# variable names are global so this will need more work to make it unique across stages.
Name: !Sub ${AWS::StackName}-ApiPageResourceVar
service: scrap-page-service
provider:
name: aws
runtime: python2.7
apiGateway:
restApiId:
"Fn::ImportValue": throw-stack-1-TestApiId
restApiRootResourceId:
"Fn::ImportValue": throw-stack-1-ApiPageResourceVar
functions:
hello:
handler: handler.hello
events:
- http:
path: ""
method: get
service: scrap-scene-service
provider:
name: aws
runtime: python2.7
apiGateway:
restApiId:
"Fn::ImportValue": throw-stack-1-TestApiId
restApiRootResourceId:
"Fn::ImportValue": throw-stack-1-ApiSceneResourceVar
functions:
hello:
handler: handler.hello
events:
- http:
path: ""
method: get