AWS:为什么我无法将自定义域分配给嵌套堆栈? [英] AWS: Why I am unable to assign a custom domain to the nested stack?
问题描述
我正在尝试将自定义域集成到 HTTP API
我正在使用 AWS API Gateway
和 AWS Lambda
进行开发.我正在使用 AWS SAM
模板.我有一个根堆栈和嵌套堆栈.
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.
对于这个问题,我将使用一个嵌套堆栈的代码片段.在那里,这就是我希望 URL 端点的样子
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
- 根堆栈 - api.example.com
- 嵌套堆栈 - api.example.com/nested
下面是我的代码
根堆栈
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
嵌套堆栈
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.
但是,有趣的事实是;如果我使用 AWS API GATEWAY Web 控制台,我可以立即执行此操作.
But, here is the fun fact; if i use the AWS API GATEWAY web console, I can do this in no time.
我怎样才能让它在 aws-sam
中工作?
How can I get this to work in aws-sam
?
更新
根据用户 LRutten 的建议,我为嵌套堆栈想出了以下代码.
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
这最终导致以下错误
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].
推荐答案
确实,当您在此处指定域名称时,SAM 总是会创建域.它也在文档中说明.
Indeed SAM always creates the domain when you specify it's name there. It stated in the docs as well.
要解决这个问题,您可以省略 AWS::Serverless::HttpApi
资源中的整个域配置,并编写由 SAM 自己创建的资源.所以添加一个带有
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
确保 ApiMapping 中的 Stage
属性也存在于 API 的 StageName
属性中.
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.
woops 并没有真正考虑清楚.你当然应该只有映射,而不是域名本身:P.
woops wasn't really thinking straight. You should of course only have the mapping, not the domain name itself again :P.
这篇关于AWS:为什么我无法将自定义域分配给嵌套堆栈?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!