AWS:为什么我无法为嵌套堆栈分配自定义域? [英] AWS: Why I am unable to assign a custom domain to the nested stack?
问题描述
我正在尝试将自定义域集成到 HTTP API
我正在使用 AWS API Gateway
和 AWS Lambda
进行开发.我正在使用 AWS SAM
模板.在那里我有一个根堆栈和嵌套堆栈.
对于这个问题,我将使用一个带有一个嵌套堆栈的代码段.在那里,这就是我希望 URL 端点的方式
- 根堆栈 - api.example.com
- 嵌套堆栈 - api.example.com/nested
下面是我的代码
根堆栈
AWSTemplateFormatVersion: '2010-09-09'转换:AWS::Serverless-2016-10-31说明:>aws-restapiaws-restapi 的示例 SAM 模板# 更多关于 Globals 的信息:https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst全球:功能:超时:5虚拟主机配置:安全组 ID:- sg-041f24xxxx921e8e子网 ID:- 子网-0xxxxx2d参数:Firebase 项目 ID:类型:字符串#不要在 AWS 控制台中手动创建这个域,所以它会在这里失败域名:类型:字符串默认值:api.example.com资源:AuthGatewayHttpApi:类型:AWS::Serverless::HttpApi特性:领域:域名: !Ref 域名端点配置:区域CertificateArn: arn:aws:acm:us-east-1:xxxx:certificate/xxxx-420d-xxxx-b40d-xxxx路线53:HostedZoneId:xxxxxxxxxxx验证:授权人:Firebase授权器:身份来源:$request.header.AuthorizationJwt配置:观众:- !Ref FirebaseProjectId发行人:!Sub https://securetoken.google.com/${FirebaseProjectId}DefaultAuthorizer:FirebaseAuthorizer身份验证功能:类型:AWS::Serverless::Function特性:CodeUri:aws-restapi/处理程序:source/testfile.lambdaHandler运行时:nodejs14.x事件:网关:类型:HttpApi特性:ApiId: !Ref AuthGatewayHttpApi路径:/你好方法:获取嵌套堆栈二:依赖:AuthGatewayHttpApi类型:AWS::CloudFormation::Stack特性:模板网址:nested_stack.yaml参数:FirebaseProjectId: !Ref FirebaseProjectId域名: !Ref 域名
嵌套堆栈
AWSTemplateFormatVersion: '2010-09-09'转换:AWS::Serverless-2016-10-31说明:>aws-restapiaws-restapi 的示例 SAM 模板全球:功能:超时:5虚拟主机配置:安全组 ID:- sg-xxxxxxxxxxxx子网 ID:- 子网-xxxxxxxxxxxx参数:Firebase 项目 ID:类型:字符串域名:类型:字符串资源:AuthGatewayHttpApi2:类型:AWS::Serverless::HttpApi特性:领域:域名: !Ref 域名基本路径:两个端点配置:区域CertificateArn: arn:aws:acm:us-east-1:xxxxx:certificate/xxxxx-xxxx-xxxx-xxxx-xxxx路线53:HostedZoneId:xxxxxxxxxxxxxxx验证:授权人:Firebase授权器:身份来源:$request.header.AuthorizationJwt配置:观众:- !Ref FirebaseProjectId发行人:!Sub https://securetoken.google.com/${FirebaseProjectId}DefaultAuthorizer:FirebaseAuthorizer获取所有促销功能:类型:AWS::Serverless::Function # 有关函数资源的更多信息:https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction特性:CodeUri:aws-restapi/处理程序:source/promotions/promotions-getall.getAllPromotions运行时:nodejs14.x事件:获取所有促销API事件:类型:HttpApi # 更多关于 API 事件源的信息:https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api特性:路径:/promotions/getall方法:获取ApiId: !Ref AuthGatewayHttpApi2
但是我无法让它工作,因为嵌套堆栈无法创建.以下是错误
CREATE_FAILED AWS::CloudFormation::Stack NestedStackTwo嵌入式堆栈 arn:aws:cloudformation:us-east-1 xxxxx:stack/aws-restapi-NestedStackTwo-8KBISZRAVYBX/a3fcc010-0ce4-11ec-9c90-0e8a861a6983 未成功创建:以下资源创建失败:[ApiGatewayDomainNameV234ac706a57]
我相信这是因为根堆栈创建了域,而嵌套堆栈试图重新创建它而不是重用相同的域.
但是,这是一个有趣的事实;如果我使用 AWS API GATEWAY Web 控制台,我可以立即执行此操作.
我怎样才能让它在 aws-sam
中工作?
更新
根据用户 LRutten 的建议,我想出了以下嵌套堆栈的代码.
AWSTemplateFormatVersion: '2010-09-09'转换:AWS::Serverless-2016-10-31说明:>aws-restapiaws-restapi 的示例 SAM 模板全球:功能:超时:5虚拟主机配置:安全组 ID:- sg-xxxxxx子网 ID:- 子网-xxxxx参数:Firebase 项目 ID:类型:字符串域名:类型:字符串资源:AuthGatewayHttpApi2:类型:AWS::Serverless::HttpApi特性:验证:授权人:Firebase授权器:身份来源:$request.header.AuthorizationJwt配置:观众:- !Ref FirebaseProjectId发行人:!Sub https://securetoken.google.com/${FirebaseProjectId}DefaultAuthorizer:FirebaseAuthorizer我的API映射:类型:'AWS::ApiGatewayV2::ApiMapping'特性:域名: !Ref 域名ApiId: !Ref AuthGatewayHttpApi2阶段:生产我的域名:类型:'AWS::ApiGatewayV2::DomainName'特性:域名: !Ref 域名域名配置:- 端点类型:区域CertificateArn: arn:aws:acm:us-east-1:716460586643:certificate/bac44716-420d-431b-b40d-01378f20432d获取所有促销功能:类型:AWS::Serverless::Function # 有关函数资源的更多信息:https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction特性:CodeUri:aws-restapi/处理程序:source/promotions/promotions-getall.getAllPromotions运行时:nodejs14.x事件:GetAllPromotionsAPIEvent:类型:HttpApi # 更多关于 API 事件的信息来源:https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api特性:路径:/promotions/getall方法:获取ApiId: !Ref AuthGatewayHttpApi2
最终出现以下错误
嵌入式堆栈 arn:aws:cloudformation:us-east-1:716460586643:stack/aws-restapi-NestedStackTwo-14SAYLRO1WD1D/62336020-xx-xx-a04e-x 未成功创建:未能创建以下资源:[MyDomainName, MyApiMapping].
确实,当您在那里指定域名称时,SAM 总是会创建域.它也在文档中说明.
要解决这个问题,您可以省略 AWS::Serverless::HttpApi
资源中的整个域配置,并自行编写 SAM 创建的资源.所以添加一个部分
类型:AWS::ApiGatewayV2::ApiMapping特性:ApiId:字符串ApiMappingKey:字符串域名:字符串阶段:字符串
文档>
确保 ApiMapping 中的 Stage
属性也存在于 API 的 StageName
属性中.
还有一个
类型:AWS::ApiGatewayV2::DomainName特性:域名:字符串域名配置:- 域名配置相互Tls身份验证:相互认证标签: Json
文档罢工>
手动添加这些而不需要两次定义域本身应该可以解决问题.
woops 并没有真正思考.您当然应该只有映射,而不是域名本身:P.
I am trying to integrate a custom domain to the HTTP API
I am developing with AWS API Gateway
and AWS Lambda
. I m using the AWS SAM
template. There I have a root stack and nested stacks.
For this question I will use a code piece with a one nested stack. There, this is how I want the URL end points to be
- root stack - api.example.com
- nested stack - api.example.com/nested
Below is my code
Root stack
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 5
VpcConfig:
SecurityGroupIds:
- sg-041f24xxxx921e8e
SubnetIds:
- subnet-0xxxxx2d
Parameters:
FirebaseProjectId:
Type: String
#Dont create this domain in the AWS Console manually, so it will fail here
DomainName:
Type: String
Default: api.example.com
Resources:
AuthGatewayHttpApi:
Type: AWS::Serverless::HttpApi
Properties:
Domain:
DomainName: !Ref DomainName
EndpointConfiguration: REGIONAL
CertificateArn: arn:aws:acm:us-east-1:xxxx:certificate/xxxx-420d-xxxx-b40d-xxxx
Route53:
HostedZoneId: xxxxxxxxxxx
Auth:
Authorizers:
FirebaseAuthorizer:
IdentitySource: $request.header.Authorization
JwtConfiguration:
audience:
- !Ref FirebaseProjectId
issuer: !Sub https://securetoken.google.com/${FirebaseProjectId}
DefaultAuthorizer: FirebaseAuthorizer
AuthFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: aws-restapi/
Handler: source/testfile.lambdaHandler
Runtime: nodejs14.x
Events:
Gateway:
Type: HttpApi
Properties:
ApiId: !Ref AuthGatewayHttpApi
Path: /hello
Method: get
NestedStackTwo:
DependsOn: AuthGatewayHttpApi
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: nested_stack.yaml
Parameters:
FirebaseProjectId: !Ref FirebaseProjectId
DomainName: !Ref DomainName
Nested stack
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
Globals:
Function:
Timeout: 5
VpcConfig:
SecurityGroupIds:
- sg-xxxxxxxxxxxx
SubnetIds:
- subnet-xxxxxxxxxxx
Parameters:
FirebaseProjectId:
Type: String
DomainName:
Type: String
Resources:
AuthGatewayHttpApi2:
Type: AWS::Serverless::HttpApi
Properties:
Domain:
DomainName: !Ref DomainName
BasePath: two
EndpointConfiguration: REGIONAL
CertificateArn: arn:aws:acm:us-east-1:xxxxx:certificate/xxxxx-xxxx-xxxx-xxxx-xxxx
Route53:
HostedZoneId: xxxxxxxxxxxxx
Auth:
Authorizers:
FirebaseAuthorizer:
IdentitySource: $request.header.Authorization
JwtConfiguration:
audience:
- !Ref FirebaseProjectId
issuer: !Sub https://securetoken.google.com/${FirebaseProjectId}
DefaultAuthorizer: FirebaseAuthorizer
GetAllPromotionsFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/promotions/promotions-getall.getAllPromotions
Runtime: nodejs14.x
Events:
GetAllPromotionsAPIEvent:
Type: HttpApi # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /promotions/getall
Method: get
ApiId: !Ref AuthGatewayHttpApi2
However I cant get this to work because the nested stack fails to create. Below is the error
CREATE_FAILED AWS::CloudFormation::Stack NestedStackTwo
Embedded stack arn:aws:cloudformation:us-east-1 xxxxx:stack/aws-restapi-NestedStackTwo-8KBISZRAVYBX/a3fcc010-0ce4-11ec-9c90-0e8a861a6983 was not successfully created:
The following resource(s) failed to create: [ApiGatewayDomainNameV234ac706a57]
I believe this is happening because the root stack creates the domain and the nested stack is trying to re-create it instead of reusing the same.
But, here is the fun fact; if i use the AWS API GATEWAY web console, I can do this in no time.
How can I get this to work in aws-sam
?
UPDATE
Following the advice from the user LRutten, I came up with the following code for the nested stack.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
Globals:
Function:
Timeout: 5
VpcConfig:
SecurityGroupIds:
- sg-xxxxxx
SubnetIds:
- subnet-xxxxx
Parameters:
FirebaseProjectId:
Type: String
DomainName:
Type: String
Resources:
AuthGatewayHttpApi2:
Type: AWS::Serverless::HttpApi
Properties:
Auth:
Authorizers:
FirebaseAuthorizer:
IdentitySource: $request.header.Authorization
JwtConfiguration:
audience:
- !Ref FirebaseProjectId
issuer: !Sub https://securetoken.google.com/${FirebaseProjectId}
DefaultAuthorizer: FirebaseAuthorizer
MyApiMapping:
Type: 'AWS::ApiGatewayV2::ApiMapping'
Properties:
DomainName: !Ref DomainName
ApiId: !Ref AuthGatewayHttpApi2
Stage: prod
MyDomainName:
Type: 'AWS::ApiGatewayV2::DomainName'
Properties:
DomainName: !Ref DomainName
DomainNameConfigurations:
- EndpointType: REGIONAL
CertificateArn: arn:aws:acm:us-east-1:716460586643:certificate/bac44716-420d-431b-b40d-01378f20432d
GetAllPromotionsFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/promotions/promotions-getall.getAllPromotions
Runtime: nodejs14.x
Events:
GetAllPromotionsAPIEvent:
Type: HttpApi # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /promotions/getall
Method: get
ApiId: !Ref AuthGatewayHttpApi2
This ended up with the following error
Embedded stack arn:aws:cloudformation:us-east-1:716460586643:stack/aws-restapi-NestedStackTwo-14SAYLRO1WD1D/62336020-xx-xx-a04e-x was not successfully created:
The following resource(s) failed to create: [MyDomainName, MyApiMapping].
Indeed SAM always creates the domain when you specify it's name there. It stated in the docs as well.
To get around this, you can omit the whole domain configuration in the AWS::Serverless::HttpApi
resource and write the resources created by SAM yourself. So add a section with
Type: AWS::ApiGatewayV2::ApiMapping
Properties:
ApiId: String
ApiMappingKey: String
DomainName: String
Stage: String
Make sure the Stage
property in the ApiMapping is also present in the StageName
property of the API.
And a
Type: AWS::ApiGatewayV2::DomainName
Properties:
DomainName: String
DomainNameConfigurations:
- DomainNameConfiguration
MutualTlsAuthentication:
MutualTlsAuthentication
Tags: Json
Manually adding these without having the domain itself defined twice should do the trick.
Edit: woops wasn't really thinking straight. You should of course only have the mapping, not the domain name itself again :P.
这篇关于AWS:为什么我无法为嵌套堆栈分配自定义域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!